Version 2.5.0-dev.1.0
Merge commit '33a5745c495f6a12af9d0fea2441a962ab63a540' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dac2a39..d3d7263 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,40 +6,48 @@
### Core libraries
-* As part of (Issue [36900][]), the following methods and properties across
- various core libraries, which used to declare a return type of `List<int>`,
- were updated to declare a return type of `Uint8List`:
+* **Breaking change** [#36900](https://github.com/dart-lang/sdk/issues/36900):
+ The following methods and
+ properties across various core libraries, which used to declare a return type
+ of `List<int>`, were updated to declare a return type of `Uint8List`:
- * `Utf8Codec.encode()` (and `Utf8Encoder.convert()`)
* `BytesBuilder.takeBytes()`
* `BytesBuilder.toBytes()`
+ * `Datagram.data`
* `File.readAsBytes()` (`Future<Uint8List>`)
* `File.readAsBytesSync()`
+ * `InternetAddress.rawAddress`
* `RandomAccessFile.read()` (`Future<Uint8List>`)
* `RandomAccessFile.readSync()`
- * `InternetAddress.rawAddress`
* `RawSocket.read()`
+ * `Utf8Codec.encode()` (and `Utf8Encoder.convert()`)
- In addition, the following typed lists were updated to have their `sublist()`
+ In addition, the following methods and classes were updated to return or
+ implement `Stream<Uint8List>` rather than `Stream<List<int>>`:
+
+ * `File.openRead()`
+ * `HttpRequest`
+ * `HttpClientResponse`
+
+ Finally, the following typed lists were updated to have their `sublist()`
methods declare a return type that is the same as the source list:
- * `Uint8List.sublist()` → `Uint8List`
* `Int8List.sublist()` → `Int8List`
- * `Uint8ClampedList.sublist()` → `Uint8ClampedList`
* `Int16List.sublist()` → `Int16List`
- * `Uint16List.sublist()` → `Uint16List`
* `Int32List.sublist()` → `Int32List`
- * `Uint32List.sublist()` → `Uint32List`
* `Int64List.sublist()` → `Int64List`
- * `Uint64List.sublist()` → `Uint64List`
+ * `Int32x4List.sublist()` → `Int32x4List`
* `Float32List.sublist()` → `Float32List`
* `Float64List.sublist()` → `Float64List`
* `Float32x4List.sublist()` → `Float32x4List`
- * `Int32x4List.sublist()` → `Int32x4List`
* `Float64x2List.sublist()` → `Float64x2List`
+ * `Uint8List.sublist()` → `Uint8List`
+ * `Uint8ClampedList.sublist()` → `Uint8ClampedList`
+ * `Uint16List.sublist()` → `Uint16List`
+ * `Uint32List.sublist()` → `Uint32List`
+ * `Uint64List.sublist()` → `Uint64List`
- [36900]: https://github.com/dart-lang/sdk/issues/36900
-
+
#### `dart:core`
* Update `Uri` class to support [RFC6874](https://tools.ietf.org/html/rfc6874):
@@ -52,8 +60,9 @@
#### `dart:io`
-* **Breaking Change:** The `Cookie` class's constructor's `name` and `value`
- optional positional parameters are now mandatory (Issue [37192][]). The
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192):
+ The `Cookie` class's constructor's `name` and `value`
+ optional positional parameters are now mandatory. The
signature changes from:
Cookie([String name, String value])
@@ -69,18 +78,27 @@
Since code could not previously correctly omit the parameters, this is not
really a breaking change.
-* **Breaking Change:** The `Cookie` class's `name` and `value` setters now
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192):
+ The `Cookie` class's `name` and `value` setters now
validates that the strings are made from the allowed character set and are not
- null (Issue [37192][]). The constructor already made these checks and this
+ null. The constructor already made these checks and this
fixes the loophole where the setters didn't also validate.
-[37192]: https://github.com/dart-lang/sdk/issues/37192
-
### Dart VM
### Tools
-## 2.4.0 - 2019-06-24
+#### Pub
+
+ * Clean-up invalid git repositories in cache when fetching from git.
+
+#### Linter
+
+The Linter was updated to `0.1.93`, which includes the following changes:
+
+* new lint: `avoid_print`
+
+## 2.4.0 - 2019-06-27
### Core libraries
@@ -113,28 +131,29 @@
[33327]: https://github.com/dart-lang/sdk/issues/33327
[35804]: https://github.com/dart-lang/sdk/issues/35804
-* The `HttpClientResponse` interface has been extended with the addition of a
+* **Breaking change** [#36971](https://github.com/dart-lang/sdk/issues/36971):
+ The `HttpClientResponse` interface has been extended with the addition of a
new `compressionState` getter, which specifies whether the body of a
response was compressed when it was received and whether it has been
- automatically uncompressed via `HttpClient.autoUncompress` (Issue [36971][]).
+ automatically uncompressed via `HttpClient.autoUncompress`.
As part of this change, a corresponding new enum was added to `dart:io`:
`HttpClientResponseCompressionState`.
- [36971]: https://github.com/dart-lang/sdk/issues/36971
-
- * **Breaking change**: For those implementing the `HttpClientResponse`
- interface, this is a breaking change, as implementing classes will need to
- implement the new getter.
+ For those implementing the `HttpClientResponse`
+ interface, this is a breaking change, as implementing classes will need to
+ implement the new getter.
#### `dart:async`
-* **Breaking change:** The `await for` allowed `null` as a stream due to a bug
+* **Breaking change** [#36382](https://github.com/dart-lang/sdk/issues/36382):
+ The `await for` allowed `null` as a stream due to a bug
in `StreamIterator` class. This bug has now been fixed.
#### `dart:core`
-* **Breaking change:** The `RegExp` interface has been extended with two new
+* **Breaking change** [#36171](https://github.com/dart-lang/sdk/issues/36171):
+ The `RegExp` interface has been extended with two new
constructor named parameters:
* `unicode:` (`bool`, default: `false`), for Unicode patterns
@@ -157,8 +176,9 @@
### Language
-* **Breaking change:** Covariance of type variables used in super-interfaces
- is now enforced (issue [35097][]). For example, the following code was
+* **Breaking change** [#35097](https://github.com/dart-lang/sdk/issues/35097):
+ Covariance of type variables used in super-interfaces
+ is now enforced. For example, the following code was
previously accepted and will now be rejected:
```dart
@@ -169,8 +189,6 @@
* The identifier `async` can now be used in asynchronous and generator
functions.
-[35097]: https://github.com/dart-lang/sdk/issues/35097
-
### Dart for the Web
#### Dart Dev Compiler (DDC)
diff --git a/DEPS b/DEPS
index e7731b9..3cbb976 100644
--- a/DEPS
+++ b/DEPS
@@ -85,7 +85,7 @@
"fixnum_tag": "0.10.9",
"glob_tag": "1.1.7",
"html_tag" : "0.14.0+1",
- "http_io_rev": "773f4bc73ef572e2c37e879b065c3b406d75e8fd",
+ "http_io_rev": "0b05781c273a040ef521b5f7771dbc0356305872",
"http_multi_server_tag" : "2.0.5",
"http_parser_tag" : "3.1.3",
"http_retry_tag": "0.1.1",
@@ -96,7 +96,7 @@
"intl_tag": "0.15.7",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.91",
+ "linter_tag": "0.1.93",
"logging_tag": "0.11.3+2",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_tag": "2.0.3",
@@ -109,14 +109,14 @@
"package_config_tag": "1.0.5",
"package_resolver_tag": "1.0.10",
"path_tag": "1.6.2",
- "pedantic_tag": "v1.7.0",
+ "pedantic_tag": "v1.8.0",
"ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
"pool_tag": "1.3.6",
"protobuf_rev": "7d34c9e4e552a4f66acce32e4344ae27756a1949",
- "pub_rev": "ecd5b413271f2699f8cd9e23aa4eebb5030c964f",
+ "pub_rev": "df0f72daaa724e29ed6075e0fb5549a6d6dc5daf",
"pub_semver_tag": "1.4.2",
"quiver-dart_tag": "2.0.0+1",
- "resource_rev": "2.1.5",
+ "resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
"root_certificates_rev": "16ef64be64c7dfdff2b9f4b910726e635ccc519e",
"shelf_static_rev": "v0.2.8",
"shelf_packages_handler_tag": "1.0.4",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 520d015..0a39483 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -17,13 +17,15 @@
def _CheckFormat(input_api, identification, extension, windows,
- hasFormatErrors):
+ hasFormatErrors, should_skip = lambda path : False):
local_root = input_api.change.RepositoryRoot()
upstream = input_api.change._upstream
unformatted_files = []
for git_file in input_api.AffectedTextFiles():
if git_file.LocalPath().startswith("pkg/front_end/testcases/"):
continue
+ if should_skip(git_file.LocalPath()):
+ continue
filename = git_file.AbsoluteLocalPath()
if filename.endswith(extension) and hasFormatErrors(filename=filename):
old_version_has_errors = False
@@ -147,8 +149,12 @@
process.communicate(input=contents)
return process.returncode != 0
+ def should_skip(path):
+ return (path.startswith("pkg/status_file/test/data/")
+ or path.startswith("pkg/front_end/"))
+
unformatted_files = _CheckFormat(input_api, "status file", ".status",
- windows, HasFormatErrors)
+ windows, HasFormatErrors, should_skip)
if unformatted_files:
normalize = os.path.join(local_root, 'pkg', 'status_file', 'bin',
diff --git a/README.md b/README.md
index 195667d..288dac5 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@
[repo]: https://github.com/dart-lang/sdk
[lang]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html
[tools]: https://www.dartlang.org/tools/
-[codelab]: https://www.dartlang.org/codelabs/darrrt/
+[codelab]: https://dart.dev/codelabs
[dartbug]: http://dartbug.com
[contrib]: https://github.com/dart-lang/sdk/wiki/Contributing
[pubsite]: https://pub.dev
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index 9fb946f..9a3fb87 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -263,7 +263,7 @@
// http://crbug.com/380554
"deadlock:g_type_add_interface_static\n"
-// http:://crbug.com/386385
+// http://crbug.com/386385
"race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"
// http://crbug.com/388730
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a1be95e..f9b7421 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -121,6 +121,7 @@
}
logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}');
return inputRaw
+ .cast<List<int>>()
.transform(systemEncoding.decoder)
.transform(new LineSplitter())
.transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap));
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index 9326583..1705c38 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -111,6 +111,20 @@
_DartUnitFoldingComputerVisitor(this._computer);
@override
+ void visitAssertInitializer(AssertInitializer node) {
+ _computer._addRegion(node.leftParenthesis.end, node.rightParenthesis.offset,
+ FoldingKind.INVOCATION);
+ super.visitAssertInitializer(node);
+ }
+
+ @override
+ void visitAssertStatement(AssertStatement node) {
+ _computer._addRegion(node.leftParenthesis.end, node.rightParenthesis.offset,
+ FoldingKind.INVOCATION);
+ super.visitAssertStatement(node);
+ }
+
+ @override
void visitBlockFunctionBody(BlockFunctionBody node) {
_computer._addRegion(node.block.leftBracket.end,
node.block.rightBracket.offset, FoldingKind.FUNCTION_BODY);
@@ -147,6 +161,14 @@
}
@override
+ void visitExtensionDeclaration(ExtensionDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ _computer._addRegion(
+ node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
+ super.visitExtensionDeclaration(node);
+ }
+
+ @override
void visitFieldDeclaration(FieldDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
super.visitFieldDeclaration(node);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index a0e1d15..6754fbb 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -122,6 +122,8 @@
ErrorOr<void> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
+ server.instrumentationService
+ .logInfo('Ignoring ${message.method} message while initializing');
return success();
}
return error(
@@ -142,6 +144,8 @@
FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
+ server.instrumentationService
+ .logInfo('Ignoring ${message.method} message while uninitialized');
return success();
}
return error(ErrorCodes.ServerNotInitialized,
@@ -159,6 +163,8 @@
FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
// Silently drop non-requests.
if (message is! RequestMessage) {
+ server.instrumentationService
+ .logInfo('Ignoring ${message.method} message while shutting down');
return success();
}
return error(ErrorCodes.InvalidRequest,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index 46ab686..aff08f1 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -118,7 +118,6 @@
final doc = params.textDocument;
final path = pathOfDocItem(doc);
return path.mapResult((path) {
- server.addPriorityFile(path);
// We don't get a VersionedTextDocumentIdentifier with a didOpen but we
// do get the necessary info to create one.
server.documentVersions[path] = new VersionedTextDocumentIdentifier(
@@ -161,6 +160,8 @@
}
}
+ server.addPriorityFile(path);
+
return success();
});
}
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 0588482..c24de75 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
@@ -234,7 +234,7 @@
_addLocalSuggestion_includeTypeNameSuggestions(
declaration.documentationComment,
declaration.name,
- declaration.functionType.returnType,
+ declaration.functionType?.returnType,
protocol.ElementKind.FUNCTION_TYPE_ALIAS,
isAbstract: true,
isDeprecated: isDeprecated(declaration));
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index e46f525..52641ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -232,4 +232,6 @@
'dart.assist.surround.tryFinally', 29, "Surround with 'try-finally'");
static const SURROUND_WITH_WHILE = const AssistKind(
'dart.assist.surround.while', 24, "Surround with 'while'");
+ static const USE_CURLY_BRACES =
+ const AssistKind('USE_CURLY_BRACES', 30, "Use curly braces");
}
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 b465c69..32ec6cd 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -149,6 +149,7 @@
await _addProposal_splitAndCondition();
await _addProposal_splitVariableDeclaration();
await _addProposal_surroundWith();
+ await _addProposal_useCurlyBraces();
if (experimentStatus.control_flow_collections) {
await _addProposal_convertConditionalExpressionToIfElement();
@@ -971,7 +972,8 @@
return;
}
ConstructorElement element = creation.staticElement;
- if (element.name != 'fromIterable' ||
+ if (element == null ||
+ element.name != 'fromIterable' ||
element.enclosingElement != typeProvider.mapType.element) {
_coverageMarker();
return;
@@ -3748,6 +3750,12 @@
selectedStatements.add(selectedNode);
}
}
+ // we want only statements in blocks
+ for (var statement in selectedStatements) {
+ if (statement.parent is! Block) {
+ return;
+ }
+ }
// we want only statements
if (selectedStatements.isEmpty ||
selectedStatements.length != selectedNodes.length) {
@@ -3940,6 +3948,132 @@
}
}
+ Future<void> _addProposal_useCurlyBraces() async {
+ Future<void> doStatement(DoStatement node) async {
+ var body = node.body;
+ if (body is Block) return;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.doKeyword, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleReplacement(
+ range.endStart(body, node.whileKeyword),
+ '$eol$prefix} ',
+ );
+ });
+
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+ }
+
+ Future<void> forStatement(ForStatement node) async {
+ var body = node.body;
+ if (body is Block) return;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(body.end, '$eol$prefix}');
+ });
+
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+ }
+
+ Future<void> ifStatement(IfStatement node, Statement thenOrElse) async {
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (builder) {
+ var thenStatement = node.thenStatement;
+ if (thenStatement is! Block &&
+ (thenOrElse == null || thenOrElse == thenStatement)) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, thenStatement),
+ ' {$eol$indent',
+ );
+ if (node.elseKeyword != null) {
+ builder.addSimpleReplacement(
+ range.endStart(thenStatement, node.elseKeyword),
+ '$eol$prefix} ',
+ );
+ } else {
+ builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
+ }
+ }
+
+ var elseStatement = node.elseStatement;
+ if (elseStatement != null &&
+ elseStatement is! Block &&
+ (thenOrElse == null || thenOrElse == elseStatement)) {
+ builder.addSimpleReplacement(
+ range.endStart(node.elseKeyword, elseStatement),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
+ }
+ });
+
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+ }
+
+ Future<void> whileStatement(WhileStatement node) async {
+ var body = node.body;
+ if (body is Block) return;
+
+ var prefix = utils.getLinePrefix(node.offset);
+ var indent = prefix + utils.getIndent(1);
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.endStart(node.rightParenthesis, body),
+ ' {$eol$indent',
+ );
+ builder.addSimpleInsertion(body.end, '$eol$prefix}');
+ });
+
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+ }
+
+ var statement = this.node.thisOrAncestorOfType<Statement>();
+ var parent = statement?.parent;
+
+ if (statement is DoStatement) {
+ return doStatement(statement);
+ } else if (parent is DoStatement) {
+ return doStatement(parent);
+ } else if (statement is ForStatement) {
+ return forStatement(statement);
+ } else if (parent is ForStatement) {
+ return forStatement(parent);
+ } else if (statement is IfStatement) {
+ if (statement.elseKeyword != null &&
+ range.token(statement.elseKeyword).contains(selectionOffset)) {
+ return ifStatement(statement, statement.elseStatement);
+ } else {
+ return ifStatement(statement, null);
+ }
+ } else if (parent is IfStatement) {
+ return ifStatement(parent, statement);
+ } else if (statement is WhileStatement) {
+ return whileStatement(statement);
+ } else if (parent is WhileStatement) {
+ return whileStatement(parent);
+ }
+ }
+
/**
* Return `true` if all of the parameters in the given list of [parameters]
* have an explicit type annotation.
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 dc43fd4..616949d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -3276,7 +3276,7 @@
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addSimpleReplacement(
- range.token((node as DefaultFormalParameter).separator), '=');
+ range.token((node as DefaultFormalParameter).separator), ' =');
});
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_COLON_WITH_EQUALS);
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index f850b80..1886f88 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -381,7 +381,7 @@
hashCode: (Token t) => t.lexeme.hashCode);
expr.accept(new _TokenLocalElementVisitor(map));
// map and join tokens
- return tokens.map((Token token) {
+ var result = tokens.map((Token token) {
String tokenString = token.lexeme;
// append token's Element id
Element element = map[token];
@@ -394,6 +394,7 @@
// done
return tokenString;
}).join(_TOKEN_SEPARATOR);
+ return result + _TOKEN_SEPARATOR;
}
/**
@@ -693,7 +694,7 @@
int endTokenIndex =
countMatches(nodeSource.substring(0, lastIndex), _TOKEN_SEPARATOR);
Token startToken = nodeTokens[startTokenIndex];
- Token endToken = nodeTokens[endTokenIndex];
+ Token endToken = nodeTokens[endTokenIndex - 1];
// add occurrence range
int start = nodeOffset + startToken.offset;
int end = nodeOffset + endToken.end;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 164d553..8bb80c3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -69,21 +69,49 @@
@override
Future<SourceChange> createChange() async {
- var changeBuilder = new DartChangeBuilder(driver.currentSession);
- final element = resolvedUnit.unit.declaredElement;
+ final DartChangeBuilder changeBuilder =
+ new DartChangeBuilder(driver.currentSession);
+ final CompilationUnitElement element = resolvedUnit.unit.declaredElement;
if (element == null) {
return changeBuilder.sourceChange;
}
- final library = element.library;
+ final LibraryElement libraryElement = element.library;
// If this element is a library, update outgoing references inside the file.
- if (element == library.definingCompilationUnit) {
- await changeBuilder.addFileEdit(library.source.fullName, (builder) {
- final oldDir = pathContext.dirname(oldFile);
- final newDir = pathContext.dirname(newFile);
- _updateUriReferences(builder, library.imports, oldDir, newDir);
- _updateUriReferences(builder, library.exports, oldDir, newDir);
- _updateUriReferences(builder, library.parts, oldDir, newDir);
+ if (element == libraryElement.definingCompilationUnit) {
+ // Handle part-of directives in this library
+ final ResolvedLibraryResult libraryResult = await driver.currentSession
+ .getResolvedLibraryByElement(libraryElement);
+ for (ResolvedUnitResult result in libraryResult.units) {
+ if (result.isPart) {
+ Iterable<PartOfDirective> partOfs = result.unit.directives
+ .whereType<PartOfDirective>()
+ .where(
+ (po) => po.uri != null && _isRelativeUri(po.uri.stringValue));
+ if (partOfs.isNotEmpty) {
+ await changeBuilder.addFileEdit(
+ result.unit.declaredElement.source.fullName, (builder) {
+ partOfs.forEach((po) {
+ final oldDir = pathContext.dirname(oldFile);
+ final newDir = pathContext.dirname(newFile);
+ String newLocation =
+ pathContext.join(newDir, pathos.basename(newFile));
+ String newUri = _getRelativeUri(newLocation, oldDir);
+ builder.addSimpleReplacement(
+ new SourceRange(po.uri.offset, po.uri.length), "'$newUri'");
+ });
+ });
+ }
+ }
+ }
+
+ await changeBuilder.addFileEdit(libraryElement.source.fullName,
+ (builder) {
+ final String oldDir = pathContext.dirname(oldFile);
+ final String newDir = pathContext.dirname(newFile);
+ _updateUriReferences(builder, libraryElement.imports, oldDir, newDir);
+ _updateUriReferences(builder, libraryElement.exports, oldDir, newDir);
+ _updateUriReferences(builder, libraryElement.parts, oldDir, newDir);
});
} else {
// Otherwise, we need to update any relative part-of references.
diff --git a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart b/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
index 6005964..baa3443 100644
--- a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
+++ b/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
@@ -31,7 +31,7 @@
HttpClientRequest request = await client
.getUrl(Uri.parse('http://localhost:${result.port}/status'));
HttpClientResponse response = await request.close();
- String responseBody = await utf8.decodeStream(response);
+ String responseBody = await utf8.decodeStream(response.cast<List<int>>());
expect(responseBody, contains('<title>Analysis Server</title>'));
}
}
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 0b90316..0b73ad4 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -34,7 +34,7 @@
HttpClientRequest request = await client
.getUrl(Uri.parse('http://localhost:${server.port}/status'));
final response = await request.close();
- final responseBody = await utf8.decodeStream(response);
+ final responseBody = await utf8.decodeStream(response.cast<List<int>>());
expect(responseBody, contains('<title>Analysis Server</title>'));
}
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 7b147df..648b7ed 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -93,6 +93,14 @@
await openFile(nestedFileUri, '');
expect(server.contextManager.includedPaths, equals([projectFolderPath]));
+ // Ensure the file was cached in each driver. This happens as a result of
+ // adding to priority files, but if that's done before the file is in an
+ // analysis root it will not occur.
+ // https://github.com/dart-lang/sdk/issues/37338
+ server.driverMap.values.forEach((driver) {
+ expect(driver.getCachedResult(nestedFilePath), isNotNull);
+ });
+
// Closing the file should remove it.
await closeFile(nestedFileUri);
expect(server.contextManager.includedPaths, equals([]));
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 07e7073..b2e9543 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -180,6 +180,7 @@
engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
engine.ElementKind.ERROR: ElementKind.UNKNOWN,
engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
+ engine.ElementKind.EXTENSION: ElementKind.UNKNOWN,
engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
engine.ElementKind.NAME: ElementKind.UNKNOWN,
@@ -258,9 +259,6 @@
String correction = null;
@override
- bool isStaticOnly;
-
- @override
int length;
MockAnalysisError(
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 4fbe052..b726924 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
@@ -2921,6 +2921,17 @@
assertSuggestFunctionTypeAlias('F', 'void');
}
+ test_functionTypeAlias_genericTypeAlias_incomplete() async {
+ addTestSource(r'''
+typedef F = int;
+main() {
+ ^
+}
+''');
+ await computeSuggestions();
+ assertSuggestFunctionTypeAlias('F', 'dynamic');
+ }
+
test_functionTypeAlias_old() async {
addTestSource(r'''
typedef void F();
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 157d574..5725680 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -734,6 +734,36 @@
expect(refactoring.isAvailable(), isTrue);
}
+ test_occurrences_differentName_samePrefix() async {
+ await indexTestUnit('''
+void main(A a) {
+ if (a.foo != 1) {
+ } else if (a.foo2 != 2) {
+ }
+}
+
+class A {
+ int foo;
+ int foo2;
+}
+''');
+ _createRefactoringWithSuffix('a.foo', ' != 1');
+ // apply refactoring
+ await _assertSuccessfulRefactoring('''
+void main(A a) {
+ var res = a.foo;
+ if (res != 1) {
+ } else if (a.foo2 != 2) {
+ }
+}
+
+class A {
+ int foo;
+ int foo2;
+}
+''');
+ }
+
test_occurrences_differentVariable() async {
await indexTestUnit('''
main() {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 6f6fe1f..69260ef 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -345,6 +345,98 @@
''');
}
+ test_renaming_part_that_uses_uri_in_part_of_2() async {
+ // If the file is a part in a library, and the part-of directive uses a URI
+ // rather than a library name, that will need updating too (if the relative
+ // path to the parent changes).
+ String pathA = convertPath('/home/test/000/1111/a.dart');
+ testFile = convertPath('/home/test/000/1111/test.dart');
+ addSource(pathA, '''
+part of 'test.dart';
+''');
+ await resolveTestUnit('''
+part 'a.dart';
+''');
+ // perform refactoring
+ _createRefactoring('/home/test/000/1111/22/test.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+part of '22/test.dart';
+''');
+ assertFileChangeResult(testFile, '''
+part '../a.dart';
+''');
+ }
+
+ test_renaming_part_that_uses_uri_in_part_of_3() async {
+ // If the file is a part in a library, and the part-of directive uses a URI
+ // rather than a library name, that will need updating too (if the relative
+ // path to the parent changes).
+ String pathA = convertPath('/home/test/000/1111/a.dart');
+ testFile = convertPath('/home/test/000/1111/test.dart');
+ addSource(pathA, '''
+part of 'test.dart';
+''');
+ await resolveTestUnit('''
+part 'a.dart';
+''');
+ // perform refactoring
+ _createRefactoring('/home/test/000/1111/test2.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+part of 'test2.dart';
+''');
+ assertFileChangeResult(testFile, '''
+part 'a.dart';
+''');
+ }
+
+ test_renaming_part_that_uses_uri_in_part_of_4() async {
+ // If the file is a part in a library, and the part-of directive uses a URI
+ // rather than a library name, that will need updating too (if the relative
+ // path to the parent changes).
+ String pathA = convertPath('/home/test/000/1111/a.dart');
+ testFile = convertPath('/home/test/000/1111/test.dart');
+ addSource(pathA, '''
+part 'test.dart';
+''');
+ await resolveTestUnit('''
+part of 'a.dart';
+''');
+ // perform refactoring
+ _createRefactoring('/home/test/000/1111/22/test.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+part '22/test.dart';
+''');
+ assertFileChangeResult(testFile, '''
+part of '../a.dart';
+''');
+ }
+
+ test_renaming_part_that_uses_uri_in_part_of_5() async {
+ // If the file is a part in a library, and the part-of directive uses a URI
+ // rather than a library name, that will need updating too (if the relative
+ // path to the parent changes).
+ String pathA = convertPath('/home/test/000/1111/a.dart');
+ testFile = convertPath('/home/test/000/1111/test.dart');
+ addSource(pathA, '''
+part 'test.dart';
+''');
+ await resolveTestUnit('''
+part of 'a.dart';
+''');
+ // perform refactoring
+ _createRefactoring('/home/test/000/1111/test2.dart');
+ await _assertSuccessfulRefactoring();
+ assertFileChangeResult(pathA, '''
+part 'test2.dart';
+''');
+ assertFileChangeResult(testFile, '''
+part of 'a.dart';
+''');
+ }
+
Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
{String expectedMessage}) async {
RefactoringStatus status = await refactoring.checkAllConditions();
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index 3f2d2ae..c4a5fff 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -78,6 +78,32 @@
_compareRegions(regions, content);
}
+ test_assertInitializer() async {
+ String content = '''
+class C {/*1:INC*/
+ C() : assert(/*2:INC*/
+ true,
+ ''
+ /*2:INC:INVOCATION*/);
+/*1:INC:CLASS_BODY*/}
+''';
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
+ test_assertStatement() async {
+ String content = '''
+main() {/*1:INC*/
+ assert(/*2:INC*/
+ true,
+ ''
+ /*2:INC:INVOCATION*/);
+/*1:INC:FUNCTION_BODY*/}
+''';
+ final regions = await _computeRegions(content);
+ _compareRegions(regions, content);
+ }
+
test_class() async {
String content = """
// Content before
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
index 597c353..0a53680 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -187,4 +187,14 @@
}
''');
}
+
+ test_undefinedConstructor() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+f() {
+ return new Unde/*caret*/fined();
+}
+''');
+ await assertNoAssist();
+ }
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
index 52f5125..365995d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
@@ -19,6 +19,18 @@
@override
AssistKind get kind => DartAssistKind.SURROUND_WITH_BLOCK;
+ test_notStatementInBlock() async {
+ await resolveTestUnit('''
+main() {
+ while (true)
+// start
+ print(0);
+// end
+}
+''');
+ await assertNoAssist();
+ }
+
test_twoStatements() async {
await resolveTestUnit('''
main() {
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 7a7f079..b26ffb7 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
@@ -78,6 +78,7 @@
import 'surround_with_try_catch_test.dart' as surround_with_try_catch;
import 'surround_with_try_finally_test.dart' as surround_with_try_finally;
import 'surround_with_while_test.dart' as surround_with_while;
+import 'use_curly_braces_test.dart' as use_curly_braces;
main() {
defineReflectiveSuite(() {
@@ -147,5 +148,6 @@
surround_with_try_catch.main();
surround_with_try_finally.main();
surround_with_while.main();
+ use_curly_braces.main();
}, name: 'assist');
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
new file mode 100644
index 0000000..f3e6589
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
@@ -0,0 +1,443 @@
+// 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(UseCurlyBracesTest);
+ });
+}
+
+@reflectiveTest
+class UseCurlyBracesTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.USE_CURLY_BRACES;
+
+ test_do_block() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/do {
+ print(0);
+ } while (true);
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_do_body_middle() async {
+ await resolveTestUnit('''
+main() {
+ do print/*caret*/(0); while (true);
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_do_body_start() async {
+ await resolveTestUnit('''
+main() {
+ do /*caret*/print(0); while (true);
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_do_condition() async {
+ await resolveTestUnit('''
+main() {
+ do print(0); while (/*caret*/true);
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_do_end() async {
+ await resolveTestUnit('''
+main() {
+ do print(0); while (true);/*caret*/
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_do_keyword_do() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/do print(0); while (true);
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_do_keyword_while() async {
+ await resolveTestUnit('''
+main() {
+ do print(0); /*caret*/while (true);
+}
+''');
+ await assertHasAssist('''
+main() {
+ do {
+ print(0);
+ } while (true);
+}
+''');
+ }
+
+ test_for_body_end() async {
+ await resolveTestUnit('''
+main() {
+ for (;;) print(0);/*caret*/
+}
+''');
+ await assertHasAssist('''
+main() {
+ for (;;) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_for_body_middle() async {
+ await resolveTestUnit('''
+main() {
+ for (;;) print/*caret*/(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ for (;;) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_for_body_start() async {
+ await resolveTestUnit('''
+main() {
+ for (;;) /*caret*/print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ for (;;) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_for_condition() async {
+ await resolveTestUnit('''
+main() {
+ for (/*caret*/;;) print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ for (;;) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_for_keyword() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/for (;;) print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ for (;;) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_for_keyword_block() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/for (;;) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_if_else_keyword() async {
+ await resolveTestUnit('''
+main(int a) {
+ if (a == 0)
+ print(0);
+ /*caret*/else print(1);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0)
+ print(0);
+ else {
+ print(1);
+ }
+}
+''');
+ }
+
+ test_if_else_statement() async {
+ await resolveTestUnit('''
+main(int a) {
+ if (a == 0)
+ print(0);
+ else /*caret*/print(1);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0)
+ print(0);
+ else {
+ print(1);
+ }
+}
+''');
+ }
+
+ test_if_keyword_blockBoth() async {
+ await resolveTestUnit('''
+main(int a) {
+ /*caret*/if (a == 0) {
+ print(0);
+ } else {
+ print(1);
+ }
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_if_keyword_blockElse() async {
+ await resolveTestUnit('''
+main(int a) {
+ /*caret*/if (a == 0) print(0);
+ else {
+ print(1);
+ }
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0) {
+ print(0);
+ } else {
+ print(1);
+ }
+}
+''');
+ }
+
+ test_if_keyword_blockThen() async {
+ await resolveTestUnit('''
+main(int a) {
+ /*caret*/if (a == 0) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_if_keyword_withElse() async {
+ await resolveTestUnit('''
+main(int a) {
+ /*caret*/if (a == 0)
+ print(0);
+ else print(1);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0) {
+ print(0);
+ } else {
+ print(1);
+ }
+}
+''');
+ }
+
+ test_if_keyword_withoutElse() async {
+ await resolveTestUnit('''
+main(int a) {
+ /*caret*/if (a == 0)
+ print(0);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_if_then_withElse() async {
+ await resolveTestUnit('''
+main(int a) {
+ if (a == 0)
+ /*caret*/print(0);
+ else print(1);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0) {
+ print(0);
+ } else print(1);
+}
+''');
+ }
+
+ test_if_then_withoutElse() async {
+ await resolveTestUnit('''
+main(int a) {
+ if (a == 0) /*caret*/print(0);
+}
+''');
+ await assertHasAssist('''
+main(int a) {
+ if (a == 0) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_body_end() async {
+ await resolveTestUnit('''
+main() {
+ while (true) print(0);/*caret*/
+}
+''');
+ await assertHasAssist('''
+main() {
+ while (true) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_body_middle() async {
+ await resolveTestUnit('''
+main() {
+ while (true) print/*caret*/(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ while (true) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_body_start() async {
+ await resolveTestUnit('''
+main() {
+ while (true) /*caret*/print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ while (true) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_condition() async {
+ await resolveTestUnit('''
+main() {
+ while (/*caret*/true) print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ while (true) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_keyword() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/while (true) print(0);
+}
+''');
+ await assertHasAssist('''
+main() {
+ while (true) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_while_keyword_block() async {
+ await resolveTestUnit('''
+main() {
+ /*caret*/while (true) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
index 375a662..85e0bb6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
@@ -32,7 +32,7 @@
await assertHasFix('''
void f1({int a}) { }
-f1({a/*LINT*/= 1}) => null;
+f1({a/*LINT*/ = 1}) => null;
''');
}
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f0d1b34a..0f4bb38 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,32 @@
-## 0.36.4-dev (not yet published)
+## 0.37.0
+* Removed deprecated getter `DartType.isUndefined`.
+* Removed deprecated class `SdkLibrariesReader`.
+* Removed deprecated method `InstanceCreationExpressionImpl.canBeConst`.
+* The `AstFactory.compilationUnit` method now uses named parameters. Clients
+ that prepared for this change by switching to `AstFactory.compilationUnit2`
+ should now switch back to `AstFactory.compilationUnit`.
+* Removed `AstNode.getAncestor`. Please use `AstNode.thisOrAncestorMatching` or
+ `AstNode.thisOrAncestorOfType`.
+* Removed deprecated getter `TypeSystem.isStrong`, and its override
+ `Dart2TypeSystem.isStrong`.
+* Removed the deprecated getter `AnalysisError.isStaticOnly` and the deprecated
+ setters `AnalysisError.isStaticOnly` and `AnalysisError.offset`.
+* Removed the `abstract` setter in `ClassElementImpl`, `EnumElementImpl`,
+ `MethodElementImpl`, and `PropertyAccessorElementImpl`. `isAbstract` should
+ be used instead.
+* Removed methods `AstVisitor.ForStatement2`, `ListLiteral.elements2`,
+ `SetOrMapLiteral.elements2`, `AstFactory.forStatement2`, and
+ `NodeLintRegistry.addForStatement2`, as well as class `ForStatement2`. Use
+ the variants with out the "2" suffix instead.
+* Changed the signature and behavior of `parseFile` to match `parseFile2`.
+ Clients that switched to using `parseFile2` when `parseFile` was deprecated
+ should now switch back to `parseFile`.
+* Removed Parser setters `enableControlFlowCollections`, `enableNonNullable`,
+ `enableSpreadCollections`, and `enableTripleShift`, and the method
+ `configureFeatures`. Made the `featureSet` parameter of the Parser
+ constructor a required parameter.
+
+## 0.36.4
* Deprecated the `isNonNullableUnit` parameter of the `TypeResolverVisitor`
constructor. TypeResolverVisitor should now be configured using the
`featureSet` parameter.
@@ -21,6 +49,16 @@
* Changed the return type of `ClassTypeAlias.declaredElement` to `ClassElement`.
There is no functional change; it has always returned an instance of
`ClassElement`.
+* Deprecated `parseFile`. Please use `parseFile2` instead--in addition to
+ supporting the same `featureSet` and `throwIfDiagnostics` parameters as
+ `parseString`, it is much more efficient than `parseFile`.
+* Added more specific deprecation notices to `package:analyzer/analyzer.dart` to
+ direct clients to suitable replacements.
+* Deprecated the enable flags `bogus-disabled` and `bogus-enabled`. Clients
+ should not be relying on the presence of these flags.
+* Deprecated the constructor parameter
+ ConstantEvaluationEngine.forAnalysisDriver, which no longer has any effect.
+* Deprecated ElementImpl.RIGHT_ARROW.
## 0.36.3
* Deprecated `AstFactory.compilationUnit`. In a future analyzer release, this
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 0e8a271..3d473b7 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -39,7 +39,14 @@
/// [suppressErrors] is `true`, in which case any errors are discarded.
///
/// If [parseFunctionBodies] is [false] then only function signatures will be
-/// parsed.
+/// parsed. (Currently broken; function bodies are always parsed).
+///
+/// Deprecated - please use the `parseString` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseString` does not support the `parseFunctionBodies` option;
+/// callers that don't require function bodies should simply ignore them.
+@Deprecated('Please use parseString instead')
CompilationUnit parseCompilationUnit(String contents,
{String name,
bool suppressErrors: false,
@@ -58,7 +65,14 @@
/// [suppressErrors] is `true`, in which case any errors are discarded.
///
/// If [parseFunctionBodies] is [false] then only function signatures will be
-/// parsed.
+/// parsed. (Currently broken; function bodies are always parsed).
+///
+/// Deprecated - please use the `parseFile2` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseFile2` does not support the `parseFunctionBodies` option;
+/// callers that don't require function bodies should simply ignore them.
+@Deprecated('Please use parseFile2 instead')
CompilationUnit parseDartFile(String path,
{bool suppressErrors: false,
bool parseFunctionBodies: true,
@@ -83,6 +97,7 @@
}
/// Parses the script tag and directives in a string of Dart code into an AST.
+/// (Currently broken; the entire file is parsed).
///
/// Stops parsing when the first non-directive is encountered. The rest of the
/// string will not be parsed.
@@ -92,6 +107,13 @@
///
/// Throws an [AnalyzerErrorGroup] if any errors occurred, unless
/// [suppressErrors] is `true`, in which case any errors are discarded.
+///
+/// Deprecated - please use the `parseString` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseString` parses the whole file; callers that only require
+/// directives should simply ignore the rest of the parse result.
+@Deprecated('Please use parseString instead')
CompilationUnit parseDirectives(String contents,
{String name, bool suppressErrors: false, FeatureSet featureSet}) {
// TODO(paulberry): make featureSet a required parameter.
@@ -112,6 +134,7 @@
}
/// Converts an AST node representing a string literal into a [String].
+@Deprecated('Please use StringLiteral.stringValue instead')
String stringLiteralToString(StringLiteral literal) {
return literal.stringValue;
}
diff --git a/pkg/analyzer/lib/dart/analysis/utilities.dart b/pkg/analyzer/lib/dart/analysis/utilities.dart
index 7b96945..f4f7dff 100644
--- a/pkg/analyzer/lib/dart/analysis/utilities.dart
+++ b/pkg/analyzer/lib/dart/analysis/utilities.dart
@@ -23,14 +23,69 @@
///
/// If a [resourceProvider] is given, it will be used to access the file system.
///
-/// Note that if more than one file is going to be parsed then this function is
-/// inefficient. Clients should instead use [AnalysisContextCollection] to
-/// create one or more contexts and use those contexts to parse the files.
-ParsedUnitResult parseFile(
- {@required String path, ResourceProvider resourceProvider}) {
- AnalysisContext context =
- _createAnalysisContext(path: path, resourceProvider: resourceProvider);
- return context.currentSession.getParsedUnit(path);
+/// [featureSet] determines what set of features will be assumed by the parser.
+/// This parameter is required because the analyzer does not yet have a
+/// performant way of computing the correct feature set for a single file to be
+/// parsed. Callers that need the feature set to be strictly correct must
+/// create an [AnalysisContextCollection], query it to get an [AnalysisContext],
+/// query it to get an [AnalysisSession], and then call `getParsedUnit`.
+///
+/// Callers that don't need the feature set to be strictly correct can pass in
+/// `FeatureSet.fromEnableFlags([])` to enable the default set of features; this
+/// is much more performant than using an analysis session, because it doesn't
+/// require the analyzer to process the SDK.
+///
+/// If [throwIfDiagnostics] is `true` (the default), then if any diagnostics are
+/// produced because of syntactic errors in the [content] an `ArgumentError`
+/// will be thrown. If the parameter is `false`, then the caller can check the
+/// result to see whether there are any errors.
+ParseStringResult parseFile(
+ {@required String path,
+ ResourceProvider resourceProvider,
+ @required FeatureSet featureSet,
+ bool throwIfDiagnostics: true}) {
+ if (featureSet == null) {
+ throw ArgumentError('A non-null feature set must be provided.');
+ }
+ resourceProvider ??= PhysicalResourceProvider.INSTANCE;
+ var content = (resourceProvider.getResource(path) as File).readAsStringSync();
+ return parseString(
+ content: content,
+ featureSet: featureSet,
+ throwIfDiagnostics: throwIfDiagnostics);
+}
+
+/// Return the result of parsing the file at the given [path].
+///
+/// If a [resourceProvider] is given, it will be used to access the file system.
+///
+/// [featureSet] determines what set of features will be assumed by the parser.
+/// This parameter is required because the analyzer does not yet have a
+/// performant way of computing the correct feature set for a single file to be
+/// parsed. Callers that need the feature set to be strictly correct must
+/// create an [AnalysisContextCollection], query it to get an [AnalysisContext],
+/// query it to get an [AnalysisSession], and then call `getParsedUnit`.
+///
+/// Callers that don't need the feature set to be strictly correct can pass in
+/// `FeatureSet.fromEnableFlags([])` to enable the default set of features; this
+/// is much more performant than using an analysis session, because it doesn't
+/// require the analyzer to process the SDK.
+///
+/// If [throwIfDiagnostics] is `true` (the default), then if any diagnostics are
+/// produced because of syntactic errors in the [content] an `ArgumentError`
+/// will be thrown. If the parameter is `false`, then the caller can check the
+/// result to see whether there are any errors.
+@Deprecated('Use parseFile')
+ParseStringResult parseFile2(
+ {@required String path,
+ ResourceProvider resourceProvider,
+ @required FeatureSet featureSet,
+ bool throwIfDiagnostics: true}) {
+ return parseFile(
+ path: path,
+ resourceProvider: resourceProvider,
+ featureSet: featureSet,
+ throwIfDiagnostics: throwIfDiagnostics);
}
/// Returns the result of parsing the given [content] as a compilation unit.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index a7b03cd..6db198d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -378,12 +378,6 @@
/// Return the token before [target] or `null` if it cannot be found.
Token findPrevious(Token target);
- /// Return the most immediate ancestor of this node for which the [predicate]
- /// returns `true`, or `null` if there is no such ancestor. Note that this
- /// node will never be returned.
- @deprecated
- E getAncestor<E extends AstNode>(Predicate<AstNode> predicate);
-
/// Return the value of the property with the given [name], or `null` if this
/// node does not have a property with the given name.
E getProperty<E>(String name);
@@ -502,6 +496,8 @@
R visitExtensionDeclaration(ExtensionDeclaration node);
+ R visitExtensionOverride(ExtensionOverride node);
+
R visitFieldDeclaration(FieldDeclaration node);
R visitFieldFormalParameter(FieldFormalParameter node);
@@ -520,9 +516,6 @@
R visitForStatement(ForStatement node);
- @Deprecated('Replaced by visitForStatement')
- R visitForStatement2(ForStatement2 node);
-
R visitFunctionDeclaration(FunctionDeclaration node);
R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
@@ -2148,6 +2141,35 @@
TypeParameterList get typeParameters;
}
+/// An override to force resolution to choose a member from a specific
+/// extension.
+///
+/// extensionOverride ::=
+/// [Identifier] [TypeArgumentList]? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExtensionOverride implements Expression {
+ /// Return the list of arguments to the override. In valid code this will
+ /// contain a single argument, which evaluates to the object being extended.
+ ArgumentList get argumentList;
+
+ /// Return the name of the extension being selected.
+ Identifier get extensionName;
+
+ /// Return the type arguments to be applied to the extension, or `null` if no
+ /// type arguments were provided.
+ TypeArgumentList get typeArguments;
+
+ /// Return the actual type arguments to be applied to the extension, either
+ /// explicitly specified in [typeArguments], or inferred.
+ ///
+ /// If the AST has been resolved, never returns `null`, returns an empty list
+ /// if the extension does not have type parameters.
+ ///
+ /// Return `null` if the AST structure has not been resolved.
+ List<DartType> get typeArgumentTypes;
+}
+
/// The declaration of one or more fields of the same type.
///
/// fieldDeclaration ::=
@@ -2540,26 +2562,6 @@
Token get rightParenthesis;
}
-/// A for or for-each statement.
-///
-/// forStatement ::=
-/// 'for' '(' forLoopParts ')' [Statement]
-///
-/// forLoopParts ::=
-/// [VariableDeclaration] ';' [Expression]? ';' expressionList?
-/// | [Expression]? ';' [Expression]? ';' expressionList?
-/// | [DeclaredIdentifier] 'in' [Expression]
-/// | [SimpleIdentifier] 'in' [Expression]
-///
-/// This is the class that is used to represent a for loop when either the
-/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
-/// If neither of those experiments are enabled, then either `ForStatement` or
-/// `ForEachStatement` will be used.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Replaced by ForStatement')
-abstract class ForStatement2 extends ForStatement {}
-
/// A node representing the body of a function or method.
///
/// functionBody ::=
@@ -3653,10 +3655,6 @@
/// Return the syntactic elements used to compute the elements of the list.
NodeList<CollectionElement> get elements;
- /// Return the syntactic elements used to compute the elements of the list.
- @Deprecated('Replaced by elements')
- NodeList<CollectionElement> get elements2;
-
/// Return the left square bracket.
Token get leftBracket;
@@ -4529,11 +4527,6 @@
/// map.
NodeList<CollectionElement> get elements;
- /// Return the syntactic elements used to compute the elements of the set or
- /// map.
- @Deprecated('Replaced by elements')
- NodeList<CollectionElement> get elements2;
-
/// Return `true` if this literal represents a map literal.
///
/// This getter will always return `false` if [isSet] returns `true`.
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 2796e1a..d8cffd0 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -151,19 +151,21 @@
/// can be `null` if the reference is not to a constructor.
CommentReference commentReference(Token newKeyword, Identifier identifier);
- /// Returns a newly created compilation unit to have the given directives
- /// and declarations. The [scriptTag] can be `null` if there is no script tag
- /// in the compilation unit. The list of [directives] can be `null` if there
- /// are no directives in the compilation unit. The list of [declarations] can
- /// be `null` if there are no declarations in the compilation unit.
- @Deprecated('Use compilationUnit2')
+ /// Returns a newly created compilation unit to have the given directives and
+ /// declarations. The [scriptTag] can be `null` (or omitted) if there is no
+ /// script tag in the compilation unit. The list of [declarations] can be
+ /// `null` (or omitted) if there are no directives in the compilation unit.
+ /// The list of `declarations` can be `null` (or omitted) if there are no
+ /// declarations in the compilation unit. The [featureSet] can be `null` if
+ /// the set of features for this compilation unit is not known (this
+ /// restricts what analysis can be done of the compilation unit).
CompilationUnit compilationUnit(
- Token beginToken,
+ {@required Token beginToken,
ScriptTag scriptTag,
List<Directive> directives,
List<CompilationUnitMember> declarations,
- Token endToken,
- [FeatureSet featureSet]);
+ @required Token endToken,
+ @required FeatureSet featureSet});
/// Returns a newly created compilation unit to have the given directives and
/// declarations. The [scriptTag] can be `null` (or omitted) if there is no
@@ -173,6 +175,7 @@
/// declarations in the compilation unit. The [featureSet] can be `null` if
/// the set of features for this compilation unit is not known (this
/// restricts what analysis can be done of the compilation unit).
+ @Deprecated('Use compilationUnit')
CompilationUnit compilationUnit2(
{@required Token beginToken,
ScriptTag scriptTag,
@@ -339,7 +342,7 @@
/// Returns a newly created extends clause.
ExtendsClause extendsClause(Token extendsKeyword, TypeName superclass);
- /// Return a newly created extention declaration. The list of [typeParameters]
+ /// Return a newly created extension declaration. The list of [typeParameters]
/// can be `null` if there are no type parameters.
ExtensionDeclaration extensionDeclaration(
{Comment comment,
@@ -353,6 +356,13 @@
List<ClassMember> members,
Token rightBracket});
+ /// Return a newly created extension override. The list of [typeArguments]
+ /// can be `null` if there are no type arguments.
+ ExtensionOverride extensionOverride(
+ {@required Identifier extensionName,
+ TypeArgumentList typeArguments,
+ @required ArgumentList argumentList});
+
/// Returns a newly created field declaration. Either or both of the [comment]
/// and [metadata] can be `null` if the declaration does not have the
/// corresponding attribute. The [staticKeyword] can be `null` if the field is
@@ -470,16 +480,6 @@
Token rightParenthesis,
Statement body});
- /// Returns a newly created for statement.
- @Deprecated('Replaced by forStatement')
- ForStatement forStatement2(
- {Token awaitKeyword,
- Token forKeyword,
- Token leftParenthesis,
- ForLoopParts forLoopParts,
- Token rightParenthesis,
- Statement body});
-
/// Returns a newly created function declaration. Either or both of the
/// [comment] and [metadata] can be `null` if the function does not have the
/// corresponding attribute. The [externalKeyword] can be `null` if the
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 1d89813..7aae724 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -22,7 +22,6 @@
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart' show UIAsCodeVisitorMixin;
/// An AST visitor that will recursively visit all of the nodes in an AST
/// structure, similar to [GeneralizingAstVisitor]. This visitor uses a
@@ -128,9 +127,7 @@
/// invoked and will cause the children of the visited node to not be visited.
///
/// Clients may extend this class.
-class GeneralizingAstVisitor<R>
- with UIAsCodeVisitorMixin<R>
- implements AstVisitor<R> {
+class GeneralizingAstVisitor<R> implements AstVisitor<R> {
@override
R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
@@ -281,6 +278,9 @@
visitCompilationUnitMember(node);
@override
+ R visitExtensionOverride(ExtensionOverride node) => visitExpression(node);
+
+ @override
R visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
@override
@@ -605,9 +605,7 @@
/// visited.
///
/// Clients may extend this class.
-class RecursiveAstVisitor<R>
- with UIAsCodeVisitorMixin<R>
- implements AstVisitor<R> {
+class RecursiveAstVisitor<R> implements AstVisitor<R> {
@override
R visitAdjacentStrings(AdjacentStrings node) {
node.visitChildren(this);
@@ -849,6 +847,12 @@
}
@override
+ R visitExtensionOverride(ExtensionOverride node) {
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitFieldDeclaration(FieldDeclaration node) {
node.visitChildren(this);
return null;
@@ -1336,9 +1340,7 @@
/// a whole structure) and that only need to visit a small number of node types.
///
/// Clients may extend this class.
-class SimpleAstVisitor<R>
- with UIAsCodeVisitorMixin<R>
- implements AstVisitor<R> {
+class SimpleAstVisitor<R> implements AstVisitor<R> {
@override
R visitAdjacentStrings(AdjacentStrings node) => null;
@@ -1460,6 +1462,9 @@
R visitExtensionDeclaration(ExtensionDeclaration node) => null;
@override
+ R visitExtensionOverride(ExtensionOverride node) => null;
+
+ @override
R visitFieldDeclaration(FieldDeclaration node) => null;
@override
@@ -1713,9 +1718,7 @@
/// want to catch when any other visit methods have been invoked.
///
/// Clients may extend this class.
-class ThrowingAstVisitor<R>
- with UIAsCodeVisitorMixin<R>
- implements AstVisitor<R> {
+class ThrowingAstVisitor<R> implements AstVisitor<R> {
@override
R visitAdjacentStrings(AdjacentStrings node) => _throw(node);
@@ -1838,6 +1841,9 @@
R visitExtensionDeclaration(ExtensionDeclaration node) => _throw(node);
@override
+ R visitExtensionOverride(ExtensionOverride node) => _throw(node);
+
+ @override
R visitFieldDeclaration(FieldDeclaration node) => _throw(node);
@override
@@ -2097,7 +2103,7 @@
/// An AST visitor that captures visit call timings.
///
/// Clients may not extend, implement or mix-in this class.
-class TimedAstVisitor<T> with UIAsCodeVisitorMixin<T> implements AstVisitor<T> {
+class TimedAstVisitor<T> implements AstVisitor<T> {
/// The base visitor whose visit methods will be timed.
final AstVisitor<T> _baseVisitor;
@@ -2430,6 +2436,14 @@
}
@override
+ T visitExtensionOverride(ExtensionOverride node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitExtensionOverride(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
T visitFieldDeclaration(FieldDeclaration node) {
stopwatch.start();
T result = _baseVisitor.visitFieldDeclaration(node);
@@ -3082,9 +3096,7 @@
/// visited.
///
/// Clients may extend this class.
-class UnifyingAstVisitor<R>
- with UIAsCodeVisitorMixin<R>
- implements AstVisitor<R> {
+class UnifyingAstVisitor<R> implements AstVisitor<R> {
@override
R visitAdjacentStrings(AdjacentStrings node) => visitNode(node);
@@ -3208,6 +3220,9 @@
R visitExtensionDeclaration(ExtensionDeclaration node) => visitNode(node);
@override
+ R visitExtensionOverride(ExtensionOverride node) => visitNode(node);
+
+ @override
R visitFieldDeclaration(FieldDeclaration node) => visitNode(node);
@override
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index ba10def..9559ff3 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -373,6 +373,10 @@
/// unit.
List<ClassElement> get enums;
+ /// Return a list containing all of the extensions contained in this
+ /// compilation unit.
+ List<ExtensionElement> get extensions;
+
/// Return a list containing all of the top-level functions contained in this
/// compilation unit.
List<FunctionElement> get functions;
@@ -818,6 +822,9 @@
static const ElementKind EXPORT =
const ElementKind('EXPORT', 5, "export directive");
+ static const ElementKind EXTENSION =
+ const ElementKind('EXTENSION', 24, "extension");
+
static const ElementKind FIELD = const ElementKind('FIELD', 6, "field");
static const ElementKind FUNCTION =
@@ -957,6 +964,8 @@
R visitExportElement(ExportElement element);
+ R visitExtensionElement(ExtensionElement element);
+
R visitFieldElement(FieldElement element);
R visitFieldFormalParameterElement(FieldFormalParameterElement element);
@@ -1046,6 +1055,40 @@
LibraryElement get exportedLibrary;
}
+/// An element that represents an extension.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExtensionElement implements Element {
+ /// Return a list containing all of the accessors (getters and setters)
+ /// declared in this extension.
+ List<PropertyAccessorElement> get accessors;
+
+ /// Return the type that is extended by this extension.
+ DartType get extendedType;
+
+ /// Return a list containing all of the methods declared in this extension.
+ List<MethodElement> get methods;
+
+ /// Return a list containing all of the type parameters declared by this
+ /// extension.
+ List<TypeParameterElement> get typeParameters;
+
+ /// Return the element representing the getter with the given [name] that is
+ /// declared in this extension, or `null` if this extension does not declare a
+ /// getter with the given name.
+ PropertyAccessorElement /*?*/ getGetter(String name);
+
+ /// Return the element representing the method with the given [name] that is
+ /// declared in this extension, or `null` if this extension does not declare a
+ /// method with the given name.
+ MethodElement /*?*/ getMethod(String name);
+
+ /// Return the element representing the setter with the given [name] that is
+ /// declared in this extension, or `null` if this extension does not declare a
+ /// setter with the given name.
+ PropertyAccessorElement /*?*/ getSetter(String name);
+}
+
/// A field defined within a type.
///
/// Clients may not extend, implement or mix-in this class.
@@ -1266,6 +1309,8 @@
/// Return `true` if this library is part of the SDK.
bool get isInSdk;
+ bool get isNonNullableByDefault;
+
/// Return a list containing the strongly connected component in the
/// import/export graph in which the current library resides.
List<LibraryElement> get libraryCycle;
@@ -1299,8 +1344,6 @@
/// included using the `part` directive.
List<CompilationUnitElement> get units;
- bool get isNonNullableByDefault;
-
/// Return a list containing all of the imports that share the given [prefix],
/// or an empty array if there are no such imports.
List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
@@ -1453,7 +1496,8 @@
bool get isRequiredPositional;
/// Return the kind of this parameter.
- @deprecated
+ @Deprecated('Use the getters isOptionalNamed, isOptionalPositional, '
+ 'isRequiredNamed, and isRequiredPositional')
ParameterKind get parameterKind;
/// Return a list containing all of the parameters defined by this parameter.
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 7c2812a..f54f8c4 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -81,11 +81,6 @@
/// Return `true` if this type represents the type 'Object'.
bool get isObject;
- /// Return `true` if this type represents a typename that couldn't be
- /// resolved.
- @deprecated
- bool get isUndefined;
-
/// Return `true` if this type represents the type 'void'.
bool get isVoid;
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index fc6d4a6..f1543ad 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -101,6 +101,9 @@
R visitExportElement(ExportElement element) => visitElement(element);
@override
+ R visitExtensionElement(ExtensionElement element) => visitElement(element);
+
+ @override
R visitFieldElement(FieldElement element) =>
visitPropertyInducingElement(element);
@@ -213,6 +216,12 @@
}
@override
+ R visitExtensionElement(ExtensionElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitFieldElement(FieldElement element) {
element.visitChildren(this);
return null;
@@ -329,6 +338,9 @@
R visitExportElement(ExportElement element) => null;
@override
+ R visitExtensionElement(ExtensionElement element) => null;
+
+ @override
R visitFieldElement(FieldElement element) => null;
@override
@@ -400,6 +412,9 @@
R visitExportElement(ExportElement element) => _throw(element);
@override
+ R visitExtensionElement(ExtensionElement element) => _throw(element);
+
+ @override
R visitFieldElement(FieldElement element) => _throw(element);
@override
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 7c1fa00..e15ffd3 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -235,9 +235,10 @@
CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
CompileTimeErrorCode.NON_SYNC_FACTORY,
+ CompileTimeErrorCode.NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+ CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD,
CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
- CompileTimeErrorCode.NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
CompileTimeErrorCode.NOT_MAP_SPREAD,
CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
@@ -605,7 +606,6 @@
StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
- StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT,
StaticTypeWarningCode.UNDEFINED_FUNCTION,
@@ -796,8 +796,15 @@
*/
final ErrorCode errorCode;
+ /**
+ * The message describing the problem.
+ */
DiagnosticMessage _problemMessage;
+ /**
+ * The context messages associated with the problem. This list will be empty
+ * if there are no context messages.
+ */
List<DiagnosticMessage> _contextMessages;
/**
@@ -819,7 +826,8 @@
* [contextMessages] are provided, they will be recorded with the error.
*/
AnalysisError(this.source, int offset, int length, this.errorCode,
- [List<Object> arguments, List<DiagnosticMessage> contextMessages]) {
+ [List<Object> arguments,
+ List<DiagnosticMessage> contextMessages = const []]) {
String message = formatList(errorCode.message, arguments);
String correctionTemplate = errorCode.correction;
if (correctionTemplate != null) {
@@ -837,15 +845,17 @@
* Initialize a newly created analysis error with given values.
*/
AnalysisError.forValues(this.source, int offset, int length, this.errorCode,
- String message, this._correction) {
+ String message, this._correction,
+ {List<DiagnosticMessage> contextMessages = const []}) {
_problemMessage = new DiagnosticMessageImpl(
filePath: source?.fullName,
length: length,
message: message,
offset: offset);
+ _contextMessages = contextMessages;
}
- List<DiagnosticMessage> get contextMessages => _contextMessages ?? const [];
+ List<DiagnosticMessage> get contextMessages => _contextMessages;
/**
* Return the template used to create the correction to be displayed for this
@@ -866,18 +876,6 @@
}
/**
- * Return `true` if this error can be shown to be a non-issue because of the
- * result of type propagation.
- */
- @Deprecated(
- 'Type propagation is no longer performed, so this will never be true')
- bool get isStaticOnly => false;
-
- @Deprecated(
- 'Type propagation is no longer performed, so this can never be true')
- void set isStaticOnly(bool value) {}
-
- /**
* The number of characters from the offset to the end of the source which
* encompasses the compilation error.
*/
@@ -895,13 +893,6 @@
*/
int get offset => _problemMessage.offset;
- /**
- * The character offset from the beginning of the source (zero based) where
- * the error occurred.
- */
- @Deprecated('Set the offset when the error is created')
- set offset(int offset) {}
-
@override
DiagnosticMessage get problemMessage => _problemMessage;
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index e593f13..f483397 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -70,6 +70,7 @@
static const String TAG_ERROR = 'Err';
static const String TAG_EXCEPTION = 'Ex';
static const String TAG_FILE_READ = 'Read';
+ static const String TAG_INFO = 'Info';
static const String TAG_LOG_ENTRY = 'Log';
static const String TAG_NOTIFICATION = 'Noti';
static const String TAG_PERFORMANCE = 'Perf';
@@ -164,6 +165,11 @@
}
/**
+ * Log unstructured text information for debugging purposes.
+ */
+ void logInfo(String message) => _log(TAG_INFO, message);
+
+ /**
* Log that a log entry that was written to the analysis engine's log. The log
* entry has the given [level] and [message], and was created at the given
* [time].
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index ead50fe5..fb120f5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -29,6 +29,7 @@
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/diagnostic/diagnostic.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart'
show
@@ -94,7 +95,7 @@
/**
* The version of data format, should be incremented on every format change.
*/
- static const int DATA_VERSION = 83;
+ static const int DATA_VERSION = 85;
/**
* The number of exception contexts allowed to write. Once this field is
@@ -1717,13 +1718,25 @@
AnalysisEngine.instance.instrumentationService
.logError('No error code for "$error" in "$file"');
} else {
+ List<DiagnosticMessageImpl> contextMessages;
+ if (error.contextMessages.isNotEmpty) {
+ contextMessages = <DiagnosticMessageImpl>[];
+ for (var message in error.contextMessages) {
+ contextMessages.add(DiagnosticMessageImpl(
+ filePath: message.filePath,
+ length: message.length,
+ message: message.message,
+ offset: message.offset));
+ }
+ }
errors.add(new AnalysisError.forValues(
file.source,
error.offset,
error.length,
errorCode,
error.message,
- error.correction.isEmpty ? null : error.correction));
+ error.correction.isEmpty ? null : error.correction,
+ contextMessages: contextMessages ?? const []));
}
}
return errors;
@@ -1814,14 +1827,26 @@
? indexUnit(resolvedUnit)
: new AnalysisDriverUnitIndexBuilder();
return new AnalysisDriverResolvedUnitBuilder(
- errors: errors
- .map((error) => new AnalysisDriverUnitErrorBuilder(
- offset: error.offset,
- length: error.length,
- uniqueName: error.errorCode.uniqueName,
- message: error.message,
- correction: error.correction))
- .toList(),
+ errors: errors.map((error) {
+ List<DiagnosticMessageBuilder> contextMessages;
+ if (error.contextMessages != null) {
+ contextMessages = <DiagnosticMessageBuilder>[];
+ for (var message in error.contextMessages) {
+ contextMessages.add(DiagnosticMessageBuilder(
+ filePath: message.filePath,
+ length: message.length,
+ message: message.message,
+ offset: message.offset));
+ }
+ }
+ return new AnalysisDriverUnitErrorBuilder(
+ offset: error.offset,
+ length: error.length,
+ uniqueName: error.errorCode.uniqueName,
+ message: error.message,
+ correction: error.correction,
+ contextMessages: contextMessages);
+ }).toList(),
index: index)
.toBuffer();
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index abd0bd5..0a2ac39 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -182,7 +182,7 @@
static const bool constant_update_2018 = false;
/// Expiration status of the experiment "control-flow-collections"
- static const bool control_flow_collections = true;
+ static const bool control_flow_collections = false;
/// Expiration status of the experiment "extension-methods"
static const bool extension_methods = false;
@@ -194,7 +194,7 @@
static const bool set_literals = true;
/// Expiration status of the experiment "spread-collections"
- static const bool spread_collections = true;
+ static const bool spread_collections = false;
/// Expiration status of the experiment "triple-shift"
static const bool triple_shift = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 665f248..f93cdc2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -686,7 +686,7 @@
CompilationUnit _createEmptyCompilationUnit(FeatureSet featureSet) {
var token = new Token.eof(0);
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: token, endToken: token, featureSet: featureSet)
..lineInfo = new LineInfo(const <int>[0]);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 1c23029..51debbd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -533,9 +533,8 @@
}
}
- void recordUriReference(Element element, UriBasedDirective directive) {
- recordRelation(
- element, IndexRelationKind.IS_REFERENCED_BY, directive.uri, true);
+ void recordUriReference(Element element, StringLiteral uri) {
+ recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, uri, true);
}
@override
@@ -603,7 +602,7 @@
@override
visitExportDirective(ExportDirective node) {
ExportElement element = node.element;
- recordUriReference(element?.exportedLibrary, node);
+ recordUriReference(element?.exportedLibrary, node.uri);
super.visitExportDirective(node);
}
@@ -632,7 +631,7 @@
@override
visitImportDirective(ImportDirective node) {
ImportElement element = node.element;
- recordUriReference(element?.importedLibrary, node);
+ recordUriReference(element?.importedLibrary, node.uri);
super.visitImportDirective(node);
}
@@ -686,7 +685,7 @@
visitPartDirective(PartDirective node) {
CompilationUnitElement element = node.element;
if (element?.source != null) {
- recordUriReference(element, node);
+ recordUriReference(element, node.uri);
}
super.visitPartDirective(node);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index ba3be49..a52b70d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -21,6 +21,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/inheritance_override.dart';
@@ -76,6 +77,7 @@
final Map<FileState, IgnoreInfo> _fileToIgnoreInfo = {};
final Map<FileState, RecordingErrorListener> _errorListeners = {};
final Map<FileState, ErrorReporter> _errorReporters = {};
+ final Map<FileState, FlowAnalysisResult> _fileToFlowAnalysisResult = {};
final List<UsedImportedElements> _usedImportedElementsList = [];
final List<UsedLocalElements> _usedLocalElementsList = [];
final Map<FileState, List<PendingError>> _fileToPendingErrors = {};
@@ -411,7 +413,8 @@
// Use the ErrorVerifier to compute errors.
//
ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter, _libraryElement, _typeProvider, _inheritance, false);
+ errorReporter, _libraryElement, _typeProvider, _inheritance, false,
+ flowAnalysisResult: _fileToFlowAnalysisResult[file]);
unit.accept(errorVerifier);
}
@@ -698,9 +701,16 @@
// Nothing for RESOLVED_UNIT9?
// Nothing for RESOLVED_UNIT10?
+ FlowAnalysisHelper flowAnalysisHelper;
+ if (unit.featureSet.isEnabled(Feature.non_nullable)) {
+ flowAnalysisHelper = FlowAnalysisHelper(_context.typeSystem, unit);
+ _fileToFlowAnalysisResult[file] = flowAnalysisHelper.result;
+ flowAnalysisHelper.result.putIntoNode(unit);
+ }
+
unit.accept(new ResolverVisitor(
_inheritance, _libraryElement, source, _typeProvider, errorListener,
- featureSet: unit.featureSet));
+ featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
}
/**
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
index dfbaf6a..6fce596 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -105,6 +105,7 @@
signature.addInt(variableList.variables.length);
for (var variable in variableList.variables) {
addTokens(variable.beginToken, variable.name.endToken);
+ signature.addBool(variable.initializer != null);
addToken(variable.endToken.next); // `,` or `;`
}
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index f327523..31c1d5e 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -17,7 +17,6 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/constant/constant_verifier.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -807,11 +806,6 @@
util.findPrevious(beginToken, target) ?? parent?.findPrevious(target);
@override
- @deprecated
- E getAncestor<E extends AstNode>(Predicate<AstNode> predicate) =>
- thisOrAncestorMatching(predicate);
-
- @override
E getProperty<E>(String name) {
if (_propertyMap == null) {
return null;
@@ -3935,6 +3929,85 @@
}
}
+/// An override to force resolution to choose a member from a specific
+/// extension.
+///
+/// extensionOverride ::=
+/// [Identifier] [TypeArgumentList]? [ArgumentList]
+class ExtensionOverrideImpl extends ExpressionImpl
+ implements ExtensionOverride {
+ /// The list of arguments to the override. In valid code this will contain a
+ /// single argument, which evaluates to the object being extended.
+ ArgumentListImpl _argumentList;
+
+ /// The name of the extension being selected.
+ IdentifierImpl _extensionName;
+
+ /// The type arguments to be applied to the extension, or `null` if no type
+ /// arguments were provided.
+ TypeArgumentListImpl _typeArguments;
+
+ ExtensionOverrideImpl(IdentifierImpl extensionName,
+ TypeArgumentListImpl typeArguments, ArgumentListImpl argumentList) {
+ _extensionName = _becomeParentOf(extensionName);
+ _typeArguments = _becomeParentOf(typeArguments);
+ _argumentList = _becomeParentOf(argumentList);
+ }
+
+ @override
+ ArgumentList get argumentList => _argumentList;
+
+ void set argumentList(ArgumentList argumentList) {
+ _argumentList = _becomeParentOf(argumentList as ArgumentListImpl);
+ }
+
+ @override
+ Token get beginToken => _extensionName?.beginToken;
+
+ @override
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+ ..add(_extensionName)
+ ..add(_typeArguments)
+ ..add(_argumentList);
+
+ @override
+ Token get endToken => _argumentList?.endToken;
+
+ @override
+ Identifier get extensionName => _extensionName;
+
+ void set extensionName(Identifier extensionName) {
+ _extensionName = _becomeParentOf(extensionName as IdentifierImpl);
+ }
+
+ @override
+ Precedence get precedence => Precedence.postfix;
+
+ @override
+ TypeArgumentList get typeArguments => _typeArguments;
+
+ void set typeArguments(TypeArgumentList typeArguments) {
+ _typeArguments = _becomeParentOf(typeArguments as TypeArgumentListImpl);
+ }
+
+ @override
+ // TODO(brianwilkerson) Either implement this getter or remove it if it isn't
+ // needed.
+ List<DartType> get typeArgumentTypes => null;
+
+ @override
+ E accept<E>(AstVisitor<E> visitor) {
+ return visitor.visitExtensionOverride(this);
+ }
+
+ @override
+ void visitChildren(AstVisitor visitor) {
+ _extensionName?.accept(visitor);
+ _typeArguments?.accept(visitor);
+ _argumentList?.accept(visitor);
+ }
+}
+
/// The declaration of one or more fields of the same type.
///
/// fieldDeclaration ::=
@@ -4646,12 +4719,20 @@
}
}
-@Deprecated('Replaced by ForStatementImpl')
-class ForStatement2Impl extends ForStatementImpl implements ForStatement2 {
+class ForStatementImpl extends StatementImpl
+ with ForMixin
+ implements ForStatement {
+ /// The body of the loop.
+ StatementImpl _body;
+
/// Initialize a newly created for statement.
- ForStatement2Impl(Token awaitKeyword, Token forKeyword, Token leftParenthesis,
- ForLoopPartsImpl forLoopParts, Token rightParenthesis, StatementImpl body)
- : super._() {
+ ForStatementImpl(
+ Token awaitKeyword,
+ Token forKeyword,
+ Token leftParenthesis,
+ ForLoopPartsImpl forLoopParts,
+ Token rightParenthesis,
+ StatementImpl body) {
this.awaitKeyword = awaitKeyword;
this.forKeyword = forKeyword;
this.leftParenthesis = leftParenthesis;
@@ -4660,26 +4741,6 @@
_body = _becomeParentOf(body);
}
- @override
- E accept<E>(AstVisitor<E> visitor) => visitor.visitForStatement2(this);
-}
-
-abstract class ForStatementImpl extends StatementImpl
- with ForMixin
- implements ForStatement {
- /// The body of the loop.
- StatementImpl _body;
-
- /// Initialize a newly created for statement.
- factory ForStatementImpl(
- Token awaitKeyword,
- Token forKeyword,
- Token leftParenthesis,
- ForLoopPartsImpl forLoopParts,
- Token rightParenthesis,
- // ignore: deprecated_member_use_from_same_package
- StatementImpl body) = ForStatement2Impl;
-
ForStatementImpl._();
Statement get body => _body;
@@ -6110,88 +6171,6 @@
E accept<E>(AstVisitor<E> visitor) =>
visitor.visitInstanceCreationExpression(this);
- /// Return `true` if it would be valid for this instance creation expression
- /// to have a keyword of `const`. It is valid if
- ///
- /// * the invoked constructor is a `const` constructor,
- /// * all of the arguments are, or could be, constant expressions, and
- /// * the evaluation of the constructor would not produce an exception.
- ///
- /// Note that this method will return `false` if the AST has not been resolved
- /// because without resolution it cannot be determined whether the constructor
- /// is a `const` constructor.
- ///
- /// Also note that this method can cause constant evaluation to occur, which
- /// can be computationally expensive.
- ///
- /// Deprecated: Use `LinterContext.canBeConst` instead.
- @deprecated
- bool canBeConst() {
- //
- // Verify that the invoked constructor is a const constructor.
- //
- ConstructorElement element = staticElement;
- if (element == null || !element.isConst) {
- return false;
- }
- //
- // Verify that all of the arguments are, or could be, constant expressions.
- //
- for (Expression argument in argumentList.arguments) {
- argument = argument.unParenthesized;
- if (argument is NamedExpression) {
- argument = (argument as NamedExpression).expression.unParenthesized;
- }
- if (argument is InstanceCreationExpression) {
- if (!argument.isConst) {
- return false;
- }
- } else if (argument is TypedLiteral) {
- if (!argument.isConst) {
- return false;
- }
- } else if (argument is LiteralImpl) {
- if (argument is StringInterpolation) {
- return false;
- } else if (argument is AdjacentStrings) {
- for (StringLiteral string in (argument as AdjacentStrings).strings) {
- if (string is StringInterpolation) {
- return false;
- }
- }
- }
- } else if (argument is Identifier) {
- Element element = argument.staticElement;
- if (element is PropertyAccessorElement && !element.variable.isConst) {
- return false;
- } else if (element is VariableElement && !element.isConst) {
- return false;
- }
- } else {
- return false;
- }
- }
- //
- // Verify that the evaluation of the constructor would not produce an
- // exception.
- //
- Token oldKeyword = keyword;
- ConstantAnalysisErrorListener listener =
- new ConstantAnalysisErrorListener();
- try {
- keyword = new KeywordToken(Keyword.CONST, offset);
- LibraryElement library = element.library;
- AnalysisContext context = library.context;
- ErrorReporter errorReporter = new ErrorReporter(listener, element.source);
- accept(new ConstantVerifier(errorReporter, library, context.typeProvider,
- context.declaredVariables,
- featureSet: FeatureSet.fromEnableFlags([])));
- } finally {
- keyword = oldKeyword;
- }
- return !listener.hasConstError;
- }
-
@override
void visitChildren(AstVisitor visitor) {
_constructorName?.accept(visitor);
@@ -6827,10 +6806,6 @@
NodeList<CollectionElement> get elements => _elements;
@override
- @Deprecated('Replaced by elements')
- NodeList<CollectionElement> get elements2 => _elements;
-
- @override
Token get endToken => rightBracket;
@override
@@ -8748,10 +8723,6 @@
NodeList<CollectionElement> get elements => _elements;
@override
- @Deprecated('Replaced by elements')
- NodeList<CollectionElement> get elements2 => _elements;
-
- @override
Token get endToken => rightBracket;
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 1cd13f3..f542bd2 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -179,18 +179,18 @@
new CommentReferenceImpl(newKeyword, identifier);
@override
- @deprecated
CompilationUnit compilationUnit(
- Token beginToken,
+ {Token beginToken,
ScriptTag scriptTag,
List<Directive> directives,
List<CompilationUnitMember> declarations,
Token endToken,
- [FeatureSet featureSet]) =>
+ FeatureSet featureSet}) =>
new CompilationUnitImpl(beginToken, scriptTag, directives, declarations,
endToken, featureSet);
@override
+ @deprecated
CompilationUnit compilationUnit2(
{Token beginToken,
ScriptTag scriptTag,
@@ -394,6 +394,13 @@
rightBracket);
@override
+ ExtensionOverride extensionOverride(
+ {@required Identifier extensionName,
+ TypeArgumentList typeArguments,
+ @required ArgumentList argumentList}) =>
+ ExtensionOverrideImpl(extensionName, typeArguments, argumentList);
+
+ @override
FieldDeclaration fieldDeclaration(
Comment comment,
List<Annotation> metadata,
@@ -522,23 +529,6 @@
}
@override
- @Deprecated('Replaced by forStatement')
- ForStatement forStatement2(
- {Token awaitKeyword,
- Token forKeyword,
- Token leftParenthesis,
- ForLoopParts forLoopParts,
- Token rightParenthesis,
- Statement body}) =>
- forStatement(
- awaitKeyword: awaitKeyword,
- forKeyword: forKeyword,
- leftParenthesis: leftParenthesis,
- forLoopParts: forLoopParts,
- rightParenthesis: rightParenthesis,
- body: body);
-
- @override
FunctionDeclaration functionDeclaration(
Comment comment,
List<Annotation> metadata,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 807d3c6..f1a7574 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -30,9 +30,7 @@
* will only clone the structure, it will not preserve any resolution results or
* properties associated with the nodes.
*/
-class AstCloner
- with UIAsCodeVisitorMixin<AstNode>
- implements AstVisitor<AstNode> {
+class AstCloner implements AstVisitor<AstNode> {
/**
* A flag indicating whether tokens should be cloned while cloning an AST
* structure.
@@ -285,7 +283,7 @@
@override
CompilationUnit visitCompilationUnit(CompilationUnit node) {
- CompilationUnit clone = astFactory.compilationUnit2(
+ CompilationUnit clone = astFactory.compilationUnit(
beginToken: cloneToken(node.beginToken),
scriptTag: cloneNode(node.scriptTag),
directives: cloneNodeList(node.directives),
@@ -464,6 +462,13 @@
rightBracket: cloneToken(node.rightBracket));
@override
+ ExtensionOverride visitExtensionOverride(ExtensionOverride node) =>
+ astFactory.extensionOverride(
+ extensionName: cloneNode(node.extensionName),
+ typeArguments: cloneNode(node.typeArguments),
+ argumentList: cloneNode(node.argumentList));
+
+ @override
FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
astFactory.fieldDeclaration2(
comment: cloneNode(node.documentationComment),
@@ -1128,9 +1133,7 @@
* An AstVisitor that compares the structure of two AstNodes to see whether they
* are equal.
*/
-class AstComparator
- with UIAsCodeVisitorMixin<bool>
- implements AstVisitor<bool> {
+class AstComparator implements AstVisitor<bool> {
/**
* The AST node with which the node being visited is to be compared. This is
* only valid at the beginning of each visit method (until [isEqualNodes] is
@@ -1608,6 +1611,14 @@
}
@override
+ bool visitExtensionOverride(ExtensionOverride node) {
+ ExtensionOverride other = _other as ExtensionOverride;
+ return isEqualNodes(node.extensionName, other.extensionName) &&
+ isEqualNodes(node.typeArguments, other.typeArguments) &&
+ isEqualNodes(node.argumentList, other.argumentList);
+ }
+
+ @override
bool visitFieldDeclaration(FieldDeclaration node) {
FieldDeclaration other = _other as FieldDeclaration;
return isEqualNodes(
@@ -2477,9 +2488,7 @@
* results.
*/
@deprecated
-class IncrementalAstCloner
- with UIAsCodeVisitorMixin<AstNode>
- implements AstVisitor<AstNode> {
+class IncrementalAstCloner implements AstVisitor<AstNode> {
/**
* The node to be replaced during the cloning process.
*/
@@ -2674,7 +2683,7 @@
@override
CompilationUnit visitCompilationUnit(CompilationUnit node) {
- CompilationUnitImpl copy = astFactory.compilationUnit2(
+ CompilationUnitImpl copy = astFactory.compilationUnit(
beginToken: _mapToken(node.beginToken),
scriptTag: _cloneNode(node.scriptTag),
directives: _cloneNodeList(node.directives),
@@ -2862,6 +2871,13 @@
rightBracket: _mapToken(node.rightBracket));
@override
+ ExtensionOverride visitExtensionOverride(ExtensionOverride node) =>
+ astFactory.extensionOverride(
+ extensionName: _cloneNode(node.extensionName),
+ typeArguments: _cloneNode(node.typeArguments),
+ argumentList: _cloneNode(node.argumentList));
+
+ @override
FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
astFactory.fieldDeclaration2(
comment: _cloneNode(node.documentationComment),
@@ -3825,7 +3841,7 @@
/**
* An object that will replace one child node in an AST node with another node.
*/
-class NodeReplacer with UIAsCodeVisitorMixin<bool> implements AstVisitor<bool> {
+class NodeReplacer implements AstVisitor<bool> {
/**
* The node being replaced.
*/
@@ -4300,6 +4316,22 @@
}
@override
+ bool visitExtensionOverride(ExtensionOverride node) {
+ if (identical(node.extensionName, _oldNode)) {
+ (node as ExtensionOverrideImpl).extensionName = _newNode as Identifier;
+ return true;
+ } else if (identical(node.typeArguments, _oldNode)) {
+ (node as ExtensionOverrideImpl).typeArguments =
+ _newNode as TypeArgumentList;
+ return true;
+ } else if (identical(node.argumentList, _oldNode)) {
+ (node as ExtensionOverrideImpl).argumentList = _newNode as ArgumentList;
+ return true;
+ }
+ return visitNode(node);
+ }
+
+ @override
bool visitFieldDeclaration(FieldDeclaration node) {
if (identical(node.fields, _oldNode)) {
node.fields = _newNode as VariableDeclarationList;
@@ -5187,9 +5219,7 @@
* another as long as the structures of the corresponding children of a pair of
* nodes are the same.
*/
-class ResolutionCopier
- with UIAsCodeVisitorMixin<bool>
- implements AstVisitor<bool> {
+class ResolutionCopier implements AstVisitor<bool> {
/**
* The AST node with which the node being visited is to be compared. This is
* only valid at the beginning of each visit method (until [isEqualNodes] is
@@ -5673,6 +5703,15 @@
}
@override
+ bool visitExtensionOverride(ExtensionOverride node) {
+ ExtensionOverride toNode = this._toNode as ExtensionOverride;
+ return _and(
+ _isEqualNodes(node.extensionName, toNode.extensionName),
+ _isEqualNodes(node.typeArguments, toNode.typeArguments),
+ _isEqualNodes(node.argumentList, toNode.argumentList));
+ }
+
+ @override
bool visitFieldDeclaration(FieldDeclaration node) {
FieldDeclaration toNode = this._toNode as FieldDeclaration;
return _and(
@@ -6896,9 +6935,7 @@
* This class has been deprecated. Use the class ToSourceVisitor2 instead.
*/
@deprecated
-class ToSourceVisitor
- with UIAsCodeVisitorMixin<void>
- implements AstVisitor<void> {
+class ToSourceVisitor implements AstVisitor<void> {
/**
* The writer to which the source is to be written.
*/
@@ -7258,6 +7295,13 @@
}
@override
+ void visitExtensionOverride(ExtensionOverride node) {
+ _visitNode(node.extensionName);
+ _visitNode(node.typeArguments);
+ _visitNode(node.argumentList);
+ }
+
+ @override
void visitFieldDeclaration(FieldDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.staticKeyword, " ");
@@ -8057,9 +8101,7 @@
* A visitor used to write a source representation of a visited AST node (and
* all of it's children) to a sink.
*/
-class ToSourceVisitor2
- with UIAsCodeVisitorMixin<void>
- implements AstVisitor<void> {
+class ToSourceVisitor2 implements AstVisitor<void> {
/**
* The sink to which the source is to be written.
*/
@@ -8560,6 +8602,13 @@
}
@override
+ void visitExtensionOverride(ExtensionOverride node) {
+ safelyVisitNode(node.extensionName);
+ safelyVisitNode(node.typeArguments);
+ safelyVisitNode(node.argumentList);
+ }
+
+ @override
void visitFieldDeclaration(FieldDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.staticKeyword, " ");
@@ -9240,13 +9289,3 @@
}
}
}
-
-/// Mixin allowing visitor classes to forward the visit method for
-/// `ForStatement2` to `ForStatement`
-mixin UIAsCodeVisitorMixin<R> implements AstVisitor<R> {
- @override
- @deprecated
- R visitForStatement2(ForStatement2 node) {
- return visitForStatement(node);
- }
-}
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 8086e2c..caa0877 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -1332,6 +1332,7 @@
variableName.staticElement = element;
element.isConst = isConst;
element.isFinal = isFinal;
+ element.isLate = node.isLate;
buildVariableInitializer(element, initializerNode);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 199de05..e323a01 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -479,12 +479,6 @@
this._unlinkedClass, CompilationUnitElementImpl enclosingUnit)
: super.forSerialized(enclosingUnit);
- /// Set whether this class is abstract.
- @Deprecated('Use isAbstract instead')
- void set abstract(bool isAbstract) {
- this.isAbstract = isAbstract;
- }
-
@override
List<PropertyAccessorElement> get accessors {
if (_accessors != null) return _accessors;
@@ -1618,6 +1612,10 @@
/// A list containing all of the enums contained in this compilation unit.
List<ClassElement> _enums;
+ /// A list containing all of the extensions contained in this compilation
+ /// unit.
+ List<ExtensionElement> _extensions;
+
/// A list containing all of the top-level functions contained in this
/// compilation unit.
List<FunctionElement> _functions;
@@ -1774,6 +1772,32 @@
}
@override
+ List<ExtensionElement> get extensions {
+ if (_extensions != null) {
+ return _extensions;
+ }
+
+ if (linkedNode != null) {
+ // TODO(brianwilkerson) Implement this.
+ } else if (_unlinkedUnit != null) {
+ return _extensions = _unlinkedUnit.extensions
+ .map((e) => ExtensionElementImpl.forSerialized(e, this))
+ .toList(growable: false);
+ }
+
+ return _extensions ?? const <ExtensionElement>[];
+ }
+
+ /// Set the extensions contained in this compilation unit to the given
+ /// [extensions].
+ void set extensions(List<ExtensionElement> extensions) {
+ for (ExtensionElement extension in extensions) {
+ (extension as ExtensionElementImpl).enclosingElement = this;
+ }
+ this._extensions = extensions;
+ }
+
+ @override
List<FunctionElement> get functions {
if (_functions != null) return _functions;
@@ -4036,12 +4060,6 @@
this._unlinkedEnum, CompilationUnitElementImpl enclosingUnit)
: super.forSerialized(enclosingUnit);
- /// Set whether this class is abstract.
- @Deprecated('This setter will be removed')
- void set abstract(bool isAbstract) {
- _assertNotResynthesized(_unlinkedEnum);
- }
-
@override
List<PropertyAccessorElement> get accessors {
if (_accessors == null) {
@@ -4907,6 +4925,267 @@
}
}
+/// A concrete implementation of an [ExtensionElement].
+class ExtensionElementImpl extends ElementImpl implements ExtensionElement {
+ /// The unlinked representation of the extension in the summary.
+ final /* UnlinkedExtension */ _unlinkedExtension;
+
+ /// A list containing all of the type parameters declared by this extension.
+ List<TypeParameterElement> _typeParameters;
+
+ /// The type being extended.
+ DartType _extendedType;
+
+ /// A list containing all of the accessors (getters and setters) contained in
+ /// this extension.
+ List<PropertyAccessorElement> _accessors;
+
+ /// A list containing all of the methods contained in this extension.
+ List<MethodElement> _methods;
+
+ /// Initialize a newly created extension element to have the given [name] at
+ /// the given [offset] in the file that contains the declaration of this
+ /// element.
+ ExtensionElementImpl(String name, int nameOffset)
+ : _unlinkedExtension = null,
+ super(name, nameOffset);
+
+ /// Initialize a newly created extension element to have the given [name].
+ ExtensionElementImpl.forNode(Identifier name)
+ : _unlinkedExtension = null,
+ super.forNode(name);
+
+ /// Initialize using the given serialized information.
+ ExtensionElementImpl.forSerialized(
+ this._unlinkedExtension, CompilationUnitElementImpl enclosingUnit)
+ : super.forSerialized(enclosingUnit);
+
+ @override
+ List<PropertyAccessorElement> get accessors {
+ if (_accessors != null) {
+ return _accessors;
+ }
+
+ if (linkedNode != null) {
+ if (linkedNode is ExtensionDeclaration) {
+ // TODO(brianwilkerson) Implement this.
+// _createPropertiesAndAccessors();
+// assert(_accessors != null);
+// return _accessors;
+ } else {
+ return _accessors = const [];
+ }
+ } else if (_unlinkedExtension != null) {
+ // TODO(brianwilkerson) Implement this.
+// _resynthesizePropertyAccessors();
+ }
+
+ return _accessors ??= const <PropertyAccessorElement>[];
+ }
+
+ void set accessors(List<PropertyAccessorElement> accessors) {
+ _assertNotResynthesized(_unlinkedExtension);
+ for (PropertyAccessorElement accessor in accessors) {
+ (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+ }
+ _accessors = accessors;
+ }
+
+ @override
+ DartType get extendedType {
+ if (_extendedType != null) {
+ return _extendedType;
+ }
+
+ if (linkedNode != null) {
+ // TODO(brianwilkerson) Implement this.
+// var context = enclosingUnit.linkedContext;
+// return _extendedType = context.getExtendedType(linkedNode)?.type;
+ } else if (_unlinkedExtension != null) {
+ return _extendedType = enclosingUnit.resynthesizerContext
+ .resolveTypeRef(this, _unlinkedExtension.extendedType);
+ }
+
+ return _extendedType;
+ }
+
+ void set extendedType(DartType extendedType) {
+ _assertNotResynthesized(_unlinkedExtension);
+ _extendedType = extendedType;
+ }
+
+ @override
+ ElementKind get kind => ElementKind.EXTENSION;
+
+ @override
+ List<MethodElement> get methods {
+ if (_methods != null) {
+ return _methods;
+ }
+
+ if (linkedNode != null) {
+ // TODO(brianwilkerson) Implement this.
+// var context = enclosingUnit.linkedContext;
+// var containerRef = reference.getChild('@method');
+// return _methods = context
+// .getMethods(linkedNode)
+// .where((node) => node.propertyKeyword == null)
+// .map((node) {
+// var name = node.name.name;
+// var reference = containerRef.getChild(name);
+// if (reference.hasElementFor(node)) {
+// return reference.element as MethodElement;
+// }
+// return MethodElementImpl.forLinkedNode(this, reference, node);
+// }).toList();
+ } else if (_unlinkedExtension != null) {
+ // TODO(brianwilkerson) Implement this.
+// var unlinkedExecutables = _unlinkedExtension.executables;
+//
+// var length = unlinkedExecutables.length;
+// if (length == 0) {
+// return _methods = const <MethodElement>[];
+// }
+//
+// var count = 0;
+// for (var i = 0; i < length; i++) {
+// var e = unlinkedExecutables[i];
+// if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+// count++;
+// }
+// }
+// if (count == 0) {
+// return _methods = const <MethodElement>[];
+// }
+//
+// var methods = new List<MethodElement>(count);
+// var index = 0;
+// for (var i = 0; i < length; i++) {
+// var e = unlinkedExecutables[i];
+// if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+// methods[index++] = new MethodElementImpl.forSerialized(e, this);
+// }
+// }
+// return _methods = methods;
+ }
+ return _methods = const <MethodElement>[];
+ }
+
+ /// Set the methods contained in this extension to the given [methods].
+ void set methods(List<MethodElement> methods) {
+ _assertNotResynthesized(_unlinkedExtension);
+ for (MethodElement method in methods) {
+ (method as MethodElementImpl).enclosingElement = this;
+ }
+ _methods = methods;
+ }
+
+ @override
+ String get name {
+ if (linkedNode != null) {
+ return reference.name;
+ }
+ if (_unlinkedExtension != null) {
+ return _unlinkedExtension.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (linkedNode != null) {
+ return enclosingUnit.linkedContext.getNameOffset(linkedNode);
+ }
+
+ int offset = super.nameOffset;
+ if (offset == 0 && _unlinkedExtension != null) {
+ return _unlinkedExtension.nameOffset;
+ }
+ return offset;
+ }
+
+ @override
+ List<TypeParameterElement> get typeParameters {
+ if (_typeParameters != null) {
+ return _typeParameters;
+ }
+
+ if (linkedNode != null) {
+ var typeParameters = linkedContext.getTypeParameters2(linkedNode);
+ if (typeParameters == null) {
+ return _typeParameters = const [];
+ }
+ var containerRef = reference.getChild('@typeParameter');
+ return _typeParameters =
+ typeParameters.typeParameters.map<TypeParameterElement>((node) {
+ var reference = containerRef.getChild(node.name.name);
+ if (reference.hasElementFor(node)) {
+ return reference.element as TypeParameterElement;
+ }
+ return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+ }).toList();
+ } else if (_unlinkedExtension != null) {
+ List<UnlinkedTypeParam> unlinkedParams =
+ _unlinkedExtension?.typeParameters;
+ if (unlinkedParams != null) {
+ int numTypeParameters = unlinkedParams.length;
+ _typeParameters = new List<TypeParameterElement>(numTypeParameters);
+ for (int i = 0; i < numTypeParameters; i++) {
+ _typeParameters[i] = new TypeParameterElementImpl.forSerialized(
+ unlinkedParams[i], this);
+ }
+ }
+ }
+
+ return _typeParameters ?? const <TypeParameterElement>[];
+ }
+
+ /// Set the type parameters defined by this extension to the given
+ /// [typeParameters].
+ void set typeParameters(List<TypeParameterElement> typeParameters) {
+ _assertNotResynthesized(_unlinkedExtension);
+ for (TypeParameterElement typeParameter in typeParameters) {
+ (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+ }
+ this._typeParameters = typeParameters;
+ }
+
+ @override
+ T accept<T>(ElementVisitor<T> visitor) {
+ return visitor.visitExtensionElement(this);
+ }
+
+ @override
+ PropertyAccessorElement getGetter(String getterName) {
+ int length = accessors.length;
+ for (int i = 0; i < length; i++) {
+ PropertyAccessorElement accessor = accessors[i];
+ if (accessor.isGetter && accessor.name == getterName) {
+ return accessor;
+ }
+ }
+ return null;
+ }
+
+ @override
+ MethodElement getMethod(String methodName) {
+ int length = methods.length;
+ for (int i = 0; i < length; i++) {
+ MethodElement method = methods[i];
+ if (method.name == methodName) {
+ return method;
+ }
+ }
+ return null;
+ }
+
+ @override
+ PropertyAccessorElement getSetter(String setterName) {
+ return AbstractClassElementImpl.getSetterFromAccessors(
+ setterName, accessors);
+ }
+}
+
/// A concrete implementation of a [FieldElement].
class FieldElementImpl extends PropertyInducingElementImpl
implements FieldElement {
@@ -7162,15 +7441,17 @@
@override
bool get isLate {
- if (linkedNode != null) {
- return enclosingUnit.linkedContext.isLate(linkedNode);
- }
if (_unlinkedVariable != null) {
return _unlinkedVariable.isLate;
}
return hasModifier(Modifier.LATE);
}
+ /// Set whether this variable is late.
+ void set isLate(bool isLate) {
+ setModifier(Modifier.LATE, isLate);
+ }
+
@override
bool get isPotentiallyMutatedInClosure => true;
@@ -7230,12 +7511,6 @@
UnlinkedExecutable serializedExecutable, ClassElementImpl enclosingClass)
: super.forSerialized(serializedExecutable, enclosingClass);
- /// Set whether this method is abstract.
- @Deprecated('Use isAbstract instead')
- void set abstract(bool isAbstract) {
- this.isAbstract = isAbstract;
- }
-
@override
String get displayName {
String displayName = super.displayName;
@@ -8942,12 +9217,6 @@
isSynthetic = true;
}
- /// Set whether this accessor is abstract.
- @Deprecated('Use isAbstract instead')
- void set abstract(bool isAbstract) {
- this.isAbstract = isAbstract;
- }
-
@override
PropertyAccessorElement get correspondingGetter {
if (isGetter || variable == null) {
@@ -9514,7 +9783,7 @@
/// Initialize using the given serialized information.
TypeParameterElementImpl.forSerialized(
- this._unlinkedTypeParam, TypeParameterizedElementMixin enclosingElement)
+ this._unlinkedTypeParam, ElementImpl enclosingElement)
: super.forSerialized(enclosingElement);
/// Initialize a newly created synthetic type parameter element to have the
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 67f745c..597c39a 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -214,6 +214,9 @@
List<ClassElement> get enums => actualElement.enums;
@override
+ List<ExtensionElement> get extensions => actualElement.extensions;
+
+ @override
List<FunctionElement> get functions => actualElement.functions;
@override
@@ -894,9 +897,6 @@
LibraryElement get actualElement => super.actualElement as LibraryElement;
@override
- bool get isNonNullableByDefault => actualElement.isNonNullableByDefault;
-
- @override
CompilationUnitElement get definingCompilationUnit =>
actualElement.definingCompilationUnit;
@@ -940,6 +940,9 @@
bool get isInSdk => actualElement.isInSdk;
@override
+ bool get isNonNullableByDefault => actualElement.isNonNullableByDefault;
+
+ @override
ElementKind get kind => ElementKind.LIBRARY;
@override
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 27dd52e..90c8f23 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1212,14 +1212,18 @@
variables1.add(variable1);
variables2.add(variable2);
variablesFresh.add(variableFresh);
+
DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
bound1 = bound1.substitute2(variablesFresh, variables1);
bound2 = bound2.substitute2(variablesFresh, variables2);
- pFresh.bound = bound2;
if (!relation(bound2, bound1, p2, p1)) {
return null;
}
+
+ if (!bound2.isDynamic) {
+ pFresh.bound = bound2;
+ }
}
return variablesFresh;
}
@@ -2838,9 +2842,6 @@
bool get isObject => false;
@override
- bool get isUndefined => false;
-
- @override
bool get isVoid => false;
/**
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index ab41831..99d3f9e 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -40,6 +40,9 @@
List<ClassElement> get enums => wrappedUnit.enums;
@override
+ List<ExtensionElement> get extensions => wrappedUnit.extensions;
+
+ @override
List<FunctionElement> get functions => wrappedUnit.functions;
@override
@@ -187,11 +190,12 @@
int get uriOffset => wrappedUnit.uriOffset;
@override
- T accept<T>(ElementVisitor<T> visitor) => wrappedUnit.accept(visitor);
+ T accept<T>(ElementVisitor<T> visitor) => wrappedUnit
+ .accept(visitor); // ignore: deprecated_member_use_from_same_package
@override
- String computeDocumentationComment() => wrappedUnit
- .computeDocumentationComment(); // ignore: deprecated_member_use_from_same_package
+ String computeDocumentationComment() =>
+ wrappedUnit.computeDocumentationComment();
@deprecated
@override
@@ -426,9 +430,6 @@
AnalysisContext get context => wrappedLib.context;
@override
- bool get isNonNullableByDefault => wrappedLib.isNonNullableByDefault;
-
- @override
CompilationUnitElement get definingCompilationUnit =>
wrappedLib.definingCompilationUnit;
@@ -541,6 +542,9 @@
bool get isJS => hasJS;
@override
+ bool get isNonNullableByDefault => wrappedLib.isNonNullableByDefault;
+
+ @override
bool get isOverride => hasOverride;
@override
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
index b711bcb..237c3ab 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
@@ -2,15 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/// Sets of variables that are potentially assigned in a statement.
+/// Sets of local variables that are potentially assigned in a statement.
+///
+/// These statements are loops, `switch`, and `try` statements.
class AssignedVariables<Statement, Element> {
final emptySet = Set<Element>();
- /// Mapping from a [Statement] representing a loop to the set of variables
- /// that are potentially assigned in that loop.
+ /// Mapping from a [Statement] to the set of local variables that are
+ /// potentially assigned in that statement.
final Map<Statement, Set<Element>> _map = {};
- /// The stack of nested nodes.
+ /// The stack of nested statements.
final List<Set<Element>> _stack = [];
AssignedVariables();
@@ -21,12 +23,12 @@
return _map[statement] ?? emptySet;
}
- void beginLoop() {
+ void beginStatement() {
var set = Set<Element>.identity();
_stack.add(set);
}
- void endLoop(Statement node) {
+ void endStatement(Statement node) {
_map[node] = _stack.removeLast();
}
@@ -41,10 +43,6 @@
final _ElementSet<Element> _emptySet;
final _State<Element, Type> _identity;
- /// The output list of variables that were read before they were written.
- /// TODO(scheglov) use _ElementSet?
- final List<Element> readBeforeWritten = [];
-
/// The [NodeOperations], used to manipulate expressions.
final NodeOperations<Expression> nodeOperations;
@@ -126,6 +124,17 @@
_current = _current.add(variable, assigned: assigned);
}
+ void booleanLiteral(Expression expression, bool value) {
+ _condition = expression;
+ if (value) {
+ _conditionTrue = _current;
+ _conditionFalse = _identity;
+ } else {
+ _conditionTrue = _identity;
+ _conditionFalse = _current;
+ }
+ }
+
void conditional_elseBegin(Expression conditionalExpression,
Expression thenExpression, bool isBool) {
var afterThen = _current;
@@ -223,12 +232,6 @@
_current = _join(falseCondition, breakState);
}
- void falseLiteral(Expression expression) {
- _condition = expression;
- _conditionTrue = _identity;
- _conditionFalse = _current;
- }
-
void forEachStatement_bodyBegin(Set<Element> loopAssigned) {
_stack.add(_current);
_current = _current.removePromotedAll(loopAssigned);
@@ -352,6 +355,11 @@
_current = trueCondition;
}
+ /// Return whether the [variable] is definitely assigned in the current state.
+ bool isAssigned(Element variable) {
+ return !_current.notAssigned.contains(variable);
+ }
+
void isExpression_end(
Expression isExpression, Element variable, bool isNot, Type type) {
if (functionBody.isPotentiallyMutatedInClosure(variable)) {
@@ -368,12 +376,12 @@
}
}
- /// Return `true` if the [variable] is known to be be nullable.
+ /// Return `true` if the [variable] is known to be be non-nullable.
bool isNonNullable(Element variable) {
return !_current.notNonNullable.contains(variable);
}
- /// Return `true` if the [variable] is known to be be non-nullable.
+ /// Return `true` if the [variable] is known to be be nullable.
bool isNullable(Element variable) {
return !_current.notNullable.contains(variable);
}
@@ -452,20 +460,6 @@
return _current.promoted[variable];
}
- /// Register read of the given [variable] in the current state.
- void read(Element variable) {
- if (_current.notAssigned.contains(variable)) {
- // Add to the list of violating variables, if not there yet.
- for (var i = 0; i < readBeforeWritten.length; ++i) {
- var violatingVariable = readBeforeWritten[i];
- if (identical(violatingVariable, variable)) {
- return;
- }
- }
- readBeforeWritten.add(variable);
- }
- }
-
/// The [notPromoted] set contains all variables that are potentially
/// assigned in other cases that might target this with `continue`, so
/// these variables might have different types and are "un-promoted" from
@@ -494,12 +488,6 @@
_stack.add(_current); // afterExpression
}
- void trueLiteral(Expression expression) {
- _condition = expression;
- _conditionTrue = _current;
- _conditionFalse = _identity;
- }
-
void tryCatchStatement_bodyBegin() {
_stack.add(_current);
// Tail of the stack: beforeBody
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
new file mode 100644
index 0000000..79d3217
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -0,0 +1,514 @@
+// 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/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
+
+/// The helper for performing flow analysis during resolution.
+///
+/// It contains related precomputed data, result, and non-trivial pieces of
+/// code that are independent from visiting AST during resolution, so can
+/// be extracted.
+class FlowAnalysisHelper {
+ static final _trueLiteral = astFactory.booleanLiteral(null, true);
+
+ /// The reused instance for creating new [FlowAnalysis] instances.
+ final NodeOperations<Expression> _nodeOperations;
+
+ /// The reused instance for creating new [FlowAnalysis] instances.
+ final _TypeSystemTypeOperations _typeOperations;
+
+ /// Precomputed sets of potentially assigned variables.
+ final AssignedVariables<Statement, VariableElement> assignedVariables;
+
+ /// The result for post-resolution stages of analysis.
+ final FlowAnalysisResult result = FlowAnalysisResult();
+
+ /// The current flow, when resolving a function body, or `null` otherwise.
+ FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
+
+ int _blockFunctionBodyLevel = 0;
+
+ factory FlowAnalysisHelper(TypeSystem typeSystem, AstNode node) {
+ var assignedVariables = AssignedVariables<Statement, VariableElement>();
+ node.accept(_AssignedVariablesVisitor(assignedVariables));
+
+ return FlowAnalysisHelper._(
+ _NodeOperations(),
+ _TypeSystemTypeOperations(typeSystem),
+ assignedVariables,
+ );
+ }
+
+ FlowAnalysisHelper._(
+ this._nodeOperations,
+ this._typeOperations,
+ this.assignedVariables,
+ );
+
+ LocalVariableTypeProvider get localVariableTypeProvider {
+ return _LocalVariableTypeProvider(this);
+ }
+
+ VariableElement assignmentExpression(AssignmentExpression node) {
+ if (flow == null) return null;
+
+ var left = node.leftHandSide;
+
+ if (left is SimpleIdentifier) {
+ var element = left.staticElement;
+ if (element is VariableElement) {
+ return element;
+ }
+ }
+
+ return null;
+ }
+
+ void assignmentExpression_afterRight(
+ VariableElement localElement, Expression right) {
+ if (localElement == null) return;
+
+ flow.write(
+ localElement,
+ isNull: _isNull(right),
+ isNonNull: _isNonNull(right),
+ );
+ }
+
+ void binaryExpression_bangEq(
+ BinaryExpression node,
+ Expression left,
+ Expression right,
+ ) {
+ if (flow == null) return;
+
+ if (right is NullLiteral) {
+ if (left is SimpleIdentifier) {
+ var element = left.staticElement;
+ if (element is VariableElement) {
+ flow.conditionNotEqNull(node, element);
+ }
+ }
+ } else if (left is NullLiteral) {
+ if (right is SimpleIdentifier) {
+ var element = right.staticElement;
+ if (element is VariableElement) {
+ flow.conditionNotEqNull(node, element);
+ }
+ }
+ }
+ }
+
+ void binaryExpression_eqEq(
+ BinaryExpression node,
+ Expression left,
+ Expression right,
+ ) {
+ if (flow == null) return;
+
+ if (right is NullLiteral) {
+ if (left is SimpleIdentifier) {
+ var element = left.staticElement;
+ if (element is VariableElement) {
+ flow.conditionEqNull(node, element);
+ }
+ }
+ } else if (left is NullLiteral) {
+ if (right is SimpleIdentifier) {
+ var element = right.staticElement;
+ if (element is VariableElement) {
+ flow.conditionEqNull(node, element);
+ }
+ }
+ }
+ }
+
+ void blockFunctionBody_enter(BlockFunctionBody node) {
+ _blockFunctionBodyLevel++;
+
+ if (_blockFunctionBodyLevel > 1) {
+ assert(flow != null);
+ return;
+ }
+
+ flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
+ _nodeOperations,
+ _typeOperations,
+ _FunctionBodyAccess(node),
+ );
+
+ var parameters = _enclosingExecutableParameters(node);
+ if (parameters != null) {
+ for (var parameter in parameters.parameters) {
+ flow.add(parameter.declaredElement, assigned: true);
+ }
+ }
+ }
+
+ void blockFunctionBody_exit(BlockFunctionBody node) {
+ _blockFunctionBodyLevel--;
+
+ if (_blockFunctionBodyLevel > 0) {
+ return;
+ }
+
+ if (!flow.isReachable) {
+ result.functionBodiesThatDontComplete.add(node);
+ }
+
+ flow.verifyStackEmpty();
+ flow = null;
+ }
+
+ void breakStatement(BreakStatement node) {
+ var target = _getLabelTarget(node, node.label?.staticElement);
+ flow.handleBreak(target);
+ }
+
+ /// Mark the [node] as unreachable if it is not covered by another node that
+ /// is already known to be unreachable.
+ void checkUnreachableNode(AstNode node) {
+ if (flow == null) return;
+ if (flow.isReachable) return;
+
+ // Ignore the [node] if it is fully covered by the last unreachable.
+ if (result.unreachableNodes.isNotEmpty) {
+ var last = result.unreachableNodes.last;
+ if (node.offset >= last.offset && node.end <= last.end) return;
+ }
+
+ result.unreachableNodes.add(node);
+ }
+
+ void continueStatement(ContinueStatement node) {
+ var target = _getLabelTarget(node, node.label?.staticElement);
+ flow.handleContinue(target);
+ }
+
+ void forStatement_bodyBegin(ForStatement node, Expression condition) {
+ flow.forStatement_bodyBegin(node, condition ?? _trueLiteral);
+ }
+
+ void forStatement_conditionBegin(ForStatement node, Expression condition) {
+ if (condition != null) {
+ var assigned = assignedVariables[node];
+ flow.forStatement_conditionBegin(assigned);
+ } else {
+ flow.booleanLiteral(_trueLiteral, true);
+ }
+ }
+
+ void isExpression(IsExpression node) {
+ if (flow == null) return;
+
+ var expression = node.expression;
+ var typeAnnotation = node.type;
+
+ if (expression is SimpleIdentifier) {
+ var element = expression.staticElement;
+ if (element is VariableElement) {
+ flow.isExpression_end(
+ node,
+ element,
+ node.notOperator != null,
+ typeAnnotation.type,
+ );
+ }
+ }
+ }
+
+ bool isPotentiallyNonNullableLocalReadBeforeWrite(SimpleIdentifier node) {
+ if (flow == null) return false;
+
+ if (node.inDeclarationContext()) return false;
+ if (!node.inGetterContext()) return false;
+
+ var element = node.staticElement;
+ if (element is LocalVariableElement) {
+ if (element.isLate) return false;
+
+ var typeSystem = _typeOperations.typeSystem;
+ if (typeSystem.isPotentiallyNonNullable(element.type)) {
+ return !flow.isAssigned(element);
+ }
+ }
+
+ return false;
+ }
+
+ void simpleIdentifier(SimpleIdentifier node) {
+ if (flow == null) return;
+
+ var element = node.staticElement;
+ var isLocalVariable = element is LocalVariableElement;
+ if (isLocalVariable || element is ParameterElement) {
+ if (node.inGetterContext() && !node.inDeclarationContext()) {
+ if (flow.isNullable(element)) {
+ result.nullableNodes.add(node);
+ }
+
+ if (flow.isNonNullable(element)) {
+ result.nonNullableNodes.add(node);
+ }
+ }
+ }
+ }
+
+ void variableDeclarationStatement(VariableDeclarationStatement node) {
+ var variables = node.variables.variables;
+ for (var i = 0; i < variables.length; ++i) {
+ var variable = variables[i];
+ flow.add(variable.declaredElement,
+ assigned: variable.initializer != null);
+ }
+ }
+
+ FormalParameterList _enclosingExecutableParameters(FunctionBody node) {
+ var parent = node.parent;
+ if (parent is ConstructorDeclaration) {
+ return parent.parameters;
+ }
+ if (parent is FunctionExpression) {
+ return parent.parameters;
+ }
+ if (parent is MethodDeclaration) {
+ return parent.parameters;
+ }
+ return null;
+ }
+
+ /// Return the target of the `break` or `continue` statement with the
+ /// [element] label. The [element] might be `null` (when the statement does
+ /// not specify a label), so the default enclosing target is returned.
+ AstNode _getLabelTarget(AstNode node, LabelElement element) {
+ for (; node != null; node = node.parent) {
+ if (node is DoStatement ||
+ node is ForStatement ||
+ node is SwitchStatement ||
+ node is WhileStatement) {
+ if (element == null) {
+ return node;
+ }
+ var parent = node.parent;
+ if (parent is LabeledStatement) {
+ for (var nodeLabel in parent.labels) {
+ if (identical(nodeLabel.label.staticElement, element)) {
+ return node;
+ }
+ }
+ }
+ }
+ if (element != null && node is SwitchStatement) {
+ for (var member in node.members) {
+ for (var nodeLabel in member.labels) {
+ if (identical(nodeLabel.label.staticElement, element)) {
+ return node;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ static bool _isNonNull(Expression node) {
+ if (node is NullLiteral) return false;
+
+ return node is Literal;
+ }
+
+ static bool _isNull(Expression node) {
+ return node is NullLiteral;
+ }
+}
+
+/// The result of performing flow analysis on a unit.
+class FlowAnalysisResult {
+ static const _astKey = 'FlowAnalysisResult';
+
+ /// The list of identifiers, resolved to a local variable or a parameter,
+ /// where the variable is known to be nullable.
+ final List<SimpleIdentifier> nullableNodes = [];
+
+ /// The list of identifiers, resolved to a local variable or a parameter,
+ /// where the variable is known to be non-nullable.
+ final List<SimpleIdentifier> nonNullableNodes = [];
+
+ /// The list of nodes, [Expression]s or [Statement]s, that cannot be reached,
+ /// for example because a previous statement always exits.
+ final List<AstNode> unreachableNodes = [];
+
+ /// The list of [FunctionBody]s that don't complete, for example because
+ /// there is a `return` statement at the end of the function body block.
+ final List<FunctionBody> functionBodiesThatDontComplete = [];
+
+ void putIntoNode(AstNode node) {
+ node.setProperty(_astKey, this);
+ }
+
+ static FlowAnalysisResult getFromNode(AstNode node) {
+ return node.getProperty(_astKey);
+ }
+}
+
+/// The visitor that gathers local variables that are potentially assigned
+/// in corresponding statements, such as loops, `switch` and `try`.
+class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
+ final AssignedVariables assignedVariables;
+
+ _AssignedVariablesVisitor(this.assignedVariables);
+
+ @override
+ void visitAssignmentExpression(AssignmentExpression node) {
+ var left = node.leftHandSide;
+
+ super.visitAssignmentExpression(node);
+
+ if (left is SimpleIdentifier) {
+ var element = left.staticElement;
+ if (element is VariableElement) {
+ assignedVariables.write(element);
+ }
+ }
+ }
+
+ @override
+ void visitDoStatement(DoStatement node) {
+ assignedVariables.beginStatement();
+ super.visitDoStatement(node);
+ assignedVariables.endStatement(node);
+ }
+
+ @override
+ void visitForStatement(ForStatement node) {
+ var forLoopParts = node.forLoopParts;
+ if (forLoopParts is ForParts) {
+ if (forLoopParts is ForPartsWithExpression) {
+ forLoopParts.initialization?.accept(this);
+ } else if (forLoopParts is ForPartsWithDeclarations) {
+ forLoopParts.variables?.accept(this);
+ } else {
+ throw new StateError('Unrecognized for loop parts');
+ }
+
+ assignedVariables.beginStatement();
+ forLoopParts.condition?.accept(this);
+ node.body.accept(this);
+ forLoopParts.updaters?.accept(this);
+ assignedVariables.endStatement(node);
+ } else if (forLoopParts is ForEachParts) {
+ var iterable = forLoopParts.iterable;
+ var body = node.body;
+
+ iterable.accept(this);
+
+ assignedVariables.beginStatement();
+ body.accept(this);
+ assignedVariables.endStatement(node);
+ } else {
+ throw new StateError('Unrecognized for loop parts');
+ }
+ }
+
+ @override
+ void visitSwitchStatement(SwitchStatement node) {
+ var expression = node.expression;
+ var members = node.members;
+
+ expression.accept(this);
+
+ assignedVariables.beginStatement();
+ members.accept(this);
+ assignedVariables.endStatement(node);
+ }
+
+ @override
+ void visitTryStatement(TryStatement node) {
+ assignedVariables.beginStatement();
+ node.body.accept(this);
+ assignedVariables.endStatement(node.body);
+
+ node.catchClauses.accept(this);
+
+ var finallyBlock = node.finallyBlock;
+ if (finallyBlock != null) {
+ assignedVariables.beginStatement();
+ finallyBlock.accept(this);
+ assignedVariables.endStatement(finallyBlock);
+ }
+ }
+
+ @override
+ void visitWhileStatement(WhileStatement node) {
+ assignedVariables.beginStatement();
+ super.visitWhileStatement(node);
+ assignedVariables.endStatement(node);
+ }
+}
+
+class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
+ final FunctionBody node;
+
+ _FunctionBodyAccess(this.node);
+
+ @override
+ bool isPotentiallyMutatedInClosure(VariableElement variable) {
+ return node.isPotentiallyMutatedInClosure(variable);
+ }
+
+ @override
+ bool isPotentiallyMutatedInScope(VariableElement variable) {
+ return node.isPotentiallyMutatedInScope(variable);
+ }
+}
+
+/// The flow analysis based implementation of [LocalVariableTypeProvider].
+class _LocalVariableTypeProvider implements LocalVariableTypeProvider {
+ final FlowAnalysisHelper _manager;
+
+ _LocalVariableTypeProvider(this._manager);
+
+ @override
+ DartType getType(SimpleIdentifier node) {
+ var variable = node.staticElement as VariableElement;
+ var promotedType = _manager.flow?.promotedType(variable);
+ return promotedType ?? variable.type;
+ }
+}
+
+class _NodeOperations implements NodeOperations<Expression> {
+ @override
+ Expression unwrapParenthesized(Expression node) {
+ return node.unParenthesized;
+ }
+}
+
+class _TypeSystemTypeOperations
+ implements TypeOperations<VariableElement, DartType> {
+ final TypeSystem typeSystem;
+
+ _TypeSystemTypeOperations(this.typeSystem);
+
+ @override
+ DartType elementType(VariableElement element) {
+ return element.type;
+ }
+
+ @override
+ bool isLocalVariable(VariableElement element) {
+ return element is LocalVariableElement;
+ }
+
+ @override
+ bool isSubtypeOf(DartType leftType, DartType rightType) {
+ return typeSystem.isSubtypeOf(leftType, rightType);
+ }
+}
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 184d379..3bb5ec4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
class MethodInvocationResolver {
static final _nameCall = new Name(null, 'call');
@@ -35,8 +36,8 @@
/// The URI of [_definingLibrary].
final Uri _definingLibraryUri;
- /// The object keeping track of which elements have had their types promoted.
- final TypePromotionManager _promoteManager;
+ /// The object providing promoted or declared types of variables.
+ final LocalVariableTypeProvider _localVariableTypeProvider;
/// The invocation being resolved.
MethodInvocationImpl _invocation;
@@ -49,7 +50,7 @@
_inheritance = _resolver.inheritance,
_definingLibrary = _resolver.definingLibrary,
_definingLibraryUri = _resolver.definingLibrary.source.uri,
- _promoteManager = _resolver.promoteManager;
+ _localVariableTypeProvider = _resolver.localVariableTypeProvider;
/// The scope used to resolve identifiers.
Scope get nameScope => _resolver.nameScope;
@@ -400,7 +401,7 @@
return _setResolution(node, calleeType);
}
if (element is VariableElement) {
- var targetType = _promoteManager.getStaticType(element);
+ var targetType = _localVariableTypeProvider.getType(nameNode);
return _setResolution(node, targetType);
}
// TODO(scheglov) This is a questionable distinction.
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index e2194c6..b7eb69e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -587,6 +587,9 @@
for (ClassElement element in compilationUnit.enums) {
define(element);
}
+ for (ExtensionElement element in compilationUnit.extensions) {
+ define(element);
+ }
for (FunctionElement element in compilationUnit.functions) {
define(element);
}
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
index 7b359dd..c742828 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
@@ -44,6 +44,6 @@
identifier.length,
CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
[name],
- contextMessages);
+ contextMessages ?? const []);
}
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 791135a..a5590ab 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2437,6 +2437,24 @@
"Factory bodies can't use 'async', 'async*', or 'sync*'.");
/**
+ * It is an error if a potentially non-nullable local variable which has no
+ * initializer expression and is not marked `late` is used before it is
+ * definitely assigned.
+ *
+ * Parameters:
+ * 0: the name of the variable that is invalid
+ */
+ static const CompileTimeErrorCode
+ NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
+ const CompileTimeErrorCode(
+ 'NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
+ "Non-nullable local variable '{0}' must be assigned before "
+ "it can be used.",
+ correction: "Try giving it an initializer expression, "
+ "or ensure that it is assigned on every execution path, "
+ "or mark it 'late'.");
+
+ /**
* 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i>
* or if <i>m > n</i>.
*
@@ -2453,6 +2471,18 @@
correction: "Try adding the missing arguments.");
/**
+ * It is an error if a static variable with potentially non-nullable type has
+ * no initializer expression.
+ *
+ * Parameters:
+ * 0: the name of the field that is invalid
+ */
+ static const CompileTimeErrorCode NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD =
+ const CompileTimeErrorCode('NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD',
+ "Non-nullable static field '{0}' must be initialized.",
+ correction: "Try adding an initializer expression.");
+
+ /**
* It is an error if a top level variable <cut> with potentially non-nullable
* type has no initializer expression <cut>.
*
@@ -2467,25 +2497,6 @@
correction: "Try adding an initializer expression.");
/**
- * It is an error if a potentially non-nullable local variable which has no
- * initializer expression and is not marked `late` is used before it is
- * definitely assigned.
- *
- * TODO(scheglov) Update the code and the message when implement definite
- * assignment analysis.
- *
- * Parameters:
- * 0: the name of the variable that is invalid
- */
- static const CompileTimeErrorCode
- NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
- const CompileTimeErrorCode(
- 'NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
- "Non-nullable local variable '{0}' must be initialized.",
- correction:
- "Try giving it an initializer expression, or mark it 'late'.");
-
- /**
* No parameters.
*/
// #### Description
@@ -2962,8 +2973,6 @@
* 0: the name of the type used in the instance creation that should be
* limited by the bound as specified in the class declaration
* 1: the name of the bounding type
- *
- * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
*/
static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
const CompileTimeErrorCode(
@@ -3493,39 +3502,6 @@
"The return type '{0}' isn't a '{1}', as defined by anonymous closure.");
/**
- * 12.11 Instance Creation: It is a static type warning if any of the type
- * arguments to a constructor of a generic type <i>G</i> invoked by a new
- * expression or a constant object expression are not subtypes of the bounds
- * of the corresponding formal type parameters of <i>G</i>.
- *
- * 15.8 Parameterized Types: If <i>S</i> is the static type of a member
- * <i>m</i> of <i>G</i>, then the static type of the member <i>m</i> of
- * <i>G<A<sub>1</sub>, …, A<sub>n</sub>></i> is <i>[A<sub>1</sub>,
- * …, A<sub>n</sub>/T<sub>1</sub>, …, T<sub>n</sub>]S</i> where
- * <i>T<sub>1</sub>, …, T<sub>n</sub></i> are the formal type
- * parameters of <i>G</i>. Let <i>B<sub>i</sub></i> be the bounds of
- * <i>T<sub>i</sub>, 1 <= i <= n</i>. It is a static type warning if
- * <i>A<sub>i</sub></i> is not a subtype of <i>[A<sub>1</sub>, …,
- * A<sub>n</sub>/T<sub>1</sub>, …, T<sub>n</sub>]B<sub>i</sub>, 1 <=
- * i <= n</i>.
- *
- * 7.6.2 Factories: It is a static type warning if any of the type arguments
- * to <i>k'</i> are not subtypes of the bounds of the corresponding formal
- * type parameters of type.
- *
- * Parameters:
- * 0: the name of the type used in the instance creation that should be
- * limited by the bound as specified in the class declaration
- * 1: the name of the bounding type
- *
- * See [TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
- */
- static const StaticTypeWarningCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
- const StaticTypeWarningCode(
- 'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', "'{0}' doesn't extend '{1}'.",
- correction: "Try using a type that is or is a subclass of '{1}'.");
-
- /**
* 10 Generics: It is a static type warning if a type parameter is a supertype
* of its upper bound.
*
@@ -3533,7 +3509,7 @@
* 0: the name of the type parameter
* 1: the name of the bounding type
*
- * See [TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
+ * See [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
*/
static const StaticTypeWarningCode TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND =
const StaticTypeWarningCode('TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND',
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 955d11e..e3454ce 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -21,6 +21,7 @@
show
LocatedMessage,
Message,
+ MessageCode,
messageConstConstructorWithBody,
messageConstMethod,
messageConstructorWithReturnType,
@@ -109,25 +110,29 @@
bool parseFunctionBodies = true;
/// `true` if non-nullable behavior is enabled.
- ///
- /// When setting this field, be sure to set `scanner.enableNonNullable`
- /// to the same value.
- bool enableNonNullable = false;
+ final bool enableNonNullable;
/// `true` if spread-collections behavior is enabled
- bool enableSpreadCollections = false;
+ final bool enableSpreadCollections;
/// `true` if control-flow-collections behavior is enabled
- bool enableControlFlowCollections = false;
+ final bool enableControlFlowCollections;
/// `true` if triple-shift behavior is enabled
- bool enableTripleShift = false;
+ final bool enableTripleShift;
- FeatureSet _featureSet;
+ final FeatureSet _featureSet;
AstBuilder(ErrorReporter errorReporter, this.fileUri, this.isFullAst,
+ this._featureSet,
[Uri uri])
: this.errorReporter = new FastaErrorReporter(errorReporter),
+ this.enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
+ this.enableSpreadCollections =
+ _featureSet.isEnabled(Feature.spread_collections),
+ this.enableControlFlowCollections =
+ _featureSet.isEnabled(Feature.control_flow_collections),
+ this.enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
uri = uri ?? fileUri;
NodeList<ClassMember> get currentDeclarationMembers {
@@ -203,7 +208,7 @@
SimpleIdentifier name;
if (nameToken != null) {
- name = ast.simpleIdentifier(nameToken);
+ name = ast.simpleIdentifier(nameToken, isDeclaration: true);
}
extensionDeclaration = ast.extensionDeclaration(
@@ -449,21 +454,6 @@
}
}
- /// Configures the parser appropriately for the given [featureSet].
- ///
- /// TODO(paulberry): stop exposing `enableNonNullable`,
- /// `enableSpreadCollections`, `enableControlFlowCollections`, and
- /// `enableTripleShift` so that callers are forced to use this API. Note that
- /// this will not be a breaking change, because this code is in `lib/src`.
- void configureFeatures(FeatureSet featureSet) {
- enableNonNullable = featureSet.isEnabled(Feature.non_nullable);
- enableSpreadCollections = featureSet.isEnabled(Feature.spread_collections);
- enableControlFlowCollections =
- featureSet.isEnabled(Feature.control_flow_collections);
- enableTripleShift = featureSet.isEnabled(Feature.triple_shift);
- _featureSet = featureSet;
- }
-
@override
void debugEvent(String name) {
// printEvent('AstBuilder: $name');
@@ -573,6 +563,12 @@
push(ast.awaitExpression(awaitKeyword, pop()));
}
+ void endInvalidAwaitExpression(
+ Token awaitKeyword, Token endToken, MessageCode errorCode) {
+ debugEvent("InvalidAwaitExpression");
+ endAwaitExpression(awaitKeyword, endToken);
+ }
+
@override
void endBinaryExpression(Token operatorToken) {
assert(operatorToken.isOperator ||
@@ -680,7 +676,7 @@
Token beginToken = pop();
checkEmpty(endToken.charOffset);
- CompilationUnitImpl unit = ast.compilationUnit2(
+ CompilationUnitImpl unit = ast.compilationUnit(
beginToken: beginToken,
scriptTag: scriptTag,
directives: directives,
@@ -1458,8 +1454,8 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
assert(getOrSet == null ||
optional('get', getOrSet) ||
optional('set', getOrSet));
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4b370a9..2603f21 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -22,6 +22,7 @@
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -43,7 +44,7 @@
class ErrorVerifier extends RecursiveAstVisitor<void> {
/**
* Properties on the object class which are safe to call on nullable types.
- *
+ *
* Note that this must include tear-offs.
*
* TODO(mfairhurst): Calculate these fields rather than hard-code them.
@@ -293,6 +294,10 @@
/// fixed.
final bool disableConflictingGenericsCheck;
+ /// If running with [_isNonNullable], the result of the flow analysis of the
+ /// unit being verified by this visitor.
+ final FlowAnalysisResult flowAnalysisResult;
+
/// The features enabled in the unit currently being checked for errors.
FeatureSet _featureSet;
@@ -301,7 +306,7 @@
*/
ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
this._typeProvider, this._inheritanceManager, bool enableSuperMixins,
- {this.disableConflictingGenericsCheck: false})
+ {this.disableConflictingGenericsCheck: false, this.flowAnalysisResult})
: _errorReporter = errorReporter,
_uninstantiatedBoundChecker =
new _UninstantiatedBoundChecker(errorReporter) {
@@ -713,6 +718,7 @@
}
}
try {
+ _checkForNotInitializedNonNullableStaticField(node);
super.visitFieldDeclaration(node);
} finally {
_isInStaticVariableDeclaration = false;
@@ -1440,7 +1446,6 @@
@override
void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
_checkForFinalNotInitialized(node.variables);
- _checkForNotInitializedPotentiallyNonNullableLocalVariable(node.variables);
super.visitVariableDeclarationStatement(node);
}
@@ -3369,75 +3374,6 @@
}
}
- void _checkForNotInitializedPotentiallyNonNullableLocalVariable(
- VariableDeclarationList node,
- ) {
- // Const and final checked separately.
- if (node.isConst || node.isFinal) {
- return;
- }
-
- if (!_isNonNullable) {
- return;
- }
-
- if (node.isLate) {
- return;
- }
-
- if (node.type == null) {
- return;
- }
- var type = node.type.type;
-
- if (!_typeSystem.isPotentiallyNonNullable(type)) {
- return;
- }
-
- for (var variable in node.variables) {
- if (variable.initializer == null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
- variable.name,
- [variable.name.name],
- );
- }
- }
- }
-
- void _checkForNotInitializedNonNullableTopLevelVariable(
- VariableDeclarationList node,
- ) {
- // Const and final checked separately.
- if (node.isConst || node.isFinal) {
- return;
- }
-
- if (!_isNonNullable) {
- return;
- }
-
- if (node.type == null) {
- return;
- }
- var type = node.type.type;
-
- if (!_typeSystem.isPotentiallyNonNullable(type)) {
- return;
- }
-
- for (var variable in node.variables) {
- if (variable.initializer == null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
- variable.name,
- [variable.name.name],
- );
- }
- }
- }
-
/**
* If there are no constructors in the given [members], verify that all
* final fields are initialized. Cases in which there is at least one
@@ -4026,6 +3962,8 @@
void _checkForListConstructor(
InstanceCreationExpression node, InterfaceType type) {
+ if (!_isNonNullable) return;
+
if (node.argumentList.arguments.length == 1 &&
_isDartCoreList(type) &&
_typeSystem.isPotentiallyNonNullable(type.typeArguments[0])) {
@@ -4741,6 +4679,62 @@
}
}
+ void _checkForNotInitializedNonNullableStaticField(FieldDeclaration node) {
+ if (!_isNonNullable) return;
+
+ if (!node.isStatic) return;
+
+ var fields = node.fields;
+
+ // Const and final checked separately.
+ if (fields.isConst || fields.isFinal) return;
+
+ if (fields.type == null) return;
+ var type = fields.type.type;
+
+ if (!_typeSystem.isPotentiallyNonNullable(type)) return;
+
+ for (var variable in fields.variables) {
+ if (variable.initializer == null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD,
+ variable.name,
+ [variable.name.name],
+ );
+ }
+ }
+ }
+
+ void _checkForNotInitializedNonNullableTopLevelVariable(
+ VariableDeclarationList node,
+ ) {
+ if (!_isNonNullable) return;
+
+ // Const and final checked separately.
+ if (node.isConst || node.isFinal) {
+ return;
+ }
+
+ if (node.type == null) {
+ return;
+ }
+ var type = node.type.type;
+
+ if (!_typeSystem.isPotentiallyNonNullable(type)) {
+ return;
+ }
+
+ for (var variable in node.variables) {
+ if (variable.initializer == null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
+ variable.name,
+ [variable.name.name],
+ );
+ }
+ }
+ }
+
/**
* Check for illegal derefences of nullables, ie, "unchecked" usages of
* nullable values. Note that *any* usage of a null value is an "unchecked"
@@ -5396,10 +5390,6 @@
/**
* Verify that the type arguments in the given [typeName] are all within
* their bounds.
- *
- * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS],
- * [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS],
- * [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_BOUND].
*/
void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
// prepare Type
@@ -5459,14 +5449,6 @@
}
if (!_typeSystem.isSubtypeOf(argType, boundType)) {
- ErrorCode errorCode;
- if (_isInConstInstanceCreation) {
- errorCode =
- CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
- } else {
- errorCode =
- StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
- }
if (_shouldAllowSuperBoundedTypes(typeName)) {
var replacedType =
(argType as TypeImpl).replaceTopAndBottom(_typeProvider);
@@ -5477,7 +5459,9 @@
}
}
_errorReporter.reportTypeErrorForNode(
- errorCode, argumentNode, [argType, boundType]);
+ CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+ argumentNode,
+ [argType, boundType]);
}
}
}
@@ -5987,8 +5971,6 @@
/**
* Verify that the given [typeArguments] are all within their bounds, as
* defined by the given [element].
- *
- * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
*/
void _checkTypeArguments(InvocationExpression node) {
NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
@@ -6033,7 +6015,7 @@
fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
if (!_typeSystem.isSubtypeOf(argType, bound)) {
_errorReporter.reportTypeErrorForNode(
- StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+ CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
typeArgumentList[i],
[argType, bound]);
}
@@ -6059,6 +6041,8 @@
}
void _checkUseOfDefaultValuesInParameters(FormalParameterList node) {
+ if (!_isNonNullable) return;
+
AstNode parent = node.parent;
if (parent is FieldFormalParameter ||
parent is FunctionTypeAlias ||
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index d494c4e..3248dd0 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
@@ -31,6 +30,7 @@
import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
import 'package:front_end/src/fasta/parser/type_info.dart' as fasta;
import 'package:front_end/src/fasta/scanner.dart' as fasta;
+import 'package:meta/meta.dart';
export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
export 'package:analyzer/src/dart/error/syntactic_errors.dart';
@@ -199,17 +199,12 @@
/// Initialize a newly created parser to parse tokens in the given [_source]
/// and to report any errors that are found to the given [_errorListener].
- ///
- /// In a future major version release of the analyzer, the [featureSet]
- /// argument will be required.
factory Parser(Source source, AnalysisErrorListener errorListener,
- {bool useFasta, FeatureSet featureSet}) {
+ {bool useFasta, @required FeatureSet featureSet}) {
+ featureSet ??= FeatureSet.fromEnableFlags([]);
if (useFasta ?? Parser.useFasta) {
- var parser = new _Parser2(source, errorListener, allowNativeClause: true);
- if (featureSet != null) {
- parser.configureFeatures(featureSet);
- }
- return parser;
+ return new _Parser2(source, errorListener, featureSet,
+ allowNativeClause: true);
} else {
return new Parser.withoutFasta(source, errorListener,
featureSet: featureSet);
@@ -245,24 +240,6 @@
@deprecated
void set enableAssertInitializer(bool enable) {}
- /// Enables or disables parsing of control flow collections.
- @Deprecated('Pass a FeatureSet to the constructor instead')
- void set enableControlFlowCollections(bool value) {
- if (value) {
- throw new UnimplementedError('control_flow_collections experiment'
- ' not supported by analyzer parser');
- }
- }
-
- /// Enables or disables non-nullable by default.
- @Deprecated('Pass a FeatureSet to the constructor instead')
- void set enableNonNullable(bool value) {
- if (value) {
- throw new UnimplementedError(
- 'non-nullable experiment not supported by analyzer parser');
- }
- }
-
/// Return `true` if the parser should parse instance creation expressions
/// that lack either the `new` or `const` keyword.
bool get enableOptionalNewAndConst => _enableOptionalNewAndConst;
@@ -279,24 +256,6 @@
// has been removed from dartfmt.
}
- /// Enables or disables parsing of spread collections.
- @Deprecated('Pass a FeatureSet to the constructor instead')
- void set enableSpreadCollections(bool value) {
- if (value) {
- throw new UnimplementedError(
- 'spread_collections experiment not supported by analyzer parser');
- }
- }
-
- /// Enables or disables parsing of the triple shift operators.
- @Deprecated('Pass a FeatureSet to the constructor instead')
- void set enableTripleShift(bool value) {
- if (value) {
- throw new UnimplementedError('triple_shift experiment'
- ' not supported by analyzer parser');
- }
- }
-
/// Return `true` if the parser is to allow URI's in part-of directives.
@deprecated
bool get enableUriInPartOf => true;
@@ -363,12 +322,6 @@
return buffer.toString();
}
- /// Configures the parser appropriately for the given [featureSet].
- @Deprecated('Pass a FeatureSet to the constructor instead')
- void configureFeatures(FeatureSet featureSet) {
- _configureFeatures(featureSet);
- }
-
/// Return a synthetic identifier.
SimpleIdentifier createSyntheticIdentifier({bool isDeclaration: false}) {
Token syntheticToken;
@@ -1937,7 +1890,7 @@
} on _TooDeepTreeError {
_reportErrorForToken(ParserErrorCode.STACK_OVERFLOW, _currentToken);
Token eof = new Token.eof(0);
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: eof, endToken: eof, featureSet: _featureSet);
}
if (member != null) {
@@ -1987,7 +1940,7 @@
// }
}
}
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: firstToken,
scriptTag: scriptTag,
directives: directives,
@@ -2443,7 +2396,7 @@
while (!_matches(TokenType.EOF)) {
_advance();
}
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: firstToken,
scriptTag: scriptTag,
directives: directives,
@@ -2451,7 +2404,7 @@
featureSet: _featureSet);
}
}
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: firstToken,
scriptTag: scriptTag,
directives: directives,
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index f7c72e0..5f560dd 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -24,15 +24,13 @@
final AstBuilder astBuilder;
ParserAdapter(this.currentToken, ErrorReporter errorReporter, Uri fileUri,
- {bool allowNativeClause: false, FeatureSet featureSet})
+ FeatureSet featureSet,
+ {bool allowNativeClause: false})
: fastaParser = new fasta.Parser(null),
- astBuilder = new AstBuilder(errorReporter, fileUri, true) {
+ astBuilder = new AstBuilder(errorReporter, fileUri, true, featureSet) {
fastaParser.listener = astBuilder;
astBuilder.parser = fastaParser;
astBuilder.allowNativeClause = allowNativeClause;
- if (featureSet != null) {
- astBuilder.configureFeatures(featureSet);
- }
}
@override
@@ -41,25 +39,6 @@
}
@override
- void set enableControlFlowCollections(bool value) {
- if (IsExpired.control_flow_collections &&
- value != IsEnabledByDefault.control_flow_collections) {
- throw new StateError('control_flow_collections may only be set'
- ' to ${IsEnabledByDefault.control_flow_collections}');
- }
- astBuilder.enableControlFlowCollections = value;
- }
-
- /// Enables or disables non-nullable by default.
- void set enableNonNullable(bool value) {
- if (IsExpired.non_nullable && value != IsEnabledByDefault.non_nullable) {
- throw new StateError(
- 'non_nullable may only be set to ${IsEnabledByDefault.non_nullable}');
- }
- astBuilder.enableNonNullable = value;
- }
-
- @override
bool get enableOptionalNewAndConst => false;
@override
@@ -72,25 +51,6 @@
}
@override
- void set enableSpreadCollections(bool value) {
- if (IsExpired.spread_collections &&
- value != IsEnabledByDefault.spread_collections) {
- throw new StateError('spread_collections may only be set'
- ' to ${IsEnabledByDefault.spread_collections}');
- }
- astBuilder.enableSpreadCollections = value;
- }
-
- @override
- void set enableTripleShift(bool value) {
- if (IsExpired.triple_shift && value != IsEnabledByDefault.triple_shift) {
- throw new StateError('triple_shift may only be set'
- ' to ${IsEnabledByDefault.triple_shift}');
- }
- astBuilder.enableTripleShift = value;
- }
-
- @override
void set parseFunctionBodies(bool parseFunctionBodies) {
astBuilder.parseFunctionBodies = parseFunctionBodies;
}
@@ -111,11 +71,6 @@
}
@override
- void configureFeatures(FeatureSet featureSet) {
- astBuilder.configureFeatures(featureSet);
- }
-
- @override
Expression parseAdditiveExpression() => parseExpression2();
@override
@@ -423,16 +378,17 @@
@override
bool enableUriInPartOf = true;
- factory _Parser2(Source source, AnalysisErrorListener errorListener,
+ factory _Parser2(
+ Source source, AnalysisErrorListener errorListener, FeatureSet featureSet,
{bool allowNativeClause: false}) {
var errorReporter = new ErrorReporter(errorListener, source);
- return new _Parser2._(source, errorReporter, source.uri,
+ return new _Parser2._(source, errorReporter, source.uri, featureSet,
allowNativeClause: allowNativeClause);
}
_Parser2._(this._source, ErrorReporter errorReporter, Uri fileUri,
- {bool allowNativeClause: false})
- : super(null, errorReporter, fileUri,
+ FeatureSet featureSet, {bool allowNativeClause: false})
+ : super(null, errorReporter, fileUri, featureSet,
allowNativeClause: allowNativeClause);
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b5b6b72..26f2d52 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -26,6 +26,7 @@
import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/exit_detector.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -35,7 +36,9 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/static_type_analyzer.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/type_promotion_manager.dart';
import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:meta/meta.dart';
@@ -3715,7 +3718,9 @@
InferenceContext inferenceContext = null;
/// The object keeping track of which elements have had their types promoted.
- TypePromotionManager _promoteManager = new TypePromotionManager();
+ TypePromotionManager _promoteManager;
+
+ final FlowAnalysisHelper _flowAnalysis;
/// A comment before a function should be resolved in the context of the
/// function. But when we incrementally resolve a comment, we don't want to
@@ -3725,9 +3730,6 @@
/// be built and the comment resolved.
bool resolveOnlyCommentInFunctionBody = false;
- /// Body of the function currently being analyzed, if any.
- FunctionBody _currentFunctionBody;
-
/// The type of the expression of the immediately enclosing [SwitchStatement],
/// or `null` if not in a [SwitchStatement].
DartType _enclosingSwitchStatementExpressionType;
@@ -3755,7 +3757,8 @@
{FeatureSet featureSet,
Scope nameScope,
bool propagateTypes: true,
- reportConstEvaluationErrors: true})
+ reportConstEvaluationErrors: true,
+ FlowAnalysisHelper flowAnalysisHelper})
: this._(
inheritance,
definingLibrary,
@@ -3766,7 +3769,8 @@
definingLibrary.context.analysisOptions.contextFeatures,
nameScope,
propagateTypes,
- reportConstEvaluationErrors);
+ reportConstEvaluationErrors,
+ flowAnalysisHelper);
ResolverVisitor._(
this.inheritance,
@@ -3777,16 +3781,18 @@
FeatureSet featureSet,
Scope nameScope,
bool propagateTypes,
- reportConstEvaluationErrors)
+ reportConstEvaluationErrors,
+ this._flowAnalysis)
: _analysisOptions = definingLibrary.context.analysisOptions,
_uiAsCodeEnabled =
featureSet.isEnabled(Feature.control_flow_collections) ||
featureSet.isEnabled(Feature.spread_collections),
super(definingLibrary, source, typeProvider, errorListener,
nameScope: nameScope) {
+ this.typeSystem = definingLibrary.context.typeSystem;
+ this._promoteManager = TypePromotionManager(typeSystem);
this.elementResolver = new ElementResolver(this,
reportConstEvaluationErrors: reportConstEvaluationErrors);
- this.typeSystem = definingLibrary.context.typeSystem;
bool strongModeHints = false;
AnalysisOptions options = _analysisOptions;
if (options is AnalysisOptionsImpl) {
@@ -3803,12 +3809,14 @@
/// @return the element representing the function containing the current node
ExecutableElement get enclosingFunction => _enclosingFunction;
- /// Return the object keeping track of which elements have had their types
- /// promoted.
- ///
- /// @return the object keeping track of which elements have had their types
- /// promoted
- TypePromotionManager get promoteManager => _promoteManager;
+ /// Return the object providing promoted or declared types of variables.
+ LocalVariableTypeProvider get localVariableTypeProvider {
+ if (_flowAnalysis != null) {
+ return _flowAnalysis.localVariableTypeProvider;
+ } else {
+ return _promoteManager.localVariableTypeProvider;
+ }
+ }
/// Return the static element associated with the given expression whose type
/// can be overridden, or `null` if there is no element whose type can be
@@ -3831,24 +3839,6 @@
return null;
}
- /// Return the static element associated with the given expression whose type
- /// can be promoted, or `null` if there is no element whose type can be
- /// promoted.
- VariableElement getPromotionStaticElement(Expression expression) {
- expression = expression?.unParenthesized;
- if (expression is SimpleIdentifier) {
- Element element = expression.staticElement;
- if (element is VariableElement) {
- ElementKind kind = element.kind;
- if (kind == ElementKind.LOCAL_VARIABLE ||
- kind == ElementKind.PARAMETER) {
- return element;
- }
- }
- }
- return null;
- }
-
/// Given a downward inference type [fnType], and the declared
/// [typeParameterList] for a function expression, determines if we can enable
/// downward inference and if so, returns the function type to use for
@@ -3907,7 +3897,7 @@
/// Set the enclosing function body when partial AST is resolved.
void prepareCurrentFunctionBody(FunctionBody body) {
- _currentFunctionBody = body;
+ _promoteManager.enterFunctionBody(body);
}
/// Set information about enclosing declarations.
@@ -4019,14 +4009,22 @@
@override
void visitAssignmentExpression(AssignmentExpression node) {
- node.leftHandSide?.accept(this);
+ var left = node.leftHandSide;
+ var right = node.rightHandSide;
+
+ left?.accept(this);
+
+ var leftLocalVariable = _flowAnalysis?.assignmentExpression(node);
+
TokenType operator = node.operator.type;
if (operator == TokenType.EQ ||
operator == TokenType.QUESTION_QUESTION_EQ) {
- InferenceContext.setType(
- node.rightHandSide, node.leftHandSide.staticType);
+ InferenceContext.setType(right, left.staticType);
}
- node.rightHandSide?.accept(this);
+
+ right?.accept(this);
+ _flowAnalysis?.assignmentExpression_afterRight(leftLocalVariable, right);
+
node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4043,66 +4041,92 @@
@override
void visitBinaryExpression(BinaryExpression node) {
- TokenType operatorType = node.operator.type;
- Expression leftOperand = node.leftOperand;
- Expression rightOperand = node.rightOperand;
- if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
- InferenceContext.setType(leftOperand, typeProvider.boolType);
- InferenceContext.setType(rightOperand, typeProvider.boolType);
- leftOperand?.accept(this);
- if (rightOperand != null) {
- _promoteManager.enterScope();
- try {
- // Type promotion.
- _promoteTypes(leftOperand);
- _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
- _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
- _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
- rightOperand);
- // Visit right operand.
- rightOperand.accept(this);
- } finally {
- _promoteManager.exitScope();
- }
+ TokenType operator = node.operator.type;
+ Expression left = node.leftOperand;
+ Expression right = node.rightOperand;
+ var flow = _flowAnalysis?.flow;
+
+ if (operator == TokenType.AMPERSAND_AMPERSAND) {
+ InferenceContext.setType(left, typeProvider.boolType);
+ InferenceContext.setType(right, typeProvider.boolType);
+
+ // TODO(scheglov) Do we need these checks for null?
+ left?.accept(this);
+
+ if (_flowAnalysis != null) {
+ flow?.logicalAnd_rightBegin(node, left);
+ _flowAnalysis.checkUnreachableNode(right);
+ right.accept(this);
+ flow?.logicalAnd_end(node, right);
+ } else {
+ _promoteManager.visitBinaryExpression_and_rhs(
+ left,
+ right,
+ () {
+ right.accept(this);
+ },
+ );
}
+
node.accept(elementResolver);
- } else if (operatorType == TokenType.BAR_BAR) {
- InferenceContext.setType(leftOperand, typeProvider.boolType);
- InferenceContext.setType(rightOperand, typeProvider.boolType);
- leftOperand?.accept(this);
- if (rightOperand != null) {
- rightOperand.accept(this);
- }
+ } else if (operator == TokenType.BAR_BAR) {
+ InferenceContext.setType(left, typeProvider.boolType);
+ InferenceContext.setType(right, typeProvider.boolType);
+
+ left?.accept(this);
+
+ flow?.logicalOr_rightBegin(node, left);
+ _flowAnalysis?.checkUnreachableNode(right);
+ right.accept(this);
+ flow?.logicalOr_end(node, right);
+
node.accept(elementResolver);
+ } else if (operator == TokenType.BANG_EQ) {
+ left.accept(this);
+ right.accept(this);
+ node.accept(elementResolver);
+ _flowAnalysis?.binaryExpression_bangEq(node, left, right);
+ } else if (operator == TokenType.EQ_EQ) {
+ left.accept(this);
+ right.accept(this);
+ node.accept(elementResolver);
+ _flowAnalysis?.binaryExpression_eqEq(node, left, right);
} else {
- if (operatorType == TokenType.QUESTION_QUESTION) {
- InferenceContext.setTypeFromNode(leftOperand, node);
+ if (operator == TokenType.QUESTION_QUESTION) {
+ InferenceContext.setTypeFromNode(left, node);
}
- leftOperand?.accept(this);
+ left?.accept(this);
// Call ElementResolver.visitBinaryExpression to resolve the user-defined
// operator method, if applicable.
node.accept(elementResolver);
- if (operatorType == TokenType.QUESTION_QUESTION) {
+ if (operator == TokenType.QUESTION_QUESTION) {
// Set the right side, either from the context, or using the information
// from the left side if it is more precise.
DartType contextType = InferenceContext.getContext(node);
- DartType leftType = leftOperand?.staticType;
+ DartType leftType = left?.staticType;
if (contextType == null || contextType.isDynamic) {
contextType = leftType;
}
- InferenceContext.setType(rightOperand, contextType);
+ InferenceContext.setType(right, contextType);
} else {
var invokeType = node.staticInvokeType;
if (invokeType != null && invokeType.parameters.isNotEmpty) {
// If this is a user-defined operator, set the right operand context
// using the operator method's parameter type.
var rightParam = invokeType.parameters[0];
- InferenceContext.setType(rightOperand, rightParam.type);
+ InferenceContext.setType(right, rightParam.type);
}
}
- rightOperand?.accept(this);
+
+ if (operator == TokenType.QUESTION_QUESTION) {
+ flow?.ifNullExpression_rightBegin();
+ right.accept(this);
+ flow?.ifNullExpression_end();
+ } else {
+ right?.accept(this);
+ }
}
node.accept(typeAnalyzer);
}
@@ -4110,14 +4134,22 @@
@override
void visitBlockFunctionBody(BlockFunctionBody node) {
try {
+ _flowAnalysis?.blockFunctionBody_enter(node);
inferenceContext.pushReturnContext(node);
super.visitBlockFunctionBody(node);
} finally {
inferenceContext.popReturnContext(node);
+ _flowAnalysis?.blockFunctionBody_exit(node);
}
}
@override
+ void visitBooleanLiteral(BooleanLiteral node) {
+ _flowAnalysis?.flow?.booleanLiteral(node, node.value);
+ super.visitBooleanLiteral(node);
+ }
+
+ @override
void visitBreakStatement(BreakStatement node) {
//
// We do not visit the label because it needs to be visited in the context
@@ -4125,6 +4157,7 @@
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
+ _flowAnalysis?.breakStatement(node);
}
@override
@@ -4215,28 +4248,43 @@
@override
void visitConditionalExpression(ConditionalExpression node) {
Expression condition = node.condition;
+ var flow = _flowAnalysis?.flow;
+
+ // TODO(scheglov) Do we need these checks for null?
condition?.accept(this);
+
Expression thenExpression = node.thenExpression;
- if (thenExpression != null) {
- _promoteManager.enterScope();
- try {
- // Type promotion.
- _promoteTypes(condition);
- _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
- _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
- thenExpression);
- // Visit "then" expression.
- InferenceContext.setTypeFromNode(thenExpression, node);
- thenExpression.accept(this);
- } finally {
- _promoteManager.exitScope();
+ InferenceContext.setTypeFromNode(thenExpression, node);
+
+ if (_flowAnalysis != null) {
+ if (flow != null) {
+ flow.conditional_thenBegin(node, condition);
+ _flowAnalysis.checkUnreachableNode(thenExpression);
}
+ thenExpression.accept(this);
+ } else {
+ _promoteManager.visitConditionalExpression_then(
+ condition,
+ thenExpression,
+ () {
+ thenExpression.accept(this);
+ },
+ );
}
+
Expression elseExpression = node.elseExpression;
- if (elseExpression != null) {
- InferenceContext.setTypeFromNode(elseExpression, node);
+ InferenceContext.setTypeFromNode(elseExpression, node);
+
+ if (flow != null) {
+ var isBool = thenExpression.staticType.isDartCoreBool;
+ flow.conditional_elseBegin(node, thenExpression, isBool);
+ _flowAnalysis.checkUnreachableNode(elseExpression);
+ elseExpression.accept(this);
+ flow.conditional_end(node, elseExpression, isBool);
+ } else {
elseExpression.accept(this);
}
+
node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4244,15 +4292,14 @@
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
- FunctionBody outerFunctionBody = _currentFunctionBody;
try {
- _currentFunctionBody = node.body;
+ _promoteManager.enterFunctionBody(node.body);
_enclosingFunction = node.declaredElement;
FunctionType type = _enclosingFunction.type;
InferenceContext.setType(node.body, type.returnType);
super.visitConstructorDeclaration(node);
} finally {
- _currentFunctionBody = outerFunctionBody;
+ _promoteManager.exitFunctionBody();
_enclosingFunction = outerFunction;
}
ConstructorElementImpl constructor = node.declaredElement;
@@ -4304,6 +4351,7 @@
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
+ _flowAnalysis?.continueStatement(node);
}
@override
@@ -4327,9 +4375,24 @@
}
@override
- void visitDoStatement(DoStatement node) {
+ void visitDoStatementInScope(DoStatement node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
+ var body = node.body;
+ var condition = node.condition;
+
InferenceContext.setType(node.condition, typeProvider.boolType);
- super.visitDoStatement(node);
+
+ _flowAnalysis?.flow?.doStatement_bodyBegin(
+ node,
+ _flowAnalysis?.assignedVariables[node],
+ );
+ visitStatementInScope(body);
+
+ _flowAnalysis?.flow?.doStatement_conditionBegin();
+ condition.accept(this);
+
+ _flowAnalysis?.flow?.doStatement_end(node, node.condition);
}
@override
@@ -4444,6 +4507,8 @@
@override
void visitForStatementInScope(ForStatement node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
ForLoopParts forLoopParts = node.forLoopParts;
if (forLoopParts is ForParts) {
if (forLoopParts is ForPartsWithDeclarations) {
@@ -4451,10 +4516,22 @@
} else if (forLoopParts is ForPartsWithExpression) {
forLoopParts.initialization?.accept(this);
}
- InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
- forLoopParts.condition?.accept(this);
+
+ var condition = forLoopParts.condition;
+ InferenceContext.setType(condition, typeProvider.boolType);
+
+ _flowAnalysis?.forStatement_conditionBegin(node, condition);
+ if (condition != null) {
+ condition.accept(this);
+ }
+
+ _flowAnalysis?.forStatement_bodyBegin(node, condition);
visitStatementInScope(node.body);
+
+ _flowAnalysis?.flow?.forStatement_updaterBegin();
forLoopParts.updaters.accept(this);
+
+ _flowAnalysis?.flow?.forStatement_end();
} else if (forLoopParts is ForEachParts) {
Expression iterable = forLoopParts.iterable;
DeclaredIdentifier loopVariable;
@@ -4493,10 +4570,18 @@
//
iterable?.accept(this);
loopVariable?.accept(this);
+
+ _flowAnalysis?.flow?.forEachStatement_bodyBegin(
+ _flowAnalysis?.assignedVariables[node],
+ );
+
Statement body = node.body;
if (body != null) {
visitStatementInScope(body);
}
+
+ _flowAnalysis?.flow?.forEachStatement_end();
+
node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4505,16 +4590,15 @@
@override
void visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
- FunctionBody outerFunctionBody = _currentFunctionBody;
try {
SimpleIdentifier functionName = node.name;
- _currentFunctionBody = node.functionExpression.body;
+ _promoteManager.enterFunctionBody(node.functionExpression.body);
_enclosingFunction = functionName.staticElement as ExecutableElement;
InferenceContext.setType(
node.functionExpression, _enclosingFunction.type);
super.visitFunctionDeclaration(node);
} finally {
- _currentFunctionBody = outerFunctionBody;
+ _promoteManager.exitFunctionBody();
_enclosingFunction = outerFunction;
}
}
@@ -4528,9 +4612,13 @@
@override
void visitFunctionExpression(FunctionExpression node) {
ExecutableElement outerFunction = _enclosingFunction;
- FunctionBody outerFunctionBody = _currentFunctionBody;
try {
- _currentFunctionBody = node.body;
+ if (_flowAnalysis != null) {
+ _flowAnalysis.flow?.functionExpression_begin();
+ } else {
+ _promoteManager.enterFunctionBody(node.body);
+ }
+
_enclosingFunction = node.declaredElement;
DartType functionType = InferenceContext.getContext(node);
if (functionType is FunctionType) {
@@ -4544,7 +4632,12 @@
}
super.visitFunctionExpression(node);
} finally {
- _currentFunctionBody = outerFunctionBody;
+ if (_flowAnalysis != null) {
+ _flowAnalysis.flow?.functionExpression_end();
+ } else {
+ _promoteManager.exitFunctionBody();
+ }
+
_enclosingFunction = outerFunction;
}
}
@@ -4592,22 +4685,16 @@
void visitIfElement(IfElement node) {
Expression condition = node.condition;
InferenceContext.setType(condition, typeProvider.boolType);
+ // TODO(scheglov) Do we need these checks for null?
condition?.accept(this);
CollectionElement thenElement = node.thenElement;
- if (thenElement != null) {
- _promoteManager.enterScope();
- try {
- // Type promotion.
- _promoteTypes(condition);
- _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
- _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
- thenElement);
- // Visit "then".
+ _promoteManager.visitIfElement_thenElement(
+ condition,
+ thenElement,
+ () {
thenElement.accept(this);
- } finally {
- _promoteManager.exitScope();
- }
- }
+ },
+ );
node.elseElement?.accept(this);
node.accept(elementResolver);
@@ -4616,28 +4703,35 @@
@override
void visitIfStatement(IfStatement node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
Expression condition = node.condition;
+
InferenceContext.setType(condition, typeProvider.boolType);
condition?.accept(this);
+
Statement thenStatement = node.thenStatement;
- if (thenStatement != null) {
- _promoteManager.enterScope();
- try {
- // Type promotion.
- _promoteTypes(condition);
- _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
- _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
- thenStatement);
- // Visit "then".
- visitStatementInScope(thenStatement);
- } finally {
- _promoteManager.exitScope();
- }
+ if (_flowAnalysis != null) {
+ _flowAnalysis.flow.ifStatement_thenBegin(node, condition);
+ visitStatementInScope(thenStatement);
+ } else {
+ _promoteManager.visitIfStatement_thenStatement(
+ condition,
+ thenStatement,
+ () {
+ visitStatementInScope(thenStatement);
+ },
+ );
}
+
Statement elseStatement = node.elseStatement;
if (elseStatement != null) {
+ _flowAnalysis?.flow?.ifStatement_elseBegin();
visitStatementInScope(elseStatement);
}
+
+ _flowAnalysis?.flow?.ifStatement_end(elseStatement != null);
+
node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4665,6 +4759,12 @@
}
@override
+ void visitIsExpression(IsExpression node) {
+ super.visitIsExpression(node);
+ _flowAnalysis?.isExpression(node);
+ }
+
+ @override
void visitLabel(Label node) {}
@override
@@ -4701,16 +4801,15 @@
@override
void visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
- FunctionBody outerFunctionBody = _currentFunctionBody;
try {
- _currentFunctionBody = node.body;
+ _promoteManager.enterFunctionBody(node.body);
_enclosingFunction = node.declaredElement;
DartType returnType =
_computeReturnOrYieldType(_enclosingFunction.type?.returnType);
InferenceContext.setType(node.body, returnType);
super.visitMethodDeclaration(node);
} finally {
- _currentFunctionBody = outerFunctionBody;
+ _promoteManager.exitFunctionBody();
_enclosingFunction = outerFunction;
}
}
@@ -4767,6 +4866,7 @@
@override
void visitNode(AstNode node) {
+ _flowAnalysis?.checkUnreachableNode(node);
node.visitChildren(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
@@ -4790,6 +4890,16 @@
}
@override
+ void visitPrefixExpression(PrefixExpression node) {
+ super.visitPrefixExpression(node);
+
+ var operator = node.operator.type;
+ if (operator == TokenType.BANG) {
+ _flowAnalysis?.flow?.logicalNot_end(node, node.operand);
+ }
+ }
+
+ @override
void visitPropertyAccess(PropertyAccess node) {
//
// We visit the target, but do not visit the property name because it needs
@@ -4816,6 +4926,12 @@
}
@override
+ void visitRethrowExpression(RethrowExpression node) {
+ super.visitRethrowExpression(node);
+ _flowAnalysis?.flow?.handleExit();
+ }
+
+ @override
void visitReturnStatement(ReturnStatement node) {
Expression e = node.expression;
InferenceContext.setType(e, inferenceContext.returnContext);
@@ -4829,6 +4945,7 @@
}
inferenceContext.addReturnOrYieldType(type);
}
+ _flowAnalysis?.flow?.handleExit();
}
@override
@@ -4889,6 +5006,23 @@
void visitShowCombinator(ShowCombinator node) {}
@override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ _flowAnalysis?.simpleIdentifier(node);
+
+ if (_flowAnalysis != null &&
+ _flowAnalysis.isPotentiallyNonNullableLocalReadBeforeWrite(node)) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ node,
+ [node.name],
+ );
+ }
+
+ super.visitSimpleIdentifier(node);
+ }
+
+ @override
void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
//
// We visit the argument list, but do not visit the optional identifier
@@ -4904,6 +5038,8 @@
@override
void visitSwitchCase(SwitchCase node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
InferenceContext.setType(
node.expression, _enclosingSwitchStatementExpressionType);
super.visitSwitchCase(node);
@@ -4911,17 +5047,97 @@
@override
void visitSwitchStatementInScope(SwitchStatement node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
var previousExpressionType = _enclosingSwitchStatementExpressionType;
try {
- node.expression?.accept(this);
- _enclosingSwitchStatementExpressionType = node.expression.staticType;
- node.members.accept(this);
+ var expression = node.expression;
+ expression.accept(this);
+ _enclosingSwitchStatementExpressionType = expression.staticType;
+
+ if (_flowAnalysis != null) {
+ var flow = _flowAnalysis.flow;
+ var assignedInCases = _flowAnalysis.assignedVariables[node];
+
+ flow.switchStatement_expressionEnd(node);
+
+ var hasDefault = false;
+ var members = node.members;
+ for (var member in members) {
+ flow.switchStatement_beginCase(
+ member.labels.isNotEmpty
+ ? assignedInCases
+ : _flowAnalysis.assignedVariables.emptySet,
+ );
+ member.accept(this);
+
+ // Implicit `break` at the end of `default`.
+ if (member is SwitchDefault) {
+ hasDefault = true;
+ flow.handleBreak(node);
+ }
+ }
+
+ flow.switchStatement_end(node, hasDefault);
+ } else {
+ node.members.accept(this);
+ }
} finally {
_enclosingSwitchStatementExpressionType = previousExpressionType;
}
}
@override
+ void visitThrowExpression(ThrowExpression node) {
+ super.visitThrowExpression(node);
+ _flowAnalysis?.flow?.handleExit();
+ }
+
+ @override
+ void visitTryStatement(TryStatement node) {
+ if (_flowAnalysis == null) {
+ return super.visitTryStatement(node);
+ }
+
+ _flowAnalysis.checkUnreachableNode(node);
+ var flow = _flowAnalysis.flow;
+
+ var body = node.body;
+ var catchClauses = node.catchClauses;
+ var finallyBlock = node.finallyBlock;
+
+ if (finallyBlock != null) {
+ flow.tryFinallyStatement_bodyBegin();
+ }
+
+ flow.tryCatchStatement_bodyBegin();
+ body.accept(this);
+ flow.tryCatchStatement_bodyEnd(
+ _flowAnalysis.assignedVariables[body],
+ );
+
+ var catchLength = catchClauses.length;
+ for (var i = 0; i < catchLength; ++i) {
+ var catchClause = catchClauses[i];
+ flow.tryCatchStatement_catchBegin();
+ catchClause.accept(this);
+ flow.tryCatchStatement_catchEnd();
+ }
+
+ flow.tryCatchStatement_end();
+
+ if (finallyBlock != null) {
+ flow.tryFinallyStatement_finallyBegin(
+ _flowAnalysis.assignedVariables[body],
+ );
+ finallyBlock.accept(this);
+ flow.tryFinallyStatement_end(
+ _flowAnalysis.assignedVariables[finallyBlock],
+ );
+ }
+ }
+
+ @override
void visitTypeName(TypeName node) {}
@override
@@ -4954,18 +5170,34 @@
}
@override
+ void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ _flowAnalysis?.variableDeclarationStatement(node);
+ super.visitVariableDeclarationStatement(node);
+ }
+
+ @override
void visitWhileStatement(WhileStatement node) {
+ _flowAnalysis?.checkUnreachableNode(node);
+
// Note: since we don't call the base class, we have to maintain
// _implicitLabelScope ourselves.
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
_implicitLabelScope = _implicitLabelScope.nest(node);
+
Expression condition = node.condition;
InferenceContext.setType(condition, typeProvider.boolType);
+
+ _flowAnalysis?.flow?.whileStatement_conditionBegin(
+ _flowAnalysis?.assignedVariables[node],
+ );
condition?.accept(this);
+
Statement body = node.body;
if (body != null) {
+ _flowAnalysis?.flow?.whileStatement_bodyBegin(node, condition);
visitStatementInScope(body);
+ _flowAnalysis?.flow?.whileStatement_end();
}
} finally {
_implicitLabelScope = outerImplicitScope;
@@ -5021,36 +5253,6 @@
}
}
- /// Checks each promoted variable in the current scope for compliance with the
- /// following specification statement:
- ///
- /// If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i>
- /// then the variable <i>v</i> is not potentially mutated anywhere in the
- /// scope of <i>v</i>.
- void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
- AstNode target) {
- for (Element element in _promoteManager.promotedElements) {
- if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
- if (_isVariableAccessedInClosure(element, target)) {
- _promoteManager.setType(element, null);
- }
- }
- }
- }
-
- /// Checks each promoted variable in the current scope for compliance with the
- /// following specification statement:
- ///
- /// <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a
- /// closure.
- void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) {
- for (Element element in _promoteManager.promotedElements) {
- if (_isVariablePotentiallyMutatedIn(element, target)) {
- _promoteManager.setType(element, null);
- }
- }
- }
-
/// Given the declared return type of a function, compute the type of the
/// values which should be returned or yielded as appropriate. If a type
/// cannot be computed from the declared return type, return null.
@@ -5333,86 +5535,6 @@
}
}
- /// Return `true` if the given variable is accessed within a closure in the
- /// given [AstNode] and also mutated somewhere in variable scope. This
- /// information is only available for local variables (including parameters).
- ///
- /// @param variable the variable to check
- /// @param target the [AstNode] to check within
- /// @return `true` if this variable is potentially mutated somewhere in the
- /// given ASTNode
- bool _isVariableAccessedInClosure(Element variable, AstNode target) {
- _ResolverVisitor_isVariableAccessedInClosure visitor =
- new _ResolverVisitor_isVariableAccessedInClosure(variable);
- target.accept(visitor);
- return visitor.result;
- }
-
- /// Return `true` if the given variable is potentially mutated somewhere in
- /// the given [AstNode]. This information is only available for local
- /// variables (including parameters).
- ///
- /// @param variable the variable to check
- /// @param target the [AstNode] to check within
- /// @return `true` if this variable is potentially mutated somewhere in the
- /// given ASTNode
- bool _isVariablePotentiallyMutatedIn(Element variable, AstNode target) {
- _ResolverVisitor_isVariablePotentiallyMutatedIn visitor =
- new _ResolverVisitor_isVariablePotentiallyMutatedIn(variable);
- target.accept(visitor);
- return visitor.result;
- }
-
- /// If it is appropriate to do so, promotes the current type of the static
- /// element associated with the given expression with the given type.
- /// Generally speaking, it is appropriate if the given type is more specific
- /// than the current type.
- ///
- /// @param expression the expression used to access the static element whose
- /// types might be promoted
- /// @param potentialType the potential type of the elements
- void _promote(Expression expression, DartType potentialType) {
- VariableElement element = getPromotionStaticElement(expression);
- if (element != null) {
- // may be mutated somewhere in closure
- if (_currentFunctionBody.isPotentiallyMutatedInClosure(element)) {
- return;
- }
- // prepare current variable type
- DartType type = _promoteManager.getType(element) ??
- expression.staticType ??
- DynamicTypeImpl.instance;
-
- potentialType ??= DynamicTypeImpl.instance;
-
- // Check if we can promote to potentialType from type.
- DartType promoteType = typeSystem.tryPromoteToType(potentialType, type);
- if (promoteType != null) {
- // Do promote type of variable.
- _promoteManager.setType(element, promoteType);
- }
- }
- }
-
- /// Promotes type information using given condition.
- void _promoteTypes(Expression condition) {
- if (condition is BinaryExpression) {
- if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) {
- Expression left = condition.leftOperand;
- Expression right = condition.rightOperand;
- _promoteTypes(left);
- _promoteTypes(right);
- _clearTypePromotionsIfPotentiallyMutatedIn(right);
- }
- } else if (condition is IsExpression) {
- if (condition.notOperator == null) {
- _promote(condition.expression, condition.type.type);
- }
- } else if (condition is ParenthesizedExpression) {
- _promoteTypes(condition.expression);
- }
- }
-
void _pushCollectionTypesDown(CollectionElement element,
{DartType elementType,
@required DartType iterableType,
@@ -5809,13 +5931,17 @@
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
_implicitLabelScope = _implicitLabelScope.nest(node);
- visitStatementInScope(node.body);
- node.condition?.accept(this);
+ visitDoStatementInScope(node);
} finally {
_implicitLabelScope = outerImplicitScope;
}
}
+ void visitDoStatementInScope(DoStatement node) {
+ visitStatementInScope(node.body);
+ node.condition?.accept(this);
+ }
+
@override
void visitEnumDeclaration(EnumDeclaration node) {
ClassElement classElement = node.declaredElement;
@@ -7110,93 +7236,6 @@
}
}
-/// Instances of the class `TypePromotionManager` manage the ability to promote
-/// types of local variables and formal parameters from their declared types
-/// based on control flow.
-class TypePromotionManager {
- /// The current promotion scope, or `null` if no scope has been entered.
- TypePromotionManager_TypePromoteScope currentScope;
-
- /// Returns the elements with promoted types.
- Iterable<Element> get promotedElements => currentScope.promotedElements;
-
- /// Enter a new promotions scope.
- void enterScope() {
- currentScope = new TypePromotionManager_TypePromoteScope(currentScope);
- }
-
- /// Exit the current promotion scope.
- void exitScope() {
- if (currentScope == null) {
- throw new StateError("No scope to exit");
- }
- currentScope = currentScope._outerScope;
- }
-
- /// Return the static type of the given [variable] - declared or promoted.
- DartType getStaticType(VariableElement variable) =>
- getType(variable) ?? variable.type;
-
- /// Return the promoted type of the given [element], or `null` if the type of
- /// the element has not been promoted.
- DartType getType(Element element) => currentScope?.getType(element);
-
- /// Set the promoted type of the given element to the given type.
- ///
- /// @param element the element whose type might have been promoted
- /// @param type the promoted type of the given element
- void setType(Element element, DartType type) {
- if (currentScope == null) {
- throw new StateError("Cannot promote without a scope");
- }
- currentScope.setType(element, type);
- }
-}
-
-/// Instances of the class `TypePromoteScope` represent a scope in which the
-/// types of elements can be promoted.
-class TypePromotionManager_TypePromoteScope {
- /// The outer scope in which types might be promoter.
- final TypePromotionManager_TypePromoteScope _outerScope;
-
- /// A table mapping elements to the promoted type of that element.
- Map<Element, DartType> _promotedTypes = new HashMap<Element, DartType>();
-
- /// Initialize a newly created scope to be an empty child of the given scope.
- ///
- /// @param outerScope the outer scope in which types might be promoted
- TypePromotionManager_TypePromoteScope(this._outerScope);
-
- /// Returns the elements with promoted types.
- Iterable<Element> get promotedElements => _promotedTypes.keys.toSet();
-
- /// Return the promoted type of the given element, or `null` if the type of
- /// the element has not been promoted.
- ///
- /// @param element the element whose type might have been promoted
- /// @return the promoted type of the given element
- DartType getType(Element element) {
- DartType type = _promotedTypes[element];
- if (type == null && element is PropertyAccessorElement) {
- type = _promotedTypes[element.variable];
- }
- if (type != null) {
- return type;
- } else if (_outerScope != null) {
- return _outerScope.getType(element);
- }
- return null;
- }
-
- /// Set the promoted type of the given element to the given type.
- ///
- /// @param element the element whose type might have been promoted
- /// @param type the promoted type of the given element
- void setType(Element element, DartType type) {
- _promotedTypes[element] = type;
- }
-}
-
/// The interface `TypeProvider` defines the behavior of objects that provide
/// access to types defined by the language.
abstract class TypeProvider {
@@ -9076,56 +9115,3 @@
/// The kind of literal to which an unknown literal should be resolved.
enum _LiteralResolutionKind { ambiguous, map, set }
-
-class _ResolverVisitor_isVariableAccessedInClosure
- extends RecursiveAstVisitor<void> {
- final Element variable;
-
- bool result = false;
-
- bool _inClosure = false;
-
- _ResolverVisitor_isVariableAccessedInClosure(this.variable);
-
- @override
- void visitFunctionExpression(FunctionExpression node) {
- bool inClosure = this._inClosure;
- try {
- this._inClosure = true;
- super.visitFunctionExpression(node);
- } finally {
- this._inClosure = inClosure;
- }
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- if (result) {
- return;
- }
- if (_inClosure && identical(node.staticElement, variable)) {
- result = true;
- }
- }
-}
-
-class _ResolverVisitor_isVariablePotentiallyMutatedIn
- extends RecursiveAstVisitor<void> {
- final Element variable;
-
- bool result = false;
-
- _ResolverVisitor_isVariablePotentiallyMutatedIn(this.variable);
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- if (result) {
- return;
- }
- if (identical(node.staticElement, variable)) {
- if (node.inSetterContext()) {
- result = true;
- }
- }
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 86ef733..b1ec9e0 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -7,16 +7,10 @@
import 'dart:collection';
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
@@ -227,72 +221,3 @@
return null;
}
}
-
-/**
- * An object used to read and parse the libraries file
- * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for information
- * about the libraries in an SDK. The library information is represented as a
- * Dart file containing a single top-level variable whose value is a const map.
- * The keys of the map are the names of libraries defined in the SDK and the
- * values in the map are info objects defining the library. For example, a
- * subset of a typical SDK might have a libraries file that looks like the
- * following:
- *
- * final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
- * // Used by VM applications
- * "builtin" : const LibraryInfo(
- * "builtin/builtin_runtime.dart",
- * category: "Server",
- * platforms: VM_PLATFORM),
- *
- * "compiler" : const LibraryInfo(
- * "compiler/compiler.dart",
- * category: "Tools",
- * platforms: 0),
- * };
- */
-@deprecated
-class SdkLibrariesReader {
- /**
- * A flag indicating whether the dart2js path should be used when it is
- * available.
- */
- final bool _useDart2jsPaths;
-
- /**
- * Initialize a newly created library reader to use the dart2js path if
- * [_useDart2jsPaths] is `true`.
- */
- SdkLibrariesReader(this._useDart2jsPaths);
-
- /**
- * Return the library map read from the given [file], given that the content
- * of the file is already known to be [libraryFileContents].
- */
- LibraryMap readFromFile(JavaFile file, String libraryFileContents) =>
- readFromSource(new FileBasedSource(file), libraryFileContents);
-
- /**
- * Return the library map read from the given [source], given that the content
- * of the file is already known to be [libraryFileContents].
- */
- LibraryMap readFromSource(Source source, String libraryFileContents) {
- BooleanErrorListener errorListener = new BooleanErrorListener();
- // TODO(paulberry): initialize the feature set appropriately based on the
- // version of the SDK we are reading, and enable flags.
- var featureSet = FeatureSet.fromEnableFlags([]);
- Scanner scanner = new Scanner(
- source, new CharSequenceReader(libraryFileContents), errorListener)
- ..configureFeatures(featureSet);
- Parser parser = new Parser(source, errorListener, featureSet: featureSet);
- CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
- SdkLibrariesReader_LibraryBuilder libraryBuilder =
- new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths);
- // If any syntactic errors were found then don't try to visit the AST
- // structure.
- if (!errorListener.errorReported) {
- unit.accept(libraryBuilder);
- }
- return libraryBuilder.librariesMap;
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 1ce52ef..efa1dc9 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.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.
-import 'dart:collection';
-
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -21,6 +19,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
import 'package:analyzer/src/task/strong/checker.dart'
show getExpressionType, getReadType;
import 'package:meta/meta.dart';
@@ -72,9 +71,9 @@
InterfaceType thisType;
/**
- * The object keeping track of which elements have had their types promoted.
+ * The object providing promoted or declared types of variables.
*/
- TypePromotionManager _promoteManager;
+ LocalVariableTypeProvider _localVariableTypeProvider;
/**
* Initialize a newly created static type analyzer to analyze types for the
@@ -86,7 +85,7 @@
_typeProvider = _resolver.typeProvider;
_typeSystem = _resolver.typeSystem;
_dynamicType = _typeProvider.dynamicType;
- _promoteManager = _resolver.promoteManager;
+ _localVariableTypeProvider = _resolver.localVariableTypeProvider;
AnalysisOptionsImpl analysisOptions =
_resolver.definingLibrary.context.analysisOptions;
_strictInference = analysisOptions.strictInference;
@@ -1042,8 +1041,7 @@
} else if (element is TypeParameterElement) {
staticType = _nonNullable(_typeProvider.typeType);
} else if (element is VariableElement) {
- VariableElement variable = element;
- staticType = _promoteManager.getStaticType(variable);
+ staticType = _localVariableTypeProvider.getType(node);
} else if (element is PrefixElement) {
var parent = node.parent;
if (parent is PrefixedIdentifier && parent.prefix == node ||
@@ -1296,9 +1294,6 @@
}
} else if (element is ExecutableElement) {
return _computeInvokeReturnType(element.type, isNullableInvoke: false);
- } else if (element is VariableElement) {
- DartType variableType = _promoteManager.getStaticType(element);
- return _computeInvokeReturnType(variableType, isNullableInvoke: false);
}
return _dynamicType;
}
@@ -1320,48 +1315,6 @@
return returnType.type;
}
- DartType _findIteratedType(DartType type, DartType targetType) {
- // TODO(vsm): Use leafp's matchType here?
- // Set by _find if match is found
- DartType result;
- // Elements we've already visited on a given inheritance path.
- HashSet<ClassElement> visitedClasses;
-
- type = type.resolveToBound(_typeProvider.objectType);
-
- bool _find(InterfaceType type) {
- ClassElement element = type.element;
- if (type == _typeProvider.objectType || element == null) {
- return false;
- }
- if (element == targetType.element) {
- List<DartType> typeArguments = type.typeArguments;
- assert(typeArguments.length == 1);
- result = typeArguments[0];
- return true;
- }
- if (visitedClasses == null) {
- visitedClasses = new HashSet<ClassElement>();
- }
- // Already visited this class along this path
- if (!visitedClasses.add(element)) {
- return false;
- }
- try {
- return _find(type.superclass) ||
- type.interfaces.any(_find) ||
- type.mixins.any(_find);
- } finally {
- visitedClasses.remove(element);
- }
- }
-
- if (type is InterfaceType) {
- _find(type);
- }
- return result;
- }
-
/**
* If the given element name can be mapped to the name of a class defined within the given
* library, return the type specified by the argument.
@@ -1573,14 +1526,22 @@
}
if (iterable != null) {
LocalVariableElementImpl element = loopVariable.declaredElement;
- DartType exprType = iterable.staticType;
- DartType targetType = (awaitKeyword == null)
- ? _typeProvider.iterableType
- : _typeProvider.streamType;
- DartType iteratedType = _findIteratedType(exprType, targetType);
+
+ DartType iterableType = iterable.staticType;
+ iterableType = iterableType.resolveToBound(_typeProvider.objectType);
+
+ ClassElement iteratedElement = (awaitKeyword == null)
+ ? _typeProvider.iterableType.element
+ : _typeProvider.streamType.element;
+
+ InterfaceType iteratedType = iterableType is InterfaceTypeImpl
+ ? iterableType.asInstanceOf(iteratedElement)
+ : null;
+
if (element != null && iteratedType != null) {
- element.type = iteratedType;
- loopVariable.identifier.staticType = iteratedType;
+ DartType elementType = iteratedType.typeArguments.single;
+ element.type = elementType;
+ loopVariable.identifier.staticType = elementType;
}
}
}
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 9237339..a84c48b 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -277,7 +277,7 @@
String scriptTag,
List<Directive> directives,
List<CompilationUnitMember> declarations) =>
- astFactory.compilationUnit2(
+ astFactory.compilationUnit(
beginToken: TokenFactory.tokenFromType(TokenType.EOF),
scriptTag:
scriptTag == null ? null : AstTestFactory.scriptTag(scriptTag),
@@ -293,7 +293,7 @@
List<Directive> directives,
List<CompilationUnitMember> declarations,
FeatureSet featureSet}) =>
- astFactory.compilationUnit2(
+ astFactory.compilationUnit(
beginToken: TokenFactory.tokenFromType(TokenType.EOF),
scriptTag:
scriptTag == null ? null : AstTestFactory.scriptTag(scriptTag),
@@ -505,6 +505,15 @@
rightBracket:
TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
+ static ExtensionOverride extensionOverride(
+ {@required Identifier extensionName,
+ TypeArgumentList typeArguments,
+ @required ArgumentList argumentList}) =>
+ astFactory.extensionOverride(
+ extensionName: extensionName,
+ typeArguments: typeArguments,
+ argumentList: argumentList);
+
static FieldDeclaration fieldDeclaration(bool isStatic, Keyword keyword,
TypeAnnotation type, List<VariableDeclaration> variables) =>
astFactory.fieldDeclaration2(
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 8ea7304..b408d5f 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -121,11 +121,6 @@
InterfaceType _mapObjectObjectType;
/**
- * The type representing the built-in type 'Never'.
- */
- InterfaceType _neverType;
-
- /**
* An shared object representing the value 'null'.
*/
DartObjectImpl _nullObject;
@@ -446,13 +441,8 @@
}
@override
- InterfaceType get neverType {
- if (_neverType == null) {
- ClassElementImpl neverElement =
- ElementFactory.classElement('Never', objectType);
- _neverType = neverElement.type;
- }
- return _neverType;
+ DartType get neverType {
+ return BottomTypeImpl.instance;
}
@override
diff --git a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
new file mode 100644
index 0000000..14f1835
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
@@ -0,0 +1,395 @@
+// 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/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
+
+/// Instances of the class `TypePromotionManager` manage the ability to promote
+/// types of local variables and formal parameters from their declared types
+/// based on control flow.
+class TypePromotionManager {
+ final TypeSystem _typeSystem;
+
+ /// The current promotion scope, or `null` if no scope has been entered.
+ _TypePromoteScope _currentScope;
+
+ final List<FunctionBody> _functionBodyStack = [];
+
+ /// Body of the function currently being analyzed, if any.
+ FunctionBody _currentFunctionBody;
+
+ TypePromotionManager(this._typeSystem);
+
+ LocalVariableTypeProvider get localVariableTypeProvider {
+ return _LegacyLocalVariableTypeProvider(this);
+ }
+
+ /// Returns the elements with promoted types.
+ Iterable<Element> get _promotedElements {
+ return _currentScope.promotedElements;
+ }
+
+ void enterFunctionBody(FunctionBody body) {
+ _functionBodyStack.add(_currentFunctionBody);
+ _currentFunctionBody = body;
+ }
+
+ void exitFunctionBody() {
+ _currentFunctionBody = _functionBodyStack.removeLast();
+ }
+
+ void visitBinaryExpression_and_rhs(
+ Expression leftOperand, Expression rightOperand, void f()) {
+ if (rightOperand != null) {
+ _enterScope();
+ try {
+ // Type promotion.
+ _promoteTypes(leftOperand);
+ _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
+ _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
+ _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+ rightOperand);
+ // Visit right operand.
+ f();
+ } finally {
+ _exitScope();
+ }
+ }
+ }
+
+ void visitConditionalExpression_then(
+ Expression condition, Expression thenExpression, void f()) {
+ if (thenExpression != null) {
+ _enterScope();
+ try {
+ // Type promotion.
+ _promoteTypes(condition);
+ _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
+ _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+ thenExpression,
+ );
+ // Visit "then" expression.
+ f();
+ } finally {
+ _exitScope();
+ }
+ }
+ }
+
+ void visitIfElement_thenElement(
+ Expression condition, CollectionElement thenElement, void f()) {
+ if (thenElement != null) {
+ _enterScope();
+ try {
+ // Type promotion.
+ _promoteTypes(condition);
+ _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
+ _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+ thenElement);
+ // Visit "then".
+ f();
+ } finally {
+ _exitScope();
+ }
+ }
+ }
+
+ void visitIfStatement_thenStatement(
+ Expression condition, Statement thenStatement, void f()) {
+ if (thenStatement != null) {
+ _enterScope();
+ try {
+ // Type promotion.
+ _promoteTypes(condition);
+ _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
+ _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+ thenStatement);
+ // Visit "then".
+ f();
+ } finally {
+ _exitScope();
+ }
+ }
+ }
+
+ /// Checks each promoted variable in the current scope for compliance with the
+ /// following specification statement:
+ ///
+ /// If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i>
+ /// then the variable <i>v</i> is not potentially mutated anywhere in the
+ /// scope of <i>v</i>.
+ void _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+ AstNode target) {
+ for (Element element in _promotedElements) {
+ if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
+ if (_isVariableAccessedInClosure(element, target)) {
+ _setType(element, null);
+ }
+ }
+ }
+ }
+
+ /// Checks each promoted variable in the current scope for compliance with the
+ /// following specification statement:
+ ///
+ /// <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a
+ /// closure.
+ void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) {
+ for (Element element in _promotedElements) {
+ if (_isVariablePotentiallyMutatedIn(element, target)) {
+ _setType(element, null);
+ }
+ }
+ }
+
+ /// Enter a new promotions scope.
+ void _enterScope() {
+ _currentScope = new _TypePromoteScope(_currentScope);
+ }
+
+ /// Exit the current promotion scope.
+ void _exitScope() {
+ if (_currentScope == null) {
+ throw new StateError("No scope to exit");
+ }
+ _currentScope = _currentScope._outerScope;
+ }
+
+ /// Return the promoted type of the given [element], or `null` if the type of
+ /// the element has not been promoted.
+ DartType _getPromotedType(Element element) {
+ return _currentScope?.getType(element);
+ }
+
+ /// Return the static element associated with the given expression whose type
+ /// can be promoted, or `null` if there is no element whose type can be
+ /// promoted.
+ VariableElement _getPromotionStaticElement(Expression expression) {
+ expression = expression?.unParenthesized;
+ if (expression is SimpleIdentifier) {
+ Element element = expression.staticElement;
+ if (element is VariableElement) {
+ ElementKind kind = element.kind;
+ if (kind == ElementKind.LOCAL_VARIABLE ||
+ kind == ElementKind.PARAMETER) {
+ return element;
+ }
+ }
+ }
+ return null;
+ }
+
+ /// Given that the [node] is a reference to a [VariableElement], return the
+ /// static type of the variable at this node - declared or promoted.
+ DartType _getType(SimpleIdentifier node) {
+ var variable = node.staticElement as VariableElement;
+ return _getPromotedType(variable) ?? variable.type;
+ }
+
+ /// Return `true` if the given variable is accessed within a closure in the
+ /// given [AstNode] and also mutated somewhere in variable scope. This
+ /// information is only available for local variables (including parameters).
+ ///
+ /// @param variable the variable to check
+ /// @param target the [AstNode] to check within
+ /// @return `true` if this variable is potentially mutated somewhere in the
+ /// given ASTNode
+ bool _isVariableAccessedInClosure(Element variable, AstNode target) {
+ _ResolverVisitor_isVariableAccessedInClosure visitor =
+ new _ResolverVisitor_isVariableAccessedInClosure(variable);
+ target.accept(visitor);
+ return visitor.result;
+ }
+
+ /// Return `true` if the given variable is potentially mutated somewhere in
+ /// the given [AstNode]. This information is only available for local
+ /// variables (including parameters).
+ ///
+ /// @param variable the variable to check
+ /// @param target the [AstNode] to check within
+ /// @return `true` if this variable is potentially mutated somewhere in the
+ /// given ASTNode
+ bool _isVariablePotentiallyMutatedIn(Element variable, AstNode target) {
+ _ResolverVisitor_isVariablePotentiallyMutatedIn visitor =
+ new _ResolverVisitor_isVariablePotentiallyMutatedIn(variable);
+ target.accept(visitor);
+ return visitor.result;
+ }
+
+ /// If it is appropriate to do so, promotes the current type of the static
+ /// element associated with the given expression with the given type.
+ /// Generally speaking, it is appropriate if the given type is more specific
+ /// than the current type.
+ ///
+ /// @param expression the expression used to access the static element whose
+ /// types might be promoted
+ /// @param potentialType the potential type of the elements
+ void _promote(Expression expression, DartType potentialType) {
+ VariableElement element = _getPromotionStaticElement(expression);
+ if (element != null) {
+ // may be mutated somewhere in closure
+ if (_currentFunctionBody.isPotentiallyMutatedInClosure(element)) {
+ return;
+ }
+ // prepare current variable type
+ DartType type = _getPromotedType(element) ??
+ expression.staticType ??
+ DynamicTypeImpl.instance;
+
+ potentialType ??= DynamicTypeImpl.instance;
+
+ // Check if we can promote to potentialType from type.
+ DartType promoteType = _typeSystem.tryPromoteToType(potentialType, type);
+ if (promoteType != null) {
+ // Do promote type of variable.
+ _setType(element, promoteType);
+ }
+ }
+ }
+
+ /// Promotes type information using given condition.
+ void _promoteTypes(Expression condition) {
+ if (condition is BinaryExpression) {
+ if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+ Expression left = condition.leftOperand;
+ Expression right = condition.rightOperand;
+ _promoteTypes(left);
+ _promoteTypes(right);
+ _clearTypePromotionsIfPotentiallyMutatedIn(right);
+ }
+ } else if (condition is IsExpression) {
+ if (condition.notOperator == null) {
+ _promote(condition.expression, condition.type.type);
+ }
+ } else if (condition is ParenthesizedExpression) {
+ _promoteTypes(condition.expression);
+ }
+ }
+
+ /// Set the promoted type of the given element to the given type.
+ ///
+ /// @param element the element whose type might have been promoted
+ /// @param type the promoted type of the given element
+ void _setType(Element element, DartType type) {
+ if (_currentScope == null) {
+ throw new StateError("Cannot promote without a scope");
+ }
+ _currentScope.setType(element, type);
+ }
+}
+
+/// The legacy, pre-NNBD implementation of [LocalVariableTypeProvider].
+class _LegacyLocalVariableTypeProvider implements LocalVariableTypeProvider {
+ final TypePromotionManager _manager;
+
+ _LegacyLocalVariableTypeProvider(this._manager);
+
+ @override
+ DartType getType(SimpleIdentifier node) {
+ return _manager._getType(node);
+ }
+}
+
+class _ResolverVisitor_isVariableAccessedInClosure
+ extends RecursiveAstVisitor<void> {
+ final Element variable;
+
+ bool result = false;
+
+ bool _inClosure = false;
+
+ _ResolverVisitor_isVariableAccessedInClosure(this.variable);
+
+ @override
+ void visitFunctionExpression(FunctionExpression node) {
+ bool inClosure = this._inClosure;
+ try {
+ this._inClosure = true;
+ super.visitFunctionExpression(node);
+ } finally {
+ this._inClosure = inClosure;
+ }
+ }
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ if (result) {
+ return;
+ }
+ if (_inClosure && identical(node.staticElement, variable)) {
+ result = true;
+ }
+ }
+}
+
+class _ResolverVisitor_isVariablePotentiallyMutatedIn
+ extends RecursiveAstVisitor<void> {
+ final Element variable;
+
+ bool result = false;
+
+ _ResolverVisitor_isVariablePotentiallyMutatedIn(this.variable);
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ if (result) {
+ return;
+ }
+ if (identical(node.staticElement, variable)) {
+ if (node.inSetterContext()) {
+ result = true;
+ }
+ }
+ }
+}
+
+/// Instances of the class `TypePromoteScope` represent a scope in which the
+/// types of elements can be promoted.
+class _TypePromoteScope {
+ /// The outer scope in which types might be promoter.
+ final _TypePromoteScope _outerScope;
+
+ /// A table mapping elements to the promoted type of that element.
+ Map<Element, DartType> _promotedTypes = {};
+
+ /// Initialize a newly created scope to be an empty child of the given scope.
+ ///
+ /// @param outerScope the outer scope in which types might be promoted
+ _TypePromoteScope(this._outerScope);
+
+ /// Returns the elements with promoted types.
+ Iterable<Element> get promotedElements => _promotedTypes.keys.toSet();
+
+ /// Return the promoted type of the given element, or `null` if the type of
+ /// the element has not been promoted.
+ ///
+ /// @param element the element whose type might have been promoted
+ /// @return the promoted type of the given element
+ DartType getType(Element element) {
+ DartType type = _promotedTypes[element];
+ if (type == null && element is PropertyAccessorElement) {
+ type = _promotedTypes[element.variable];
+ }
+ if (type != null) {
+ return type;
+ } else if (_outerScope != null) {
+ return _outerScope.getType(element);
+ }
+ return null;
+ }
+
+ /// Set the promoted type of the given element to the given type.
+ ///
+ /// @param element the element whose type might have been promoted
+ /// @param type the promoted type of the given element
+ void setType(Element element, DartType type) {
+ _promotedTypes[element] = type;
+ }
+}
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 53d06e1..523beb8 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -65,11 +65,17 @@
}
/// Is [t] the top of the legacy type hierarch.
-bool _isLegacyTop(DartType t, {@required bool orTrueTop}) =>
-// TODO(mfairhurst): handle FutureOr<LegacyTop> cases, with tests.
- (t.isObject &&
- (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) ||
- (orTrueTop ? _isTop(t) : false);
+bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
+ if (t.isDartAsyncFutureOr) {
+ return _isLegacyTop((t as InterfaceType).typeArguments[0],
+ orTrueTop: orTrueTop);
+ }
+ if (t.isObject &&
+ (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) {
+ return true;
+ }
+ return orTrueTop ? _isTop(t) : false;
+}
bool _isTop(DartType t) {
if (t.isDartAsyncFutureOr) {
@@ -103,10 +109,6 @@
Dart2TypeSystem(this.typeProvider, {this.implicitCasts: true});
- @deprecated
- @override
- bool get isStrong => true;
-
/// Returns true iff the type [t] accepts function types, and requires an
/// implicit coercion if interface types with a `call` method are passed in.
///
@@ -631,6 +633,7 @@
}
// Legacy top case. Must be done now to find Object* <: Object.
+ // TODO: handle false positives like FutureOr<Object?>* and T* extends int?.
if (t1.nullabilitySuffix == NullabilitySuffix.star &&
_isLegacyTop(t2, orTrueTop: false)) {
return true;
@@ -1923,12 +1926,6 @@
// TODO(brianwilkerson) Rename this class to TypeSystemImpl.
abstract class TypeSystem implements public.TypeSystem {
/**
- * Whether the type system is strong or not.
- */
- @deprecated
- bool get isStrong;
-
- /**
* The provider of types for the system
*/
TypeProvider get typeProvider;
@@ -2105,11 +2102,11 @@
bool isNonNullable(DartType type) {
if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
return false;
- } else if (type.isDartAsyncFutureOr) {
- isNonNullable((type as InterfaceType).typeArguments[0]);
} else if ((type as TypeImpl).nullabilitySuffix ==
NullabilitySuffix.question) {
return false;
+ } else if (type.isDartAsyncFutureOr) {
+ return isNonNullable((type as InterfaceType).typeArguments[0]);
} else if (type is TypeParameterType) {
return isNonNullable(type.bound);
}
@@ -2120,10 +2117,13 @@
bool isNullable(DartType type) {
if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
return true;
+ } else if ((type as TypeImpl).nullabilitySuffix ==
+ NullabilitySuffix.question) {
+ return true;
} else if (type.isDartAsyncFutureOr) {
- isNullable((type as InterfaceType).typeArguments[0]);
+ return isNullable((type as InterfaceType).typeArguments[0]);
}
- return (type as TypeImpl).nullabilitySuffix != NullabilitySuffix.none;
+ return false;
}
/// Check that [f1] is a subtype of [f2] for a member override.
@@ -2342,8 +2342,30 @@
* Return a function type with those types.
*/
DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
- // TODO(rnystrom): Right now, this assumes f and g do not have any type
- // parameters. Revisit that in the presence of generic methods.
+ var fTypeFormals = f.typeFormals;
+ var gTypeFormals = g.typeFormals;
+
+ // If F and G differ in their number of type parameters, then the
+ // least upper bound of F and G is Function.
+ if (fTypeFormals.length != gTypeFormals.length) {
+ return typeProvider.functionType;
+ }
+
+ // If F and G differ in bounds of their of type parameters, then the
+ // least upper bound of F and G is Function.
+ var freshTypeFormalTypes =
+ FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
+ if (freshTypeFormalTypes == null) {
+ return typeProvider.functionType;
+ }
+
+ var typeFormals = freshTypeFormalTypes
+ .map<TypeParameterElement>((t) => t.element)
+ .toList();
+
+ f = f.instantiate(freshTypeFormalTypes);
+ g = g.instantiate(freshTypeFormalTypes);
+
List<DartType> fRequired = f.normalParameterTypes;
List<DartType> gRequired = g.normalParameterTypes;
@@ -2394,7 +2416,14 @@
// Calculate the LUB of the return type.
DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
- return new FunctionElementImpl.synthetic(parameters, returnType).type;
+
+ if (AnalysisDriver.useSummary2) {
+ return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
+ }
+
+ var element = FunctionElementImpl.synthetic(parameters, returnType);
+ element.typeParameters = typeFormals;
+ return element.type;
}
/**
diff --git a/pkg/analyzer/lib/src/generated/variable_type_provider.dart b/pkg/analyzer/lib/src/generated/variable_type_provider.dart
new file mode 100644
index 0000000..376d102
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/variable_type_provider.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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+
+/// Provider of types for local variables and formal parameters.
+abstract class LocalVariableTypeProvider {
+ /// Given that the [node] is a reference to a local variable, or a parameter,
+ /// return the type of the variable at the node - declared or promoted.
+ DartType getType(SimpleIdentifier node);
+}
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 79fff64..7e0df3b 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -1082,11 +1082,6 @@
_forForStatement.add(new _Subscription(linter, visitor, _getTimer(linter)));
}
- @Deprecated('Replaced by addForStatement')
- void addForStatement2(LintRule linter, AstVisitor visitor) {
- addForStatement(linter, visitor);
- }
-
void addFunctionDeclaration(LintRule linter, AstVisitor visitor) {
_forFunctionDeclaration
.add(new _Subscription(linter, visitor, _getTimer(linter)));
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 5c6d947..93b3719 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -887,6 +887,7 @@
class AnalysisDriverUnitErrorBuilder extends Object
with _AnalysisDriverUnitErrorMixin
implements idl.AnalysisDriverUnitError {
+ List<DiagnosticMessageBuilder> _contextMessages;
String _correction;
int _length;
String _message;
@@ -894,6 +895,15 @@
String _uniqueName;
@override
+ List<DiagnosticMessageBuilder> get contextMessages =>
+ _contextMessages ??= <DiagnosticMessageBuilder>[];
+
+ /// The context messages associated with the error.
+ set contextMessages(List<DiagnosticMessageBuilder> value) {
+ this._contextMessages = value;
+ }
+
+ @override
String get correction => _correction ??= '';
/// The optional correction hint for the error.
@@ -936,19 +946,23 @@
}
AnalysisDriverUnitErrorBuilder(
- {String correction,
+ {List<DiagnosticMessageBuilder> contextMessages,
+ String correction,
int length,
String message,
int offset,
String uniqueName})
- : _correction = correction,
+ : _contextMessages = contextMessages,
+ _correction = correction,
_length = length,
_message = message,
_offset = offset,
_uniqueName = uniqueName;
/// Flush [informative] data recursively.
- void flushInformative() {}
+ void flushInformative() {
+ _contextMessages?.forEach((b) => b.flushInformative());
+ }
/// Accumulate non-[informative] data into [signature].
void collectApiSignature(api_sig.ApiSignature signature) {
@@ -957,12 +971,25 @@
signature.addString(this._uniqueName ?? '');
signature.addString(this._message ?? '');
signature.addString(this._correction ?? '');
+ if (this._contextMessages == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._contextMessages.length);
+ for (var x in this._contextMessages) {
+ x?.collectApiSignature(signature);
+ }
+ }
}
fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_contextMessages;
fb.Offset offset_correction;
fb.Offset offset_message;
fb.Offset offset_uniqueName;
+ if (!(_contextMessages == null || _contextMessages.isEmpty)) {
+ offset_contextMessages = fbBuilder
+ .writeList(_contextMessages.map((b) => b.finish(fbBuilder)).toList());
+ }
if (_correction != null) {
offset_correction = fbBuilder.writeString(_correction);
}
@@ -973,6 +1000,9 @@
offset_uniqueName = fbBuilder.writeString(_uniqueName);
}
fbBuilder.startTable();
+ if (offset_contextMessages != null) {
+ fbBuilder.addOffset(5, offset_contextMessages);
+ }
if (offset_correction != null) {
fbBuilder.addOffset(4, offset_correction);
}
@@ -1009,6 +1039,7 @@
_AnalysisDriverUnitErrorImpl(this._bc, this._bcOffset);
+ List<idl.DiagnosticMessage> _contextMessages;
String _correction;
int _length;
String _message;
@@ -1016,6 +1047,14 @@
String _uniqueName;
@override
+ List<idl.DiagnosticMessage> get contextMessages {
+ _contextMessages ??= const fb.ListReader<idl.DiagnosticMessage>(
+ const _DiagnosticMessageReader())
+ .vTableGet(_bc, _bcOffset, 5, const <idl.DiagnosticMessage>[]);
+ return _contextMessages;
+ }
+
+ @override
String get correction {
_correction ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
return _correction;
@@ -1051,6 +1090,9 @@
@override
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
+ if (contextMessages.isNotEmpty)
+ _result["contextMessages"] =
+ contextMessages.map((_value) => _value.toJson()).toList();
if (correction != '') _result["correction"] = correction;
if (length != 0) _result["length"] = length;
if (message != '') _result["message"] = message;
@@ -1061,6 +1103,7 @@
@override
Map<String, Object> toMap() => {
+ "contextMessages": contextMessages,
"correction": correction,
"length": length,
"message": message,
@@ -3526,6 +3569,162 @@
String toString() => convert.json.encode(toJson());
}
+class DiagnosticMessageBuilder extends Object
+ with _DiagnosticMessageMixin
+ implements idl.DiagnosticMessage {
+ String _filePath;
+ int _length;
+ String _message;
+ int _offset;
+
+ @override
+ String get filePath => _filePath ??= '';
+
+ /// The absolute and normalized path of the file associated with this message.
+ set filePath(String value) {
+ this._filePath = value;
+ }
+
+ @override
+ int get length => _length ??= 0;
+
+ /// The length of the source range associated with this message.
+ set length(int value) {
+ assert(value == null || value >= 0);
+ this._length = value;
+ }
+
+ @override
+ String get message => _message ??= '';
+
+ /// The text of the message.
+ set message(String value) {
+ this._message = value;
+ }
+
+ @override
+ int get offset => _offset ??= 0;
+
+ /// The zero-based offset from the start of the file to the beginning of the
+ /// source range associated with this message.
+ set offset(int value) {
+ assert(value == null || value >= 0);
+ this._offset = value;
+ }
+
+ DiagnosticMessageBuilder(
+ {String filePath, int length, String message, int offset})
+ : _filePath = filePath,
+ _length = length,
+ _message = message,
+ _offset = offset;
+
+ /// Flush [informative] data recursively.
+ void flushInformative() {}
+
+ /// Accumulate non-[informative] data into [signature].
+ void collectApiSignature(api_sig.ApiSignature signature) {
+ signature.addString(this._filePath ?? '');
+ signature.addInt(this._length ?? 0);
+ signature.addString(this._message ?? '');
+ signature.addInt(this._offset ?? 0);
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_filePath;
+ fb.Offset offset_message;
+ if (_filePath != null) {
+ offset_filePath = fbBuilder.writeString(_filePath);
+ }
+ if (_message != null) {
+ offset_message = fbBuilder.writeString(_message);
+ }
+ fbBuilder.startTable();
+ if (offset_filePath != null) {
+ fbBuilder.addOffset(0, offset_filePath);
+ }
+ if (_length != null && _length != 0) {
+ fbBuilder.addUint32(1, _length);
+ }
+ if (offset_message != null) {
+ fbBuilder.addOffset(2, offset_message);
+ }
+ if (_offset != null && _offset != 0) {
+ fbBuilder.addUint32(3, _offset);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _DiagnosticMessageReader extends fb.TableReader<_DiagnosticMessageImpl> {
+ const _DiagnosticMessageReader();
+
+ @override
+ _DiagnosticMessageImpl createObject(fb.BufferContext bc, int offset) =>
+ new _DiagnosticMessageImpl(bc, offset);
+}
+
+class _DiagnosticMessageImpl extends Object
+ with _DiagnosticMessageMixin
+ implements idl.DiagnosticMessage {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _DiagnosticMessageImpl(this._bc, this._bcOffset);
+
+ String _filePath;
+ int _length;
+ String _message;
+ int _offset;
+
+ @override
+ String get filePath {
+ _filePath ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+ return _filePath;
+ }
+
+ @override
+ int get length {
+ _length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
+ return _length;
+ }
+
+ @override
+ String get message {
+ _message ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, '');
+ return _message;
+ }
+
+ @override
+ int get offset {
+ _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
+ return _offset;
+ }
+}
+
+abstract class _DiagnosticMessageMixin implements idl.DiagnosticMessage {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (filePath != '') _result["filePath"] = filePath;
+ if (length != 0) _result["length"] = length;
+ if (message != '') _result["message"] = message;
+ if (offset != 0) _result["offset"] = offset;
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "filePath": filePath,
+ "length": length,
+ "message": message,
+ "offset": offset,
+ };
+
+ @override
+ String toString() => convert.json.encode(toJson());
+}
+
class DirectiveInfoBuilder extends Object
with _DirectiveInfoMixin
implements idl.DirectiveInfo {
@@ -22257,6 +22456,331 @@
String toString() => convert.json.encode(toJson());
}
+class UnlinkedExtensionBuilder extends Object
+ with _UnlinkedExtensionMixin
+ implements idl.UnlinkedExtension {
+ List<UnlinkedExprBuilder> _annotations;
+ CodeRangeBuilder _codeRange;
+ UnlinkedDocumentationCommentBuilder _documentationComment;
+ List<UnlinkedExecutableBuilder> _executables;
+ EntityRefBuilder _extendedType;
+ String _name;
+ int _nameOffset;
+ List<UnlinkedTypeParamBuilder> _typeParameters;
+
+ @override
+ List<UnlinkedExprBuilder> get annotations =>
+ _annotations ??= <UnlinkedExprBuilder>[];
+
+ /// Annotations for this extension.
+ set annotations(List<UnlinkedExprBuilder> value) {
+ this._annotations = value;
+ }
+
+ @override
+ CodeRangeBuilder get codeRange => _codeRange;
+
+ /// Code range of the extension.
+ set codeRange(CodeRangeBuilder value) {
+ this._codeRange = value;
+ }
+
+ @override
+ UnlinkedDocumentationCommentBuilder get documentationComment =>
+ _documentationComment;
+
+ /// Documentation comment for the extension, or `null` if there is no
+ /// documentation comment.
+ set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+ this._documentationComment = value;
+ }
+
+ @override
+ List<UnlinkedExecutableBuilder> get executables =>
+ _executables ??= <UnlinkedExecutableBuilder>[];
+
+ /// Executable objects (methods, getters, and setters) contained in the
+ /// extension.
+ set executables(List<UnlinkedExecutableBuilder> value) {
+ this._executables = value;
+ }
+
+ @override
+ EntityRefBuilder get extendedType => _extendedType;
+
+ /// The type being extended.
+ set extendedType(EntityRefBuilder value) {
+ this._extendedType = value;
+ }
+
+ @override
+ String get name => _name ??= '';
+
+ /// Name of the extension, or an empty string if there is no name.
+ set name(String value) {
+ this._name = value;
+ }
+
+ @override
+ int get nameOffset => _nameOffset ??= 0;
+
+ /// Offset of the extension name relative to the beginning of the file, or
+ /// zero if there is no name.
+ set nameOffset(int value) {
+ assert(value == null || value >= 0);
+ this._nameOffset = value;
+ }
+
+ @override
+ List<UnlinkedTypeParamBuilder> get typeParameters =>
+ _typeParameters ??= <UnlinkedTypeParamBuilder>[];
+
+ /// Type parameters of the extension, if any.
+ set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+ this._typeParameters = value;
+ }
+
+ UnlinkedExtensionBuilder(
+ {List<UnlinkedExprBuilder> annotations,
+ CodeRangeBuilder codeRange,
+ UnlinkedDocumentationCommentBuilder documentationComment,
+ List<UnlinkedExecutableBuilder> executables,
+ EntityRefBuilder extendedType,
+ String name,
+ int nameOffset,
+ List<UnlinkedTypeParamBuilder> typeParameters})
+ : _annotations = annotations,
+ _codeRange = codeRange,
+ _documentationComment = documentationComment,
+ _executables = executables,
+ _extendedType = extendedType,
+ _name = name,
+ _nameOffset = nameOffset,
+ _typeParameters = typeParameters;
+
+ /// Flush [informative] data recursively.
+ void flushInformative() {
+ _annotations?.forEach((b) => b.flushInformative());
+ _codeRange = null;
+ _documentationComment = null;
+ _executables?.forEach((b) => b.flushInformative());
+ _extendedType?.flushInformative();
+ _nameOffset = null;
+ _typeParameters?.forEach((b) => b.flushInformative());
+ }
+
+ /// Accumulate non-[informative] data into [signature].
+ void collectApiSignature(api_sig.ApiSignature signature) {
+ signature.addString(this._name ?? '');
+ if (this._executables == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._executables.length);
+ for (var x in this._executables) {
+ x?.collectApiSignature(signature);
+ }
+ }
+ signature.addBool(this._extendedType != null);
+ this._extendedType?.collectApiSignature(signature);
+ if (this._annotations == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._annotations.length);
+ for (var x in this._annotations) {
+ x?.collectApiSignature(signature);
+ }
+ }
+ if (this._typeParameters == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._typeParameters.length);
+ for (var x in this._typeParameters) {
+ x?.collectApiSignature(signature);
+ }
+ }
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_annotations;
+ fb.Offset offset_codeRange;
+ fb.Offset offset_documentationComment;
+ fb.Offset offset_executables;
+ fb.Offset offset_extendedType;
+ fb.Offset offset_name;
+ fb.Offset offset_typeParameters;
+ if (!(_annotations == null || _annotations.isEmpty)) {
+ offset_annotations = fbBuilder
+ .writeList(_annotations.map((b) => b.finish(fbBuilder)).toList());
+ }
+ if (_codeRange != null) {
+ offset_codeRange = _codeRange.finish(fbBuilder);
+ }
+ if (_documentationComment != null) {
+ offset_documentationComment = _documentationComment.finish(fbBuilder);
+ }
+ if (!(_executables == null || _executables.isEmpty)) {
+ offset_executables = fbBuilder
+ .writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+ }
+ if (_extendedType != null) {
+ offset_extendedType = _extendedType.finish(fbBuilder);
+ }
+ if (_name != null) {
+ offset_name = fbBuilder.writeString(_name);
+ }
+ if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+ offset_typeParameters = fbBuilder
+ .writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+ }
+ fbBuilder.startTable();
+ if (offset_annotations != null) {
+ fbBuilder.addOffset(4, offset_annotations);
+ }
+ if (offset_codeRange != null) {
+ fbBuilder.addOffset(7, offset_codeRange);
+ }
+ if (offset_documentationComment != null) {
+ fbBuilder.addOffset(5, offset_documentationComment);
+ }
+ if (offset_executables != null) {
+ fbBuilder.addOffset(2, offset_executables);
+ }
+ if (offset_extendedType != null) {
+ fbBuilder.addOffset(3, offset_extendedType);
+ }
+ if (offset_name != null) {
+ fbBuilder.addOffset(0, offset_name);
+ }
+ if (_nameOffset != null && _nameOffset != 0) {
+ fbBuilder.addUint32(1, _nameOffset);
+ }
+ if (offset_typeParameters != null) {
+ fbBuilder.addOffset(6, offset_typeParameters);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _UnlinkedExtensionReader extends fb.TableReader<_UnlinkedExtensionImpl> {
+ const _UnlinkedExtensionReader();
+
+ @override
+ _UnlinkedExtensionImpl createObject(fb.BufferContext bc, int offset) =>
+ new _UnlinkedExtensionImpl(bc, offset);
+}
+
+class _UnlinkedExtensionImpl extends Object
+ with _UnlinkedExtensionMixin
+ implements idl.UnlinkedExtension {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _UnlinkedExtensionImpl(this._bc, this._bcOffset);
+
+ List<idl.UnlinkedExpr> _annotations;
+ idl.CodeRange _codeRange;
+ idl.UnlinkedDocumentationComment _documentationComment;
+ List<idl.UnlinkedExecutable> _executables;
+ idl.EntityRef _extendedType;
+ String _name;
+ int _nameOffset;
+ List<idl.UnlinkedTypeParam> _typeParameters;
+
+ @override
+ List<idl.UnlinkedExpr> get annotations {
+ _annotations ??=
+ const fb.ListReader<idl.UnlinkedExpr>(const _UnlinkedExprReader())
+ .vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedExpr>[]);
+ return _annotations;
+ }
+
+ @override
+ idl.CodeRange get codeRange {
+ _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 7, null);
+ return _codeRange;
+ }
+
+ @override
+ idl.UnlinkedDocumentationComment get documentationComment {
+ _documentationComment ??= const _UnlinkedDocumentationCommentReader()
+ .vTableGet(_bc, _bcOffset, 5, null);
+ return _documentationComment;
+ }
+
+ @override
+ List<idl.UnlinkedExecutable> get executables {
+ _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(
+ const _UnlinkedExecutableReader())
+ .vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedExecutable>[]);
+ return _executables;
+ }
+
+ @override
+ idl.EntityRef get extendedType {
+ _extendedType ??=
+ const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
+ return _extendedType;
+ }
+
+ @override
+ String get name {
+ _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+ return _name;
+ }
+
+ @override
+ int get nameOffset {
+ _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
+ return _nameOffset;
+ }
+
+ @override
+ List<idl.UnlinkedTypeParam> get typeParameters {
+ _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(
+ const _UnlinkedTypeParamReader())
+ .vTableGet(_bc, _bcOffset, 6, const <idl.UnlinkedTypeParam>[]);
+ return _typeParameters;
+ }
+}
+
+abstract class _UnlinkedExtensionMixin implements idl.UnlinkedExtension {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (annotations.isNotEmpty)
+ _result["annotations"] =
+ annotations.map((_value) => _value.toJson()).toList();
+ if (codeRange != null) _result["codeRange"] = codeRange.toJson();
+ if (documentationComment != null)
+ _result["documentationComment"] = documentationComment.toJson();
+ if (executables.isNotEmpty)
+ _result["executables"] =
+ executables.map((_value) => _value.toJson()).toList();
+ if (extendedType != null) _result["extendedType"] = extendedType.toJson();
+ if (name != '') _result["name"] = name;
+ if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+ if (typeParameters.isNotEmpty)
+ _result["typeParameters"] =
+ typeParameters.map((_value) => _value.toJson()).toList();
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "annotations": annotations,
+ "codeRange": codeRange,
+ "documentationComment": documentationComment,
+ "executables": executables,
+ "extendedType": extendedType,
+ "name": name,
+ "nameOffset": nameOffset,
+ "typeParameters": typeParameters,
+ };
+
+ @override
+ String toString() => convert.json.encode(toJson());
+}
+
class UnlinkedImportBuilder extends Object
with _UnlinkedImportMixin
implements idl.UnlinkedImport {
@@ -26053,6 +26577,7 @@
implements idl.UnlinkedUnit {
List<int> _apiSignature;
List<UnlinkedClassBuilder> _classes;
+ List<UnlinkedExtensionBuilder> _extensions;
CodeRangeBuilder _codeRange;
List<UnlinkedEnumBuilder> _enums;
List<UnlinkedExecutableBuilder> _executables;
@@ -26094,6 +26619,15 @@
}
@override
+ List<UnlinkedExtensionBuilder> get extensions =>
+ _extensions ??= <UnlinkedExtensionBuilder>[];
+
+ /// Extensions declared in the compilation unit.
+ set extensions(List<UnlinkedExtensionBuilder> value) {
+ this._extensions = value;
+ }
+
+ @override
CodeRangeBuilder get codeRange => _codeRange;
/// Code range of the unit.
@@ -26272,6 +26806,7 @@
UnlinkedUnitBuilder(
{List<int> apiSignature,
List<UnlinkedClassBuilder> classes,
+ List<UnlinkedExtensionBuilder> extensions,
CodeRangeBuilder codeRange,
List<UnlinkedEnumBuilder> enums,
List<UnlinkedExecutableBuilder> executables,
@@ -26293,6 +26828,7 @@
List<UnlinkedVariableBuilder> variables})
: _apiSignature = apiSignature,
_classes = classes,
+ _extensions = extensions,
_codeRange = codeRange,
_enums = enums,
_executables = executables,
@@ -26316,6 +26852,7 @@
/// Flush [informative] data recursively.
void flushInformative() {
_classes?.forEach((b) => b.flushInformative());
+ _extensions?.forEach((b) => b.flushInformative());
_codeRange = null;
_enums?.forEach((b) => b.flushInformative());
_executables?.forEach((b) => b.flushInformative());
@@ -26437,6 +26974,14 @@
}
}
signature.addBool(this._isNNBD == true);
+ if (this._extensions == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._extensions.length);
+ for (var x in this._extensions) {
+ x?.collectApiSignature(signature);
+ }
+ }
}
List<int> toBuffer() {
@@ -26447,6 +26992,7 @@
fb.Offset finish(fb.Builder fbBuilder) {
fb.Offset offset_apiSignature;
fb.Offset offset_classes;
+ fb.Offset offset_extensions;
fb.Offset offset_codeRange;
fb.Offset offset_enums;
fb.Offset offset_executables;
@@ -26469,6 +27015,10 @@
offset_classes = fbBuilder
.writeList(_classes.map((b) => b.finish(fbBuilder)).toList());
}
+ if (!(_extensions == null || _extensions.isEmpty)) {
+ offset_extensions = fbBuilder
+ .writeList(_extensions.map((b) => b.finish(fbBuilder)).toList());
+ }
if (_codeRange != null) {
offset_codeRange = _codeRange.finish(fbBuilder);
}
@@ -26532,6 +27082,9 @@
if (offset_classes != null) {
fbBuilder.addOffset(2, offset_classes);
}
+ if (offset_extensions != null) {
+ fbBuilder.addOffset(22, offset_extensions);
+ }
if (offset_codeRange != null) {
fbBuilder.addOffset(15, offset_codeRange);
}
@@ -26616,6 +27169,7 @@
List<int> _apiSignature;
List<idl.UnlinkedClass> _classes;
+ List<idl.UnlinkedExtension> _extensions;
idl.CodeRange _codeRange;
List<idl.UnlinkedEnum> _enums;
List<idl.UnlinkedExecutable> _executables;
@@ -26652,6 +27206,14 @@
}
@override
+ List<idl.UnlinkedExtension> get extensions {
+ _extensions ??= const fb.ListReader<idl.UnlinkedExtension>(
+ const _UnlinkedExtensionReader())
+ .vTableGet(_bc, _bcOffset, 22, const <idl.UnlinkedExtension>[]);
+ return _extensions;
+ }
+
+ @override
idl.CodeRange get codeRange {
_codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 15, null);
return _codeRange;
@@ -26802,6 +27364,9 @@
if (apiSignature.isNotEmpty) _result["apiSignature"] = apiSignature;
if (classes.isNotEmpty)
_result["classes"] = classes.map((_value) => _value.toJson()).toList();
+ if (extensions.isNotEmpty)
+ _result["extensions"] =
+ extensions.map((_value) => _value.toJson()).toList();
if (codeRange != null) _result["codeRange"] = codeRange.toJson();
if (enums.isNotEmpty)
_result["enums"] = enums.map((_value) => _value.toJson()).toList();
@@ -26847,6 +27412,7 @@
Map<String, Object> toMap() => {
"apiSignature": apiSignature,
"classes": classes,
+ "extensions": extensions,
"codeRange": codeRange,
"enums": enums,
"executables": executables,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index caaf7d3..f4e0ac1 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1455,6 +1455,9 @@
/// Information about an error in a resolved unit.
table AnalysisDriverUnitError {
+ /// The context messages associated with the error.
+ contextMessages:[DiagnosticMessage] (id: 5);
+
/// The optional correction hint for the error.
correction:string (id: 4);
@@ -1689,6 +1692,21 @@
offset:uint (id: 0);
}
+table DiagnosticMessage {
+ /// The absolute and normalized path of the file associated with this message.
+ filePath:string (id: 0);
+
+ /// The length of the source range associated with this message.
+ length:uint (id: 1);
+
+ /// The text of the message.
+ message:string (id: 2);
+
+ /// The zero-based offset from the start of the file to the beginning of the
+ /// source range associated with this message.
+ offset:uint (id: 3);
+}
+
/// Information about the Dartdoc directives in an [AvailableFile].
table DirectiveInfo {
/// The names of the defined templates.
@@ -2702,6 +2720,36 @@
strings:[string] (id: 3);
}
+/// Unlinked summary information about an extension declaration.
+table UnlinkedExtension {
+ /// Annotations for this extension.
+ annotations:[UnlinkedExpr] (id: 4);
+
+ /// Code range of the extension.
+ codeRange:CodeRange (id: 7);
+
+ /// Documentation comment for the extension, or `null` if there is no
+ /// documentation comment.
+ documentationComment:UnlinkedDocumentationComment (id: 5);
+
+ /// Executable objects (methods, getters, and setters) contained in the
+ /// extension.
+ executables:[UnlinkedExecutable] (id: 2);
+
+ /// The type being extended.
+ extendedType:EntityRef (id: 3);
+
+ /// Name of the extension, or an empty string if there is no name.
+ name:string (id: 0);
+
+ /// Offset of the extension name relative to the beginning of the file, or
+ /// zero if there is no name.
+ nameOffset:uint (id: 1);
+
+ /// Type parameters of the extension, if any.
+ typeParameters:[UnlinkedTypeParam] (id: 6);
+}
+
/// Unlinked summary information about an import declaration.
table UnlinkedImport {
/// Annotations for this import declaration.
@@ -3022,6 +3070,9 @@
/// Classes declared in the compilation unit.
classes:[UnlinkedClass] (id: 2);
+ /// Extensions declared in the compilation unit.
+ extensions:[UnlinkedExtension] (id: 22);
+
/// Code range of the unit.
codeRange:CodeRange (id: 15);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 1034e2b..b157cdf 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -118,6 +118,10 @@
/// Information about an error in a resolved unit.
abstract class AnalysisDriverUnitError extends base.SummaryClass {
+ /// The context messages associated with the error.
+ @Id(5)
+ List<DiagnosticMessage> get contextMessages;
+
/// The optional correction hint for the error.
@Id(4)
String get correction;
@@ -444,6 +448,25 @@
int get offset;
}
+abstract class DiagnosticMessage extends base.SummaryClass {
+ /// The absolute and normalized path of the file associated with this message.
+ @Id(0)
+ String get filePath;
+
+ /// The length of the source range associated with this message.
+ @Id(1)
+ int get length;
+
+ /// The text of the message.
+ @Id(2)
+ String get message;
+
+ /// The zero-based offset from the start of the file to the beginning of the
+ /// source range associated with this message.
+ @Id(3)
+ int get offset;
+}
+
/// Information about the Dartdoc directives in an [AvailableFile].
abstract class DirectiveInfo extends base.SummaryClass {
/// The names of the defined templates.
@@ -3473,6 +3496,47 @@
bitShiftRightLogical,
}
+/// Unlinked summary information about an extension declaration.
+abstract class UnlinkedExtension extends base.SummaryClass {
+ /// Annotations for this extension.
+ @Id(4)
+ List<UnlinkedExpr> get annotations;
+
+ /// Code range of the extension.
+ @informative
+ @Id(7)
+ CodeRange get codeRange;
+
+ /// Documentation comment for the extension, or `null` if there is no
+ /// documentation comment.
+ @informative
+ @Id(5)
+ UnlinkedDocumentationComment get documentationComment;
+
+ /// Executable objects (methods, getters, and setters) contained in the
+ /// extension.
+ @Id(2)
+ List<UnlinkedExecutable> get executables;
+
+ /// The type being extended.
+ @Id(3)
+ EntityRef get extendedType;
+
+ /// Name of the extension, or an empty string if there is no name.
+ @Id(0)
+ String get name;
+
+ /// Offset of the extension name relative to the beginning of the file, or
+ /// zero if there is no name.
+ @informative
+ @Id(1)
+ int get nameOffset;
+
+ /// Type parameters of the extension, if any.
+ @Id(6)
+ List<UnlinkedTypeParam> get typeParameters;
+}
+
/// Unlinked summary information about an import declaration.
abstract class UnlinkedImport extends base.SummaryClass {
/// Annotations for this import declaration.
@@ -4128,6 +4192,10 @@
@Id(2)
List<UnlinkedClass> get classes;
+ /// Extensions declared in the compilation unit.
+ @Id(22)
+ List<UnlinkedExtension> get extensions;
+
/// Code range of the unit.
@informative
@Id(15)
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 5bc3580..e5e51d3 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1075,6 +1075,7 @@
Map<String, ReferenceableElementForLink> _containedNames;
List<TopLevelVariableElementForLink> _topLevelVariables;
List<ClassElementForLink_Enum> _enums;
+ List<ExtensionElementForLink> _extensions;
List<TopLevelFunctionElementForLink> _functions;
List<PropertyAccessorElementForLink> _accessors;
List<FunctionTypeAliasElementForLink> _functionTypeAliases;
@@ -1153,6 +1154,17 @@
}
@override
+ List<ExtensionElementForLink> get extensions {
+ if (_extensions == null) {
+ _extensions = <ExtensionElementForLink>[];
+ for (UnlinkedExtension unlinkedExtension in _unlinkedUnit.extensions) {
+ _extensions.add(ExtensionElementForLink(this, unlinkedExtension));
+ }
+ }
+ return _extensions;
+ }
+
+ @override
List<TopLevelFunctionElementForLink> get functions {
if (_functions == null) {
_functions = <TopLevelFunctionElementForLink>[];
@@ -2553,6 +2565,21 @@
}
}
+class ExtensionElementForLink
+ with ReferenceableElementForLink
+ implements ExtensionElementImpl {
+ @override
+ final CompilationUnitElementForLink enclosingElement;
+
+ // TODO(brianwilkerson) Remove this field if it remains unreferenced.
+ final UnlinkedExtension _unlinkedExtension;
+
+ ExtensionElementForLink(this.enclosingElement, this._unlinkedExtension);
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
/// Element representing a field resynthesized from a summary during
/// linking.
abstract class FieldElementForLink implements FieldElement {
@@ -3605,9 +3632,6 @@
}
@override
- bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
-
- @override
ContextForLink get context => _linker.context;
@override
@@ -3644,6 +3668,9 @@
bool get isInSdk => _absoluteUri.scheme == 'dart';
@override
+ bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
+
+ @override
bool get isSynthetic => _linkedLibrary == null;
/// If this library is part of the build unit being linked, return the library
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 3608b07..f5da9a7 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -238,6 +238,10 @@
/// [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
+ /// List of objects which should be written to [UnlinkedUnit.extensions].
+ final List<UnlinkedExtensionBuilder> extensions =
+ <UnlinkedExtensionBuilder>[];
+
/// List of objects which should be written to [UnlinkedUnit.exports].
final List<UnlinkedExportNonPublicBuilder> exports =
<UnlinkedExportNonPublicBuilder>[];
@@ -504,6 +508,7 @@
b.classes = classes;
b.enums = enums;
b.executables = executables;
+ b.extensions = extensions;
b.exports = exports;
b.imports = unlinkedImports;
b.mixins = mixins;
@@ -1184,6 +1189,41 @@
}
@override
+ visitExtensionDeclaration(ExtensionDeclaration node) {
+ int oldScopesLength = scopes.length;
+ enclosingClassHasConstConstructor = false;
+ List<UnlinkedExecutableBuilder> oldExecutables = executables;
+ executables = <UnlinkedExecutableBuilder>[];
+ List<UnlinkedVariableBuilder> oldVariables = variables;
+ variables = <UnlinkedVariableBuilder>[];
+ _TypeParameterScope typeParameterScope = new _TypeParameterScope();
+ scopes.add(typeParameterScope);
+
+ UnlinkedExtensionBuilder b = UnlinkedExtensionBuilder();
+ b.name = node.name?.name;
+ b.nameOffset = node.name?.offset ?? 0;
+ b.typeParameters =
+ serializeTypeParameters(node.typeParameters, typeParameterScope);
+ if (node.members != null) {
+ scopes.add(buildClassMemberScope(node.name?.name, node.members));
+ for (ClassMember member in node.members) {
+ member.accept(this);
+ }
+ scopes.removeLast();
+ }
+ b.executables = executables;
+ b.documentationComment = serializeDocumentation(node.documentationComment);
+ b.annotations = serializeAnnotations(node.metadata);
+ b.codeRange = serializeCodeRange(node);
+ extensions.add(b);
+
+ scopes.removeLast();
+ assert(scopes.length == oldScopesLength);
+ executables = oldExecutables;
+ variables = oldVariables;
+ }
+
+ @override
void visitFieldDeclaration(FieldDeclaration node) {
serializeVariables(node.fields, node.staticKeyword != null,
node.documentationComment, node.metadata, true);
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 46f9ec4..0bb6202 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -344,7 +344,7 @@
}
CompilationUnit _read_compilationUnit(LinkedNode data) {
- return astFactory.compilationUnit2(
+ return astFactory.compilationUnit(
beginToken: null,
scriptTag: _readNode(data.compilationUnit_scriptTag),
directives: _readNodeList(data.compilationUnit_directives),
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ec6a624..b7ed57f 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -804,9 +804,6 @@
if (node is VariableDeclaration) {
return node.isLate;
}
- if (node is VariableDeclarationList) {
- return node.isLate;
- }
if (node is EnumConstantDeclaration) {
return false;
}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index ac469fd..0da3ffe 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -93,8 +93,8 @@
initializerInference.createNodes();
_performOverrideInference();
- initializerInference.perform();
_inferConstructorFieldFormals();
+ initializerInference.perform();
}
void _inferConstructorFieldFormals() {
@@ -103,6 +103,7 @@
for (var class_ in unit.types) {
var fields = <String, DartType>{};
for (var field in class_.fields) {
+ if (field.isStatic) continue;
if (field.isSynthetic) continue;
var name = field.name;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 9bc342b..d84a7ab 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -175,7 +175,7 @@
];
// Supported 'analyzer' optional checks options.
- static const List<String> optionalCecksOptions = const [
+ static const List<String> optionalChecksOptions = const [
chromeOsManifestChecks,
];
}
@@ -497,7 +497,8 @@
/// Validates `analyzer` optional-checks value configuration options.
class OptionalChecksValueValidator extends OptionsValidator {
- ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.optionalCecksOptions);
+ ErrorBuilder builder =
+ new ErrorBuilder(AnalyzerOptions.optionalChecksOptions);
ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
@override
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 917fc1c..52afb8a 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -461,6 +461,7 @@
double nextDouble() => 2.0;
int nextInt() => 1;
}
+class Point<T extends num> {}
''');
const List<SdkLibrary> _LIBRARIES = const [
diff --git a/pkg/analyzer/lib/src/util/ast_data_extractor.dart b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
new file mode 100644
index 0000000..bf528bd
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
@@ -0,0 +1,118 @@
+// 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';
+import 'package:front_end/src/testing/id.dart'
+ show ActualData, DataRegistry, Id, IdKind, MemberId, NodeId;
+
+/// Abstract IR visitor for computing data corresponding to a node or element,
+/// and record it with a generic [Id]
+/// TODO(paulberry): if I try to extend GeneralizingAstVisitor<void>, the VM
+/// crashes.
+abstract class AstDataExtractor<T> extends GeneralizingAstVisitor<dynamic>
+ with DataRegistry<T> {
+ final Uri uri;
+
+ @override
+ final Map<Id, ActualData<T>> actualMap;
+
+ AstDataExtractor(this.uri, this.actualMap);
+
+ NodeId computeDefaultNodeId(AstNode node) =>
+ NodeId(_nodeOffset(node), IdKind.node);
+
+ void computeForExpression(Expression node, NodeId id) {
+ if (id == null) return;
+ T value = computeNodeValue(id, node);
+ registerValue(uri, node.offset, id, value, node);
+ }
+
+ void computeForMember(Declaration node, Id id) {
+ if (id == null) return;
+ T value = computeNodeValue(id, node);
+ registerValue(uri, node.offset, id, value, node);
+ }
+
+ void computeForStatement(Statement node, NodeId id) {
+ if (id == null) return;
+ T value = computeNodeValue(id, node);
+ registerValue(uri, node.offset, id, value, node);
+ }
+
+ /// Implement this to compute the data corresponding to [node].
+ ///
+ /// If `null` is returned, [node] has no associated data.
+ T computeNodeValue(Id id, AstNode node);
+
+ Id createMemberId(Declaration node) {
+ var element = node.declaredElement;
+ if (element.enclosingElement is CompilationUnitElement) {
+ var memberName = element.name;
+ if (element is PropertyAccessorElement && element.isSetter) {
+ memberName += '=';
+ }
+ return MemberId.internal(memberName);
+ }
+ throw UnimplementedError(
+ 'TODO(paulberry): $element (${element.runtimeType})');
+ }
+
+ NodeId createStatementId(Statement node) =>
+ NodeId(_nodeOffset(node), IdKind.stmt);
+
+ @override
+ void fail(String message) {
+ throw _Failure(message);
+ }
+
+ @override
+ void report(Uri uri, int offset, String message) {
+ // TODO(paulberry): find a way to print the error more nicely.
+ print('$uri:$offset: $message');
+ }
+
+ void run(CompilationUnit unit) {
+ unit.accept(this);
+ }
+
+ @override
+ visitExpression(Expression node) {
+ computeForExpression(node, computeDefaultNodeId(node));
+ super.visitExpression(node);
+ }
+
+ @override
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ if (node.parent is CompilationUnit) {
+ computeForMember(node, createMemberId(node));
+ }
+ return super.visitFunctionDeclaration(node);
+ }
+
+ @override
+ visitStatement(Statement node) {
+ computeForStatement(node, createStatementId(node));
+ super.visitStatement(node);
+ }
+
+ int _nodeOffset(AstNode node) {
+ var offset = node.offset;
+ assert(offset != null && offset >= 0,
+ "No fileOffset on $node (${node.runtimeType})");
+ return offset;
+ }
+}
+
+class _Failure implements Exception {
+ final message;
+
+ _Failure([this.message]);
+
+ String toString() {
+ if (message == null) return "Exception";
+ return "Exception: $message";
+ }
+}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 29b6585..6f7bc5b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.36.4-dev
+version: 0.37.0
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.18
+ front_end: 0.1.20
glob: ^1.0.3
html: '>=0.13.4+1 <0.15.0'
- kernel: 0.3.18
+ kernel: 0.3.20
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/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 1aebc1fe8..2f4eb29 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -2,10 +2,14 @@
// for 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';
+
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -17,6 +21,109 @@
@reflectiveTest
class UtilitiesTest with ResourceProviderMixin {
+ FeatureSet get defaultFeatureSet =>
+ FeatureSet.forTesting(sdkVersion: '2.2.2');
+
+ test_parseFile_default_resource_provider() {
+ String content = '''
+void main() => print('Hello, world!');
+ ''';
+ ParseStringResult result = _withTemporaryFile(content,
+ (path) => parseFile(path: path, featureSet: defaultFeatureSet));
+ expect(result.content, content);
+ expect(result.errors, isEmpty);
+ expect(result.lineInfo, isNotNull);
+ expect(result.unit.toString(),
+ equals("void main() => print('Hello, world!');"));
+ }
+
+ test_parseFile_errors_noThrow() {
+ String content = '''
+void main() => print('Hello, world!')
+''';
+ ParseStringResult result = _withMemoryFile(
+ content,
+ (resourceProvider, path) => parseFile(
+ path: path,
+ featureSet: defaultFeatureSet,
+ resourceProvider: resourceProvider,
+ throwIfDiagnostics: false));
+ expect(result.content, content);
+ expect(result.errors, hasLength(1));
+ expect(result.lineInfo, isNotNull);
+ expect(result.unit.toString(),
+ equals("void main() => print('Hello, world!');"));
+ }
+
+ test_parseFile_errors_throw() {
+ String content = '''
+void main() => print('Hello, world!')
+''';
+ expect(
+ () => _withMemoryFile(
+ content,
+ (resourceProvider, path) => parseFile(
+ path: path,
+ featureSet: defaultFeatureSet,
+ resourceProvider: resourceProvider)),
+ throwsA(const TypeMatcher<ArgumentError>()));
+ }
+
+ test_parseFile_featureSet_nnbd_off() {
+ String content = '''
+int? f() => 1;
+''';
+ var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0');
+ expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
+ ParseStringResult result = _withMemoryFile(
+ content,
+ (resourceProvider, path) => parseFile(
+ path: path,
+ resourceProvider: resourceProvider,
+ throwIfDiagnostics: false,
+ featureSet: featureSet));
+ expect(result.content, content);
+ expect(result.errors, hasLength(1));
+ expect(result.lineInfo, isNotNull);
+ expect(result.unit.toString(), equals('int? f() => 1;'));
+ }
+
+ test_parseFile_featureSet_nnbd_on() {
+ String content = '''
+int? f() => 1;
+''';
+ var featureSet =
+ FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
+ ParseStringResult result = _withMemoryFile(
+ content,
+ (resourceProvider, path) => parseFile(
+ path: path,
+ resourceProvider: resourceProvider,
+ throwIfDiagnostics: false,
+ featureSet: featureSet));
+ expect(result.content, content);
+ expect(result.errors, isEmpty);
+ expect(result.lineInfo, isNotNull);
+ expect(result.unit.toString(), equals('int? f() => 1;'));
+ }
+
+ test_parseFile_noErrors() {
+ String content = '''
+void main() => print('Hello, world!');
+''';
+ ParseStringResult result = _withMemoryFile(
+ content,
+ (resourceProvider, path) => parseFile(
+ path: path,
+ featureSet: defaultFeatureSet,
+ resourceProvider: resourceProvider));
+ expect(result.content, content);
+ expect(result.errors, isEmpty);
+ expect(result.lineInfo, isNotNull);
+ expect(result.unit.toString(),
+ equals("void main() => print('Hello, world!');"));
+ }
+
test_parseString_errors_noThrow() {
String content = '''
void main() => print('Hello, world!')
@@ -88,4 +195,24 @@
expect(result.unit.toString(),
equals("void main() => print('Hello, world!');"));
}
+
+ T _withMemoryFile<T>(String content,
+ T callback(MemoryResourceProvider resourceProvider, String path)) {
+ var resourceProvider = MemoryResourceProvider();
+ var path =
+ resourceProvider.pathContext.fromUri(Uri.parse('file:///test.dart'));
+ resourceProvider.newFile(path, content);
+ return callback(resourceProvider, path);
+ }
+
+ T _withTemporaryFile<T>(String content, T callback(String path)) {
+ var tempDir = Directory.systemTemp.createTempSync();
+ try {
+ var file = File(p.join(tempDir.path, 'test.dart'));
+ file.writeAsStringSync(content);
+ return callback(file.path);
+ } finally {
+ tempDir.deleteSync(recursive: true);
+ }
+ }
}
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index a7de7ad..adfcf2e 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -274,7 +274,7 @@
null,
AstTestFactory.typeName4('int'),
[AstTestFactory.variableDeclaration('V')]);
- CompilationUnit unit = astFactory.compilationUnit2(
+ CompilationUnit unit = astFactory.compilationUnit(
beginToken: topLevelVariableDeclaration.beginToken,
declarations: [topLevelVariableDeclaration],
endToken: topLevelVariableDeclaration.endToken,
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a860794..7e37544 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -15,7 +15,6 @@
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/sdk_io.dart'; // ignore: deprecated_member_use_from_same_package
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';
@@ -38,8 +37,6 @@
defineReflectiveTests(ErrorSeverityTest);
defineReflectiveTests(FileBasedSourceTest);
defineReflectiveTests(ResolveRelativeUriTest);
- // ignore: deprecated_member_use_from_same_package
- defineReflectiveTests(SDKLibrariesReaderTest);
defineReflectiveTests(UriKindTest);
});
}
@@ -520,80 +517,6 @@
}
}
-@deprecated
-@reflectiveTest
-class SDKLibrariesReaderTest extends EngineTestCase {
- test_readFrom_dart2js() async {
- LibraryMap libraryMap = new SdkLibrariesReader(true)
- .readFromFile(FileUtilities2.createFile("/libs.dart"), r'''
-final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
- 'first' : const LibraryInfo(
- 'first/first.dart',
- categories: 'Client',
- documented: true,
- platforms: VM_PLATFORM,
- dart2jsPath: 'first/first_dart2js.dart'),
-};''');
- expect(libraryMap, isNotNull);
- expect(libraryMap.size(), 1);
- SdkLibrary first = libraryMap.getLibrary("dart:first");
- expect(first, isNotNull);
- expect(first.category, "Client");
- expect(first.path, "first/first_dart2js.dart");
- expect(first.shortName, "dart:first");
- expect(first.isDart2JsLibrary, false);
- expect(first.isDocumented, true);
- expect(first.isImplementation, false);
- expect(first.isVmLibrary, true);
- }
-
- test_readFrom_empty() async {
- LibraryMap libraryMap = new SdkLibrariesReader(false)
- .readFromFile(FileUtilities2.createFile("/libs.dart"), "");
- expect(libraryMap, isNotNull);
- expect(libraryMap.size(), 0);
- }
-
- test_readFrom_normal() async {
- LibraryMap libraryMap = new SdkLibrariesReader(false)
- .readFromFile(FileUtilities2.createFile("/libs.dart"), r'''
-final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
- 'first' : const LibraryInfo(
- 'first/first.dart',
- categories: 'Client',
- documented: true,
- platforms: VM_PLATFORM),
-
- 'second' : const LibraryInfo(
- 'second/second.dart',
- categories: 'Server',
- documented: false,
- implementation: true,
- platforms: 0),
-};''');
- expect(libraryMap, isNotNull);
- expect(libraryMap.size(), 2);
- SdkLibrary first = libraryMap.getLibrary("dart:first");
- expect(first, isNotNull);
- expect(first.category, "Client");
- expect(first.path, "first/first.dart");
- expect(first.shortName, "dart:first");
- expect(first.isDart2JsLibrary, false);
- expect(first.isDocumented, true);
- expect(first.isImplementation, false);
- expect(first.isVmLibrary, true);
- SdkLibrary second = libraryMap.getLibrary("dart:second");
- expect(second, isNotNull);
- expect(second.category, "Server");
- expect(second.path, "second/second.dart");
- expect(second.shortName, "dart:second");
- expect(second.isDart2JsLibrary, false);
- expect(second.isDocumented, false);
- expect(second.isImplementation, true);
- expect(second.isVmLibrary, false);
- }
-}
-
@reflectiveTest
class UriKindTest {
test_fromEncoding() async {
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 181575f..21bcf7c 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -2459,7 +2459,7 @@
class Baz extends Bar {}
void main() {}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3),
]);
// Instantiate-to-bounds should have instantiated "Bar" to "Bar<Foo>".
expect(result.unit.declaredElement.getType('Baz').supertype.toString(),
@@ -4723,7 +4723,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+ expectedMessages: [message('/test/lib/test.dart', 34, 1)]),
]);
}
@@ -4736,7 +4737,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+ expectedMessages: [message('/test/lib/test.dart', 38, 1)]),
]);
}
@@ -4751,7 +4753,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1,
+ expectedMessages: [message('/test/lib/test.dart', 48, 1)]),
]);
}
@@ -4761,7 +4764,8 @@
var v = () => v;
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1,
+ expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
]);
}
@@ -4771,7 +4775,8 @@
var v = v;
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1,
+ expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
]);
}
@@ -4783,7 +4788,8 @@
print(s + String);
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+ expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
]);
}
@@ -4795,7 +4801,8 @@
print(s + String);
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+ expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
]);
}
@@ -5141,7 +5148,7 @@
];
if (!AnalysisDriver.useSummary2) {
errors.add(
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
);
}
await assertErrorsInCode('''
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index a8a660d..5b08f71 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.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:front_end/src/fasta/messages.dart' show MessageCode;
import 'package:front_end/src/fasta/parser.dart';
import 'package:front_end/src/fasta/parser/forwarding_listener.dart';
import 'package:front_end/src/scanner/token.dart';
@@ -578,6 +579,13 @@
}
@override
+ void endInvalidAwaitExpression(
+ Token beginToken, Token endToken, MessageCode errorCode) {
+ end('InvalidAwaitExpression');
+ super.endInvalidAwaitExpression(beginToken, endToken, errorCode);
+ }
+
+ @override
void endBlock(int count, Token beginToken, Token endToken) {
end('Block');
super.endBlock(count, beginToken, endToken);
@@ -908,10 +916,11 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
end('Method');
- super.endMethod(getOrSet, beginToken, beginParam, endToken);
+ super.endMethod(
+ getOrSet, beginToken, beginParam, beginInitializers, endToken);
}
@override
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index cb15507..e67ca0b 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1845,8 +1845,8 @@
// Run parser
ErrorReporter errorReporter = new ErrorReporter(listener, source);
fasta.Parser parser = new fasta.Parser(null);
- AstBuilder astBuilder = new AstBuilder(errorReporter, source.uri, true)
- ..configureFeatures(featureSet);
+ AstBuilder astBuilder =
+ new AstBuilder(errorReporter, source.uri, true, featureSet);
parser.listener = astBuilder;
astBuilder.parser = parser;
astBuilder.allowNativeClause = allowNativeClause;
@@ -2780,9 +2780,8 @@
ParserProxy._(analyzer.Token firstToken, ErrorReporter errorReporter,
Uri fileUri, this._errorListener, FeatureSet featureSet,
{bool allowNativeClause: false, this.expectedEndOffset})
- : super(firstToken, errorReporter, fileUri,
+ : super(firstToken, errorReporter, fileUri, featureSet,
allowNativeClause: allowNativeClause) {
- configureFeatures(featureSet);
_eventListener = new ForwardingTestListener(astBuilder);
fastaParser.listener = _eventListener;
}
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index ad2f86f..6b2cfd5 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1071,7 +1071,7 @@
class G<E extends A> {}
class D = G<B> with C;
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
]);
}
@@ -1082,7 +1082,7 @@
class G<E extends A> {}
class C extends G<B>{}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
]);
}
@@ -1092,7 +1092,7 @@
class X<T extends Type> {}
class Y<U> extends X<U> {}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
]);
}
@@ -1106,7 +1106,7 @@
C(G<B> this.f) {}
}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
]);
}
@@ -1117,7 +1117,7 @@
class G<E extends A> {}
G<B> f() { return null; }
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
]);
}
@@ -1128,7 +1128,7 @@
class G<E extends A> {}
typedef G<B> f();
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
]);
}
@@ -1139,7 +1139,7 @@
class G<E extends A> {}
f(G<B> h()) {}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
]);
}
@@ -1150,7 +1150,7 @@
class G<E extends A> {}
class C implements G<B>{}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
]);
}
@@ -1161,7 +1161,7 @@
class G<E extends A> {}
var b = 1 is G<B>;
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
]);
}
@@ -1178,7 +1178,7 @@
print(f<String>('hello', 'world'));
}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
]);
}
@@ -1198,7 +1198,7 @@
print(factory.point<String>('hello', 'world'));
}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
]);
}
@@ -1216,7 +1216,7 @@
print(f<String>('hello', 'world'));
}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
]);
}
@@ -1229,7 +1229,7 @@
G<B> m() { return null; }
}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
]);
}
@@ -1240,7 +1240,7 @@
class G<E extends A> {}
f() { return new G<B>(); }
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
]);
}
@@ -1252,7 +1252,7 @@
class G<E extends B> {}
f() { return new G<A>(); }
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
]);
}
@@ -1263,7 +1263,7 @@
typedef F<T extends A>();
F<B> fff;
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
]);
}
@@ -1274,7 +1274,7 @@
class G<E extends A> {}
f(G<B> g) {}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
]);
}
@@ -1288,7 +1288,7 @@
}
''', [
error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
]);
}
@@ -1300,7 +1300,7 @@
class D<E extends A> {}
C<D<B>> Var;
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
]);
}
@@ -1312,7 +1312,7 @@
class G<E extends A> {}
class D<F extends G<B>> {}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
]);
}
@@ -1323,7 +1323,7 @@
class G<E extends A> {}
G<B> g;
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
]);
}
@@ -1334,7 +1334,7 @@
class G<E extends A> {}
class C extends Object with G<B>{}
''', [
- error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
]);
}
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 176d24f..0c95349 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -5051,7 +5051,7 @@
''';
await resolveTestUnit(code, noErrors: false);
assertErrors(
- testSource, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ testSource, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
}
test_instantiateToBounds_class_error_instantiation_malbounded() async {
@@ -5066,7 +5066,7 @@
await resolveTestUnit(code, noErrors: false);
assertErrors(testSource, [
StrongModeCode.COULD_NOT_INFER,
- StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+ CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
]);
expectIdentifierType('c =', 'C<List<dynamic>, List<List<dynamic>>>');
}
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 25a512d..b795962 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
@@ -118,15 +119,61 @@
/// The offset of the beginning of the error's region.
final int length;
+ /// The list of context messages that are expected to be associated with the
+ /// error.
+ final List<ExpectedMessage> expectedMessages;
+
/// Initialize a newly created error description.
- ExpectedError(this.code, this.offset, this.length);
+ ExpectedError(this.code, this.offset, this.length,
+ {this.expectedMessages = const <ExpectedMessage>[]});
/// Return `true` if the [error] matches this description of what it's
/// expected to be.
bool matches(AnalysisError error) {
- return error.offset == offset &&
- error.length == length &&
- error.errorCode == code;
+ if (error.offset != offset ||
+ error.length != length ||
+ error.errorCode != code) {
+ return false;
+ }
+ List<DiagnosticMessage> contextMessages = error.contextMessages.toList();
+ contextMessages.sort((first, second) {
+ int result = first.filePath.compareTo(second.filePath);
+ if (result != 0) {
+ return result;
+ }
+ return second.offset - first.offset;
+ });
+ if (contextMessages.length != expectedMessages.length) {
+ return false;
+ }
+ for (int i = 0; i < expectedMessages.length; i++) {
+ if (!expectedMessages[i].matches(contextMessages[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+/// A description of a message that is expected to be reported with an error.
+class ExpectedMessage {
+ /// The path of the file with which the message is associated.
+ final String filePath;
+
+ /// The offset of the beginning of the error's region.
+ final int offset;
+
+ /// The offset of the beginning of the error's region.
+ final int length;
+
+ ExpectedMessage(this.filePath, this.offset, this.length);
+
+ /// Return `true` if the [message] matches this description of what it's
+ /// expected to be.
+ bool matches(DiagnosticMessage message) {
+ return message.filePath == filePath &&
+ message.offset == offset &&
+ message.length == length;
}
}
@@ -227,12 +274,30 @@
buffer.writeln();
buffer.writeln('To accept the current state, expect:');
for (AnalysisError actual in errors) {
+ List<DiagnosticMessage> contextMessages = actual.contextMessages;
buffer.write(' error(');
buffer.write(actual.errorCode);
buffer.write(', ');
buffer.write(actual.offset);
buffer.write(', ');
buffer.write(actual.length);
+ if (contextMessages.isNotEmpty) {
+ buffer.write(', expectedMessages: [');
+ for (int i = 0; i < contextMessages.length; i++) {
+ DiagnosticMessage message = contextMessages[i];
+ if (i > 0) {
+ buffer.write(', ');
+ }
+ buffer.write('message(resourceProvider.convertPath(\'');
+ buffer.write(message.filePath);
+ buffer.write('\'), ');
+ buffer.write(message.offset);
+ buffer.write(', ');
+ buffer.write(message.length);
+ buffer.write(')');
+ }
+ buffer.write(']');
+ }
buffer.writeln('),');
}
fail(buffer.toString());
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 511ce30..eca10d8 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -54,6 +54,7 @@
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;
InterfaceType get numType => typeProvider.numType;
InterfaceType get objectType => typeProvider.objectType;
@@ -414,17 +415,66 @@
*
* The return type defaults to `void` if omitted.
*/
- FunctionType _functionType(List<DartType> required,
- {List<DartType> optional,
- Map<String, DartType> named,
- DartType returns}) {
- if (returns == null) {
- returns = voidType;
+ 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.',
+ );
}
- return ElementFactory.functionElement8(required, returns,
- optional: optional, named: named)
- .type;
+ 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;
}
}
@@ -1205,92 +1255,170 @@
}
void test_functionsDifferentNamedTakeUnion() {
- FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
- FunctionType type2 =
- _functionType([], named: {'b': doubleType, 'c': stringType});
- FunctionType expected =
- _functionType([], named: {'a': intType, 'b': numType, 'c': stringType});
+ var type1 = _functionType(
+ named: {'a': intType, 'b': intType},
+ );
+ var type2 = _functionType(
+ named: {'b': doubleType, 'c': stringType},
+ );
+ var expected = _functionType(
+ named: {'a': intType, 'b': numType, 'c': stringType},
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsDifferentOptionalArityTakeMax() {
- FunctionType type1 = _functionType([], optional: [intType]);
- FunctionType type2 =
- _functionType([], optional: [doubleType, stringType, objectType]);
- FunctionType expected =
- _functionType([], optional: [numType, stringType, objectType]);
+ var type1 = _functionType(
+ optional: [intType],
+ );
+ var type2 = _functionType(
+ required: [],
+ optional: [doubleType, stringType, objectType],
+ );
+ var expected = _functionType(
+ optional: [numType, stringType, objectType],
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsDifferentRequiredArityBecomeOptional() {
- FunctionType type1 = _functionType([intType]);
- FunctionType type2 = _functionType([intType, intType, intType]);
- FunctionType expected =
- _functionType([intType], optional: [intType, intType]);
+ var type1 = _functionType(
+ required: [intType],
+ );
+ var type2 = _functionType(
+ required: [intType, intType, intType],
+ );
+ var expected = _functionType(
+ required: [intType],
+ optional: [intType, intType],
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsFromDynamic() {
- FunctionType type1 = _functionType([dynamicType]);
- FunctionType type2 = _functionType([intType]);
- FunctionType expected = _functionType([dynamicType]);
+ var type1 = _functionType(required: [dynamicType]);
+ var type2 = _functionType(required: [intType]);
+ var expected = _functionType(required: [dynamicType]);
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsGlbReturnType() {
- FunctionType type1 = _functionType([], returns: intType);
- FunctionType type2 = _functionType([], returns: numType);
- FunctionType expected = _functionType([], returns: intType);
+ var type1 = _functionType(returns: intType);
+ var type2 = _functionType(returns: numType);
+ var expected = _functionType(returns: intType);
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsLubNamedParams() {
- FunctionType type1 =
- _functionType([], named: {'a': stringType, 'b': intType});
- FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
- FunctionType expected =
- _functionType([], named: {'a': objectType, 'b': numType});
+ var type1 = _functionType(
+ named: {'a': stringType, 'b': intType},
+ );
+ var type2 = _functionType(
+ named: {'a': intType, 'b': numType},
+ );
+ var expected = _functionType(
+ named: {'a': objectType, 'b': numType},
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsLubPositionalParams() {
- FunctionType type1 = _functionType([], optional: [stringType, intType]);
- FunctionType type2 = _functionType([], optional: [intType, numType]);
- FunctionType expected = _functionType([], optional: [objectType, numType]);
+ var type1 = _functionType(
+ optional: [stringType, intType],
+ );
+ var type2 = _functionType(
+ optional: [intType, numType],
+ );
+ var expected = _functionType(
+ optional: [objectType, numType],
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsLubRequiredParams() {
- FunctionType type1 = _functionType([stringType, intType, intType]);
- FunctionType type2 = _functionType([intType, doubleType, numType]);
- FunctionType expected = _functionType([objectType, numType, numType]);
+ var type1 = _functionType(
+ required: [stringType, intType, intType],
+ );
+ var type2 = _functionType(
+ required: [intType, doubleType, numType],
+ );
+ var expected = _functionType(
+ required: [objectType, numType, numType],
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsMixedOptionalAndRequiredBecomeOptional() {
- FunctionType type1 = _functionType([intType, intType],
- optional: [intType, intType, intType]);
- FunctionType type2 = _functionType([intType], optional: [intType, intType]);
- FunctionType expected = _functionType([intType],
- optional: [intType, intType, intType, intType]);
+ var type1 = _functionType(
+ required: [intType, intType],
+ optional: [intType, intType, intType],
+ );
+ var type2 = _functionType(
+ required: [intType],
+ optional: [intType, intType],
+ );
+ var expected = _functionType(
+ required: [intType],
+ optional: [intType, intType, intType, intType],
+ );
_checkGreatestLowerBound(type1, type2, expected);
}
void test_functionsReturnBottomIfMixOptionalAndNamed() {
// Dart doesn't allow a function to have both optional and named parameters,
// so if we would have synthethized that, pick bottom instead.
- FunctionType type1 = _functionType([intType], named: {'a': intType});
- FunctionType type2 = _functionType([], named: {'a': intType});
+ var type1 = _functionType(
+ required: [intType],
+ named: {'a': intType},
+ );
+ var type2 = _functionType(
+ required: [],
+ named: {'a': intType},
+ );
_checkGreatestLowerBound(type1, type2, bottomType);
}
- void test_functionsSameType() {
- FunctionType type1 = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
- FunctionType type2 = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
- FunctionType expected = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
+ void test_functionsSameType_withNamed() {
+ var type1 = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ var type2 = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ var expected = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ _checkGreatestLowerBound(type1, type2, expected);
+ }
+
+ void test_functionsSameType_withOptional() {
+ var type1 = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
+ var type2 = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
+ var expected = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
_checkGreatestLowerBound(type1, type2, expected);
}
@@ -1386,8 +1514,11 @@
ElementFactory.typeParameterElement('T').type
];
for (DartType type in types) {
- _checkGreatestLowerBound(_functionType([], returns: voidType),
- _functionType([], returns: type), _functionType([], returns: type));
+ _checkGreatestLowerBound(
+ _functionType(required: [], returns: voidType),
+ _functionType(required: [], returns: type),
+ _functionType(required: [], returns: type),
+ );
}
}
}
@@ -1399,71 +1530,164 @@
typeSystem = new Dart2TypeSystem(typeProvider);
}
- void test_functionsDifferentRequiredArity() {
- FunctionType type1 = _functionType([intType, intType]);
- FunctionType type2 = _functionType([intType, intType, intType]);
+ void test_differentRequiredArity() {
+ var type1 = _functionType(required: [intType, intType]);
+ var type2 = _functionType(required: [intType, intType, intType]);
_checkLeastUpperBound(type1, type2, functionType);
}
- void test_functionsFuzzyArrows() {
- FunctionType type1 = _functionType([dynamicType]);
- FunctionType type2 = _functionType([intType]);
- FunctionType expected = _functionType([intType]);
+ void test_fuzzyArrows() {
+ var type1 = _functionType(required: [dynamicType]);
+ var type2 = _functionType(required: [intType]);
+ var expected = _functionType(required: [intType]);
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsGlbNamedParams() {
- FunctionType type1 =
- _functionType([], named: {'a': stringType, 'b': intType});
- FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
- FunctionType expected =
- _functionType([], named: {'a': bottomType, 'b': intType});
+ void test_glbNamedParams() {
+ var type1 = _functionType(
+ named: {'a': stringType, 'b': intType},
+ );
+ var type2 = _functionType(
+ named: {'a': intType, 'b': numType},
+ );
+ var expected = _functionType(
+ named: {'a': bottomType, 'b': intType},
+ );
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsGlbPositionalParams() {
- FunctionType type1 = _functionType([], optional: [stringType, intType]);
- FunctionType type2 = _functionType([], optional: [intType, numType]);
- FunctionType expected = _functionType([], optional: [bottomType, intType]);
+ void test_glbPositionalParams() {
+ var type1 = _functionType(
+ optional: [stringType, intType],
+ );
+ var type2 = _functionType(
+ optional: [intType, numType],
+ );
+ var expected = _functionType(
+ optional: [bottomType, intType],
+ );
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsGlbRequiredParams() {
- FunctionType type1 = _functionType([stringType, intType, intType]);
- FunctionType type2 = _functionType([intType, doubleType, numType]);
- FunctionType expected = _functionType([bottomType, bottomType, intType]);
+ void test_glbRequiredParams() {
+ var type1 = _functionType(
+ required: [stringType, intType, intType],
+ );
+ var type2 = _functionType(
+ required: [intType, doubleType, numType],
+ );
+ var expected = _functionType(
+ required: [bottomType, bottomType, intType],
+ );
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsIgnoreExtraNamedParams() {
- FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
- FunctionType type2 = _functionType([], named: {'a': intType, 'c': intType});
- FunctionType expected = _functionType([], named: {'a': intType});
+ void test_ignoreExtraNamedParams() {
+ var type1 = _functionType(
+ named: {'a': intType, 'b': intType},
+ );
+ var type2 = _functionType(
+ named: {'a': intType, 'c': intType},
+ );
+ var expected = _functionType(
+ named: {'a': intType},
+ );
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsIgnoreExtraPositionalParams() {
- FunctionType type1 =
- _functionType([], optional: [intType, intType, stringType]);
- FunctionType type2 = _functionType([], optional: [intType]);
- FunctionType expected = _functionType([], optional: [intType]);
+ void test_ignoreExtraPositionalParams() {
+ var type1 = _functionType(
+ optional: [intType, intType, stringType],
+ );
+ var type2 = _functionType(
+ optional: [intType],
+ );
+ var expected = _functionType(
+ optional: [intType],
+ );
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsLubReturnType() {
- FunctionType type1 = _functionType([], returns: intType);
- FunctionType type2 = _functionType([], returns: doubleType);
- FunctionType expected = _functionType([], returns: numType);
+ void test_lubReturnType() {
+ var type1 = _functionType(returns: intType);
+ var type2 = _functionType(returns: doubleType);
+ var expected = _functionType(returns: numType);
_checkLeastUpperBound(type1, type2, expected);
}
- void test_functionsSameType() {
- FunctionType type1 = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
- FunctionType type2 = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
- FunctionType expected = _functionType([stringType, intType, numType],
- optional: [doubleType], named: {'n': numType}, returns: intType);
+ void test_sameType_withNamed() {
+ var type1 = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ var type2 = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ var expected = _functionType(
+ required: [stringType, intType, numType],
+ named: {'n': numType},
+ returns: intType,
+ );
+
+ _checkLeastUpperBound(type1, type2, expected);
+ }
+
+ void test_sameType_withOptional() {
+ var type1 = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
+ var type2 = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
+ var expected = _functionType(
+ required: [stringType, intType, numType],
+ optional: [doubleType],
+ returns: intType,
+ );
+
+ _checkLeastUpperBound(type1, type2, expected);
+ }
+
+ void test_typeFormals_differentBounds() {
+ var T1 = _typeParameterElement('T1', bound: intType);
+ var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+ var T2 = _typeParameterElement('T2', bound: doubleType);
+ var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+ _checkLeastUpperBound(type1, type2, functionType);
+ }
+
+ void test_typeFormals_differentNumber() {
+ var T1 = _typeParameterElement('T1', bound: numType);
+ var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+ var type2 = _functionType(returns: intType);
+
+ _checkLeastUpperBound(type1, type2, functionType);
+ }
+
+ void test_typeFormals_sameBounds() {
+ var T1 = _typeParameterElement('T1', bound: numType);
+ var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+ var T2 = _typeParameterElement('T2', bound: numType);
+ var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+ var TE = _typeParameterElement('T', bound: numType);
+ var expected = _functionType(typeFormals: [TE], returns: TE.type);
+
_checkLeastUpperBound(type1, type2, expected);
}
}
@@ -1566,32 +1790,38 @@
}
void test_nestedFunctionsLubInnerParamTypes() {
- FunctionType type1 = _functionType([
- _functionType([stringType, intType, intType])
- ]);
- FunctionType type2 = _functionType([
- _functionType([intType, doubleType, numType])
- ]);
- FunctionType expected = _functionType([
- _functionType([objectType, numType, numType])
- ]);
+ var type1 = _functionType(
+ required: [
+ _functionType(required: [stringType, intType, intType])
+ ],
+ );
+ var type2 = _functionType(
+ required: [
+ _functionType(required: [intType, doubleType, numType])
+ ],
+ );
+ var expected = _functionType(
+ required: [
+ _functionType(required: [objectType, numType, numType])
+ ],
+ );
_checkLeastUpperBound(type1, type2, expected);
}
void test_nestedNestedFunctionsGlbInnermostParamTypes() {
- FunctionType type1 = _functionType([
- _functionType([
- _functionType([stringType, intType, intType])
+ FunctionType type1 = _functionType(required: [
+ _functionType(required: [
+ _functionType(required: [stringType, intType, intType])
])
]);
- FunctionType type2 = _functionType([
- _functionType([
- _functionType([intType, doubleType, numType])
+ FunctionType type2 = _functionType(required: [
+ _functionType(required: [
+ _functionType(required: [intType, doubleType, numType])
])
]);
- FunctionType expected = _functionType([
- _functionType([
- _functionType([bottomType, bottomType, intType])
+ FunctionType expected = _functionType(required: [
+ _functionType(required: [
+ _functionType(required: [bottomType, bottomType, intType])
])
]);
_checkLeastUpperBound(type1, type2, expected);
@@ -1840,9 +2070,10 @@
];
for (DartType type in types) {
_checkLeastUpperBound(
- _functionType([], returns: voidType),
- _functionType([], returns: type),
- _functionType([], returns: voidType));
+ _functionType(returns: voidType),
+ _functionType(returns: type),
+ _functionType(returns: voidType),
+ );
}
}
}
@@ -1878,6 +2109,46 @@
_checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
}
+ @failingTest
+ void test_futureOr_topTypes() {
+ var objectStar =
+ (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 futureOrStarObject =
+ (futureOrObject as TypeImpl).withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObject = (futureOrObject as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+ var futureOrStarObjectStar = (futureOrObjectStar as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObjectStar = (futureOrObjectStar as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+ var futureOrStarObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+
+ //FutureOr<Object> <: FutureOr*<Object?>
+ _checkGroups(futureOrObject, equivalents: [
+ objectStar,
+ futureOrObjectStar,
+ futureOrStarObject,
+ futureOrStarObjectStar,
+ objectType
+ ], subtypes: [], supertypes: [
+ objectQuestion,
+ futureOrQuestionObject,
+ futureOrObjectQuestion,
+ futureOrQuestionObject,
+ futureOrQuestionObjectStar,
+ futureOrStarObjectQuestion,
+ futureOrQuestionObjectQuestion
+ ]);
+ }
+
void test_int_nullableTypes() {
List<DartType> equivalents = <DartType>[
intType,
@@ -2458,56 +2729,222 @@
@reflectiveTest
class TypeSystemTest extends AbstractTypeSystemTest {
- DartType get futureOrWithNoneType =>
- typeProvider.futureOrType.instantiate([noneType]);
+ DartType get functionClassTypeNone {
+ return InterfaceTypeImpl.explicit(
+ typeProvider.functionType.element,
+ const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
- DartType get futureOrWithQuestionType =>
- typeProvider.futureOrType.instantiate([questionType]);
+ DartType get functionClassTypeQuestion {
+ return InterfaceTypeImpl.explicit(
+ typeProvider.functionType.element,
+ const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ }
- DartType get futureOrWithStarType =>
- typeProvider.futureOrType.instantiate([starType]);
+ DartType get functionClassTypeStar {
+ return InterfaceTypeImpl.explicit(
+ typeProvider.functionType.element,
+ const <DartType>[],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
DartType get noneType => (typeProvider.stringType as TypeImpl)
.withNullability(NullabilitySuffix.none);
+ FunctionType get nothingToVoidFunctionTypeNone {
+ return FunctionTypeImpl.synthetic(
+ voidType,
+ const <TypeParameterElement>[],
+ const <ParameterElement>[],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
+
+ FunctionType get nothingToVoidFunctionTypeQuestion {
+ return FunctionTypeImpl.synthetic(
+ voidType,
+ const <TypeParameterElement>[],
+ const <ParameterElement>[],
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ }
+
+ FunctionType get nothingToVoidFunctionTypeStar {
+ return FunctionTypeImpl.synthetic(
+ voidType,
+ const <TypeParameterElement>[],
+ const <ParameterElement>[],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
+
DartType get questionType => (typeProvider.stringType as TypeImpl)
.withNullability(NullabilitySuffix.question);
DartType get starType => (typeProvider.stringType as TypeImpl)
.withNullability(NullabilitySuffix.star);
+ DartType futureOrTypeNone({@required DartType argument}) {
+ var element = typeProvider.futureOrType.element;
+ return InterfaceTypeImpl.explicit(
+ element,
+ <DartType>[argument],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
+
+ DartType futureOrTypeQuestion({@required DartType argument}) {
+ var element = typeProvider.futureOrType.element;
+ return InterfaceTypeImpl.explicit(
+ element,
+ <DartType>[argument],
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ }
+
+ DartType futureOrTypeStar({@required DartType argument}) {
+ var element = typeProvider.futureOrType.element;
+ return InterfaceTypeImpl.explicit(
+ element,
+ <DartType>[argument],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
+
test_isNonNullable_dynamic() {
expect(typeSystem.isNonNullable(dynamicType), false);
}
- test_isNonNullable_futureOr_noneArg() {
- expect(typeSystem.isNonNullable(futureOrWithNoneType), true);
+ test_isNonNullable_function_none() {
+ expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeNone), true);
}
- test_isNonNullable_futureOr_questionArg() {
- expect(typeSystem.isNonNullable(futureOrWithQuestionType), true);
+ test_isNonNullable_function_question() {
+ expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeQuestion), false);
}
- test_isNonNullable_futureOr_starArg() {
- expect(typeSystem.isNonNullable(futureOrWithStarType), true);
+ test_isNonNullable_function_star() {
+ expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeStar), true);
}
- test_isNonNullable_none() {
+ test_isNonNullable_functionClass_none() {
+ expect(typeSystem.isNonNullable(functionClassTypeNone), true);
+ }
+
+ test_isNonNullable_functionClass_question() {
+ expect(typeSystem.isNonNullable(functionClassTypeQuestion), false);
+ }
+
+ test_isNonNullable_functionClass_star() {
+ expect(typeSystem.isNonNullable(functionClassTypeStar), true);
+ }
+
+ test_isNonNullable_futureOr_noneArgument_none() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeNone(argument: noneType),
+ ),
+ true,
+ );
+ }
+
+ test_isNonNullable_futureOr_noneArgument_question() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeQuestion(argument: noneType),
+ ),
+ false,
+ );
+ }
+
+ test_isNonNullable_futureOr_noneArgument_star() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeStar(argument: noneType),
+ ),
+ true,
+ );
+ }
+
+ test_isNonNullable_futureOr_questionArgument_none() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeNone(argument: questionType),
+ ),
+ false,
+ );
+ }
+
+ test_isNonNullable_futureOr_questionArgument_question() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeQuestion(argument: questionType),
+ ),
+ false,
+ );
+ }
+
+ test_isNonNullable_futureOr_questionArgument_star() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeStar(argument: questionType),
+ ),
+ false,
+ );
+ }
+
+ test_isNonNullable_futureOr_starArgument_none() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeNone(argument: starType),
+ ),
+ true,
+ );
+ }
+
+ test_isNonNullable_futureOr_starArgument_question() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeStar(argument: questionType),
+ ),
+ false,
+ );
+ }
+
+ test_isNonNullable_futureOr_starArgument_star() {
+ expect(
+ typeSystem.isNonNullable(
+ futureOrTypeStar(argument: starType),
+ ),
+ true,
+ );
+ }
+
+ test_isNonNullable_interface_none() {
expect(typeSystem.isNonNullable(noneType), true);
}
+ test_isNonNullable_interface_question() {
+ expect(typeSystem.isNonNullable(questionType), false);
+ }
+
+ test_isNonNullable_interface_star() {
+ expect(typeSystem.isNonNullable(starType), true);
+ }
+
+ test_isNonNullable_never() {
+ expect(typeSystem.isNonNullable(neverType), true);
+ }
+
test_isNonNullable_null() {
expect(typeSystem.isNonNullable(nullType), false);
}
- test_isNonNullable_question() {
- expect(typeSystem.isNonNullable(questionType), false);
- }
-
- test_isNonNullable_star() {
- expect(typeSystem.isNonNullable(starType), true);
- }
-
test_isNonNullable_typeParameter_noneBound_none() {
expect(
typeSystem.isNonNullable(
@@ -2561,34 +2998,131 @@
expect(typeSystem.isNullable(dynamicType), true);
}
- test_isNullable_futureOr_noneArg() {
- expect(typeSystem.isNullable(futureOrWithNoneType), true);
+ test_isNullable_function_none() {
+ expect(typeSystem.isNullable(nothingToVoidFunctionTypeNone), false);
}
- test_isNullable_futureOr_questionArg() {
- expect(typeSystem.isNullable(futureOrWithQuestionType), true);
+ test_isNullable_function_question() {
+ expect(typeSystem.isNullable(nothingToVoidFunctionTypeQuestion), true);
}
- test_isNullable_futureOr_starArg() {
- expect(typeSystem.isNullable(futureOrWithStarType), true);
+ test_isNullable_function_star() {
+ expect(typeSystem.isNullable(nothingToVoidFunctionTypeStar), false);
}
- test_isNullable_none() {
+ test_isNullable_functionClass_none() {
+ expect(typeSystem.isNullable(functionClassTypeNone), false);
+ }
+
+ test_isNullable_functionClass_question() {
+ expect(typeSystem.isNullable(functionClassTypeQuestion), true);
+ }
+
+ test_isNullable_functionClass_star() {
+ expect(typeSystem.isNullable(functionClassTypeStar), false);
+ }
+
+ test_isNullable_futureOr_noneArgument_none() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeNone(argument: noneType),
+ ),
+ false,
+ );
+ }
+
+ test_isNullable_futureOr_noneArgument_question() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeQuestion(argument: noneType),
+ ),
+ true,
+ );
+ }
+
+ test_isNullable_futureOr_noneArgument_star() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeStar(argument: noneType),
+ ),
+ false,
+ );
+ }
+
+ test_isNullable_futureOr_questionArgument_none() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeNone(argument: questionType),
+ ),
+ true,
+ );
+ }
+
+ test_isNullable_futureOr_questionArgument_question() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeQuestion(argument: questionType),
+ ),
+ true,
+ );
+ }
+
+ test_isNullable_futureOr_questionArgument_star() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeStar(argument: questionType),
+ ),
+ true,
+ );
+ }
+
+ test_isNullable_futureOr_starArgument_none() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeNone(argument: starType),
+ ),
+ false,
+ );
+ }
+
+ test_isNullable_futureOr_starArgument_question() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeQuestion(argument: starType),
+ ),
+ true,
+ );
+ }
+
+ test_isNullable_futureOr_starArgument_star() {
+ expect(
+ typeSystem.isNullable(
+ futureOrTypeStar(argument: starType),
+ ),
+ false,
+ );
+ }
+
+ test_isNullable_interface_none() {
expect(typeSystem.isNullable(noneType), false);
}
+ test_isNullable_interface_question() {
+ expect(typeSystem.isNullable(questionType), true);
+ }
+
+ test_isNullable_interface_star() {
+ expect(typeSystem.isNullable(starType), false);
+ }
+
+ test_isNullable_never() {
+ expect(typeSystem.isNullable(neverType), false);
+ }
+
test_isNullable_null() {
expect(typeSystem.isNullable(nullType), true);
}
- test_isNullable_question() {
- expect(typeSystem.isNullable(questionType), true);
- }
-
- test_isNullable_star() {
- expect(typeSystem.isNullable(starType), true);
- }
-
test_isNullable_typeParameter_noneBound_none() {
expect(
typeSystem.isNullable(
@@ -2630,7 +3164,7 @@
typeSystem.isNullable(
typeParameterTypeStar(bound: starType),
),
- true,
+ false,
);
}
@@ -2642,17 +3176,35 @@
expect(typeSystem.isPotentiallyNonNullable(dynamicType), false);
}
- test_isPotentiallyNonNullable_futureOr_noneArg() {
- expect(typeSystem.isPotentiallyNonNullable(futureOrWithNoneType), false);
- }
-
- test_isPotentiallyNonNullable_futureOr_questionArg() {
+ test_isPotentiallyNonNullable_futureOr_noneArgument_none() {
expect(
- typeSystem.isPotentiallyNonNullable(futureOrWithQuestionType), false);
+ typeSystem.isPotentiallyNonNullable(
+ futureOrTypeNone(argument: noneType),
+ ),
+ true,
+ );
}
- test_isPotentiallyNonNullable_futureOr_starArg() {
- expect(typeSystem.isPotentiallyNonNullable(futureOrWithStarType), false);
+ test_isPotentiallyNonNullable_futureOr_questionArgument_none() {
+ expect(
+ typeSystem.isPotentiallyNonNullable(
+ futureOrTypeNone(argument: questionType),
+ ),
+ false,
+ );
+ }
+
+ test_isPotentiallyNonNullable_futureOr_starArgument_none() {
+ expect(
+ typeSystem.isPotentiallyNonNullable(
+ futureOrTypeNone(argument: starType),
+ ),
+ true,
+ );
+ }
+
+ test_isPotentiallyNonNullable_never() {
+ expect(typeSystem.isPotentiallyNonNullable(neverType), true);
}
test_isPotentiallyNonNullable_none() {
@@ -2668,7 +3220,7 @@
}
test_isPotentiallyNonNullable_star() {
- expect(typeSystem.isPotentiallyNonNullable(starType), false);
+ expect(typeSystem.isPotentiallyNonNullable(starType), true);
}
test_isPotentiallyNonNullable_void() {
@@ -2679,16 +3231,35 @@
expect(typeSystem.isPotentiallyNullable(dynamicType), true);
}
- test_isPotentiallyNullable_futureOr_noneArg() {
- expect(typeSystem.isPotentiallyNullable(futureOrWithNoneType), false);
+ test_isPotentiallyNullable_futureOr_noneArgument_none() {
+ expect(
+ typeSystem.isPotentiallyNullable(
+ futureOrTypeNone(argument: noneType),
+ ),
+ false,
+ );
}
- test_isPotentiallyNullable_futureOr_questionArg() {
- expect(typeSystem.isPotentiallyNullable(futureOrWithQuestionType), false);
+ test_isPotentiallyNullable_futureOr_questionArgument_none() {
+ expect(
+ typeSystem.isPotentiallyNullable(
+ futureOrTypeNone(argument: questionType),
+ ),
+ true,
+ );
}
- test_isPotentiallyNullable_futureOr_starArg() {
- expect(typeSystem.isPotentiallyNullable(futureOrWithStarType), false);
+ test_isPotentiallyNullable_futureOr_starArgument_none() {
+ expect(
+ typeSystem.isPotentiallyNullable(
+ futureOrTypeNone(argument: starType),
+ ),
+ false,
+ );
+ }
+
+ test_isPotentiallyNullable_never() {
+ expect(typeSystem.isPotentiallyNullable(neverType), false);
}
test_isPotentiallyNullable_none() {
@@ -2715,23 +3286,29 @@
expect(bound, isNotNull);
var element = TypeParameterElementImpl.synthetic('T');
element.bound = bound;
- return TypeParameterTypeImpl(element,
- nullabilitySuffix: NullabilitySuffix.none);
+ return TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
}
DartType typeParameterTypeQuestion({@required DartType bound}) {
expect(bound, isNotNull);
var element = TypeParameterElementImpl.synthetic('T');
element.bound = bound;
- return TypeParameterTypeImpl(element,
- nullabilitySuffix: NullabilitySuffix.question);
+ return TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
}
DartType typeParameterTypeStar({@required DartType bound}) {
expect(bound, isNotNull);
var element = TypeParameterElementImpl.synthetic('T');
element.bound = bound;
- return TypeParameterTypeImpl(element,
- nullabilitySuffix: NullabilitySuffix.star);
+ return TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
}
}
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 3fec6a9..4bb1920 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -8,6 +8,7 @@
void main() {
test("parses a valid compilation unit successfully", () {
+ // ignore: deprecated_member_use_from_same_package
var unit = parseCompilationUnit("void main() => print('Hello, world!');");
expect(unit.toString(), equals("void main() => print('Hello, world!');"));
});
@@ -24,9 +25,11 @@
test('with errors suppressed', () {
checkCompilationUnit(
+ // ignore: deprecated_member_use_from_same_package
parseCompilationUnit(contents, suppressErrors: true));
});
test('with errors enabled', () {
+ // ignore: deprecated_member_use_from_same_package
checkCompilationUnit(parseCompilationUnit(contents));
});
});
@@ -45,15 +48,18 @@
test('with errors suppressed', () {
checkCompilationUnit(
+ // ignore: deprecated_member_use_from_same_package
parseCompilationUnit(contents, suppressErrors: true));
});
test('with errors enabled', () {
+ // ignore: deprecated_member_use_from_same_package
checkCompilationUnit(parseCompilationUnit(contents));
});
});
test("throws errors for an invalid compilation unit", () {
expect(() {
+ // ignore: deprecated_member_use_from_same_package
parseCompilationUnit("void main() => print('Hello, world!')",
name: 'test.dart');
}, throwsA(predicate((error) {
@@ -64,6 +70,7 @@
test("defaults to '<unknown source>' if no name is provided", () {
expect(() {
+ // ignore: deprecated_member_use_from_same_package
parseCompilationUnit("void main() => print('Hello, world!')");
}, throwsA(predicate((error) {
return error is AnalyzerErrorGroup &&
@@ -74,12 +81,14 @@
});
test("allows you to specify whether or not to parse function bodies", () {
+ // ignore: deprecated_member_use_from_same_package
var unit = parseCompilationUnit("void main() => print('Hello, world!');",
parseFunctionBodies: false);
expect(unit.toString(), equals("void main();"));
});
test("allows you to specify whether or not to parse function bodies 2", () {
+ // ignore: deprecated_member_use_from_same_package
var unit = parseCompilationUnit("void main() { print('Hello, world!'); }",
parseFunctionBodies: false);
expect(unit.toString(), equals("void main();"));
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index 8222c70..f7562ed 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -226,11 +226,11 @@
test_class_field_withType() {
assertSameSignature(r'''
class C {
- int a = 1, b, c = 3;
+ int a = 1;
}
''', r'''
class C {
- int a = 0, b = 2, c;
+ int a = 2;
}
''');
}
@@ -744,11 +744,11 @@
test_mixin_field_withType() {
assertSameSignature(r'''
mixin M {
- int a = 1, b, c = 3;
+ int a = 1;
}
''', r'''
mixin M {
- int a = 0, b = 2, c;
+ int a = 2;
}
''');
}
@@ -819,9 +819,9 @@
test_topLevelVariable_withType() {
assertSameSignature(r'''
-int a = 1, b, c = 3;
+int a = 1;
''', r'''
-int a = 0, b = 2, c;
+int a = 2;
''');
}
@@ -841,6 +841,22 @@
''');
}
+ test_topLevelVariable_withType_initializer_add() {
+ assertNotSameSignature(r'''
+int a;
+''', r'''
+int a = 1;
+''');
+ }
+
+ test_topLevelVariable_withType_initializer_remove() {
+ assertNotSameSignature(r'''
+int a = 1;
+''', r'''
+int a;
+''');
+ }
+
test_typedef_generic_parameters_type() {
assertNotSameSignature(r'''
typedef F = void Function(int);
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 00cf65e..0a8e03d 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -1755,6 +1755,46 @@
]));
}
+ void test_visitExtensionOverride_prefixedName_noTypeArgs() {
+ _assertSource(
+ 'p.E(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier5('p', 'E'),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_prefixedName_typeArgs() {
+ _assertSource(
+ 'p.E<A>(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier5('p', 'E'),
+ typeArguments: AstTestFactory.typeArgumentList(
+ [AstTestFactory.typeName4('A')]),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_simpleName_noTypeArgs() {
+ _assertSource(
+ 'E(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier3('E'),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_simpleName_typeArgs() {
+ _assertSource(
+ 'E<A>(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier3('E'),
+ typeArguments: AstTestFactory.typeArgumentList(
+ [AstTestFactory.typeName4('A')]),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
void test_visitFieldDeclaration_instance() {
_assertSource(
"var a;",
@@ -4521,6 +4561,46 @@
]));
}
+ void test_visitExtensionOverride_prefixedName_noTypeArgs() {
+ _assertSource(
+ 'p.E(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier5('p', 'E'),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_prefixedName_typeArgs() {
+ _assertSource(
+ 'p.E<A>(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier5('p', 'E'),
+ typeArguments: AstTestFactory.typeArgumentList(
+ [AstTestFactory.typeName4('A')]),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_simpleName_noTypeArgs() {
+ _assertSource(
+ 'E(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier3('E'),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
+ void test_visitExtensionOverride_simpleName_typeArgs() {
+ _assertSource(
+ 'E<A>(o)',
+ AstTestFactory.extensionOverride(
+ extensionName: AstTestFactory.identifier3('E'),
+ typeArguments: AstTestFactory.typeArgumentList(
+ [AstTestFactory.typeName4('A')]),
+ argumentList: AstTestFactory.argumentList(
+ [AstTestFactory.identifier3('o')])));
+ }
+
void test_visitFieldDeclaration_instance() {
_assertSource(
"var a;",
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
index 6a39734..8cd4944 100644
--- a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -2,1488 +2,204 @@
// for 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/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.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/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
-import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/ast_data_extractor.dart';
+import 'package:front_end/src/testing/id.dart' show ActualData, Id;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../util/id_equivalence_helper.dart';
import 'driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NullableFlowTest);
- defineReflectiveTests(DefiniteAssignmentFlowTest);
defineReflectiveTests(ReachableFlowTest);
- defineReflectiveTests(TypePromotionFlowTest);
});
}
-@reflectiveTest
-class DefiniteAssignmentFlowTest extends DriverResolutionTest {
- final List<LocalVariableElement> readBeforeWritten = [];
+class FlowTestBase extends DriverResolutionTest {
+ FlowAnalysisResult flowResult;
- /// Assert that only local variables with the given names are marked as read
- /// before being written. All the other local variables are implicitly
- /// considered definitely assigned.
- void assertReadBeforeWritten(
- [String name1, String name2, String name3, String name4]) {
- var expected = [name1, name2, name3, name4]
- .where((i) => i != null)
- .map((name) => findElement.localVar(name))
- .toList();
- expect(readBeforeWritten, unorderedEquals(expected));
- }
-
- test_assignment_leftExpression() async {
- await trackCode(r'''
-void f() {
- List<int> v;
- v[0] = (v = [1, 2])[1];
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_assignment_leftLocal_compound() async {
- await trackCode(r'''
-void f() {
- int v;
- v += 1;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_assignment_leftLocal_compound_assignInRight() async {
- await trackCode(r'''
-void f() {
- int v;
- v += (v = v);
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_assignment_leftLocal_pure_eq() async {
- await trackCode(r'''
-void f() {
- int v;
- v = 0;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_assignment_leftLocal_pure_eq_self() async {
- await trackCode(r'''
-void f() {
- int v;
- v = v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_assignment_leftLocal_pure_questionEq() async {
- await trackCode(r'''
-void f() {
- int v;
- v ??= 0;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_assignment_leftLocal_pure_questionEq_self() async {
- await trackCode(r'''
-void f() {
- int v;
- v ??= v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_binaryExpression_ifNull_left() async {
- await trackCode(r'''
-void f() {
- int v;
- (v = 0) ?? 0;
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_binaryExpression_ifNull_right() async {
- await trackCode(r'''
-void f(int a) {
- int v;
- a ?? (v = 0);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_binaryExpression_logicalAnd_left() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- ((v = 0) >= 0) && c;
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_binaryExpression_logicalAnd_right() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- c && ((v = 0) >= 0);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_binaryExpression_logicalOr_left() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- ((v = 0) >= 0) || c;
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_binaryExpression_logicalOr_right() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- c || ((v = 0) >= 0);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_binaryExpression_plus_left() async {
- await trackCode(r'''
-main() {
- int v;
- (v = 0) + 1;
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_binaryExpression_plus_right() async {
- await trackCode(r'''
-main() {
- int v;
- 1 + (v = 0);
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_conditional_both() async {
- await trackCode(r'''
-f(bool v) {
- int v;
- b ? (v = 1) : (v = 2);
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_conditional_else() async {
- await trackCode(r'''
-f(bool v) {
- int v;
- b ? 1 : (v = 2);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_conditional_then() async {
- await trackCode(r'''
-f(bool v) {
- int v;
- b ? (v = 1) : 2;
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_conditionalExpression_condition() async {
- await trackCode(r'''
-main() {
- int v;
- (v = 0) >= 0 ? 1 : 2;
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_doWhile_break_afterAssignment() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- do {
- v = 0;
- v;
- if (b) break;
- } while (b);
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_doWhile_break_beforeAssignment() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- do {
- if (b) break;
- v = 0;
- } while (b);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_doWhile_breakOuterFromInner() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2, v3;
- L1: do {
- do {
- v1 = 0;
- if (b) break L1;
- v2 = 0;
- v3 = 0;
- } while (b);
- v2;
- } while (b);
- v1;
- v3;
-}
-''');
- assertReadBeforeWritten('v3');
- }
-
- test_doWhile_condition() async {
- await trackCode(r'''
-void f() {
- int v1, v2;
- do {
- v1; // assigned in the condition, but not yet
- } while ((v1 = 0) + (v2 = 0) >= 0);
- v2;
-}
-''');
- assertReadBeforeWritten('v1');
- }
-
- test_doWhile_condition_break() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- do {
- if (b) break;
- } while ((v = 0) >= 0);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_doWhile_condition_break_continue() async {
- await trackCode(r'''
-void f(bool b1, b2) {
- int v1, v2, v3, v4, v5, v6;
- do {
- v1 = 0; // visible outside, visible to the condition
- if (b1) break;
- v2 = 0; // not visible outside, visible to the condition
- v3 = 0; // not visible outside, visible to the condition
- if (b2) continue;
- v4 = 0; // not visible
- v5 = 0; // not visible
- } while ((v6 = v1 + v2 + v4) == 0); // has break => v6 is not visible outside
- v1;
- v3;
- v5;
- v6;
-}
-''');
- assertReadBeforeWritten('v3', 'v4', 'v5', 'v6');
- }
-
- test_doWhile_condition_continue() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2, v3, v4;
- do {
- v1 = 0; // visible outside, visible to the condition
- if (b) continue;
- v2 = 0; // not visible
- v3 = 0; // not visible
- } while ((v4 = v1 + v2) == 0); // no break => v4 visible outside
- v1;
- v3;
- v4;
-}
-''');
- assertReadBeforeWritten('v2', 'v3');
- }
-
- test_doWhile_continue_beforeAssignment() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- do {
- if (b) continue;
- v = 0;
- } while (b);
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_doWhile_true_assignInBreak() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- do {
- if (b) {
- v = 0;
- break;
- }
- } while (true);
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_for_body() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- for (; b;) {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_for_break() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (; b;) {
- v1 = 0;
- if (b) break;
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v1', 'v2');
- }
-
- test_for_break_updaters() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (; b; v1 + v2) {
- v1 = 0;
- if (b) break;
- v2 = 0;
- }
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_for_condition() async {
- await trackCode(r'''
-void f() {
- int v;
- for (; (v = 0) >= 0;) {
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_for_continue() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (; b;) {
- v1 = 0;
- if (b) continue;
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v1', 'v2');
- }
-
- test_for_continue_updaters() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (; b; v1 + v2) {
- v1 = 0;
- if (b) continue;
- v2 = 0;
- }
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_for_initializer_expression() async {
- await trackCode(r'''
-void f() {
- int v;
- for (v = 0;;) {
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_for_initializer_variable() async {
- await trackCode(r'''
-void f() {
- int v;
- for (var t = (v = 0);;) {
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_for_updaters() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2, v3, v4;
- for (; b; v1 = 0, v2 = 0, v3 = 0, v4) {
- v1;
- }
- v2;
-}
-''');
- assertReadBeforeWritten('v1', 'v2', 'v4');
- }
-
- test_for_updaters_afterBody() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- for (; b; v) {
- v = 0;
- }
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_forEach() async {
- await trackCode(r'''
-void f() {
- int v1, v2;
- for (var _ in (v1 = [0, 1, 2])) {
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_forEach_break() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (var _ in [0, 1, 2]) {
- v1 = 0;
- if (b) break;
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v1', 'v2');
- }
-
- test_forEach_continue() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- for (var _ in [0, 1, 2]) {
- v1 = 0;
- if (b) continue;
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v1', 'v2');
- }
-
- test_functionExpression_closure_read() async {
- await trackCode(r'''
-void f() {
- int v1, v2;
-
- v1 = 0;
-
- [0, 1, 2].forEach((t) {
- v1;
- v2;
- });
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_functionExpression_closure_write() async {
- await trackCode(r'''
-void f() {
- int v;
-
- [0, 1, 2].forEach((t) {
- v = t;
- });
-
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_functionExpression_localFunction_local() async {
- await trackCode(r'''
-void f() {
- int v;
-
- v = 0;
-
- void f() {
- int v; // 1
- v;
- }
-}
-''');
- var localV = findNode.simple('v; // 1').staticElement;
- expect(readBeforeWritten, unorderedEquals([localV]));
- }
-
- test_functionExpression_localFunction_local2() async {
- await trackCode(r'''
-void f() {
- int v1;
-
- v1 = 0;
-
- void f() {
- int v2, v3;
- v2 = 0;
- v1;
- v2;
- v3;
- }
-}
-''');
- assertReadBeforeWritten('v3');
- }
-
- test_functionExpression_localFunction_read() async {
- await trackCode(r'''
-void f() {
- int v1, v2, v3;
-
- v1 = 0;
-
- void f() {
- v1;
- v2;
- }
-
- v2 = 0;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_functionExpression_localFunction_write() async {
- await trackCode(r'''
-void f() {
- int v;
-
- void f() {
- v = 0;
- }
-
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_if_condition() async {
- await trackCode(r'''
-main() {
- int v;
- if ((v = 0) >= 0) {
- v;
- } else {
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_false() async {
- await trackCode(r'''
-void f() {
- int v;
- if (false) {
- // not assigned
- } else {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_logicalAnd_else() async {
- await trackCode(r'''
-void f(bool b, int i) {
- int v;
- if (b && (v = i) > 0) {
- } else {
- v;
- }
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_if_condition_logicalAnd_then() async {
- await trackCode(r'''
-void f(bool b, int i) {
- int v;
- if (b && (v = i) > 0) {
- v;
- }
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_logicalOr_else() async {
- await trackCode(r'''
-void f(bool b, int i) {
- int v;
- if (b || (v = i) > 0) {
- } else {
- v;
- }
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_logicalOr_then() async {
- await trackCode(r'''
-void f(bool b, int i) {
- int v;
- if (b || (v = i) > 0) {
- v;
- } else {
- }
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_if_condition_notFalse() async {
- await trackCode(r'''
-void f() {
- int v;
- if (!false) {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_notTrue() async {
- await trackCode(r'''
-void f() {
- int v;
- if (!true) {
- // not assigned
- } else {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_condition_true() async {
- await trackCode(r'''
-void f() {
- int v;
- if (true) {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_then() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- if (c) {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_if_thenElse_all() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- if (c) {
- v = 0;
- v;
- } else {
- v = 0;
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_if_thenElse_else() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- if (c) {
- // not assigned
- } else {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_if_thenElse_then() async {
- await trackCode(r'''
-main(bool c) {
- int v;
- if (c) {
- v = 0;
- } else {
- // not assigned
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_switch_case1_default() async {
- await trackCode(r'''
-void f(int e) {
- int v;
- switch (e) {
- case 1:
- v = 0;
- break;
- case 2:
- // not assigned
- break;
- default:
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_switch_case2_default() async {
- await trackCode(r'''
-void f(int e) {
- int v1, v2;
- switch (e) {
- case 1:
- v1 = 0;
- v2 = 0;
- v1;
- break;
- default:
- v1 = 0;
- v1;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_switch_case_default_break() async {
- await trackCode(r'''
-void f(bool b, int e) {
- int v1, v2;
- switch (e) {
- case 1:
- v1 = 0;
- if (b) break;
- v2 = 0;
- break;
- default:
- v1 = 0;
- if (b) break;
- v2 = 0;
- }
- v1;
- v2;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_switch_case_default_continue() async {
- await trackCode(r'''
-void f(int e) {
- int v;
- switch (e) {
- L: case 1:
- v = 0;
- break;
- case 2:
- continue L;
- break;
- default:
- v = 0;
- }
- v;
-}
-''');
- // We don't analyze to which `case` we go from `continue L`,
- // but we don't have to. If all cases assign, then the variable is
- // removed from the unassigned set in the `breakState`. And if there is a
- // case when it is not assigned, then the variable will be left unassigned
- // in the `breakState`.
- assertReadBeforeWritten();
- }
-
- test_switch_case_noDefault() async {
- await trackCode(r'''
-void f(int e) {
- int v;
- switch (e) {
- case 1:
- v = 0;
- break;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_switch_expression() async {
- await trackCode(r'''
-void f() {
- int v;
- switch (v = 0) {}
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_tryCatch_body() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- v = 0;
- } catch (_) {
- // not assigned
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_tryCatch_body_catch() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- g();
- v = 0;
- } catch (_) {
- v = 0;
- }
- v;
-}
-
-void g() {}
-''');
- assertReadBeforeWritten();
- }
-
- test_tryCatch_body_catchRethrow() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- v = 0;
- } catch (_) {
- rethrow;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_tryCatch_catch() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- // not assigned
- } catch (_) {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_tryCatchFinally_body() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- v = 0;
- } catch (_) {
- // not assigned
- } finally {
- // not assigned
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_tryCatchFinally_catch() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- // not assigned
- } catch (_) {
- v = 0;
- } finally {
- // not assigned
- }
- v;
-}
-''');
- assertReadBeforeWritten('v');
- }
-
- test_tryCatchFinally_finally() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- // not assigned
- } catch (_) {
- // not assigned
- } finally {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_tryCatchFinally_useInFinally() async {
- await trackCode(r'''
-f() {
- int x;
- try {
- g(); // may throw an exception
- x = 1;
- } catch (_) {
- x = 1;
- } finally {
- x; // BAD
- }
-}
-
-void g() {}
-''');
- assertReadBeforeWritten('x');
- }
-
- test_tryFinally_body() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- v = 0;
- } finally {
- // not assigned
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_tryFinally_finally() async {
- await trackCode(r'''
-void f() {
- int v;
- try {
- // not assigned
- } finally {
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_condition() async {
- await trackCode(r'''
-void f() {
- int v;
- while ((v = 0) >= 0) {
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_condition_notTrue() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- while (b) {
- v1 = 0;
- v2 = 0;
- v1;
- }
- v2;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_while_true_break_afterAssignment() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- while (true) {
- v1 = 0;
- v1;
- if (b) break;
- v1;
- v2 = 0;
- v2;
- }
- v1;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_true_break_beforeAssignment() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- while (true) {
- if (b) break;
- v1 = 0;
- v2 = 0;
- v2;
- }
- v1;
-}
-''');
- assertReadBeforeWritten('v1');
- }
-
- test_while_true_break_if() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- while (true) {
- if (b) {
- v = 0;
- break;
- } else {
- v = 0;
- break;
- }
- v;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_true_break_if2() async {
- await trackCode(r'''
-void f(bool b) {
- var v;
- while (true) {
- if (b) {
- break;
- } else {
- v = 0;
- }
- v;
- }
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_true_break_if3() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2;
- while (true) {
- if (b) {
- v1 = 0;
- v2 = 0;
- if (b) break;
- } else {
- if (b) break;
- v1 = 0;
- v2 = 0;
- }
- v1;
- }
- v2;
-}
-''');
- assertReadBeforeWritten('v2');
- }
-
- test_while_true_breakOuterFromInner() async {
- await trackCode(r'''
-void f(bool b) {
- int v1, v2, v3;
- L1: while (true) {
- L2: while (true) {
- v1 = 0;
- if (b) break L1;
- v2 = 0;
- v3 = 0;
- if (b) break L2;
- }
- v2;
- }
- v1;
- v3;
-}
-''');
- assertReadBeforeWritten('v3');
- }
-
- test_while_true_continue() async {
- await trackCode(r'''
-void f(bool b) {
- int v;
- while (true) {
- if (b) continue;
- v = 0;
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- test_while_true_noBreak() async {
- await trackCode(r'''
-void f() {
- int v;
- while (true) {
- // No assignment, but no break.
- // So, we don't exit the loop.
- // So, all variables are assigned.
- }
- v;
-}
-''');
- assertReadBeforeWritten();
- }
-
- /// Resolve the given [code] and track assignments in the unit.
+ /// Resolve the given [code] and track nullability in the unit.
Future<void> trackCode(String code) async {
+ if (await checkTests(
+ code, _resultComputer, const _FlowAnalysisDataComputer())) {
+ fail('Failure(s)');
+ }
+ }
+
+ Future<ResolvedUnitResult> _resultComputer(String code) async {
addTestFile(code);
await resolveTestFile();
-
var unit = result.unit;
-
- var assignedVariables = AssignedVariables<Statement, VariableElement>();
- unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
- var typeSystem = unit.declaredElement.context.typeSystem;
- unit.accept(_AstVisitor(
- typeSystem,
- assignedVariables,
- {},
- readBeforeWritten,
- [],
- [],
- [],
- [],
- ));
+ flowResult = FlowAnalysisResult.getFromNode(unit);
+ return result;
}
}
@reflectiveTest
-class NullableFlowTest extends DriverResolutionTest {
- final List<AstNode> nullableNodes = [];
- final List<AstNode> nonNullableNodes = [];
-
- void assertNonNullable([
- String search1,
- String search2,
- String search3,
- String search4,
- String search5,
- ]) {
- var expected = [search1, search2, search3, search4, search5]
- .where((i) => i != null)
- .map((search) => findNode.simple(search))
- .toList();
- expect(nonNullableNodes, unorderedEquals(expected));
- }
-
- void assertNullable([
- String search1,
- String search2,
- String search3,
- String search4,
- String search5,
- ]) {
- var expected = [search1, search2, search3, search4, search5]
- .where((i) => i != null)
- .map((search) => findNode.simple(search))
- .toList();
- expect(nullableNodes, unorderedEquals(expected));
- }
+class NullableFlowTest extends FlowTestBase {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
test_assign_toNonNull() async {
await trackCode(r'''
void f(int x) {
if (x != null) return;
- x; // 1
+ /*nullable*/ x;
x = 0;
- x; // 2
+ /*nonNullable*/ x;
}
''');
- assertNullable('x; // 1');
- assertNonNullable('x; // 2');
}
test_assign_toNull() async {
await trackCode(r'''
void f(int x) {
if (x == null) return;
- x; // 1
+ /*nonNullable*/ x;
x = null;
- x; // 2
+ /*nullable*/ x;
}
''');
- assertNullable('x; // 2');
- assertNonNullable('x; // 1');
}
test_assign_toUnknown_fromNotNull() async {
await trackCode(r'''
void f(int a, int b) {
if (a == null) return;
- a; // 1
+ /*nonNullable*/ a;
a = b;
- a; // 2
+ a;
}
''');
- assertNullable();
- assertNonNullable('a; // 1');
}
test_assign_toUnknown_fromNull() async {
await trackCode(r'''
void f(int a, int b) {
if (a != null) return;
- a; // 1
+ /*nullable*/ a;
a = b;
- a; // 2
+ a;
}
''');
- assertNullable('a; // 1');
- assertNonNullable();
}
test_binaryExpression_logicalAnd() async {
await trackCode(r'''
void f(int x) {
- x == null && x.isEven;
+ x == null && /*nullable*/ x.isEven;
}
''');
- assertNullable('x.isEven');
- assertNonNullable();
}
test_binaryExpression_logicalOr() async {
await trackCode(r'''
void f(int x) {
- x == null || x.isEven;
+ x == null || /*nonNullable*/ x.isEven;
}
''');
- assertNullable();
- assertNonNullable('x.isEven');
+ }
+
+ test_constructor_if_then_else() async {
+ await trackCode(r'''
+class C {
+ C(int x) {
+ if (x == null) {
+ /*nullable*/ x;
+ } else {
+ /*nonNullable*/ x;
+ }
+ }
+}
+''');
}
test_if_joinThenElse_ifNull() async {
await trackCode(r'''
void f(int a, int b) {
if (a == null) {
- a; // 1
+ /*nullable*/ a;
if (b == null) return;
- b; // 2
+ /*nonNullable*/ b;
} else {
- a; // 3
+ /*nonNullable*/ a;
if (b == null) return;
- b; // 4
+ /*nonNullable*/ b;
}
- a; // 5
- b; // 6
+ a;
+ /*nonNullable*/ b;
}
''');
- assertNullable('a; // 1');
- assertNonNullable('b; // 2', 'a; // 3', 'b; // 4', 'b; // 6');
}
- test_if_notNull_thenExit() async {
+ test_if_notNull_thenExit_left() async {
+ await trackCode(r'''
+void f(int x) {
+ if (null != x) return;
+ /*nullable*/ x;
+}
+''');
+ }
+
+ test_if_notNull_thenExit_right() async {
await trackCode(r'''
void f(int x) {
if (x != null) return;
- x; // 1
+ /*nullable*/ x;
}
''');
- assertNullable('x; // 1');
- assertNonNullable();
}
- test_if_null_thenExit() async {
+ test_if_null_thenExit_left() async {
+ await trackCode(r'''
+void f(int x) {
+ if (null == x) return;
+ /*nonNullable*/ x;
+}
+''');
+ }
+
+ test_if_null_thenExit_right() async {
await trackCode(r'''
void f(int x) {
if (x == null) return;
- x; // 1
+ /*nonNullable*/ x;
}
''');
- assertNullable();
- assertNonNullable('x; // 1');
}
test_if_then_else() async {
await trackCode(r'''
void f(int x) {
if (x == null) {
- x; // 1
+ /*nullable*/ x;
} else {
- x; // 2
+ /*nonNullable*/ x;
}
}
''');
- assertNullable('x; // 1');
- assertNonNullable('x; // 2');
+ }
+
+ test_method_if_then_else() async {
+ await trackCode(r'''
+class C {
+ void f(int x) {
+ if (x == null) {
+ /*nullable*/ x;
+ } else {
+ /*nonNullable*/ x;
+ }
+ }
+}
+''');
}
test_potentiallyMutatedInClosure() async {
@@ -1494,14 +210,12 @@
}
if (a == null) {
- a; // 1
+ a;
localFunction();
- a; // 2
+ a;
}
}
''');
- assertNullable();
- assertNonNullable();
}
test_tryFinally_eqNullExit_body() async {
@@ -1509,31 +223,27 @@
void f(int x) {
try {
if (x == null) return;
- x; // 1
+ /*nonNullable*/ x;
} finally {
- x; // 2
+ x;
}
- x; // 3
+ /*nonNullable*/ x;
}
''');
- assertNullable();
- assertNonNullable('x; // 1', 'x; // 3');
}
test_tryFinally_eqNullExit_finally() async {
await trackCode(r'''
void f(int x) {
try {
- x; // 1
+ x;
} finally {
if (x == null) return;
- x; // 2
+ /*nonNullable*/ x;
}
- x; // 3
+ /*nonNullable*/ x;
}
''');
- assertNullable();
- assertNonNullable('x; // 2', 'x; // 3');
}
test_tryFinally_outerEqNotNullExit_assignUnknown_body() async {
@@ -1541,17 +251,15 @@
void f(int a, int b) {
if (a != null) return;
try {
- a; // 1
+ /*nullable*/ a;
a = b;
- a; // 2
+ a;
} finally {
- a; // 3
+ a;
}
- a; // 4
+ a;
}
''');
- assertNullable('a; // 1');
- assertNonNullable();
}
test_tryFinally_outerEqNullExit_assignUnknown_body() async {
@@ -1559,17 +267,15 @@
void f(int a, int b) {
if (a == null) return;
try {
- a; // 1
+ /*nonNullable*/ a;
a = b;
- a; // 2
+ a;
} finally {
- a; // 3
+ a;
}
- a; // 4
+ a;
}
''');
- assertNullable();
- assertNonNullable('a; // 1');
}
test_tryFinally_outerEqNullExit_assignUnknown_finally() async {
@@ -1577,179 +283,130 @@
void f(int a, int b) {
if (a == null) return;
try {
- a; // 1
+ /*nonNullable*/ a;
} finally {
- a; // 2
+ /*nonNullable*/ a;
a = b;
- a; // 3
+ a;
}
- a; // 4
+ a;
}
''');
- assertNullable();
- assertNonNullable('a; // 1', 'a; // 2');
}
test_while_eqNull() async {
await trackCode(r'''
void f(int x) {
while (x == null) {
- x; // 1
+ /*nullable*/ x;
}
- x; // 2
+ /*nonNullable*/ x;
}
''');
- assertNullable('x; // 1');
- assertNonNullable('x; // 2');
}
test_while_notEqNull() async {
await trackCode(r'''
void f(int x) {
while (x != null) {
- x; // 1
+ /*nonNullable*/ x;
}
- x; // 2
+ /*nullable*/ x;
}
''');
- assertNullable('x; // 2');
- assertNonNullable('x; // 1');
- }
-
- /// Resolve the given [code] and track nullability in the unit.
- Future<void> trackCode(String code) async {
- addTestFile(code);
- await resolveTestFile();
-
- var unit = result.unit;
-
- var assignedVariables = AssignedVariables<Statement, VariableElement>();
- unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
- var typeSystem = unit.declaredElement.context.typeSystem;
- unit.accept(_AstVisitor(
- typeSystem,
- assignedVariables,
- {},
- [],
- nullableNodes,
- nonNullableNodes,
- [],
- [],
- ));
}
}
@reflectiveTest
-class ReachableFlowTest extends DriverResolutionTest {
- final List<AstNode> unreachableNodes = [];
- final List<FunctionBody> functionBodiesThatDontComplete = [];
+class ReachableFlowTest extends FlowTestBase {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
test_conditional_false() async {
await trackCode(r'''
void f() {
- false ? 1 : 2;
+ false ? /*unreachable*/ 1 : 2;
}
''');
- verify(unreachableExpressions: ['1']);
}
test_conditional_true() async {
await trackCode(r'''
void f() {
- true ? 1 : 2;
+ true ? 1 : /*unreachable*/ 2;
}
''');
- verify(unreachableExpressions: ['2']);
}
test_do_false() async {
await trackCode(r'''
void f() {
- do (true) {
+ do {
1;
} while (false);
2;
}
''');
- verify();
}
test_do_true() async {
await trackCode(r'''
-void f() { // f
- do (true) {
+/*member: f:doesNotComplete*/
+void f() {
+ do {
1;
} while (true);
- 2;
+ /*stmt: unreachable*/ 2;
}
''');
- verify(
- unreachableStatements: ['2;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_exit_beforeSplitStatement() async {
await trackCode(r'''
-void f(bool b, int i) { // f
+/*member: f:doesNotComplete*/
+void f(bool b, int i) {
return;
- do {} while (b);
- for (;;) {}
- for (_ in []) {}
- if (b) {}
- switch (i) {}
- try {} finally {}
- while (b) {}
+ /*stmt: unreachable*/ Object _;
+ /*stmt: unreachable*/ do {} while (b);
+ /*stmt: unreachable*/ for (;;) {}
+ /*stmt: unreachable*/ for (_ in []) {}
+ /*stmt: unreachable*/ if (b) {}
+ /*stmt: unreachable*/ switch (i) {}
+ /*stmt: unreachable*/ try {} finally {}
+ /*stmt: unreachable*/ while (b) {}
}
''');
- verify(
- unreachableStatements: [
- 'do {}',
- 'for (;;',
- 'for (_',
- 'if (b)',
- 'try {',
- 'switch (i)',
- 'while (b) {}'
- ],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_for_condition_true() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
for (; true;) {
1;
}
- 2;
+ /*stmt: unreachable*/ 2;
}
''');
- verify(
- unreachableStatements: ['2;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_for_condition_true_implicit() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
for (;;) {
1;
}
- 2;
+ /*stmt: unreachable*/ 2;
}
''');
- verify(
- unreachableStatements: ['2;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_forEach() async {
await trackCode(r'''
void f() {
+ Object _;
for (_ in [0, 1, 2]) {
1;
return;
@@ -1757,16 +414,15 @@
2;
}
''');
- verify();
}
test_functionBody_hasReturn() async {
await trackCode(r'''
-int f() { // f
+/*member: f:doesNotComplete*/
+int f() {
return 42;
}
''');
- verify(functionBodiesThatDontComplete: ['{ // f']);
}
test_functionBody_noReturn() async {
@@ -1775,7 +431,6 @@
1;
}
''');
- verify();
}
test_if_condition() async {
@@ -1789,67 +444,59 @@
3;
}
''');
- verify();
}
test_if_false_then_else() async {
await trackCode(r'''
void f() {
- if (false) { // 1
+ if (false) /*stmt: unreachable*/ {
1;
- } else { // 2
+ } else {
}
3;
}
''');
- verify(unreachableStatements: ['{ // 1']);
}
test_if_true_return() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
1;
if (true) {
return;
}
- 2;
+ /*stmt: unreachable*/ 2;
}
''');
- verify(
- unreachableStatements: ['2;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_if_true_then_else() async {
await trackCode(r'''
void f() {
- if (true) { // 1
- } else { // 2
+ if (true) {
+ } else /*stmt: unreachable*/ {
2;
}
3;
}
''');
- verify(unreachableStatements: ['{ // 2']);
}
test_logicalAnd_leftFalse() async {
await trackCode(r'''
void f(int x) {
- false && (x == 1);
+ false && /*unreachable*/ (x == 1);
}
''');
- verify(unreachableExpressions: ['(x == 1)']);
}
test_logicalOr_leftTrue() async {
await trackCode(r'''
void f(int x) {
- true || (x == 1);
+ true || /*unreachable*/ (x == 1);
}
''');
- verify(unreachableExpressions: ['(x == 1)']);
}
test_switch_case_neverCompletes() async {
@@ -1863,12 +510,11 @@
} else {
return;
}
- 2;
+ /*stmt: unreachable*/ 2;
}
3;
}
''');
- verify(unreachableStatements: ['2;']);
}
test_tryCatch() async {
@@ -1882,7 +528,6 @@
3;
}
''');
- verify();
}
test_tryCatch_return_body() async {
@@ -1891,14 +536,13 @@
try {
1;
return;
- 2;
+ /*stmt: unreachable*/ 2;
} catch (_) {
3;
}
4;
}
''');
- verify(unreachableStatements: ['2;']);
}
test_tryCatch_return_catch() async {
@@ -1909,12 +553,11 @@
} catch (_) {
2;
return;
- 3;
+ /*stmt: unreachable*/ 3;
}
4;
}
''');
- verify(unreachableStatements: ['3;']);
}
test_tryCatchFinally_return_body() async {
@@ -1931,12 +574,12 @@
4;
}
''');
- verify();
}
test_tryCatchFinally_return_bodyCatch() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
try {
1;
return;
@@ -1946,13 +589,9 @@
} finally {
3;
}
- 4;
+ /*stmt: unreachable*/ 4;
}
''');
- verify(
- unreachableStatements: ['4;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_tryCatchFinally_return_catch() async {
@@ -1969,53 +608,45 @@
4;
}
''');
- verify();
}
test_tryFinally_return_body() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
try {
1;
return;
} finally {
2;
}
- 3;
+ /*stmt: unreachable*/ 3;
}
''');
- verify(
- unreachableStatements: ['3;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_while_false() async {
await trackCode(r'''
void f() {
- while (false) { // 1
+ while (false) /*stmt: unreachable*/ {
1;
}
2;
}
''');
- verify(unreachableStatements: ['{ // 1']);
}
test_while_true() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
while (true) {
1;
}
- 2;
- 3;
+ /*stmt: unreachable*/ 2;
+ /*stmt: unreachable*/ 3;
}
''');
- verify(
- unreachableStatements: ['2;', '3;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
}
test_while_true_break() async {
@@ -2024,12 +655,11 @@
while (true) {
1;
break;
- 2;
+ /*stmt: unreachable*/ 2;
}
3;
}
''');
- verify(unreachableStatements: ['2;']);
}
test_while_true_breakIf() async {
@@ -2043,1553 +673,115 @@
3;
}
''');
- verify();
}
test_while_true_continue() async {
await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
while (true) {
1;
continue;
- 2;
+ /*stmt: unreachable*/ 2;
}
- 3;
+ /*stmt: unreachable*/ 3;
}
''');
- verify(
- unreachableStatements: ['2;', '3;'],
- functionBodiesThatDontComplete: ['{ // f'],
- );
- }
-
- /// Resolve the given [code] and track unreachable nodes in the unit.
- Future<void> trackCode(String code) async {
- addTestFile(code);
- await resolveTestFile();
-
- var unit = result.unit;
-
- var assignedVariables = AssignedVariables<Statement, VariableElement>();
- unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
- var typeSystem = unit.declaredElement.context.typeSystem;
- unit.accept(_AstVisitor(
- typeSystem,
- assignedVariables,
- {},
- [],
- [],
- [],
- unreachableNodes,
- functionBodiesThatDontComplete,
- ));
- }
-
- void verify({
- List<String> unreachableExpressions = const [],
- List<String> unreachableStatements = const [],
- List<String> functionBodiesThatDontComplete = const [],
- }) {
- var expectedUnreachableNodes = <AstNode>[];
- expectedUnreachableNodes.addAll(
- unreachableStatements.map((search) => findNode.statement(search)),
- );
- expectedUnreachableNodes.addAll(
- unreachableExpressions.map((search) => findNode.expression(search)),
- );
-
- expect(
- this.unreachableNodes,
- unorderedEquals(expectedUnreachableNodes),
- );
- expect(
- this.functionBodiesThatDontComplete,
- unorderedEquals(
- functionBodiesThatDontComplete
- .map((search) => findNode.functionBody(search))
- .toList(),
- ),
- );
}
}
-@reflectiveTest
-class TypePromotionFlowTest extends DriverResolutionTest {
- final Map<AstNode, DartType> promotedTypes = {};
-
- void assertNotPromoted(String search) {
- var node = findNode.simple(search);
- var actualType = promotedTypes[node];
- expect(actualType, isNull, reason: search);
- }
-
- void assertPromoted(String search, String expectedType) {
- var node = findNode.simple(search);
- var actualType = promotedTypes[node];
- if (actualType == null) {
- fail('$expectedType expected, but actually not promoted\n$search');
- }
- assertElementTypeString(actualType, expectedType);
- }
-
- test_assignment() async {
- await trackCode(r'''
-f(Object x) {
- if (x is String) {
- x = 42;
- x; // 1
- }
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_binaryExpression_ifNull() async {
- await trackCode(r'''
-void f(Object x) {
- ((x is num) || (throw 1)) ?? ((x is int) || (throw 2));
- x; // 1
-}
-''');
- assertPromoted('x; // 1', 'num');
- }
-
- test_binaryExpression_ifNull_rightUnPromote() async {
- await trackCode(r'''
-void f(Object x, Object y, Object z) {
- if (x is int) {
- x; // 1
- y ?? (x = z);
- x; // 2
- }
-}
-''');
- assertPromoted('x; // 1', 'int');
- assertNotPromoted('x; // 2');
- }
-
- test_conditional_both() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- b ? ((x is num) || (throw 1)) : ((x is int) || (throw 2));
- x; // 1
-}
-''');
- assertPromoted('x; // 1', 'num');
- }
-
- test_conditional_else() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- b ? 0 : ((x is int) || (throw 2));
- x; // 1
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_conditional_then() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- b ? ((x is num) || (throw 1)) : 0;
- x; // 1
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_do_condition_isNotType() async {
- await trackCode(r'''
-void f(Object x) {
- do {
- x; // 1
- x = '';
- } while (x is! String)
- x; // 2
-}
-''');
- assertNotPromoted('x; // 1');
- assertPromoted('x; // 2', 'String');
- }
-
- test_do_condition_isType() async {
- await trackCode(r'''
-void f(Object x) {
- do {
- x; // 1
- } while (x is String)
- x; // 2
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_do_outerIsType() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- do {
- x; // 1
- } while (b);
- x; // 2
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- }
-
- test_do_outerIsType_loopAssigned_body() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- do {
- x; // 1
- x = x.length;
- } while (b);
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_do_outerIsType_loopAssigned_condition() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- do {
- x; // 1
- x = x.length;
- } while (x != 0);
- x; // 2
- }
-}
-''');
- assertNotPromoted('x != 0');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_do_outerIsType_loopAssigned_condition2() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- do {
- x; // 1
- } while ((x = 1) != 0);
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_for_outerIsType() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- for (; b;) {
- x; // 1
- }
- x; // 2
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- }
-
- test_for_outerIsType_loopAssigned_body() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- for (; b;) {
- x; // 1
- x = 42;
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_for_outerIsType_loopAssigned_condition() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- for (; (x = 42) > 0;) {
- x; // 1
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_for_outerIsType_loopAssigned_updaters() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- for (; b; x = 42) {
- x; // 1
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_forEach_outerIsType_loopAssigned() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- for (var _ in (v1 = [0, 1, 2])) {
- x; // 1
- x = 42;
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_functionExpression_isType() async {
- await trackCode(r'''
-void f() {
- void g(Object x) {
- if (x is String) {
- x; // 1
- }
- x = 42;
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- }
-
- test_functionExpression_isType_mutatedInClosure2() async {
- await trackCode(r'''
-void f() {
- void g(Object x) {
- if (x is String) {
- x; // 1
- }
-
- void h() {
- x = 42;
- }
- }
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_functionExpression_outerIsType_assignedOutside() async {
- await trackCode(r'''
-void f(Object x) {
- void Function() g;
-
- if (x is String) {
- x; // 1
-
- g = () {
- x; // 2
- }
- }
-
- x = 42;
- x; // 3
- g();
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- assertNotPromoted('x; // 3');
- }
-
- test_if_combine_empty() async {
- await trackCode(r'''
-main(bool b, Object v) {
- if (b) {
- v is int || (throw 1);
- } else {
- v is String || (throw 2);
- }
- v; // 3
-}
-''');
- assertNotPromoted('v; // 3');
- }
-
- test_if_conditional_isNotType() async {
- await trackCode(r'''
-f(bool b, Object v) {
- if (b ? (v is! int) : (v is! num)) {
- v; // 1
- } else {
- v; // 2
- }
- v; // 3
-}
-''');
- assertNotPromoted('v; // 1');
- assertPromoted('v; // 2', 'num');
- assertNotPromoted('v; // 3');
- }
-
- test_if_conditional_isType() async {
- await trackCode(r'''
-f(bool b, Object v) {
- if (b ? (v is int) : (v is num)) {
- v; // 1
- } else {
- v; // 2
- }
- v; // 3
-}
-''');
- assertPromoted('v; // 1', 'num');
- assertNotPromoted('v; // 2');
- assertNotPromoted('v; // 3');
- }
-
- test_if_isNotType() async {
- await trackCode(r'''
-main(v) {
- if (v is! String) {
- v; // 1
- } else {
- v; // 2
- }
- v; // 3
-}
-''');
- assertNotPromoted('v; // 1');
- assertPromoted('v; // 2', 'String');
- assertNotPromoted('v; // 3');
- }
-
- test_if_isNotType_return() async {
- await trackCode(r'''
-main(v) {
- if (v is! String) return;
- v; // ref
-}
-''');
- assertPromoted('v; // ref', 'String');
- }
-
- test_if_isNotType_throw() async {
- await trackCode(r'''
-main(v) {
- if (v is! String) throw 42;
- v; // ref
-}
-''');
- assertPromoted('v; // ref', 'String');
- }
-
- test_if_isType() async {
- await trackCode(r'''
-main(v) {
- if (v is String) {
- v; // 1
- } else {
- v; // 2
- }
- v; // 3
-}
-''');
- assertPromoted('v; // 1', 'String');
- assertNotPromoted('v; // 2');
- assertNotPromoted('v; // 3');
- }
-
- test_if_isType_thenNonBoolean() async {
- await trackCode(r'''
-f(Object x) {
- if ((x is String) != 3) {
- x; // 1
- }
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_if_logicalNot_isType() async {
- await trackCode(r'''
-main(v) {
- if (!(v is String)) {
- v; // 1
- } else {
- v; // 2
- }
- v; // 3
-}
-''');
- assertNotPromoted('v; // 1');
- assertPromoted('v; // 2', 'String');
- assertNotPromoted('v; // 3');
- }
-
- test_if_then_isNotType_return() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (b) {
- if (x is! String) return;
- }
- x; // 1
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_logicalOr_throw() async {
- await trackCode(r'''
-main(v) {
- v is String || (throw 42);
- v; // ref
-}
-''');
- assertPromoted('v; // ref', 'String');
- }
-
- test_potentiallyMutatedInClosure() async {
- await trackCode(r'''
-f(Object x) {
- localFunction() {
- x = 42;
- }
-
- if (x is String) {
- localFunction();
- x; // 1
- }
-}
-''');
- assertNotPromoted('x; // 1');
- }
-
- test_potentiallyMutatedInScope() async {
- await trackCode(r'''
-f(Object x) {
- if (x is String) {
- x; // 1
- }
-
- x = 42;
-}
-''');
- assertPromoted('x; // 1', 'String');
- }
-
- test_switch_outerIsType_assignedInCase() async {
- await trackCode(r'''
-void f(int e, Object x) {
- if (x is String) {
- switch (e) {
- L: case 1:
- x; // 1
- break;
- case 2: // no label
- x; // 2
- break;
- case 3:
- x = 42;
- continue L;
- }
- x; // 3
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertPromoted('x; // 2', 'String');
- assertNotPromoted('x; // 3');
- }
-
- test_tryCatch_assigned_body() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is! String) return;
- x; // 1
- try {
- x = 42;
- g(); // might throw
- if (x is! String) return;
- x; // 2
- } catch (_) {}
- x; // 3
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- assertNotPromoted('x; // 3');
- }
-
- test_tryCatch_isNotType_exit_body() async {
- await trackCode(r'''
-void f(Object x) {
- try {
- if (x is! String) return;
- x; // 1
- } catch (_) {}
- x; // 2
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- }
-
- test_tryCatch_isNotType_exit_body_catch() async {
- await trackCode(r'''
-void f(Object x) {
- try {
- if (x is! String) return;
- x; // 1
- } catch (_) {
- if (x is! String) return;
- x; // 2
- }
- x; // 3
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- assertPromoted('x; // 3', 'String');
- }
-
- test_tryCatch_isNotType_exit_body_catchRethrow() async {
- await trackCode(r'''
-void f(Object x) {
- try {
- if (x is! String) return;
- x; // 1
- } catch (_) {
- x; // 2
- rethrow;
- }
- x; // 3
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- assertPromoted('x; // 3', 'String');
- }
-
- test_tryCatch_isNotType_exit_catch() async {
- await trackCode(r'''
-void f(Object x) {
- try {
- } catch (_) {
- if (x is! String) return;
- x; // 1
- }
- x; // 2
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- }
-
- test_tryCatchFinally_outerIsType() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- try {
- x; // 1
- } catch (_) {
- x; // 2
- } finally {
- x; // 3
- }
- x; // 4
- }
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- assertPromoted('x; // 3', 'String');
- assertPromoted('x; // 4', 'String');
- }
-
- test_tryCatchFinally_outerIsType_assigned_body() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- try {
- x; // 1
- x = 42;
- g();
- } catch (_) {
- x; // 2
- } finally {
- x; // 3
- }
- x; // 4
- }
-}
-
-void g() {}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- assertNotPromoted('x; // 3');
- assertNotPromoted('x; // 4');
- }
-
- test_tryCatchFinally_outerIsType_assigned_catch() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- try {
- x; // 1
- } catch (_) {
- x; // 2
- x = 42;
- } finally {
- x; // 3
- }
- x; // 4
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- assertNotPromoted('x; // 3');
- assertNotPromoted('x; // 4');
- }
-
- test_tryFinally_outerIsType_assigned_body() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- try {
- x; // 1
- x = 42;
- } finally {
- x; // 2
- }
- x; // 3
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- assertNotPromoted('x; // 3');
- }
-
- test_tryFinally_outerIsType_assigned_finally() async {
- await trackCode(r'''
-void f(Object x) {
- if (x is String) {
- try {
- x; // 1
- } finally {
- x; // 2
- x = 42;
- }
- x; // 3
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- assertNotPromoted('x; // 3');
- }
-
- test_while_condition_false() async {
- await trackCode(r'''
-void f(Object x) {
- while (x is! String) {
- x; // 1
- }
- x; // 2
-}
-''');
- assertNotPromoted('x; // 1');
- assertPromoted('x; // 2', 'String');
- }
-
- test_while_condition_true() async {
- await trackCode(r'''
-void f(Object x) {
- while (x is String) {
- x; // 1
- }
- x; // 2
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertNotPromoted('x; // 2');
- }
-
- test_while_outerIsType() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- while (b) {
- x; // 1
- }
- x; // 2
- }
-}
-''');
- assertPromoted('x; // 1', 'String');
- assertPromoted('x; // 2', 'String');
- }
-
- test_while_outerIsType_loopAssigned_body() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- while (b) {
- x; // 1
- x = x.length;
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- test_while_outerIsType_loopAssigned_condition() async {
- await trackCode(r'''
-void f(bool b, Object x) {
- if (x is String) {
- while (x != 0) {
- x; // 1
- x = x.length;
- }
- x; // 2
- }
-}
-''');
- assertNotPromoted('x != 0');
- assertNotPromoted('x; // 1');
- assertNotPromoted('x; // 2');
- }
-
- /// Resolve the given [code] and track assignments in the unit.
- Future<void> trackCode(String code) async {
- addTestFile(code);
- await resolveTestFile();
-
- var unit = result.unit;
-
- var assignedVariables = AssignedVariables<Statement, VariableElement>();
- unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
- var typeSystem = unit.declaredElement.context.typeSystem;
- unit.accept(_AstVisitor(
- typeSystem,
- assignedVariables,
- promotedTypes,
- [],
- [],
- [],
- [],
- [],
- ));
- }
-}
-
-class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
- final AssignedVariables assignedVariables;
-
- _AssignedVariablesVisitor(this.assignedVariables);
+class _FlowAnalysisDataComputer extends DataComputer<Set<_FlowAssertion>> {
+ const _FlowAnalysisDataComputer();
@override
- void visitAssignmentExpression(AssignmentExpression node) {
- var left = node.leftHandSide;
+ DataInterpreter<Set<_FlowAssertion>> get dataValidator =>
+ const _FlowAnalysisDataInterpreter();
- super.visitAssignmentExpression(node);
+ @override
+ void computeUnitData(CompilationUnit unit,
+ Map<Id, ActualData<Set<_FlowAssertion>>> actualMap) {
+ var flowResult = FlowAnalysisResult.getFromNode(unit);
+ _FlowAnalysisDataExtractor(
+ unit.declaredElement.source.uri, actualMap, flowResult)
+ .run(unit);
+ }
+}
- if (left is SimpleIdentifier) {
- var element = left.staticElement;
- if (element is VariableElement) {
- assignedVariables.write(element);
+class _FlowAnalysisDataExtractor extends AstDataExtractor<Set<_FlowAssertion>> {
+ FlowAnalysisResult _flowResult;
+
+ _FlowAnalysisDataExtractor(Uri uri,
+ Map<Id, ActualData<Set<_FlowAssertion>>> actualMap, this._flowResult)
+ : super(uri, actualMap);
+
+ @override
+ Set<_FlowAssertion> computeNodeValue(Id id, AstNode node) {
+ Set<_FlowAssertion> result = {};
+ if (_flowResult.nullableNodes.contains(node)) {
+ // We sometimes erroneously annotate a node as both nullable and
+ // non-nullable. Ignore for now. TODO(paulberry): fix this.
+ if (!_flowResult.nonNullableNodes.contains(node)) {
+ result.add(_FlowAssertion.nullable);
}
}
- }
-
- @override
- void visitDoStatement(DoStatement node) {
- assignedVariables.beginLoop();
- super.visitDoStatement(node);
- assignedVariables.endLoop(node);
- }
-
- @override
- void visitForStatement(ForStatement node) {
- var forLoopParts = node.forLoopParts;
- if (forLoopParts is ForParts) {
- if (forLoopParts is ForPartsWithExpression) {
- forLoopParts.initialization?.accept(this);
- } else if (forLoopParts is ForPartsWithDeclarations) {
- forLoopParts.variables?.accept(this);
- } else {
- throw new StateError('Unrecognized for loop parts');
+ if (_flowResult.nonNullableNodes.contains(node)) {
+ // We sometimes erroneously annotate a node as both nullable and
+ // non-nullable. Ignore for now. TODO(paulberry): fix this.
+ if (!_flowResult.nullableNodes.contains(node)) {
+ result.add(_FlowAssertion.nonNullable);
}
+ }
+ if (_flowResult.unreachableNodes.contains(node)) {
+ result.add(_FlowAssertion.unreachable);
+ }
+ if (node is FunctionDeclaration) {
+ var body = node.functionExpression.body;
+ if (body != null &&
+ _flowResult.functionBodiesThatDontComplete.contains(body)) {
+ result.add(_FlowAssertion.doesNotComplete);
+ }
+ }
+ return result.isEmpty ? null : result;
+ }
+}
- assignedVariables.beginLoop();
- forLoopParts.condition?.accept(this);
- node.body.accept(this);
- forLoopParts.updaters?.accept(this);
- assignedVariables.endLoop(node);
- } else if (forLoopParts is ForEachParts) {
- var iterable = forLoopParts.iterable;
- var body = node.body;
+class _FlowAnalysisDataInterpreter
+ implements DataInterpreter<Set<_FlowAssertion>> {
+ const _FlowAnalysisDataInterpreter();
- iterable.accept(this);
+ @override
+ String getText(Set<_FlowAssertion> actualData) =>
+ _sortedRepresentation(_toStrings(actualData));
- assignedVariables.beginLoop();
- body.accept(this);
- assignedVariables.endLoop(node);
+ @override
+ String isAsExpected(Set<_FlowAssertion> actualData, String expectedData) {
+ var actualStrings = _toStrings(actualData);
+ var actualSorted = _sortedRepresentation(actualStrings);
+ var expectedSorted = _sortedRepresentation(expectedData?.split(','));
+ if (actualSorted == expectedSorted) {
+ return null;
} else {
- throw new StateError('Unrecognized for loop parts');
+ return 'Expected $expectedData, got $actualSorted';
}
}
@override
- void visitSwitchStatement(SwitchStatement node) {
- var expression = node.expression;
- var members = node.members;
+ bool isEmpty(Set<_FlowAssertion> actualData) => actualData.isEmpty;
- expression.accept(this);
-
- assignedVariables.beginLoop();
- members.accept(this);
- assignedVariables.endLoop(node);
+ String _sortedRepresentation(Iterable<String> values) {
+ var list = values == null || values.isEmpty ? ['none'] : values.toList();
+ list.sort();
+ return list.join(',');
}
- @override
- void visitTryStatement(TryStatement node) {
- assignedVariables.beginLoop();
- node.body.accept(this);
- assignedVariables.endLoop(node.body);
-
- node.catchClauses.accept(this);
-
- var finallyBlock = node.finallyBlock;
- if (finallyBlock != null) {
- assignedVariables.beginLoop();
- finallyBlock.accept(this);
- assignedVariables.endLoop(finallyBlock);
- }
- }
-
- @override
- void visitWhileStatement(WhileStatement node) {
- assignedVariables.beginLoop();
- super.visitWhileStatement(node);
- assignedVariables.endLoop(node);
- }
+ List<String> _toStrings(Set<_FlowAssertion> actualData) => actualData
+ .map((flowAssertion) => flowAssertion.toString().split('.')[1])
+ .toList();
}
-/// [AstVisitor] that drives the [flow] in the way we expect the resolver
-/// will do in production.
-class _AstVisitor extends GeneralizingAstVisitor<void> {
- static final trueLiteral = astFactory.booleanLiteral(null, true);
-
- final NodeOperations<Expression> nodeOperations;
- final TypeOperations<VariableElement, DartType> typeOperations;
- final AssignedVariables assignedVariables;
- final Map<AstNode, DartType> promotedTypes;
- final List<LocalVariableElement> readBeforeWritten;
- final List<AstNode> nullableNodes;
- final List<AstNode> nonNullableNodes;
- final List<AstNode> unreachableNodes;
- final List<FunctionBody> functionBodiesThatDontComplete;
-
- FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
-
- _AstVisitor(
- TypeSystem typeSystem,
- this.assignedVariables,
- this.promotedTypes,
- this.readBeforeWritten,
- this.nullableNodes,
- this.nonNullableNodes,
- this.unreachableNodes,
- this.functionBodiesThatDontComplete)
- : nodeOperations = _NodeOperations(),
- typeOperations = _TypeSystemTypeOperations(typeSystem);
-
- @override
- void visitAssignmentExpression(AssignmentExpression node) {
- var left = node.leftHandSide;
- var right = node.rightHandSide;
-
- VariableElement localElement;
- if (left is SimpleIdentifier) {
- var element = left.staticElement;
- if (element is VariableElement) {
- localElement = element;
- }
- }
-
- if (localElement != null) {
- var isPure = node.operator.type == TokenType.EQ;
- if (!isPure) {
- flow.read(localElement);
- }
- right.accept(this);
- flow.write(
- localElement,
- isNull: _isNull(right),
- isNonNull: _isNonNull(right),
- );
- } else {
- left.accept(this);
- right.accept(this);
- }
- }
-
- @override
- void visitBinaryExpression(BinaryExpression node) {
- var left = node.leftOperand;
- var right = node.rightOperand;
-
- var operator = node.operator.type;
-
- if (operator == TokenType.AMPERSAND_AMPERSAND) {
- left.accept(this);
-
- flow.logicalAnd_rightBegin(node, node.leftOperand);
- _checkUnreachableNode(node.rightOperand);
- right.accept(this);
-
- flow.logicalAnd_end(node, node.rightOperand);
- } else if (operator == TokenType.BAR_BAR) {
- left.accept(this);
-
- flow.logicalOr_rightBegin(node, node.leftOperand);
- _checkUnreachableNode(node.rightOperand);
- right.accept(this);
-
- flow.logicalOr_end(node, node.rightOperand);
- } else if (operator == TokenType.BANG_EQ) {
- left.accept(this);
- right.accept(this);
- if (right is NullLiteral) {
- if (left is SimpleIdentifier) {
- var element = left.staticElement;
- if (element is VariableElement) {
- flow.conditionNotEqNull(node, element);
- }
- }
- }
- } else if (operator == TokenType.EQ_EQ) {
- left.accept(this);
- right.accept(this);
- if (right is NullLiteral) {
- if (left is SimpleIdentifier) {
- var element = left.staticElement;
- if (element is VariableElement) {
- flow.conditionEqNull(node, element);
- }
- }
- }
- } else if (operator == TokenType.QUESTION_QUESTION) {
- left.accept(this);
-
- flow.ifNullExpression_rightBegin();
- right.accept(this);
-
- flow.ifNullExpression_end();
- } else {
- left.accept(this);
- right.accept(this);
- }
- }
-
- @override
- void visitBlockFunctionBody(BlockFunctionBody node) {
- var isFlowOwner = flow == null;
-
- if (isFlowOwner) {
- flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
- nodeOperations,
- typeOperations,
- _FunctionBodyAccess(node),
- );
-
- var function = node.parent;
- if (function is FunctionExpression) {
- var parameters = function.parameters;
- if (parameters != null) {
- for (var parameter in parameters?.parameters) {
- flow.add(parameter.declaredElement, assigned: true);
- }
- }
- }
- }
-
- super.visitBlockFunctionBody(node);
-
- if (isFlowOwner) {
- for (var variable in flow.readBeforeWritten) {
- assert(variable is LocalVariableElement);
- readBeforeWritten.add(variable);
- }
-
- if (!flow.isReachable) {
- functionBodiesThatDontComplete.add(node);
- }
-
- flow.verifyStackEmpty();
- flow = null;
- }
- }
-
- @override
- void visitBooleanLiteral(BooleanLiteral node) {
- super.visitBooleanLiteral(node);
- if (_isFalseLiteral(node)) {
- flow.falseLiteral(node);
- }
- if (_isTrueLiteral(node)) {
- flow.trueLiteral(node);
- }
- }
-
- @override
- void visitBreakStatement(BreakStatement node) {
- super.visitBreakStatement(node);
- var target = _getLabelTarget(node, node.label?.staticElement);
- flow.handleBreak(target);
- }
-
- @override
- void visitConditionalExpression(ConditionalExpression node) {
- var condition = node.condition;
- var thenExpression = node.thenExpression;
- var elseExpression = node.elseExpression;
-
- condition.accept(this);
-
- flow.conditional_thenBegin(node, node.condition);
- _checkUnreachableNode(node.thenExpression);
- thenExpression.accept(this);
- var isBool = thenExpression.staticType.isDartCoreBool;
-
- flow.conditional_elseBegin(node, node.thenExpression, isBool);
- _checkUnreachableNode(node.elseExpression);
- elseExpression.accept(this);
-
- flow.conditional_end(node, node.elseExpression, isBool);
- }
-
- @override
- void visitContinueStatement(ContinueStatement node) {
- super.visitContinueStatement(node);
- var target = _getLabelTarget(node, node.label?.staticElement);
- flow.handleContinue(target);
- }
-
- @override
- void visitDoStatement(DoStatement node) {
- _checkUnreachableNode(node);
-
- var body = node.body;
- var condition = node.condition;
-
- flow.doStatement_bodyBegin(node, assignedVariables[node]);
- body.accept(this);
-
- flow.doStatement_conditionBegin();
- condition.accept(this);
-
- flow.doStatement_end(node, node.condition);
- }
-
- @override
- void visitForStatement(ForStatement node) {
- _checkUnreachableNode(node);
-
- ForLoopParts parts = node.forLoopParts;
- if (parts is ForEachParts) {
- parts.iterable?.accept(this);
-
- flow.forEachStatement_bodyBegin(assignedVariables[node]);
-
- node.body.accept(this);
-
- flow.forEachStatement_end();
- return;
- }
- VariableDeclarationList variables;
- Expression initialization;
- Expression condition;
- NodeList<Expression> updaters;
- if (parts is ForPartsWithDeclarations) {
- variables = parts.variables;
- condition = parts.condition;
- updaters = parts.updaters;
- } else if (parts is ForPartsWithExpression) {
- initialization = parts.initialization;
- condition = parts.condition;
- updaters = parts.updaters;
- }
- initialization?.accept(this);
- variables?.accept(this);
-
- flow.forStatement_conditionBegin(assignedVariables[node]);
- if (condition != null) {
- condition.accept(this);
- } else {
- flow.trueLiteral(trueLiteral);
- }
-
- flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
- node.body.accept(this);
-
- flow.forStatement_updaterBegin();
- updaters?.accept(this);
-
- flow.forStatement_end();
- }
-
- @override
- void visitFunctionExpression(FunctionExpression node) {
- flow?.functionExpression_begin();
- super.visitFunctionExpression(node);
- flow?.functionExpression_end();
- }
-
- @override
- void visitIfStatement(IfStatement node) {
- _checkUnreachableNode(node);
-
- var condition = node.condition;
- var thenStatement = node.thenStatement;
- var elseStatement = node.elseStatement;
-
- condition.accept(this);
-
- flow.ifStatement_thenBegin(node, node.condition);
- thenStatement.accept(this);
-
- if (elseStatement != null) {
- flow.ifStatement_elseBegin();
- elseStatement.accept(this);
- }
-
- flow.ifStatement_end(elseStatement != null);
- }
-
- @override
- void visitIsExpression(IsExpression node) {
- super.visitIsExpression(node);
- var expression = node.expression;
- var typeAnnotation = node.type;
-
- if (expression is SimpleIdentifier) {
- var element = expression.staticElement;
- if (element is VariableElement) {
- flow.isExpression_end(
- node,
- element,
- node.notOperator != null,
- typeAnnotation.type,
- );
- }
- }
- }
-
- @override
- void visitPrefixExpression(PrefixExpression node) {
- var operand = node.operand;
-
- var operator = node.operator.type;
- if (operator == TokenType.BANG) {
- operand.accept(this);
- flow.logicalNot_end(node, node.operand);
- } else {
- operand.accept(this);
- }
- }
-
- @override
- void visitRethrowExpression(RethrowExpression node) {
- super.visitRethrowExpression(node);
- flow.handleExit();
- }
-
- @override
- void visitReturnStatement(ReturnStatement node) {
- super.visitReturnStatement(node);
- flow.handleExit();
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- var element = node.staticElement;
- var isLocalVariable = element is LocalVariableElement;
- if (isLocalVariable || element is ParameterElement) {
- if (node.inGetterContext() && !node.inDeclarationContext()) {
- if (isLocalVariable) {
- flow.read(element);
- }
-
- if (flow.isNullable(element)) {
- nullableNodes?.add(node);
- }
-
- if (flow.isNonNullable(element)) {
- nonNullableNodes?.add(node);
- }
-
- var promotedType = flow?.promotedType(element);
- if (promotedType != null) {
- promotedTypes[node] = promotedType;
- }
- }
- }
-
- super.visitSimpleIdentifier(node);
- }
-
- @override
- void visitStatement(Statement node) {
- _checkUnreachableNode(node);
- super.visitStatement(node);
- }
-
- @override
- void visitSwitchStatement(SwitchStatement node) {
- _checkUnreachableNode(node);
-
- node.expression.accept(this);
- flow.switchStatement_expressionEnd(node);
-
- var assignedInCases = assignedVariables[node];
-
- var members = node.members;
- var membersLength = members.length;
- var hasDefault = false;
- for (var i = 0; i < membersLength; i++) {
- var member = members[i];
-
- flow.switchStatement_beginCase(
- member.labels.isNotEmpty ? assignedInCases : assignedVariables.emptySet,
- );
- member.accept(this);
-
- // Implicit `break` at the end of `default`.
- if (member is SwitchDefault) {
- hasDefault = true;
- flow.handleBreak(node);
- }
- }
-
- flow.switchStatement_end(node, hasDefault);
- }
-
- @override
- void visitThrowExpression(ThrowExpression node) {
- super.visitThrowExpression(node);
- flow.handleExit();
- }
-
- @override
- void visitTryStatement(TryStatement node) {
- _checkUnreachableNode(node);
-
- var body = node.body;
- var catchClauses = node.catchClauses;
- var finallyBlock = node.finallyBlock;
-
- if (finallyBlock != null) {
- flow.tryFinallyStatement_bodyBegin();
- }
-
- flow.tryCatchStatement_bodyBegin();
- body.accept(this);
- flow.tryCatchStatement_bodyEnd(assignedVariables[body]);
-
- var catchLength = catchClauses.length;
- for (var i = 0; i < catchLength; ++i) {
- var catchClause = catchClauses[i];
- flow.tryCatchStatement_catchBegin();
- catchClause.accept(this);
- flow.tryCatchStatement_catchEnd();
- }
-
- flow.tryCatchStatement_end();
-
- if (finallyBlock != null) {
- flow.tryFinallyStatement_finallyBegin(assignedVariables[body]);
- finallyBlock.accept(this);
- flow.tryFinallyStatement_end(assignedVariables[finallyBlock]);
- }
- }
-
- @override
- void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
- var variables = node.variables.variables;
- for (var i = 0; i < variables.length; ++i) {
- var variable = variables[i];
- flow.add(variable.declaredElement,
- assigned: variable.initializer != null);
- }
-
- super.visitVariableDeclarationStatement(node);
- }
-
- @override
- void visitWhileStatement(WhileStatement node) {
- _checkUnreachableNode(node);
-
- var condition = node.condition;
- var body = node.body;
-
- flow.whileStatement_conditionBegin(assignedVariables[node]);
- condition.accept(this);
-
- flow.whileStatement_bodyBegin(node, node.condition);
- body.accept(this);
-
- flow.whileStatement_end();
- }
-
- /// Mark the [node] as unreachable if it is not covered by another node that
- /// is already known to be unreachable.
- void _checkUnreachableNode(AstNode node) {
- if (flow.isReachable) return;
-
- // Ignore the [node] if it is fully covered by the last unreachable.
- if (unreachableNodes.isNotEmpty) {
- var last = unreachableNodes.last;
- if (node.offset >= last.offset && node.end <= last.end) return;
- }
-
- unreachableNodes.add(node);
- }
-
- /// This code has OK performance for tests, but think if there is something
- /// better when using in production.
- AstNode _getLabelTarget(AstNode node, LabelElement element) {
- for (; node != null; node = node.parent) {
- if (node is DoStatement ||
- node is ForStatement ||
- node is SwitchStatement ||
- node is WhileStatement) {
- if (element == null) {
- return node;
- }
- var parent = node.parent;
- if (parent is LabeledStatement) {
- for (var nodeLabel in parent.labels) {
- if (identical(nodeLabel.label.staticElement, element)) {
- return node;
- }
- }
- }
- }
- if (element != null && node is SwitchStatement) {
- for (var member in node.members) {
- for (var nodeLabel in member.labels) {
- if (identical(nodeLabel.label.staticElement, element)) {
- return node;
- }
- }
- }
- }
- }
- return null;
- }
-
- static bool _isFalseLiteral(AstNode node) {
- return node is BooleanLiteral && !node.value;
- }
-
- static bool _isNonNull(Expression node) {
- if (node is NullLiteral) return false;
-
- return node is Literal;
- }
-
- static bool _isNull(Expression node) {
- return node is NullLiteral;
- }
-
- static bool _isTrueLiteral(AstNode node) {
- return node is BooleanLiteral && node.value;
- }
-}
-
-class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
- final FunctionBody node;
-
- _FunctionBodyAccess(this.node);
-
- @override
- bool isPotentiallyMutatedInClosure(VariableElement variable) {
- return node.isPotentiallyMutatedInClosure(variable);
- }
-
- @override
- bool isPotentiallyMutatedInScope(VariableElement variable) {
- return node.isPotentiallyMutatedInScope(variable);
- }
-}
-
-class _NodeOperations implements NodeOperations<Expression> {
- @override
- Expression unwrapParenthesized(Expression node) {
- while (node is ParenthesizedExpression) {
- node = (node as ParenthesizedExpression).expression;
- }
- return node;
- }
-}
-
-class _TypeSystemTypeOperations
- implements TypeOperations<VariableElement, DartType> {
- final TypeSystem typeSystem;
-
- _TypeSystemTypeOperations(this.typeSystem);
-
- @override
- DartType elementType(VariableElement element) {
- return element.type;
- }
-
- @override
- bool isSubtypeOf(DartType leftType, DartType rightType) {
- return typeSystem.isSubtypeOf(leftType, rightType);
- }
-
- @override
- bool isLocalVariable(VariableElement element) {
- return element is LocalVariableElement;
- }
+enum _FlowAssertion {
+ doesNotComplete,
+ nonNullable,
+ nullable,
+ unreachable,
}
diff --git a/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
new file mode 100644
index 0000000..929f0533
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
@@ -0,0 +1,83 @@
+// 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/src/generated/engine.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LocalVariableResolutionTest);
+ defineReflectiveTests(LocalVariableResolutionTest_NNBD);
+ });
+}
+
+@reflectiveTest
+class LocalVariableResolutionTest extends DriverResolutionTest {
+ test_element() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int x = 0;
+}
+''');
+
+ var x = findElement.localVar('x');
+ expect(x.isConst, isFalse);
+ expect(x.isFinal, isFalse);
+ expect(x.isLate, isFalse);
+ expect(x.isStatic, isFalse);
+ }
+
+ test_element_const() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ const int x = 0;
+}
+''');
+
+ var x = findElement.localVar('x');
+ expect(x.isConst, isTrue);
+ expect(x.isFinal, isFalse);
+ expect(x.isLate, isFalse);
+ expect(x.isStatic, isFalse);
+ }
+
+ test_element_final() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ final int x = 0;
+}
+''');
+
+ var x = findElement.localVar('x');
+ expect(x.isConst, isFalse);
+ expect(x.isFinal, isTrue);
+ expect(x.isLate, isFalse);
+ expect(x.isStatic, isFalse);
+ }
+}
+
+@reflectiveTest
+class LocalVariableResolutionTest_NNBD extends LocalVariableResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_element_late() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ late int x = 0;
+}
+''');
+
+ var x = findElement.localVar('x');
+ expect(x.isConst, isFalse);
+ expect(x.isFinal, isFalse);
+ expect(x.isLate, isTrue);
+ expect(x.isStatic, isFalse);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 56deafe..4040944 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -419,8 +419,10 @@
expect(node.staticType, isNull);
}
- ExpectedError error(ErrorCode code, int offset, int length) =>
- new ExpectedError(code, offset, length);
+ ExpectedError error(ErrorCode code, int offset, int length,
+ {List<ExpectedMessage> expectedMessages =
+ const <ExpectedMessage>[]}) =>
+ ExpectedError(code, offset, length, expectedMessages: expectedMessages);
Element getNodeElement(AstNode node) {
if (node is Annotation) {
@@ -450,6 +452,9 @@
}
}
+ ExpectedMessage message(String filePath, int offset, int length) =>
+ ExpectedMessage(convertPath(filePath), offset, length);
+
Future<ResolvedUnitResult> resolveFile(String path);
Future<void> resolveTestFile() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 95539c2..c03f65c 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -27,6 +27,7 @@
as instance_member_inference_class;
import 'instance_member_inference_mixin_test.dart'
as instance_member_inference_mixin;
+import 'local_variable_test.dart' as local_variable;
import 'metadata_test.dart' as metadata;
import 'method_invocation_test.dart' as method_invocation;
import 'mixin_test.dart' as mixin_resolution;
@@ -36,6 +37,7 @@
import 'property_access_test.dart' as property_access;
import 'top_type_inference_test.dart' as top_type_inference;
import 'type_inference/test_all.dart' as type_inference;
+import 'type_promotion_test.dart' as type_promotion;
main() {
defineReflectiveSuite(() {
@@ -59,6 +61,7 @@
instance_creation.main();
instance_member_inference_class.main();
instance_member_inference_mixin.main();
+ local_variable.main();
metadata.main();
method_invocation.main();
mixin_resolution.main();
@@ -67,6 +70,7 @@
optional_const.main();
property_access.main();
top_type_inference.main();
+ type_promotion.main();
type_inference.main();
}, name: 'resolution');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart b/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart
new file mode 100644
index 0000000..ff73bd4
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart
@@ -0,0 +1,757 @@
+// 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/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/ast_data_extractor.dart';
+import 'package:front_end/src/testing/id.dart' show ActualData, Id;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../util/id_equivalence_helper.dart';
+import 'driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypePromotionTest);
+ });
+}
+
+@reflectiveTest
+class TypePromotionTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ Future<void> resolveCode(String code) async {
+ if (await checkTests(
+ code, _resultComputer, const _TypePromotionDataComputer())) {
+ fail('Failure(s)');
+ }
+ }
+
+ test_assignment() async {
+ await resolveCode(r'''
+f(Object x) {
+ if (x is String) {
+ x = 42;
+ x;
+ }
+}
+''');
+ }
+
+ test_binaryExpression_ifNull() async {
+ await resolveCode(r'''
+void f(Object x) {
+ ((x is num) || (throw 1)) ?? ((/*num*/ x is int) || (throw 2));
+ /*num*/ x;
+}
+''');
+ }
+
+ test_binaryExpression_ifNull_rightUnPromote() async {
+ await resolveCode(r'''
+void f(Object x, Object y, Object z) {
+ if (x is int) {
+ /*int*/ x;
+ y ?? (x = z);
+ x;
+ }
+}
+''');
+ }
+
+ test_conditional_both() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ b ? ((x is num) || (throw 1)) : ((x is int) || (throw 2));
+ /*num*/ x;
+}
+''');
+ }
+
+ test_conditional_else() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ b ? 0 : ((x is int) || (throw 2));
+ x;
+}
+''');
+ }
+
+ test_conditional_then() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ b ? ((x is num) || (throw 1)) : 0;
+ x;
+}
+''');
+ }
+
+ test_do_condition_isNotType() async {
+ await resolveCode(r'''
+void f(Object x) {
+ do {
+ x;
+ } while (x is! String);
+ /*String*/ x;
+}
+''');
+ }
+
+ test_do_condition_isType() async {
+ await resolveCode(r'''
+void f(Object x) {
+ do {
+ x;
+ } while (x is String);
+ x;
+}
+''');
+ }
+
+ test_do_outerIsType() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ do {
+ /*String*/ x;
+ } while (b);
+ /*String*/ x;
+ }
+}
+''');
+ }
+
+ test_do_outerIsType_loopAssigned_body() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ do {
+ x;
+ x = x.length;
+ } while (b);
+ x;
+ }
+}
+''');
+ }
+
+ test_do_outerIsType_loopAssigned_condition() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ do {
+ x;
+ x = x.length;
+ } while (x != 0);
+ x;
+ }
+}
+''');
+ }
+
+ test_do_outerIsType_loopAssigned_condition2() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ do {
+ x;
+ } while ((x = 1) != 0);
+ x;
+ }
+}
+''');
+ }
+
+ test_for_outerIsType() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ for (; b;) {
+ /*String*/ x;
+ }
+ /*String*/ x;
+ }
+}
+''');
+ }
+
+ test_for_outerIsType_loopAssigned_body() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ for (; b;) {
+ x;
+ x = 42;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_for_outerIsType_loopAssigned_condition() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ for (; (x = 42) > 0;) {
+ x;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_for_outerIsType_loopAssigned_updaters() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ for (; b; x = 42) {
+ x;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_forEach_outerIsType_loopAssigned() async {
+ await resolveCode(r'''
+void f(Object x) {
+ Object v1;
+ if (x is String) {
+ for (var _ in (v1 = [0, 1, 2])) {
+ x;
+ x = 42;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_functionExpression_isType() async {
+ await resolveCode(r'''
+void f() {
+ void g(Object x) {
+ if (x is String) {
+ /*String*/ x;
+ }
+ x = 42;
+ }
+}
+''');
+ }
+
+ test_functionExpression_isType_mutatedInClosure2() async {
+ await resolveCode(r'''
+void f() {
+ void g(Object x) {
+ if (x is String) {
+ x;
+ }
+
+ void h() {
+ x = 42;
+ }
+ }
+}
+''');
+ }
+
+ test_functionExpression_outerIsType_assignedOutside() async {
+ await resolveCode(r'''
+void f(Object x) {
+ void Function() g;
+
+ if (x is String) {
+ /*String*/ x;
+
+ g = () {
+ x;
+ };
+ }
+
+ x = 42;
+ x;
+ g();
+}
+''');
+ }
+
+ test_if_combine_empty() async {
+ await resolveCode(r'''
+main(bool b, Object v) {
+ if (b) {
+ v is int || (throw 1);
+ } else {
+ v is String || (throw 2);
+ }
+ v;
+}
+''');
+ }
+
+ test_if_conditional_isNotType() async {
+ await resolveCode(r'''
+f(bool b, Object v) {
+ if (b ? (v is! int) : (v is! num)) {
+ v;
+ } else {
+ /*num*/ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_conditional_isType() async {
+ await resolveCode(r'''
+f(bool b, Object v) {
+ if (b ? (v is int) : (v is num)) {
+ /*num*/ v;
+ } else {
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_isNotType() async {
+ await resolveCode(r'''
+main(v) {
+ if (v is! String) {
+ v;
+ } else {
+ /*String*/ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_isNotType_return() async {
+ await resolveCode(r'''
+main(v) {
+ if (v is! String) return;
+ /*String*/ v;
+}
+''');
+ }
+
+ test_if_isNotType_throw() async {
+ await resolveCode(r'''
+main(v) {
+ if (v is! String) throw 42;
+ /*String*/ v;
+}
+''');
+ }
+
+ test_if_isType() async {
+ await resolveCode(r'''
+main(v) {
+ if (v is String) {
+ /*String*/ v;
+ } else {
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_isType_thenNonBoolean() async {
+ await resolveCode(r'''
+f(Object x) {
+ if ((x is String) != 3) {
+ x;
+ }
+}
+''');
+ }
+
+ test_if_logicalNot_isType() async {
+ await resolveCode(r'''
+main(v) {
+ if (!(v is String)) {
+ v;
+ } else {
+ /*String*/ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_then_isNotType_return() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (b) {
+ if (x is! String) return;
+ }
+ x;
+}
+''');
+ }
+
+ test_logicalOr_throw() async {
+ await resolveCode(r'''
+main(v) {
+ v is String || (throw 42);
+ /*String*/ v;
+}
+''');
+ }
+
+ test_potentiallyMutatedInClosure() async {
+ await resolveCode(r'''
+f(Object x) {
+ localFunction() {
+ x = 42;
+ }
+
+ if (x is String) {
+ localFunction();
+ x;
+ }
+}
+''');
+ }
+
+ test_potentiallyMutatedInScope() async {
+ await resolveCode(r'''
+f(Object x) {
+ if (x is String) {
+ /*String*/ x;
+ }
+
+ x = 42;
+}
+''');
+ }
+
+ test_switch_outerIsType_assignedInCase() async {
+ await resolveCode(r'''
+void f(int e, Object x) {
+ if (x is String) {
+ switch (e) {
+ L: case 1:
+ x;
+ break;
+ case 2: // no label
+ /*String*/ x;
+ break;
+ case 3:
+ x = 42;
+ continue L;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_tryCatch_assigned_body() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is! String) return;
+ /*String*/ x;
+ try {
+ x = 42;
+ g(); // might throw
+ if (x is! String) return;
+ /*String*/ x;
+ } catch (_) {}
+ x;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatch_isNotType_exit_body() async {
+ await resolveCode(r'''
+void f(Object x) {
+ try {
+ if (x is! String) return;
+ /*String*/ x;
+ } catch (_) {}
+ x;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatch_isNotType_exit_body_catch() async {
+ await resolveCode(r'''
+void f(Object x) {
+ try {
+ if (x is! String) return;
+ /*String*/ x;
+ } catch (_) {
+ if (x is! String) return;
+ /*String*/ x;
+ }
+ /*String*/ x;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatch_isNotType_exit_body_catchRethrow() async {
+ await resolveCode(r'''
+void f(Object x) {
+ try {
+ if (x is! String) return;
+ /*String*/ x;
+ } catch (_) {
+ x;
+ rethrow;
+ }
+ /*String*/ x;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatch_isNotType_exit_catch() async {
+ await resolveCode(r'''
+void f(Object x) {
+ try {
+ } catch (_) {
+ if (x is! String) return;
+ /*String*/ x;
+ }
+ x;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatchFinally_outerIsType() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ try {
+ /*String*/ x;
+ } catch (_) {
+ /*String*/ x;
+ } finally {
+ /*String*/ x;
+ }
+ /*String*/ x;
+ }
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatchFinally_outerIsType_assigned_body() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ try {
+ /*String*/ x;
+ x = 42;
+ g();
+ } catch (_) {
+ x;
+ } finally {
+ x;
+ }
+ x;
+ }
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatchFinally_outerIsType_assigned_catch() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ try {
+ /*String*/ x;
+ } catch (_) {
+ /*String*/ x;
+ x = 42;
+ } finally {
+ x;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_tryFinally_outerIsType_assigned_body() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ try {
+ /*String*/ x;
+ x = 42;
+ } finally {
+ x;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_tryFinally_outerIsType_assigned_finally() async {
+ await resolveCode(r'''
+void f(Object x) {
+ if (x is String) {
+ try {
+ /*String*/ x;
+ } finally {
+ /*String*/ x;
+ x = 42;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_while_condition_false() async {
+ await resolveCode(r'''
+void f(Object x) {
+ while (x is! String) {
+ x;
+ }
+ /*String*/ x;
+}
+''');
+ }
+
+ test_while_condition_true() async {
+ await resolveCode(r'''
+void f(Object x) {
+ while (x is String) {
+ /*String*/ x;
+ }
+ x;
+}
+''');
+ }
+
+ test_while_outerIsType() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ while (b) {
+ /*String*/ x;
+ }
+ /*String*/ x;
+ }
+}
+''');
+ }
+
+ test_while_outerIsType_loopAssigned_body() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ while (b) {
+ x;
+ x = x.length;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ test_while_outerIsType_loopAssigned_condition() async {
+ await resolveCode(r'''
+void f(bool b, Object x) {
+ if (x is String) {
+ while (x != 0) {
+ x;
+ x = x.length;
+ }
+ x;
+ }
+}
+''');
+ }
+
+ Future<ResolvedUnitResult> _resultComputer(String code) async {
+ addTestFile(code);
+ await resolveTestFile();
+ return result;
+ }
+}
+
+class _TypePromotionDataComputer extends DataComputer<DartType> {
+ const _TypePromotionDataComputer();
+
+ @override
+ DataInterpreter<DartType> get dataValidator =>
+ const _TypePromotionDataInterpreter();
+
+ @override
+ void computeUnitData(
+ CompilationUnit unit, Map<Id, ActualData<DartType>> actualMap) {
+ _TypePromotionDataExtractor(unit.declaredElement.source.uri, actualMap)
+ .run(unit);
+ }
+}
+
+class _TypePromotionDataExtractor extends AstDataExtractor<DartType> {
+ _TypePromotionDataExtractor(Uri uri, Map<Id, ActualData<DartType>> actualMap)
+ : super(uri, actualMap);
+
+ @override
+ DartType computeNodeValue(Id id, AstNode node) {
+ if (node is SimpleIdentifier && node.inGetterContext()) {
+ var element = node.staticElement;
+ if (element is VariableElement &&
+ (element is LocalVariableElement || element is ParameterElement)) {
+ var promotedType = node.staticType;
+ if (promotedType != element.type) {
+ return promotedType;
+ }
+ }
+ }
+ return null;
+ }
+}
+
+class _TypePromotionDataInterpreter implements DataInterpreter<DartType> {
+ const _TypePromotionDataInterpreter();
+
+ @override
+ String getText(DartType actualData) => actualData.toString();
+
+ @override
+ String isAsExpected(DartType actualData, String expectedData) {
+ if (actualData.toString() == expectedData) {
+ return null;
+ } else {
+ return 'Expected $expectedData, got $actualData';
+ }
+ }
+
+ @override
+ bool isEmpty(DartType actualData) => actualData == null;
+}
diff --git a/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
index 30e9267..c47a2fd 100644
--- a/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
@@ -22,6 +22,15 @@
..contextFeatures = new FeatureSet.forTesting(
sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+ test_inferredType() async {
+ await assertErrorsInCode('''
+class C {}
+List<C> v = List(5);
+''', [
+ error(CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR_MISMATCH, 23, 4),
+ ]);
+ }
+
test_nonNullableType() async {
await assertErrorsInCode('''
var l = new List<int>(3);
@@ -36,13 +45,11 @@
''');
}
- test_inferredType() async {
- await assertErrorsInCode('''
-class C {}
-List<C> v = List(5);
-''', [
- error(CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR_MISMATCH, 23, 4),
- ]);
+ test_optOut() async {
+ await assertNoErrorsInCode('''
+// @dart = 2.2
+var l = new List<int>(3);
+''');
}
test_typeParameter() async {
diff --git a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
new file mode 100644
index 0000000..548d473
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
@@ -0,0 +1,1426 @@
+// 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/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(
+ NotInitializedPotentiallyNonNullableLocalVariableTest,
+ );
+ });
+}
+
+@reflectiveTest
+class NotInitializedPotentiallyNonNullableLocalVariableTest
+ extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_assignment_leftExpression() async {
+ await assertErrorsInCode(r'''
+void f() {
+ List<int> v;
+ v[0] = (v = [1, 2])[1];
+ v;
+}
+''', [
+ _notAssignedError(28, 1),
+ ]);
+ }
+
+ test_assignment_leftLocal_compound() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ v += 1;
+ v;
+}
+''', [
+ _notAssignedError(22, 1),
+ ]);
+ }
+
+ test_assignment_leftLocal_compound_assignInRight() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ v += (v = v);
+}
+''', [
+ _notAssignedError(22, 1),
+ _notAssignedError(32, 1),
+ ]);
+ }
+
+ test_assignment_leftLocal_pure_eq() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ v = 0;
+ v;
+}
+''');
+ }
+
+ test_assignment_leftLocal_pure_eq_self() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ v = v;
+}
+''', [
+ _notAssignedError(26, 1),
+ ]);
+ }
+
+ test_assignment_leftLocal_pure_questionEq() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ v ??= 0;
+}
+''', [
+ _notAssignedError(22, 1),
+ error(HintCode.DEAD_CODE, 28, 1),
+ ]);
+ }
+
+ test_assignment_leftLocal_pure_questionEq_self() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ v ??= v;
+}
+''', [
+ _notAssignedError(22, 1),
+ error(HintCode.DEAD_CODE, 28, 1),
+ _notAssignedError(28, 1),
+ ]);
+ }
+
+ test_basic() async {
+ await assertNoErrorsInCode('''
+void f() {
+ int v;
+ v = 0;
+ v;
+}
+''');
+ }
+
+ test_binaryExpression_ifNull_left() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ (v = 0) ?? 0;
+ v;
+}
+''', [error(HintCode.DEAD_CODE, 33, 1)]);
+ }
+
+ test_binaryExpression_ifNull_right() async {
+ await assertErrorsInCode(r'''
+void f(int a) {
+ int v;
+ a ?? (v = 0);
+ v;
+}
+''', [
+ error(HintCode.DEAD_CODE, 32, 7),
+ _notAssignedError(43, 1),
+ ]);
+ }
+
+ test_binaryExpression_logicalAnd_left() async {
+ await assertNoErrorsInCode(r'''
+main(bool c) {
+ int v;
+ ((v = 0) >= 0) && c;
+ v;
+}
+''');
+ }
+
+ test_binaryExpression_logicalAnd_right() async {
+ await assertErrorsInCode(r'''
+main(bool c) {
+ int v;
+ c && ((v = 0) >= 0);
+ v;
+}
+''', [
+ _notAssignedError(49, 1),
+ ]);
+ }
+
+ test_binaryExpression_logicalOr_left() async {
+ await assertNoErrorsInCode(r'''
+main(bool c) {
+ int v;
+ ((v = 0) >= 0) || c;
+ v;
+}
+''');
+ }
+
+ test_binaryExpression_logicalOr_right() async {
+ await assertErrorsInCode(r'''
+main(bool c) {
+ int v;
+ c || ((v = 0) >= 0);
+ v;
+}
+''', [
+ _notAssignedError(49, 1),
+ ]);
+ }
+
+ test_binaryExpression_plus_left() async {
+ await assertNoErrorsInCode(r'''
+main() {
+ int v;
+ (v = 0) + 1;
+ v;
+}
+''');
+ }
+
+ test_binaryExpression_plus_right() async {
+ await assertNoErrorsInCode(r'''
+main() {
+ int v;
+ 1 + (v = 0);
+ v;
+}
+''');
+ }
+
+ test_conditional_both() async {
+ await assertNoErrorsInCode(r'''
+f(bool b) {
+ int v;
+ b ? (v = 1) : (v = 2);
+ v;
+}
+''');
+ }
+
+ test_conditional_else() async {
+ await assertErrorsInCode(r'''
+f(bool b) {
+ int v;
+ b ? 1 : (v = 2);
+ v;
+}
+''', [
+ _notAssignedError(42, 1),
+ ]);
+ }
+
+ test_conditional_then() async {
+ await assertErrorsInCode(r'''
+f(bool b) {
+ int v;
+ b ? (v = 1) : 2;
+ v;
+}
+''', [
+ _notAssignedError(42, 1),
+ ]);
+ }
+
+ test_conditionalExpression_condition() async {
+ await assertNoErrorsInCode(r'''
+main() {
+ int v;
+ (v = 0) >= 0 ? 1 : 2;
+ v;
+}
+''');
+ }
+
+ test_doWhile_break_afterAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ do {
+ v = 0;
+ v;
+ if (b) break;
+ } while (b);
+ v;
+}
+''');
+ }
+
+ test_doWhile_break_beforeAssignment() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ do {
+ if (b) break;
+ v = 0;
+ } while (b);
+ v;
+}
+''', [
+ _notAssignedError(79, 1),
+ ]);
+ }
+
+ test_doWhile_breakOuterFromInner() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2, v3;
+ L1: do {
+ do {
+ v1 = 0;
+ if (b) break L1;
+ v2 = 0;
+ v3 = 0;
+ } while (b);
+ v2;
+ } while (b);
+ v1;
+ v3;
+}
+''', [
+ _notAssignedError(168, 2),
+ ]);
+ }
+
+ test_doWhile_condition() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v1, v2;
+ do {
+ v1; // assigned in the condition, but not yet
+ } while ((v1 = 0) + (v2 = 0) >= 0);
+ v2;
+}
+''', [
+ _notAssignedError(36, 2),
+ ]);
+ }
+
+ test_doWhile_condition_break() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ do {
+ if (b) break;
+ } while ((v = 0) >= 0);
+ v;
+}
+''', [
+ _notAssignedError(79, 1),
+ ]);
+ }
+
+ test_doWhile_condition_break_continue() async {
+ await assertErrorsInCode(r'''
+void f(bool b1, b2) {
+ int v1, v2, v3, v4, v5, v6;
+ do {
+ v1 = 0; // visible outside, visible to the condition
+ if (b1) break;
+ v2 = 0; // not visible outside, visible to the condition
+ v3 = 0; // not visible outside, visible to the condition
+ if (b2) continue;
+ v4 = 0; // not visible
+ v5 = 0; // not visible
+ } while ((v6 = v1 + v2 + v4) == 0); // has break => v6 is not visible outside
+ v1;
+ v3;
+ v5;
+ v6;
+}
+''', [
+ _notAssignedError(360, 2),
+ _notAssignedError(421, 2),
+ _notAssignedError(427, 2),
+ _notAssignedError(433, 2),
+ ]);
+ }
+
+ test_doWhile_condition_continue() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2, v3, v4;
+ do {
+ v1 = 0; // visible outside, visible to the condition
+ if (b) continue;
+ v2 = 0; // not visible
+ v3 = 0; // not visible
+ } while ((v4 = v1 + v2) == 0); // no break => v4 visible outside
+ v1;
+ v3;
+ v4;
+}
+''', [
+ _notAssignedError(200, 2),
+ _notAssignedError(253, 2),
+ ]);
+ }
+
+ test_doWhile_continue_beforeAssignment() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ do {
+ if (b) continue;
+ v = 0;
+ } while (b);
+ v;
+}
+''', [
+ _notAssignedError(82, 1),
+ ]);
+ }
+
+ test_doWhile_true_assignInBreak() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ do {
+ if (b) {
+ v = 0;
+ break;
+ }
+ } while (true);
+ v;
+}
+''');
+ }
+
+ test_for_body() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ for (; b;) {
+ v = 0;
+ }
+ v;
+}
+''', [
+ _notAssignedError(58, 1),
+ ]);
+ }
+
+ test_for_break() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (; b;) {
+ v1 = 0;
+ if (b) break;
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(94, 2),
+ _notAssignedError(100, 2),
+ ]);
+ }
+
+ test_for_break_updaters() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (; b; v1 + v2) {
+ v1 = 0;
+ if (b) break;
+ v2 = 0;
+ }
+}
+''');
+ }
+
+ test_for_condition() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ for (; (v = 0) >= 0;) {
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_for_continue() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (; b;) {
+ v1 = 0;
+ if (b) continue;
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(97, 2),
+ _notAssignedError(103, 2),
+ ]);
+ }
+
+ test_for_continue_updaters() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (; b; v1 + v2) {
+ v1 = 0;
+ if (b) continue;
+ v2 = 0;
+ }
+}
+''', [
+ _notAssignedError(48, 2),
+ ]);
+ }
+
+ test_for_initializer_expression() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ for (v = 0;;) {
+ v;
+ }
+ v;
+}
+''', [
+ error(HintCode.DEAD_CODE, 51, 2),
+ ]);
+ }
+
+ test_for_initializer_variable() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ for (var t = (v = 0);;) {
+ v;
+ }
+ v;
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 31, 1),
+ error(HintCode.DEAD_CODE, 61, 2),
+ ]);
+ }
+
+ test_for_updaters() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2, v3, v4;
+ for (; b; v1 = 0, v2 = 0, v3 = 0, v4) {
+ v1;
+ }
+ v2;
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 31, 2),
+ _notAssignedError(75, 2),
+ _notAssignedError(85, 2),
+ _notAssignedError(95, 2),
+ ]);
+ }
+
+ test_for_updaters_afterBody() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ for (; b; v) {
+ v = 0;
+ }
+}
+''');
+ }
+
+ test_forEach() async {
+ await assertErrorsInCode(r'''
+void f() {
+ List<int> v1;
+ int v2;
+ for (var _ in (v1 = [0, 1, 2])) {
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(97, 2),
+ ]);
+ }
+
+ test_forEach_break() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (var _ in [0, 1, 2]) {
+ v1 = 0;
+ if (b) break;
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(108, 2),
+ _notAssignedError(114, 2),
+ ]);
+ }
+
+ test_forEach_continue() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ for (var _ in [0, 1, 2]) {
+ v1 = 0;
+ if (b) continue;
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(111, 2),
+ _notAssignedError(117, 2),
+ ]);
+ }
+
+ test_functionExpression_closure_read() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v1, v2;
+
+ v1 = 0;
+
+ [0, 1, 2].forEach((t) {
+ v1;
+ v2;
+ });
+}
+''', [
+ _notAssignedError(75, 2),
+ ]);
+ }
+
+ test_functionExpression_closure_write() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+
+ [0, 1, 2].forEach((t) {
+ v = t;
+ });
+
+ v;
+}
+''', [
+ _notAssignedError(67, 1),
+ ]);
+ }
+
+ test_functionExpression_localFunction_local() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+
+ v = 0;
+
+ void f() {
+ int v; // 1
+ v;
+ }
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+ error(HintCode.UNUSED_ELEMENT, 38, 1),
+ _notAssignedError(64, 1),
+ ]);
+ }
+
+ test_functionExpression_localFunction_local2() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v1;
+
+ v1 = 0;
+
+ void f() {
+ int v2, v3;
+ v2 = 0;
+ v1;
+ v2;
+ v3;
+ }
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 40, 1),
+ _notAssignedError(94, 2),
+ ]);
+ }
+
+ test_functionExpression_localFunction_read() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v1, v2;
+
+ v1 = 0;
+
+ void f() {
+ v1;
+ v2;
+ }
+
+ v2 = 0;
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 44, 1),
+ _notAssignedError(62, 2),
+ ]);
+ }
+
+ test_functionExpression_localFunction_write() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+
+ void f() {
+ v = 0;
+ }
+
+ v;
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 28, 1),
+ _notAssignedError(52, 1),
+ ]);
+ }
+
+ test_futureOr_questionArgument_none() async {
+ await assertNoErrorsInCode('''
+import 'dart:async';
+
+f() {
+ FutureOr<int?> v;
+}
+''');
+ }
+
+ test_hasInitializer() async {
+ await assertNoErrorsInCode('''
+f() {
+ int v = 0;
+ v;
+}
+''');
+ }
+
+ test_if_condition() async {
+ await assertNoErrorsInCode(r'''
+main() {
+ int v;
+ if ((v = 0) >= 0) {
+ v;
+ } else {
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_condition_false() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ if (false) {
+ // not assigned
+ } else {
+ v = 0;
+ }
+ v;
+}
+''', [
+ error(HintCode.DEAD_CODE, 33, 25),
+ ]);
+ }
+
+ test_if_condition_logicalAnd() async {
+ await assertErrorsInCode(r'''
+void f(bool b, int i) {
+ int v;
+ if (b && (v = i) > 0) {
+ v;
+ } else {
+ v;
+ }
+ v;
+}
+''', [
+ _notAssignedError(81, 1),
+ _notAssignedError(90, 1),
+ ]);
+ }
+
+ test_if_condition_logicalOr() async {
+ await assertErrorsInCode(r'''
+void f(bool b, int i) {
+ int v;
+ if (b || (v = i) > 0) {
+ v;
+ } else {
+ v;
+ }
+ v;
+}
+''', [
+ _notAssignedError(63, 1),
+ _notAssignedError(90, 1),
+ ]);
+ }
+
+ test_if_condition_notFalse() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ if (!false) {
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_condition_notTrue() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ if (!true) {
+ // not assigned
+ } else {
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_condition_true() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ if (true) {
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_then() async {
+ await assertErrorsInCode(r'''
+main(bool c) {
+ int v;
+ if (c) {
+ v = 0;
+ }
+ v;
+}
+''', [
+ _notAssignedError(52, 1),
+ ]);
+ }
+
+ test_if_thenElse_all() async {
+ await assertNoErrorsInCode(r'''
+main(bool c) {
+ int v;
+ if (c) {
+ v = 0;
+ v;
+ } else {
+ v = 0;
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_if_thenElse_else() async {
+ await assertErrorsInCode(r'''
+main(bool c) {
+ int v;
+ if (c) {
+ // not assigned
+ } else {
+ v = 0;
+ }
+ v;
+}
+''', [
+ _notAssignedError(83, 1),
+ ]);
+ }
+
+ test_if_thenElse_then() async {
+ await assertErrorsInCode(r'''
+main(bool c) {
+ int v;
+ if (c) {
+ v = 0;
+ } else {
+ // not assigned
+ }
+ v;
+}
+''', [
+ _notAssignedError(83, 1),
+ ]);
+ }
+
+ test_late() async {
+ await assertNoErrorsInCode('''
+f() {
+ late int v;
+ v;
+}
+''');
+ }
+
+ test_noInitializer() async {
+ await assertErrorsInCode('''
+f() {
+ int v;
+ v;
+}
+''', [
+ _notAssignedError(17, 1),
+ ]);
+ }
+
+ test_noInitializer_typeParameter() async {
+ await assertErrorsInCode('''
+f<T>() {
+ T v;
+ v;
+}
+''', [
+ _notAssignedError(18, 1),
+ ]);
+ }
+
+ test_notUsed() async {
+ await assertNoErrorsInCode('''
+void f() {
+ int v;
+}
+''');
+ }
+
+ test_nullable() async {
+ await assertNoErrorsInCode('''
+f() {
+ int? v;
+ v;
+}
+''');
+ }
+
+ test_switch_case1_default() async {
+ await assertErrorsInCode(r'''
+void f(int e) {
+ int v;
+ switch (e) {
+ case 1:
+ v = 0;
+ break;
+ case 2:
+ // not assigned
+ break;
+ default:
+ v = 0;
+ }
+ v;
+}
+''', [
+ _notAssignedError(157, 1),
+ ]);
+ }
+
+ test_switch_case2_default() async {
+ await assertErrorsInCode(r'''
+void f(int e) {
+ int v1, v2;
+ switch (e) {
+ case 1:
+ v1 = 0;
+ v2 = 0;
+ v1;
+ break;
+ default:
+ v1 = 0;
+ v1;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(157, 2),
+ ]);
+ }
+
+ test_switch_case_default_break() async {
+ await assertErrorsInCode(r'''
+void f(bool b, int e) {
+ int v1, v2;
+ switch (e) {
+ case 1:
+ v1 = 0;
+ if (b) break;
+ v2 = 0;
+ break;
+ default:
+ v1 = 0;
+ if (b) break;
+ v2 = 0;
+ }
+ v1;
+ v2;
+}
+''', [
+ _notAssignedError(199, 2),
+ ]);
+ }
+
+ test_switch_case_default_continue() async {
+ // We don't analyze to which `case` we go from `continue L`,
+ // but we don't have to. If all cases assign, then the variable is
+ // removed from the unassigned set in the `breakState`. And if there is a
+ // case when it is not assigned, then the variable will be left unassigned
+ // in the `breakState`.
+ await assertNoErrorsInCode(r'''
+void f(int e) {
+ int v;
+ switch (e) {
+ L: case 1:
+ v = 0;
+ break;
+ case 2:
+ continue L;
+ break;
+ default:
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_switch_case_noDefault() async {
+ await assertErrorsInCode(r'''
+void f(int e) {
+ int v;
+ switch (e) {
+ case 1:
+ v = 0;
+ break;
+ }
+ v;
+}
+''', [
+ _notAssignedError(84, 1),
+ ]);
+ }
+
+ test_switch_expression() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ switch (v = 0) {}
+ v;
+}
+''');
+ }
+
+ test_tryCatch_body() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ v = 0;
+ } catch (_) {
+ // not assigned
+ }
+ v;
+}
+''', [
+ _notAssignedError(81, 1),
+ ]);
+ }
+
+ test_tryCatch_body_catch() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ g();
+ v = 0;
+ } catch (_) {
+ v = 0;
+ }
+ v;
+}
+
+void g() {}
+''');
+ }
+
+ test_tryCatch_body_catchRethrow() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ v = 0;
+ } catch (_) {
+ rethrow;
+ }
+ v;
+}
+''');
+ }
+
+ test_tryCatch_catch() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ // not assigned
+ } catch (_) {
+ v = 0;
+ }
+ v;
+}
+''', [
+ _notAssignedError(81, 1),
+ ]);
+ }
+
+ test_tryCatchFinally_body() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ v = 0;
+ } catch (_) {
+ // not assigned
+ } finally {
+ // not assigned
+ }
+ v;
+}
+''', [
+ _notAssignedError(115, 1),
+ ]);
+ }
+
+ test_tryCatchFinally_catch() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ // not assigned
+ } catch (_) {
+ v = 0;
+ } finally {
+ // not assigned
+ }
+ v;
+}
+''', [
+ _notAssignedError(115, 1),
+ ]);
+ }
+
+ test_tryCatchFinally_finally() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ // not assigned
+ } catch (_) {
+ // not assigned
+ } finally {
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_tryCatchFinally_useInFinally() async {
+ await assertErrorsInCode(r'''
+f() {
+ int x;
+ try {
+ g(); // may throw an exception
+ x = 1;
+ } catch (_) {
+ x = 1;
+ } finally {
+ x; // BAD
+ }
+}
+
+void g() {}
+''', [
+ _notAssignedError(114, 1),
+ ]);
+ }
+
+ test_tryFinally_body() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ v = 0;
+ } finally {
+ // not assigned
+ }
+ v;
+}
+''');
+ }
+
+ test_tryFinally_finally() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ try {
+ // not assigned
+ } finally {
+ v = 0;
+ }
+ v;
+}
+''');
+ }
+
+ test_type_dynamic() async {
+ await assertNoErrorsInCode('''
+f() {
+ dynamic v;
+}
+''');
+ }
+
+ test_type_dynamicImplicit() async {
+ await assertNoErrorsInCode('''
+f() {
+ var v;
+}
+''');
+ }
+
+ test_type_void() async {
+ await assertNoErrorsInCode('''
+f() {
+ void v;
+}
+''');
+ }
+
+ test_while_condition() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ int v;
+ while ((v = 0) >= 0) {
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_while_condition_notTrue() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ while (b) {
+ v = 0;
+ v;
+ }
+ v;
+}
+''', [
+ _notAssignedError(64, 1),
+ ]);
+ }
+
+ test_while_true_break_afterAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ while (true) {
+ v1 = 0;
+ v1;
+ if (b) break;
+ v2 = 0;
+ v1;
+ v2;
+ }
+ v1;
+}
+''');
+ }
+
+ test_while_true_break_beforeAssignment() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ while (true) {
+ if (b) break;
+ v = 0;
+ v;
+ }
+ v;
+}
+''', [
+ _notAssignedError(85, 1),
+ ]);
+ }
+
+ test_while_true_break_if() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ while (true) {
+ if (b) {
+ v = 0;
+ break;
+ } else {
+ v = 0;
+ break;
+ }
+ v;
+ }
+ v;
+}
+''');
+ }
+
+ test_while_true_break_if2() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ var v;
+ while (true) {
+ if (b) {
+ break;
+ } else {
+ v = 0;
+ }
+ v;
+ }
+}
+''');
+ }
+
+ test_while_true_break_if3() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2;
+ while (true) {
+ if (b) {
+ v1 = 0;
+ v2 = 0;
+ if (b) break;
+ } else {
+ if (b) break;
+ v1 = 0;
+ v2 = 0;
+ }
+ v1;
+ }
+ v2;
+}
+''', [
+ _notAssignedError(190, 2),
+ ]);
+ }
+
+ test_while_true_breakOuterFromInner() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v1, v2, v3;
+ L1: while (true) {
+ L2: while (true) {
+ v1 = 0;
+ if (b) break L1;
+ v2 = 0;
+ v3 = 0;
+ if (b) break L2;
+ }
+ v2;
+ }
+ v1;
+ v3;
+}
+''', [
+ _notAssignedError(193, 2),
+ ]);
+ }
+
+ test_while_true_continue() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ int v;
+ while (true) {
+ if (b) continue;
+ v = 0;
+ }
+ v;
+}
+''', [
+ error(HintCode.DEAD_CODE, 81, 2),
+ ]);
+ }
+
+ test_while_true_noBreak() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int v;
+ while (true) {
+ // No assignment, but no break.
+ // So, we don't exit the loop.
+ // So, all variables are assigned.
+ }
+ v;
+}
+''', [
+ error(HintCode.DEAD_CODE, 153, 2),
+ ]);
+ }
+
+ ExpectedError _notAssignedError(int offset, int length) {
+ return error(
+ CompileTimeErrorCode
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ offset,
+ length);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
similarity index 60%
rename from pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
rename to pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
index 373e9b5..233eb2b 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
@@ -11,93 +11,84 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(
- NotInitializedPotentiallyNonNullableLocalVariableTest,
- );
+ defineReflectiveTests(NotInitializedNonNullableStaticFieldTest);
});
}
@reflectiveTest
-class NotInitializedPotentiallyNonNullableLocalVariableTest
- extends DriverResolutionTest {
+class NotInitializedNonNullableStaticFieldTest extends DriverResolutionTest {
@override
AnalysisOptionsImpl get analysisOptions =>
AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
- test_hasInitializer() async {
+ test_futureOr_questionArgument_none() async {
assertNoErrorsInCode('''
-f() {
- int v = 0;
+import 'dart:async';
+
+class A {
+ static FutureOr<int?> v;
}
''');
}
- test_late() async {
+ test_hasInitializer() async {
assertNoErrorsInCode('''
-f() {
- late int v;
+class A {
+ static int v = 0;
}
''');
}
test_noInitializer() async {
assertErrorsInCode('''
-f() {
- int v;
+class A {
+ static int x = 0, y, z = 2;
}
''', [
- error(
- CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
- 12,
+ error(CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD, 30,
1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 12, 1),
- ]);
- }
-
- test_noInitializer_typeParameter() async {
- assertErrorsInCode('''
-f<T>() {
- T v;
-}
-''', [
- error(
- CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
- 13,
- 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
]);
}
test_nullable() async {
assertNoErrorsInCode('''
-f() {
- int? v;
+class A {
+ static int? v;
}
''');
}
test_type_dynamic() async {
assertNoErrorsInCode('''
-f() {
- dynamic v;
+class A {
+ static dynamic v;
}
''');
}
- test_type_dynamicImplicit() async {
+ test_type_dynamic_implicit() async {
assertNoErrorsInCode('''
-f() {
- var v;
+class A {
+ static var v;
}
''');
}
+ test_type_never() async {
+ assertErrorsInCode('''
+class A {
+ static Never v;
+}
+''', [
+ error(CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD, 25,
+ 1),
+ ]);
+ }
+
test_type_void() async {
assertNoErrorsInCode('''
-f() {
- void v;
+class A {
+ static void v;
}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
index 9399e70..218e4ef 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
@@ -22,6 +22,14 @@
AnalysisOptionsImpl get analysisOptions =>
AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+ test_futureOr_questionArgument_none() async {
+ assertNoErrorsInCode('''
+import 'dart:async';
+
+FutureOr<int?> v;
+''');
+ }
+
test_hasInitializer() async {
assertNoErrorsInCode('''
int v = 0;
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 61643d4..810392d 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -96,10 +96,12 @@
import 'non_constant_spread_expression_from_deferred_library_test.dart'
as non_constant_spread_expression_from_deferred_library;
import 'non_null_opt_out_test.dart' as non_null_opt_out;
+import 'not_assigned_potentially_non_nullable_local_variable_test.dart'
+ as not_assigned_potentially_non_nullable_local_variable;
+import 'not_initialized_non_nullable_static_field_test.dart'
+ as not_initialized_non_nullable_static_field;
import 'not_initialized_non_nullable_top_level_variable_test.dart'
as not_initialized_non_nullable_top_level_variable;
-import 'not_initialized_potentially_non_nullable_local_variable_test.dart'
- as not_initialized_potentially_non_nullable_local_variable;
import 'not_iterable_spread_test.dart' as not_iterable_spread;
import 'not_map_spread_test.dart' as not_map_spread;
import 'not_null_aware_null_spread_test.dart' as not_null_aware_null_spread;
@@ -239,8 +241,9 @@
non_constant_set_element_from_deferred_library.main();
non_constant_spread_expression_from_deferred_library.main();
non_null_opt_out.main();
+ not_assigned_potentially_non_nullable_local_variable.main();
+ not_initialized_non_nullable_static_field.main();
not_initialized_non_nullable_top_level_variable.main();
- not_initialized_potentially_non_nullable_local_variable.main();
not_iterable_spread.main();
not_map_spread.main();
not_null_aware_null_spread.main();
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 3a24bb1..8d7a3e5 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -327,7 +327,7 @@
ClassElementForLink_Class cls = library.getContainedName('C');
expect(cls.fields, hasLength(1));
var field = cls.fields[0];
- expect(field.type.toString(), 'int Function(Never)');
+ expect(field.type.toString(), 'int Function<T>(T)');
}
void test_inferredType_instanceField_dynamic() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 282c385..3ab3089 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -136,14 +136,6 @@
return elementFactory.libraryOfUri('${source.uri}');
}
- @override
- @failingTest
- test_syntheticFunctionType_genericClosure() async {
- // TODO(scheglov) Bug in TypeSystem.getLeastUpperBound().
- // LUB(<T>(T) → int, <T>(T) → int) gives `(T) → int`, note absence of `<T>`.
- await super.test_syntheticFunctionType_genericClosure();
- }
-
void _addLibraryUnits(
Source definingSource,
CompilationUnit definingUnit,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index f4c870d..4e184c6 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9431,7 +9431,7 @@
bool f() => true;
''');
checkElementText(library, r'''
-final int Function(Never) v;
+final int Function<T>(T) v;
bool f() {}
''');
}
@@ -9580,6 +9580,21 @@
''');
}
+ test_type_inference_fieldFormal_depends_onField() async {
+ var library = await checkLibrary('''
+class A<T> {
+ var f = 0;
+ A(this.f);
+}
+''');
+ checkElementText(library, r'''
+class A<T> {
+ int f;
+ A(int this.f);
+}
+''');
+ }
+
test_type_inference_multiplyDefinedElement() async {
addLibrarySource('/a.dart', 'class C {}');
addLibrarySource('/b.dart', 'class C {}');
@@ -9622,6 +9637,34 @@
''');
}
+ test_type_inference_topVariable_depends_onFieldFormal() async {
+ var library = await checkLibrary('''
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+ final T f;
+ const C(this.f);
+}
+
+final b = B();
+final c = C(b);
+''');
+ checkElementText(library, r'''
+class A {
+}
+class B extends A {
+}
+class C<T extends A> {
+ final T f;
+ const C(T this.f);
+}
+final B b;
+final C<B> c;
+''');
+ }
+
test_type_invalid_topLevelVariableElement_asType() async {
var library = await checkLibrary('''
class C<T extends V> {}
diff --git a/pkg/analyzer/test/util/id_equivalence_helper.dart b/pkg/analyzer/test/util/id_equivalence_helper.dart
new file mode 100644
index 0000000..20ace3c
--- /dev/null
+++ b/pkg/analyzer/test/util/id_equivalence_helper.dart
@@ -0,0 +1,474 @@
+// 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.
+
+// Note: this file contains code that was mostly copied from
+// tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+// and then tweaked to work with the analyzer.
+// TODO(paulberry,johnniwinther): share this code between the analyzer and
+// dart2js.
+
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart' hide Annotation;
+import 'package:front_end/src/testing/annotated_code_helper.dart';
+import 'package:front_end/src/testing/id.dart'
+ show ActualData, Id, IdValue, MemberId, NodeId;
+
+/// Checks [compiledData] against the expected data in [expectedMap] derived
+/// from [code].
+Future<bool> checkCode<T>(
+ String mode,
+ Uri mainFileUri,
+ Map<Uri, AnnotatedCode> code,
+ MemberAnnotations<IdValue> expectedMaps,
+ CompiledData compiledData,
+ DataInterpreter<T> dataValidator,
+ {bool filterActualData(IdValue expected, ActualData<T> actualData),
+ bool fatalErrors: true}) async {
+ IdData<T> data = new IdData<T>(code, expectedMaps, compiledData);
+ bool hasFailure = false;
+ Set<Uri> neededDiffs = new Set<Uri>();
+
+ void checkActualMap(
+ Map<Id, ActualData<T>> actualMap, Map<Id, IdValue> expectedMap,
+ [Uri uri]) {
+ bool hasLocalFailure = false;
+ actualMap.forEach((Id id, ActualData<T> actualData) {
+ T actual = actualData.value;
+ String actualText = dataValidator.getText(actual);
+
+ if (!expectedMap.containsKey(id)) {
+ if (!dataValidator.isEmpty(actual)) {
+ reportError(
+ actualData.offset,
+ 'EXTRA $mode DATA for ${id.descriptor}:\n '
+ 'object : ${actualData.objectText}\n '
+ 'actual : ${colorizeActual('${IdValue.idToString(id, actualText)}')}\n '
+ 'Data was expected for these ids: ${expectedMap.keys}');
+ if (filterActualData == null || filterActualData(null, actualData)) {
+ hasLocalFailure = true;
+ }
+ }
+ } else {
+ IdValue expected = expectedMap[id];
+ String unexpectedMessage =
+ dataValidator.isAsExpected(actual, expected.value);
+ if (unexpectedMessage != null) {
+ reportError(
+ actualData.offset,
+ 'UNEXPECTED $mode DATA for ${id.descriptor}:\n '
+ 'detail : ${colorizeMessage(unexpectedMessage)}\n '
+ 'object : ${actualData.objectText}\n '
+ 'expected: ${colorizeExpected('$expected')}\n '
+ 'actual : ${colorizeActual('${IdValue.idToString(id, actualText)}')}');
+ if (filterActualData == null ||
+ filterActualData(expected, actualData)) {
+ hasLocalFailure = true;
+ }
+ }
+ }
+ });
+ if (hasLocalFailure) {
+ hasFailure = true;
+ if (uri != null) {
+ neededDiffs.add(uri);
+ }
+ }
+ }
+
+ data.actualMaps.forEach((Uri uri, Map<Id, ActualData<T>> actualMap) {
+ checkActualMap(actualMap, data.expectedMaps[uri], uri);
+ });
+ checkActualMap(data.actualMaps.globalData, data.expectedMaps.globalData);
+
+ Set<Id> missingIds = new Set<Id>();
+ void checkMissing(
+ Map<Id, IdValue> expectedMap, Map<Id, ActualData<T>> actualMap,
+ [Uri uri]) {
+ expectedMap.forEach((Id id, IdValue expected) {
+ if (!actualMap.containsKey(id)) {
+ missingIds.add(id);
+ String message = 'MISSING $mode DATA for ${id.descriptor}: '
+ 'Expected ${colorizeExpected('$expected')}';
+ if (uri != null) {
+ var begin = data.getOffsetFromId(id, uri);
+ reportError(begin, message);
+ } else {
+ print(message);
+ }
+ }
+ });
+ if (missingIds.isNotEmpty && uri != null) {
+ neededDiffs.add(uri);
+ }
+ }
+
+ data.expectedMaps.forEach((Uri uri, Map<Id, IdValue> expectedMap) {
+ checkMissing(expectedMap, data.actualMaps[uri], uri);
+ });
+ checkMissing(data.expectedMaps.globalData, data.actualMaps.globalData);
+ for (Uri uri in neededDiffs) {
+ print('--annotations diff [${uri.pathSegments.last}]-------------');
+ print(data.diffCode(uri, dataValidator));
+ print('----------------------------------------------------------');
+ }
+ if (missingIds.isNotEmpty) {
+ print("MISSING ids: $missingIds.");
+ hasFailure = true;
+ }
+ if (hasFailure && fatalErrors) {
+ throw StateError('Errors found.');
+ }
+ return hasFailure;
+}
+
+Future<bool> checkTests<T>(
+ String rawCode,
+ Future<ResolvedUnitResult> resultComputer(String rawCode),
+ DataComputer<T> dataComputer) async {
+ AnnotatedCode code =
+ new AnnotatedCode.fromText(rawCode, commentStart, commentEnd);
+ var result = await resultComputer(code.sourceCode);
+ var uri = result.libraryElement.source.uri;
+ var marker = 'normal';
+ Map<String, MemberAnnotations<IdValue>> expectedMaps = {
+ marker: new MemberAnnotations<IdValue>(),
+ };
+ computeExpectedMap(uri, code, expectedMaps);
+ MemberAnnotations<IdValue> annotations = expectedMaps[marker];
+ Map<Id, ActualData<T>> actualMap = {};
+ dataComputer.computeUnitData(result.unit, actualMap);
+ var compiledData = CompiledData<T>(uri, {uri: actualMap}, {});
+ return await checkCode(marker, uri, {uri: code}, annotations, compiledData,
+ dataComputer.dataValidator);
+}
+
+/// Colorize the actual annotation [text], if ANSI colors are supported.
+String colorizeActual(String text) {
+ return text;
+}
+
+/// Colorize annotation delimiters [start] and [end] surrounding [text], if
+/// ANSI colors are supported.
+String colorizeAnnotation(String start, String text, String end) {
+ return '${colorizeDelimiter(start)}$text${colorizeDelimiter(end)}';
+}
+
+/// Colorize delimiter [text], if ANSI colors are supported.
+String colorizeDelimiter(String text) {
+ return text;
+}
+
+/// Colorize diffs [expected] and [actual] and [delimiter], if ANSI colors are
+/// supported.
+String colorizeDiff(String expected, String delimiter, String actual) {
+ return '${colorizeExpected(expected)}'
+ '${colorizeDelimiter(delimiter)}${colorizeActual(actual)}';
+}
+
+/// Colorize an expected annotation [text], if ANSI colors are supported.
+String colorizeExpected(String text) {
+ return text;
+}
+
+/// Colorize a matching annotation [text], if ANSI colors are supported.
+String colorizeMatch(String text) {
+ return text;
+}
+
+/// Colorize a message [text], if ANSI colors are supported.
+String colorizeMessage(String text) {
+ return text;
+}
+
+/// Compute three [MemberAnnotations] objects from [code] specifying the
+/// expected annotations we anticipate encountering; one corresponding to the
+/// old implementation, one for the new implementation, and one for the new
+/// implementation using strong mode.
+///
+/// If an annotation starts with 'ast.' it is only expected for the old
+/// implementation, if it starts with 'kernel.' it is only expected for the
+/// new implementation, and if it starts with 'strong.' it is only expected for
+/// strong mode (using the common frontend). Otherwise it is expected for all
+/// implementations.
+///
+/// Most nodes have the same and expectations should match this by using
+/// annotations without prefixes.
+void computeExpectedMap(Uri sourceUri, AnnotatedCode code,
+ Map<String, MemberAnnotations<IdValue>> maps) {
+ List<String> mapKeys = maps.keys.toList();
+ Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys);
+
+ split.forEach((String marker, AnnotatedCode code) {
+ MemberAnnotations<IdValue> fileAnnotations = maps[marker];
+ assert(fileAnnotations != null, "No annotations for $marker in $maps");
+ Map<Id, IdValue> expectedValues = fileAnnotations[sourceUri];
+ for (Annotation annotation in code.annotations) {
+ String text = annotation.text;
+ IdValue idValue = IdValue.decode(annotation.offset, text);
+ if (idValue.id.isGlobal) {
+ _expectFalse(
+ fileAnnotations.globalData.containsKey(idValue.id),
+ "Duplicate annotations for ${idValue.id} in $marker: "
+ "$idValue and ${fileAnnotations.globalData[idValue.id]}.");
+ fileAnnotations.globalData[idValue.id] = idValue;
+ } else {
+ _expectFalse(
+ expectedValues.containsKey(idValue.id),
+ "Duplicate annotations for ${idValue.id} in $marker: "
+ "$idValue and ${expectedValues[idValue.id]}.");
+ expectedValues[idValue.id] = idValue;
+ }
+ }
+ });
+}
+
+/// Reports [message] as an error using [spannable] as error location.
+void reportError(int offset, String message) {
+ print('$offset: $message');
+}
+
+String withAnnotations(String sourceCode, Map<int, List<String>> annotations) {
+ StringBuffer sb = new StringBuffer();
+ int end = 0;
+ for (int offset in annotations.keys.toList()..sort()) {
+ if (offset >= sourceCode.length) {
+ sb.write('...');
+ return sb.toString();
+ }
+ if (offset > end) {
+ sb.write(sourceCode.substring(end, offset));
+ }
+ for (String annotation in annotations[offset]) {
+ sb.write(colorizeAnnotation('/*', annotation, '*/'));
+ }
+ end = offset;
+ }
+ if (end < sourceCode.length) {
+ sb.write(sourceCode.substring(end));
+ }
+ return sb.toString();
+}
+
+void _expectFalse(bool b, String message) {
+ if (b) {
+ throw StateError(message);
+ }
+}
+
+class CompiledData<T> {
+ final Uri mainUri;
+ final Map<Uri, Map<Id, ActualData<T>>> actualMaps;
+ final Map<Id, ActualData<T>> globalData;
+
+ CompiledData(this.mainUri, this.actualMaps, this.globalData);
+
+ Map<int, List<String>> computeAnnotations(Uri uri) {
+ Map<Id, ActualData<T>> thisMap = actualMaps[uri];
+ Map<int, List<String>> annotations = <int, List<String>>{};
+ thisMap.forEach((Id id, ActualData<T> data1) {
+ String value1 = '${data1.value}';
+ annotations
+ .putIfAbsent(data1.offset, () => [])
+ .add(colorizeActual(value1));
+ });
+ return annotations;
+ }
+
+ Map<int, List<String>> computeDiffAnnotationsAgainst(
+ Map<Id, ActualData<T>> thisMap, Map<Id, ActualData<T>> otherMap, Uri uri,
+ {bool includeMatches: false}) {
+ Map<int, List<String>> annotations = <int, List<String>>{};
+ thisMap.forEach((Id id, ActualData<T> data1) {
+ ActualData<T> data2 = otherMap[id];
+ String value1 = '${data1.value}';
+ if (data1.value != data2?.value) {
+ String value2 = '${data2?.value ?? '---'}';
+ annotations
+ .putIfAbsent(data1.offset, () => [])
+ .add(colorizeDiff(value1, ' | ', value2));
+ } else if (includeMatches) {
+ annotations
+ .putIfAbsent(data1.offset, () => [])
+ .add(colorizeMatch(value1));
+ }
+ });
+ otherMap.forEach((Id id, ActualData<T> data2) {
+ if (!thisMap.containsKey(id)) {
+ String value1 = '---';
+ String value2 = '${data2.value}';
+ annotations
+ .putIfAbsent(data2.offset, () => [])
+ .add(colorizeDiff(value1, ' | ', value2));
+ }
+ });
+ return annotations;
+ }
+}
+
+abstract class DataComputer<T> {
+ const DataComputer();
+
+ DataInterpreter<T> get dataValidator;
+
+ /// Function that computes a data mapping for [unit].
+ ///
+ /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+ /// for the data origin.
+ void computeUnitData(CompilationUnit unit, Map<Id, ActualData<T>> actualMap);
+}
+
+/// Interface used for interpreting annotations.
+abstract class DataInterpreter<T> {
+ /// Returns a textual representation of [actualData].
+ String getText(T actualData);
+
+ /// Returns `null` if [actualData] satisfies the [expectedData] annotation.
+ /// Otherwise, a message is returned contain the information about the
+ /// problems found.
+ String isAsExpected(T actualData, String expectedData);
+
+ /// Returns `true` if [actualData] corresponds to empty data.
+ bool isEmpty(T actualData);
+}
+
+/// Data collected by [computeData].
+class IdData<T> {
+ final Map<Uri, AnnotatedCode> code;
+ final MemberAnnotations<IdValue> expectedMaps;
+ final CompiledData _compiledData;
+ final MemberAnnotations<ActualData<T>> _actualMaps = new MemberAnnotations();
+
+ IdData(this.code, this.expectedMaps, this._compiledData) {
+ for (Uri uri in code.keys) {
+ _actualMaps[uri] = _compiledData.actualMaps[uri] ?? <Id, ActualData<T>>{};
+ }
+ _actualMaps.globalData.addAll(_compiledData.globalData);
+ }
+
+ MemberAnnotations<ActualData<T>> get actualMaps => _actualMaps;
+ Uri get mainUri => _compiledData.mainUri;
+
+ String actualCode(Uri uri) {
+ Map<int, List<String>> annotations = <int, List<String>>{};
+ actualMaps[uri].forEach((Id id, ActualData<T> data) {
+ annotations.putIfAbsent(data.offset, () => []).add('${data.value}');
+ });
+ return withAnnotations(code[uri].sourceCode, annotations);
+ }
+
+ String diffCode(Uri uri, DataInterpreter<T> dataValidator) {
+ Map<int, List<String>> annotations = <int, List<String>>{};
+ actualMaps[uri].forEach((Id id, ActualData<T> data) {
+ IdValue expectedValue = expectedMaps[uri][id];
+ T actualValue = data.value;
+ String unexpectedMessage =
+ dataValidator.isAsExpected(actualValue, expectedValue?.value);
+ if (unexpectedMessage != null) {
+ String expected = expectedValue?.toString() ?? '';
+ String actual = dataValidator.getText(actualValue);
+ int offset = getOffsetFromId(id, uri);
+ if (offset != null) {
+ String value1 = '$expected';
+ String value2 = IdValue.idToString(id, '$actual');
+ annotations
+ .putIfAbsent(offset, () => [])
+ .add(colorizeDiff(value1, ' | ', value2));
+ }
+ }
+ });
+ expectedMaps[uri].forEach((Id id, IdValue expected) {
+ if (!actualMaps[uri].containsKey(id)) {
+ int offset = getOffsetFromId(id, uri);
+ if (offset != null) {
+ String value1 = '$expected';
+ String value2 = '---';
+ annotations
+ .putIfAbsent(offset, () => [])
+ .add(colorizeDiff(value1, ' | ', value2));
+ }
+ }
+ });
+ return withAnnotations(code[uri].sourceCode, annotations);
+ }
+
+ int getOffsetFromId(Id id, Uri uri) {
+ if (id is NodeId) {
+ return id.value;
+ } else if (id is MemberId) {
+ if (id.className != null) {
+ throw UnimplementedError('TODO(paulberry): handle class members');
+ }
+ var name = id.memberName;
+ var unit =
+ parseString(content: code[uri].sourceCode, throwIfDiagnostics: false)
+ .unit;
+ for (var declaration in unit.declarations) {
+ if (declaration is FunctionDeclaration) {
+ if (declaration.name.name == name) {
+ return declaration.offset;
+ }
+ }
+ }
+ throw StateError('Member not found: $name');
+ } else {
+ throw StateError('Unexpected id ${id.runtimeType}');
+ }
+ }
+}
+
+/// Encapsulates the member data computed for each source file of interest.
+/// It's a glorified wrapper around a map of maps, but written this way to
+/// provide a little more information about what it's doing. [DataType] refers
+/// to the type this map is holding -- it is either [IdValue] or [ActualData].
+class MemberAnnotations<DataType> {
+ /// For each Uri, we create a map associating an element id with its
+ /// corresponding annotations.
+ final Map<Uri, Map<Id, DataType>> _computedDataForEachFile =
+ new Map<Uri, Map<Id, DataType>>();
+
+ /// Member or class annotations that don't refer to any of the user files.
+ final Map<Id, DataType> globalData = <Id, DataType>{};
+
+ Map<Id, DataType> operator [](Uri file) {
+ if (!_computedDataForEachFile.containsKey(file)) {
+ _computedDataForEachFile[file] = <Id, DataType>{};
+ }
+ return _computedDataForEachFile[file];
+ }
+
+ void operator []=(Uri file, Map<Id, DataType> computedData) {
+ _computedDataForEachFile[file] = computedData;
+ }
+
+ void forEach(void f(Uri file, Map<Id, DataType> computedData)) {
+ _computedDataForEachFile.forEach(f);
+ }
+
+ @override
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('MemberAnnotations(');
+ String comma = '';
+ if (_computedDataForEachFile.isNotEmpty &&
+ (_computedDataForEachFile.length > 1 ||
+ _computedDataForEachFile.values.single.isNotEmpty)) {
+ sb.write('data:{');
+ _computedDataForEachFile.forEach((Uri uri, Map<Id, DataType> data) {
+ sb.write(comma);
+ sb.write('$uri:');
+ sb.write(data);
+ comma = ',';
+ });
+ sb.write('}');
+ }
+ if (globalData.isNotEmpty) {
+ sb.write(comma);
+ sb.write('global:');
+ sb.write(globalData);
+ }
+ sb.write(')');
+ return sb.toString();
+ }
+}
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 07190a4..37bc80a 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -216,7 +216,7 @@
*/
class TypeAssertions {
// TODO(leafp): Make these matchers.
- // https://www.dartdocs.org/documentation/matcher/0.12.0%2B1/matcher/Matcher-class.html
+ // https://pub.dev/documentation/matcher/latest/matcher/Matcher-class.html
/**
* Provides primitive types for basic type assertions.
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index b218815..7a9f931 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -393,8 +393,8 @@
NullValue.Metadata);
}
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
debugEvent("Method");
pop(); // Body
pop(); // Initializers
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 617bdf9..2d88a91 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -46,7 +46,7 @@
final Set<String> files = new Set<String>();
/// All [AnalysisErrorInfo]s in the analyzed library.
- final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
+ final List<ErrorsResult> errorsResults = [];
/// If the file specified on the command line is part of a package, the name
/// of that package. Otherwise `null`. This allows us to analyze the file
@@ -108,8 +108,8 @@
/// Returns the maximal [ErrorSeverity] of the recorded errors.
ErrorSeverity computeMaxErrorSeverity() {
ErrorSeverity status = ErrorSeverity.NONE;
- for (AnalysisErrorInfo errorInfo in errorInfos) {
- for (AnalysisError error in errorInfo.errors) {
+ for (ErrorsResult result in errorsResults) {
+ for (AnalysisError error in result.errors) {
if (_defaultSeverityProcessor(error) == null) {
continue;
}
@@ -119,7 +119,7 @@
return status;
}
- /// Fills [errorInfos] using [files].
+ /// Fills [errorsResults] using [files].
Future<void> prepareErrors() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -127,8 +127,7 @@
try {
for (String path in files) {
ErrorsResult errorsResult = await analysisDriver.getErrors(path);
- errorInfos.add(new AnalysisErrorInfoImpl(
- errorsResult.errors, errorsResult.lineInfo));
+ errorsResults.add(errorsResult);
}
} finally {
previous.makeCurrent();
@@ -145,7 +144,7 @@
/// Setup local fields such as the analysis context for analysis.
void setupForAnalysis() {
files.clear();
- errorInfos.clear();
+ errorsResults.clear();
Uri libraryUri = libraryFile.uri;
if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) {
_selfPackageName = libraryUri.pathSegments[0];
@@ -170,7 +169,7 @@
// Print errors and performance numbers.
if (printMode == 1) {
- formatter.formatErrors(errorInfos);
+ formatter.formatErrors(errorsResults);
} else if (printMode == 2) {
_printColdPerf();
}
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index c50528d..dd86768 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -633,9 +633,7 @@
severityProcessor: severityProcessor);
for (Source source in explicitSources) {
var result = await analysisDriver.getErrors(source.fullName);
- var errorInfo =
- new AnalysisErrorInfoImpl(result.errors, result.lineInfo);
- formatter.formatErrors([errorInfo]);
+ formatter.formatErrors([result]);
}
formatter.flush();
if (!options.machineFormat) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index bd54543..9252730 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -14,6 +14,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/results.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';
@@ -23,8 +24,8 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart'
show PerformanceTag;
-import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/manifest/manifest_validator.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/path_filter.dart';
@@ -350,7 +351,10 @@
LineInfo lineInfo = new LineInfo.fromContent(content);
List<AnalysisError> errors = analyzeAnalysisOptions(
file.createSource(), content, analysisDriver.sourceFactory);
- formatter.formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+ formatter.formatErrors([
+ ErrorsResultImpl(analysisDriver.currentSession, path, null,
+ lineInfo, false, errors)
+ ]);
for (AnalysisError error in errors) {
ErrorSeverity severity = determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
@@ -368,8 +372,10 @@
new PubspecValidator(resourceProvider, file.createSource());
LineInfo lineInfo = new LineInfo.fromContent(content);
List<AnalysisError> errors = validator.validate(node.nodes);
- formatter
- .formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+ formatter.formatErrors([
+ ErrorsResultImpl(analysisDriver.currentSession, path, null,
+ lineInfo, false, errors)
+ ]);
for (AnalysisError error in errors) {
ErrorSeverity severity = determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
@@ -388,8 +394,10 @@
LineInfo lineInfo = new LineInfo.fromContent(content);
List<AnalysisError> errors = validator.validate(
content, analysisDriver.analysisOptions.chromeOsManifestChecks);
- formatter
- .formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+ formatter.formatErrors([
+ ErrorsResultImpl(analysisDriver.currentSession, path, null,
+ lineInfo, false, errors)
+ ]);
for (AnalysisError error in errors) {
ErrorSeverity severity = determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index e6e61f4..51e1333 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -2,9 +2,10 @@
// for 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/error/error.dart';
import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_cli/src/ansi.dart';
import 'package:analyzer_cli/src/options.dart';
@@ -109,6 +110,7 @@
final int line;
final int column;
final String message;
+ final List<ContextMessage> contextMessages;
final String errorCode;
final String correction;
final String url;
@@ -120,6 +122,7 @@
this.line,
this.column,
this.message,
+ this.contextMessages,
this.errorCode,
this.correction,
this.url,
@@ -161,6 +164,14 @@
}
}
+class ContextMessage {
+ final String filePath;
+ final String message;
+ final int line;
+ final int column;
+ ContextMessage(this.filePath, this.message, this.line, this.column);
+}
+
/// Helper for formatting [AnalysisError]s.
///
/// The two format options are a user consumable format and a machine consumable
@@ -181,19 +192,18 @@
void flush();
void formatError(
- Map<AnalysisError, LineInfo> errorToLine, AnalysisError error);
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error);
- void formatErrors(List<AnalysisErrorInfo> errorInfos) {
- stats.unfilteredCount += errorInfos.length;
+ void formatErrors(List<ErrorsResult> results) {
+ stats.unfilteredCount += results.length;
List<AnalysisError> errors = new List<AnalysisError>();
- Map<AnalysisError, LineInfo> errorToLine =
- new Map<AnalysisError, LineInfo>();
- for (AnalysisErrorInfo errorInfo in errorInfos) {
- for (AnalysisError error in errorInfo.errors) {
+ Map<AnalysisError, ErrorsResult> errorToLine = {};
+ for (ErrorsResult result in results) {
+ for (AnalysisError error in result.errors) {
if (_computeSeverity(error) != null) {
errors.add(error);
- errorToLine[error] = errorInfo.lineInfo;
+ errorToLine[error] = result;
}
}
}
@@ -253,6 +263,11 @@
// If verbose, also print any associated correction and URL.
if (options.verbose) {
String padding = ' '.padLeft(error.severity.length + 2);
+ for (var message in error.contextMessages) {
+ out.write('$padding${message.message} ');
+ out.write('at ${message.filePath}');
+ out.writeln(':${message.line}:${message.column}');
+ }
if (error.correction != null) {
out.writeln('$padding${error.correction}');
}
@@ -267,9 +282,10 @@
}
void formatError(
- Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
Source source = error.source;
- var location = errorToLine[error].getLocation(error.offset);
+ var result = errorToLine[error];
+ var location = result.lineInfo.getLocation(error.offset);
ErrorSeverity severity = _severityProcessor(error);
@@ -300,6 +316,17 @@
} else {
sourcePath = _relative(source.fullName);
}
+ List<ContextMessage> contextMessages = [];
+ for (var message in error.contextMessages) {
+ var session = result.session.analysisContext;
+ if (session is DriverBasedAnalysisContext) {
+ LineInfo lineInfo =
+ session.driver.getFileSync(message.filePath)?.lineInfo;
+ var location = lineInfo.getLocation(message.offset);
+ contextMessages.add(ContextMessage(message.filePath, message.message,
+ location.lineNumber, location.columnNumber));
+ }
+ }
batchedErrors.add(new CLIError(
severity: errorType,
@@ -308,6 +335,7 @@
line: location.lineNumber,
column: location.columnNumber,
message: message,
+ contextMessages: contextMessages,
errorCode: error.errorCode.name.toLowerCase(),
correction: error.correction,
url: error.errorCode.url,
@@ -330,13 +358,13 @@
void flush() {}
void formatError(
- Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+ Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
// Ensure we don't over-report (#36062).
if (!_seenErrors.add(error)) {
return;
}
Source source = error.source;
- var location = errorToLine[error].getLocation(error.offset);
+ var location = errorToLine[error].lineInfo.getLocation(error.offset);
int length = error.length;
ErrorSeverity severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index b5e5627..0095948 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -23,15 +23,12 @@
String message;
@override
- bool isStaticOnly;
-
- @override
int length;
MockAnalysisError(this.source, this.errorCode, this.offset, this.message);
@override
- List<DiagnosticMessage> get contextMessages => null;
+ List<DiagnosticMessage> get contextMessages => const [];
@override
String get correction => null;
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 26d37ac..e7f359b 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -4,7 +4,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/error_formatter.dart';
import 'package:test/test.dart' hide ErrorFormatter;
@@ -39,8 +39,8 @@
});
test('error', () {
- AnalysisErrorInfo error =
- mockError(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
+ ErrorsResultImpl error =
+ mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
reporter.formatErrors([error]);
reporter.flush();
@@ -49,7 +49,7 @@
});
test('hint', () {
- AnalysisErrorInfo error = mockError(ErrorType.HINT, ErrorSeverity.INFO);
+ ErrorsResultImpl error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
reporter.formatErrors([error]);
reporter.flush();
@@ -58,7 +58,7 @@
});
test('stats', () {
- AnalysisErrorInfo error = mockError(ErrorType.HINT, ErrorSeverity.INFO);
+ ErrorsResultImpl error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
reporter.formatErrors([error]);
reporter.flush();
stats.print(out);
@@ -70,7 +70,7 @@
});
}
-MockAnalysisErrorInfo mockError(ErrorType type, ErrorSeverity severity) {
+ErrorsResultImpl mockResult(ErrorType type, ErrorSeverity severity) {
// ErrorInfo
var location = new CharacterLocation(3, 3);
var lineInfo = new MockLineInfo(defaultLocation: location);
@@ -80,5 +80,6 @@
var source = new MockSource('/foo/bar/baz.dart');
var error = new MockAnalysisError(source, code, 20, 'MSG');
- return new MockAnalysisErrorInfo(lineInfo, [error]);
+ return ErrorsResultImpl(
+ null, source.fullName, null, lineInfo, false, [error]);
}
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 99bb973..87c832c 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
@@ -131,7 +131,7 @@
_visitTypeParameters(declaration, declaration.typeParameters);
_visitTypeParameters(
declaration.functionType,
- declaration.functionType.typeParameters,
+ declaration.functionType?.typeParameters,
);
} else if (declaration is MixinDeclaration) {
declaredMixin(declaration);
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 801a18f..ebc6182 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -100,6 +100,9 @@
/// Flag for a combination of flags for 'production' mode.
static const String benchmarkingProduction = '--benchmarking-production';
+ /// Flag for a combination of flags for benchmarking 'experiment' mode.
+ static const String benchmarkingExperiment = '--benchmarking-x';
+
static const String conditionalDirectives = '--conditional-directives';
// The syntax-only level of support for generic methods is included in the
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 2778f65..d21986b 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -16,6 +16,7 @@
import 'js_backend/native_data.dart' show NativeBasicData;
import 'js_model/locals.dart';
import 'kernel/dart2js_target.dart';
+import 'options.dart';
import 'universe/selector.dart' show Selector;
/// The common elements and types in Dart.
@@ -481,6 +482,9 @@
// From dart:_rti
FunctionEntity get findType;
+ FunctionEntity get instanceType;
+ FunctionEntity get typeLiteralMaker;
+ FunctionEntity get checkTypeBound;
FieldEntity get rtiAsField;
FieldEntity get rtiCheckField;
FieldEntity get rtiIsField;
@@ -613,8 +617,9 @@
class CommonElementsImpl
implements CommonElements, KCommonElements, JCommonElements {
final ElementEnvironment _env;
+ final CompilerOptions _options;
- CommonElementsImpl(this._env);
+ CommonElementsImpl(this._env, this._options);
ClassEntity _objectClass;
@override
@@ -1442,7 +1447,9 @@
ClassEntity _typeLiteralClass;
@override
ClassEntity get typeLiteralClass =>
- _typeLiteralClass ??= _findHelperClass('TypeImpl');
+ _typeLiteralClass ??= _options.experimentNewRti
+ ? _findRtiClass('_Type')
+ : _findHelperClass('TypeImpl');
ClassEntity _constMapLiteralClass;
@override
@@ -1729,8 +1736,9 @@
_findHelperFunction('throwNoSuchMethod');
@override
- FunctionEntity get createRuntimeType =>
- _findHelperFunction('createRuntimeType');
+ FunctionEntity get createRuntimeType => _options.experimentNewRti
+ ? _findRtiFunction('_createRuntimeType')
+ : _findHelperFunction('createRuntimeType');
@override
FunctionEntity get fallThroughError =>
@@ -1804,6 +1812,8 @@
// From dart:_rti
+ ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name);
+
FunctionEntity _findRtiFunction(String name) =>
_findLibraryMember(rtiLibrary, name);
@@ -1811,6 +1821,21 @@
@override
FunctionEntity get findType => _findType ??= _findRtiFunction('findType');
+ FunctionEntity _instanceType;
+ @override
+ FunctionEntity get instanceType =>
+ _instanceType ??= _findRtiFunction('instanceType');
+
+ FunctionEntity _typeLiteralMaker;
+ @override
+ FunctionEntity get typeLiteralMaker =>
+ _typeLiteralMaker ??= _findRtiFunction('typeLiteral');
+
+ FunctionEntity _checkTypeBound;
+ @override
+ FunctionEntity get checkTypeBound =>
+ _checkTypeBound ??= _findRtiFunction('checkTypeBound');
+
ClassEntity get _rtiImplClass => _findClass(rtiLibrary, 'Rti');
FieldEntity _findRtiClassField(String name) =>
_findClassMember(_rtiImplClass, name);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 7348d20..f961525 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -456,6 +456,7 @@
new OptionHandler(Flags.omitAsCasts, passThrough),
new OptionHandler(Flags.laxRuntimeTypeToString, passThrough),
new OptionHandler(Flags.benchmarkingProduction, passThrough),
+ new OptionHandler(Flags.benchmarkingExperiment, passThrough),
// TODO(floitsch): remove conditional directives flag.
// We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 118d4ed..437ff2a 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -1336,7 +1336,8 @@
Map<ClassEntity, OutputUnit> classToUnit = source.readClassMap(() {
return outputUnits[source.readInt()];
});
- Map<MemberEntity, OutputUnit> memberToUnit = source.readMemberMap(() {
+ Map<MemberEntity, OutputUnit> memberToUnit =
+ source.readMemberMap((MemberEntity member) {
return outputUnits[source.readInt()];
});
Map<ConstantValue, OutputUnit> constantToUnit = source.readConstantMap(() {
@@ -1387,7 +1388,8 @@
sink.writeClassMap(_classToUnit, (OutputUnit outputUnit) {
sink.writeInt(outputUnitIndices[outputUnit]);
});
- sink.writeMemberMap(_memberToUnit, (OutputUnit outputUnit) {
+ sink.writeMemberMap(_memberToUnit,
+ (MemberEntity member, OutputUnit outputUnit) {
sink.writeInt(outputUnitIndices[outputUnit]);
});
sink.writeConstantMap(_constantToUnit, (OutputUnit outputUnit) {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index d34c1d0..200d368 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1125,6 +1125,14 @@
/// Try to find the length given to a fixed array constructor call.
int _findLength(ir.Arguments arguments) {
+ int finish(int length) {
+ // Filter out lengths that should not be tracked.
+ if (length < 0) return null;
+ // Serialization limit.
+ if (length >= (1 << 30)) return null;
+ return length;
+ }
+
ir.Expression firstArgument = arguments.positional.first;
if (firstArgument is ir.ConstantExpression &&
firstArgument.constant is ir.DoubleConstant) {
@@ -1132,10 +1140,10 @@
double doubleValue = constant.value;
int truncatedValue = doubleValue.truncate();
if (doubleValue == truncatedValue) {
- return truncatedValue;
+ return finish(truncatedValue);
}
} else if (firstArgument is ir.IntLiteral) {
- return firstArgument.value;
+ return finish(firstArgument.value);
} else if (firstArgument is ir.StaticGet) {
MemberEntity member = _elementMap.getMember(firstArgument.target);
if (member.isField) {
@@ -1143,7 +1151,9 @@
_closedWorld.fieldAnalysis.getFieldData(member);
if (fieldData.isEffectivelyConstant && fieldData.constantValue.isInt) {
IntConstantValue intValue = fieldData.constantValue;
- return intValue.intValue.toInt();
+ if (intValue.intValue.isValidInt) {
+ return finish(intValue.intValue.toInt());
+ }
}
}
}
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 6266882..bf214c1 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -1433,49 +1433,59 @@
/// Deserializes a [GlobalTypeInferenceElementData] object from [source].
factory KernelGlobalTypeInferenceElementData.readFromDataSource(
- DataSource source, AbstractValueDomain abstractValueDomain) {
- source.begin(tag);
- Map<ir.TreeNode, AbstractValue> sendMap = source.readTreeNodeMap(
- () => abstractValueDomain.readAbstractValueFromDataSource(source),
- emptyAsNull: true);
- Map<ir.ForInStatement, AbstractValue> iteratorMap = source.readTreeNodeMap(
- () => abstractValueDomain.readAbstractValueFromDataSource(source),
- emptyAsNull: true);
- Map<ir.ForInStatement, AbstractValue> currentMap = source.readTreeNodeMap(
- () => abstractValueDomain.readAbstractValueFromDataSource(source),
- emptyAsNull: true);
- Map<ir.ForInStatement, AbstractValue> moveNextMap = source.readTreeNodeMap(
- () => abstractValueDomain.readAbstractValueFromDataSource(source),
- emptyAsNull: true);
- source.end(tag);
- return new KernelGlobalTypeInferenceElementData.internal(
- sendMap, iteratorMap, currentMap, moveNextMap);
+ DataSource source,
+ ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
+ return source.inMemberContext(context, () {
+ source.begin(tag);
+ Map<ir.TreeNode, AbstractValue> sendMap = source.readTreeNodeMapInContext(
+ () => abstractValueDomain.readAbstractValueFromDataSource(source),
+ emptyAsNull: true);
+ Map<ir.ForInStatement, AbstractValue> iteratorMap =
+ source.readTreeNodeMapInContext(
+ () => abstractValueDomain.readAbstractValueFromDataSource(source),
+ emptyAsNull: true);
+ Map<ir.ForInStatement, AbstractValue> currentMap =
+ source.readTreeNodeMapInContext(
+ () => abstractValueDomain.readAbstractValueFromDataSource(source),
+ emptyAsNull: true);
+ Map<ir.ForInStatement, AbstractValue> moveNextMap =
+ source.readTreeNodeMapInContext(
+ () => abstractValueDomain.readAbstractValueFromDataSource(source),
+ emptyAsNull: true);
+ source.end(tag);
+ return new KernelGlobalTypeInferenceElementData.internal(
+ sendMap, iteratorMap, currentMap, moveNextMap);
+ });
}
@override
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
- sink.begin(tag);
- sink.writeTreeNodeMap(
- _sendMap,
- (AbstractValue value) =>
- abstractValueDomain.writeAbstractValueToDataSink(sink, value),
- allowNull: true);
- sink.writeTreeNodeMap(
- _iteratorMap,
- (AbstractValue value) =>
- abstractValueDomain.writeAbstractValueToDataSink(sink, value),
- allowNull: true);
- sink.writeTreeNodeMap(
- _currentMap,
- (AbstractValue value) =>
- abstractValueDomain.writeAbstractValueToDataSink(sink, value),
- allowNull: true);
- sink.writeTreeNodeMap(
- _moveNextMap,
- (AbstractValue value) =>
- abstractValueDomain.writeAbstractValueToDataSink(sink, value),
- allowNull: true);
- sink.end(tag);
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
+ sink.inMemberContext(context, () {
+ sink.begin(tag);
+ sink.writeTreeNodeMapInContext(
+ _sendMap,
+ (AbstractValue value) =>
+ abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+ allowNull: true);
+ sink.writeTreeNodeMapInContext(
+ _iteratorMap,
+ (AbstractValue value) =>
+ abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+ allowNull: true);
+ sink.writeTreeNodeMapInContext(
+ _currentMap,
+ (AbstractValue value) =>
+ abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+ allowNull: true);
+ sink.writeTreeNodeMapInContext(
+ _moveNextMap,
+ (AbstractValue value) =>
+ abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+ allowNull: true);
+ sink.end(tag);
+ });
}
@override
diff --git a/pkg/compiler/lib/src/inferrer/types.dart b/pkg/compiler/lib/src/inferrer/types.dart
index f68b519..374f01a 100644
--- a/pkg/compiler/lib/src/inferrer/types.dart
+++ b/pkg/compiler/lib/src/inferrer/types.dart
@@ -11,6 +11,7 @@
import '../compiler.dart' show Compiler;
import '../elements/entities.dart';
import '../js_backend/inferred_data.dart';
+import '../js_model/element_map.dart';
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
import '../serialization/serialization.dart';
import '../universe/selector.dart' show Selector;
@@ -30,12 +31,13 @@
/// based queries (the runtime value could be anything).
abstract class GlobalTypeInferenceMemberResult {
/// Deserializes a [GlobalTypeInferenceMemberResult] object from [source].
- factory GlobalTypeInferenceMemberResult.readFromDataSource(
- DataSource source, AbstractValueDomain abstractValueDomain) =
+ factory GlobalTypeInferenceMemberResult.readFromDataSource(DataSource source,
+ ir.Member context, AbstractValueDomain abstractValueDomain) =
GlobalTypeInferenceMemberResultImpl.readFromDataSource;
/// Serializes this [GlobalTypeInferenceMemberResult] to [sink].
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain);
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain);
/// The inferred type when this result belongs to a field, null otherwise.
AbstractValue get type;
@@ -72,12 +74,13 @@
/// a single element.
abstract class GlobalTypeInferenceElementData {
/// Deserializes a [GlobalTypeInferenceElementData] object from [source].
- factory GlobalTypeInferenceElementData.readFromDataSource(
- DataSource source, AbstractValueDomain abstractValueDomain) =
+ factory GlobalTypeInferenceElementData.readFromDataSource(DataSource source,
+ ir.Member context, AbstractValueDomain abstractValueDomain) =
KernelGlobalTypeInferenceElementData.readFromDataSource;
/// Serializes this [GlobalTypeInferenceElementData] to [sink].
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain);
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain);
/// Compresses the inner representation by removing [AbstractValue] mappings
/// to `null`. Returns the data object itself or `null` if the data object
@@ -109,17 +112,20 @@
abstract class GlobalTypeInferenceResults {
/// Deserializes a [GlobalTypeInferenceResults] object from [source].
factory GlobalTypeInferenceResults.readFromDataSource(
- DataSource source, JClosedWorld closedWorld, InferredData inferredData) {
+ DataSource source,
+ JsToElementMap elementMap,
+ JClosedWorld closedWorld,
+ InferredData inferredData) {
bool isTrivial = source.readBool();
if (isTrivial) {
return new TrivialGlobalTypeInferenceResults(closedWorld);
}
return new GlobalTypeInferenceResultsImpl.readFromDataSource(
- source, closedWorld, inferredData);
+ source, elementMap, closedWorld, inferredData);
}
/// Serializes this [GlobalTypeInferenceResults] to [sink].
- void writeToDataSink(DataSink sink);
+ void writeToDataSink(DataSink sink, JsToElementMap elementMap);
JClosedWorld get closedWorld;
@@ -217,12 +223,17 @@
_trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
factory GlobalTypeInferenceResultsImpl.readFromDataSource(
- DataSource source, JClosedWorld closedWorld, InferredData inferredData) {
+ DataSource source,
+ JsToElementMap elementMap,
+ JClosedWorld closedWorld,
+ InferredData inferredData) {
source.begin(tag);
Map<MemberEntity, GlobalTypeInferenceMemberResult> memberResults =
- source.readMemberMap(() =>
+ source.readMemberMap((MemberEntity member) =>
new GlobalTypeInferenceMemberResult.readFromDataSource(
- source, closedWorld.abstractValueDomain));
+ source,
+ elementMap.getMemberContextNode(member),
+ closedWorld.abstractValueDomain));
Map<Local, AbstractValue> parameterResults = source.readLocalMap(() =>
closedWorld.abstractValueDomain
.readAbstractValueFromDataSource(source));
@@ -244,13 +255,16 @@
}
@override
- void writeToDataSink(DataSink sink) {
+ void writeToDataSink(DataSink sink, JsToElementMap elementMap) {
sink.writeBool(false); // Is _not_ trivial.
sink.begin(tag);
sink.writeMemberMap(
memberResults,
- (GlobalTypeInferenceMemberResult result) =>
- result.writeToDataSink(sink, closedWorld.abstractValueDomain));
+ (MemberEntity member, GlobalTypeInferenceMemberResult result) =>
+ result.writeToDataSink(
+ sink,
+ elementMap.getMemberContextNode(member),
+ closedWorld.abstractValueDomain));
sink.writeLocalMap(
parameterResults,
(AbstractValue value) => closedWorld.abstractValueDomain
@@ -395,11 +409,13 @@
{this.throwsAlways, this.isCalledOnce});
factory GlobalTypeInferenceMemberResultImpl.readFromDataSource(
- DataSource source, AbstractValueDomain abstractValueDomain) {
+ DataSource source,
+ ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
source.begin(tag);
GlobalTypeInferenceElementData data = source.readValueOrNull(() {
return new GlobalTypeInferenceElementData.readFromDataSource(
- source, abstractValueDomain);
+ source, context, abstractValueDomain);
});
AbstractValue returnType =
abstractValueDomain.readAbstractValueFromDataSource(source);
@@ -413,10 +429,11 @@
}
@override
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
sink.begin(tag);
sink.writeValueOrNull(_data, (GlobalTypeInferenceElementData data) {
- data.writeToDataSink(sink, abstractValueDomain);
+ data.writeToDataSink(sink, context, abstractValueDomain);
});
abstractValueDomain.writeAbstractValueToDataSink(sink, returnType);
abstractValueDomain.writeAbstractValueToDataSink(sink, type);
@@ -453,7 +470,7 @@
_trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
@override
- void writeToDataSink(DataSink sink) {
+ void writeToDataSink(DataSink sink, JsToElementMap elementMap) {
sink.writeBool(true); // Is trivial.
}
@@ -516,7 +533,8 @@
bool get isCalledOnce => false;
@override
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
throw new UnsupportedError(
"TrivialGlobalTypeInferenceMemberResult.writeToDataSink");
}
@@ -559,7 +577,8 @@
bool get isCalledOnce => false;
@override
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
throw new UnsupportedError(
"DeadFieldGlobalTypeInferenceResult.writeToDataSink");
}
@@ -602,7 +621,8 @@
bool get isCalledOnce => false;
@override
- void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+ void writeToDataSink(DataSink sink, ir.Member context,
+ AbstractValueDomain abstractValueDomain) {
throw new UnsupportedError(
"DeadFieldGlobalTypeInferenceResult.writeToDataSink");
}
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 79a7960..7276ae4 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -574,7 +574,7 @@
emptyAsNull: true);
_fieldInitializers = source.readMemberNodes(emptyAsNull: true);
_fieldConstantInitializers =
- source.readMemberMap(() => source.readTreeNodes(), emptyAsNull: true);
+ source.readMemberNodeMap(source.readTreeNodes, emptyAsNull: true);
_typeLiterals = source.readList(
() => new _TypeLiteral.fromDataSource(source),
emptyAsNull: true);
diff --git a/pkg/compiler/lib/src/ir/static_type_cache.dart b/pkg/compiler/lib/src/ir/static_type_cache.dart
index 64cf6b8..2e25d65 100644
--- a/pkg/compiler/lib/src/ir/static_type_cache.dart
+++ b/pkg/compiler/lib/src/ir/static_type_cache.dart
@@ -19,22 +19,28 @@
const StaticTypeCache(
[this._expressionTypes = const {}, this._forInIteratorTypes]);
- factory StaticTypeCache.readFromDataSource(DataSource source) {
- source.begin(tag);
- Map<ir.Expression, ir.DartType> expressionTypes =
- source.readTreeNodeMap(source.readDartTypeNode);
- Map<ir.ForInStatement, ir.DartType> forInIteratorTypes =
- source.readTreeNodeMap(source.readDartTypeNode, emptyAsNull: true);
- source.end(tag);
- return new StaticTypeCache(expressionTypes, forInIteratorTypes);
+ factory StaticTypeCache.readFromDataSource(
+ DataSource source, ir.Member context) {
+ return source.inMemberContext(context, () {
+ source.begin(tag);
+ Map<ir.Expression, ir.DartType> expressionTypes =
+ source.readTreeNodeMapInContext(source.readDartTypeNode);
+ Map<ir.ForInStatement, ir.DartType> forInIteratorTypes = source
+ .readTreeNodeMapInContext(source.readDartTypeNode, emptyAsNull: true);
+ source.end(tag);
+ return new StaticTypeCache(expressionTypes, forInIteratorTypes);
+ });
}
- void writeToDataSink(DataSink sink) {
- sink.begin(tag);
- sink.writeTreeNodeMap(_expressionTypes, sink.writeDartTypeNode);
- sink.writeTreeNodeMap(_forInIteratorTypes, sink.writeDartTypeNode,
- allowNull: true);
- sink.end(tag);
+ void writeToDataSink(DataSink sink, ir.Member context) {
+ sink.inMemberContext(context, () {
+ sink.begin(tag);
+ sink.writeTreeNodeMapInContext(_expressionTypes, sink.writeDartTypeNode);
+ sink.writeTreeNodeMapInContext(
+ _forInIteratorTypes, sink.writeDartTypeNode,
+ allowNull: true);
+ sink.end(tag);
+ });
}
ir.DartType operator [](ir.Expression node) => _expressionTypes[node];
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 1464c0b..97678ca 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -268,7 +268,8 @@
factory AnnotationsDataImpl.readFromDataSource(DataSource source) {
source.begin(tag);
Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations =
- source.readMemberMap(() => new EnumSet.fromValue(source.readInt()));
+ source.readMemberMap(
+ (MemberEntity member) => new EnumSet.fromValue(source.readInt()));
source.end(tag);
return new AnnotationsDataImpl(pragmaAnnotations);
}
@@ -276,7 +277,8 @@
@override
void writeToDataSink(DataSink sink) {
sink.begin(tag);
- sink.writeMemberMap(pragmaAnnotations, (EnumSet<PragmaAnnotation> set) {
+ sink.writeMemberMap(pragmaAnnotations,
+ (MemberEntity member, EnumSet<PragmaAnnotation> set) {
sink.writeInt(set.value);
});
sink.end(tag);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 5e22b23..b367d3a 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -20,6 +20,7 @@
import 'checked_mode_helpers.dart';
import 'namer.dart';
import 'runtime_types.dart';
+import 'runtime_types_new.dart';
abstract class FunctionCompiler {
void initialize(
@@ -305,6 +306,7 @@
CheckedModeHelpers get checkedModeHelpers;
RuntimeTypesSubstitutions get rtiSubstitutions;
RuntimeTypesEncoder get rtiEncoder;
+ RecipeEncoder get rtiRecipeEncoder;
Tracer get tracer;
RuntimeTypeTags get rtiTags;
FixedNames get fixedNames;
@@ -321,6 +323,9 @@
final RuntimeTypesEncoder rtiEncoder;
@override
+ final RecipeEncoder rtiRecipeEncoder;
+
+ @override
final Tracer tracer;
@override
@@ -329,6 +334,6 @@
@override
final FixedNames fixedNames;
- CodegenInputsImpl(this.rtiSubstitutions, this.rtiEncoder, this.tracer,
- this.rtiTags, this.fixedNames);
+ CodegenInputsImpl(this.rtiSubstitutions, this.rtiEncoder,
+ this.rtiRecipeEncoder, this.tracer, this.rtiTags, this.fixedNames);
}
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 9f683b7..f1ff33f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -101,7 +101,7 @@
_commonElements.getRuntimeTypeArgumentIntercepted,
_commonElements.getRuntimeTypeArgument,
_commonElements.getTypeArgumentByIndex,
- ]);
+ ], otherImpacts: newRtiImpacts('getRuntimeTypeArgument'));
}
BackendImpact _computeSignature;
@@ -165,7 +165,8 @@
BackendImpact get typeVariableBoundCheck {
return _typeVariableBoundCheck ??= new BackendImpact(staticUses: [
_commonElements.throwTypeError,
- _commonElements.assertIsSubtype
+ _commonElements.assertIsSubtype,
+ if (_newRti) _commonElements.checkTypeBound,
]);
}
@@ -189,7 +190,7 @@
BackendImpact get asCheck {
return _asCheck ??= new BackendImpact(staticUses: [
_commonElements.throwRuntimeError,
- ], otherImpacts: _newRti ? [usesNewRti] : []);
+ ], otherImpacts: newRtiImpacts('asCheck'));
}
BackendImpact _throwNoSuchMethod;
@@ -423,9 +424,12 @@
BackendImpact _typeLiteral;
BackendImpact get typeLiteral {
- return _typeLiteral ??= new BackendImpact(
- instantiatedClasses: [_commonElements.typeLiteralClass],
- staticUses: [_commonElements.createRuntimeType]);
+ return _typeLiteral ??= new BackendImpact(instantiatedClasses: [
+ _commonElements.typeLiteralClass
+ ], staticUses: [
+ _commonElements.createRuntimeType,
+ if (_newRti) _commonElements.typeLiteralMaker,
+ ]);
}
BackendImpact _stackTraceInCatch;
@@ -762,15 +766,17 @@
_commonElements.getInstantiationClass(typeArgumentCount),
]);
- BackendImpact _usesNewRti;
-
/// Backend impact for --experiment-new-rti.
- BackendImpact get usesNewRti {
- // TODO(sra): Can this be broken down into more selective impacts?
- return _usesNewRti ??= BackendImpact(staticUses: [
- _commonElements.findType,
- _commonElements.rtiEvalMethod,
- _commonElements.rtiBindMethod,
- ]);
+ List<BackendImpact> newRtiImpacts(String what) {
+ if (!_newRti) return [];
+ // TODO(sra): Split into refined impacts.
+ return [
+ BackendImpact(staticUses: [
+ _commonElements.findType,
+ _commonElements.instanceType,
+ _commonElements.rtiEvalMethod,
+ _commonElements.rtiBindMethod,
+ ])
+ ];
}
}
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 2306ad6..c77257b 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -182,12 +182,10 @@
helper, helper.parameterStructure.callStructure));
}
if (type.element == _commonElements.typeLiteralClass) {
- // If we use a type literal in a constant, the compile time
- // constant emitter will generate a call to the createRuntimeType
- // helper so we register a use of that.
- FunctionEntity helper = _commonElements.createRuntimeType;
- impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
- helper, helper.parameterStructure.callStructure));
+ // If we use a type literal in a constant, the compile time constant
+ // emitter will generate a call to a helper so we register the impact
+ // that contains that call.
+ _impacts.typeLiteral.registerImpact(impactBuilder, _elementEnvironment);
}
}
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 06ec784..943b3932 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -13,9 +13,11 @@
import '../js/js.dart' show js;
import '../js_backend/field_analysis.dart';
import '../js_emitter/code_emitter_task.dart';
+import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
import '../options.dart';
import 'field_analysis.dart' show JFieldAnalysis;
import 'runtime_types.dart';
+import 'runtime_types_new.dart' show RecipeEncoder;
typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
@@ -205,6 +207,7 @@
final JElementEnvironment _elementEnvironment;
final RuntimeTypesNeed _rtiNeed;
final RuntimeTypesEncoder _rtiEncoder;
+ final RecipeEncoder _rtiRecipeEncoder;
final JFieldAnalysis _fieldAnalysis;
final Emitter _emitter;
final _ConstantReferenceGenerator _constantReferenceGenerator;
@@ -219,6 +222,7 @@
this._elementEnvironment,
this._rtiNeed,
this._rtiEncoder,
+ this._rtiRecipeEncoder,
this._fieldAnalysis,
this._emitter,
this._constantReferenceGenerator,
@@ -354,19 +358,34 @@
jsAst.Expression visitType(TypeConstantValue constant, [_]) {
DartType type = constant.representedType.unaliased;
- jsAst.Expression unexpected(TypeVariableType _variable) {
- TypeVariableType variable = _variable;
- throw failedAt(
- NO_LOCATION_SPANNABLE,
- "Unexpected type variable '${variable}'"
- " in constant '${constant.toDartText()}'");
+ if (_options.experimentNewRti) {
+ assert(!type.containsTypeVariables);
+
+ jsAst.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
+ _emitter, TypeExpressionRecipe(type));
+
+ // Generate `typeLiteral(recipe)`.
+
+ // TODO(sra): `typeLiteral(r)` calls `createRuntimeType(findType(r))`.
+ // Find a way to share the `findType` call with methods that also use the
+ // type.
+ return js('#(#)',
+ [getHelperProperty(_commonElements.typeLiteralMaker), recipe]);
+ } else {
+ jsAst.Expression unexpected(TypeVariableType _variable) {
+ TypeVariableType variable = _variable;
+ throw failedAt(
+ NO_LOCATION_SPANNABLE,
+ "Unexpected type variable '${variable}'"
+ " in constant '${constant.toDartText()}'");
+ }
+
+ jsAst.Expression rti =
+ _rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
+
+ return new jsAst.Call(
+ getHelperProperty(_commonElements.createRuntimeType), [rti]);
}
-
- jsAst.Expression rti =
- _rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
-
- return new jsAst.Call(
- getHelperProperty(_commonElements.createRuntimeType), [rti]);
}
@override
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 77aa43e..aa2c328 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -235,8 +235,8 @@
factory JFieldAnalysis.readFromDataSource(
DataSource source, CompilerOptions options) {
source.begin(tag);
- Map<FieldEntity, FieldAnalysisData> fieldData = source
- .readMemberMap(() => new FieldAnalysisData.fromDataSource(source));
+ Map<FieldEntity, FieldAnalysisData> fieldData = source.readMemberMap(
+ (MemberEntity member) => new FieldAnalysisData.fromDataSource(source));
source.end(tag);
return new JFieldAnalysis._(fieldData);
}
@@ -245,7 +245,9 @@
void writeToDataSink(DataSink sink) {
sink.begin(tag);
sink.writeMemberMap(
- _fieldData, (FieldAnalysisData data) => data.writeToDataSink(sink));
+ _fieldData,
+ (MemberEntity member, FieldAnalysisData data) =>
+ data.writeToDataSink(sink));
sink.end(tag);
}
diff --git a/pkg/compiler/lib/src/js_backend/inferred_data.dart b/pkg/compiler/lib/src/js_backend/inferred_data.dart
index be9b3dc..b84035c 100644
--- a/pkg/compiler/lib/src/js_backend/inferred_data.dart
+++ b/pkg/compiler/lib/src/js_backend/inferred_data.dart
@@ -103,8 +103,8 @@
DataSource source, JClosedWorld closedWorld) {
source.begin(tag);
Set<MemberEntity> functionsCalledInLoop = source.readMembers().toSet();
- Map<FunctionEntity, SideEffects> sideEffects =
- source.readMemberMap(() => new SideEffects.readFromDataSource(source));
+ Map<FunctionEntity, SideEffects> sideEffects = source.readMemberMap(
+ (MemberEntity member) => new SideEffects.readFromDataSource(source));
Set<FunctionEntity> sideEffectsFreeElements =
source.readMembers<FunctionEntity>().toSet();
Set<FunctionEntity> elementsThatCannotThrow =
@@ -126,8 +126,10 @@
sink.writeBool(false); // Is _not_ trivial.
sink.begin(tag);
sink.writeMembers(_functionsCalledInLoop);
- sink.writeMemberMap(_sideEffects,
- (SideEffects sideEffects) => sideEffects.writeToDataSink(sink));
+ sink.writeMemberMap(
+ _sideEffects,
+ (MemberEntity member, SideEffects sideEffects) =>
+ sideEffects.writeToDataSink(sink));
sink.writeMembers(_sideEffectsFreeElements);
sink.writeMembers(_elementsThatCannotThrow);
sink.writeMembers(_functionsThatMightBePassedToApply);
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index f405dc0..dd8c765 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -140,6 +140,8 @@
CompoundName(this._parts);
+ CompoundName.from(List<jsAst.Name> parts) : this(<_NamerName>[...parts]);
+
@override
String get name {
if (_cachedName == null) {
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 3342b54..cc517d2 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -348,7 +348,7 @@
source.readClassMap(source.readString);
Set<ClassEntity> anonymousJsInteropClasses = source.readClasses().toSet();
Map<MemberEntity, String> jsInteropMembers =
- source.readMemberMap(source.readString);
+ source.readMemberMap((MemberEntity member) => source.readString());
source.end(tag);
return new NativeBasicDataImpl(
elementEnvironment,
@@ -369,7 +369,8 @@
sink.writeLibraryMap(jsInteropLibraries, sink.writeString);
sink.writeClassMap(jsInteropClasses, sink.writeString);
sink.writeClasses(anonymousJsInteropClasses);
- sink.writeMemberMap(jsInteropMembers, sink.writeString);
+ sink.writeMemberMap(jsInteropMembers,
+ (MemberEntity member, String name) => sink.writeString(name));
sink.end(tag);
}
@@ -576,13 +577,16 @@
NativeBasicData nativeBasicData =
new NativeBasicData.readFromDataSource(source, elementEnvironment);
Map<MemberEntity, String> nativeMemberName =
- source.readMemberMap(source.readString);
- Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = source
- .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
- Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = source
- .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
- Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = source
- .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
+ source.readMemberMap((MemberEntity member) => source.readString());
+ Map<FunctionEntity, NativeBehavior> nativeMethodBehavior =
+ source.readMemberMap((MemberEntity member) =>
+ new NativeBehavior.readFromDataSource(source));
+ Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior =
+ source.readMemberMap((MemberEntity member) =>
+ new NativeBehavior.readFromDataSource(source));
+ Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior =
+ source.readMemberMap((MemberEntity member) =>
+ new NativeBehavior.readFromDataSource(source));
source.end(tag);
return new NativeDataImpl(
nativeBasicData,
@@ -597,16 +601,20 @@
sink.begin(tag);
_nativeBasicData.writeToDataSink(sink);
- sink.writeMemberMap(nativeMemberName, sink.writeString);
+ sink.writeMemberMap(nativeMemberName,
+ (MemberEntity member, String name) => sink.writeString(name));
- sink.writeMemberMap(nativeMethodBehavior, (NativeBehavior behavior) {
+ sink.writeMemberMap(nativeMethodBehavior,
+ (MemberEntity member, NativeBehavior behavior) {
behavior.writeToDataSink(sink);
});
- sink.writeMemberMap(nativeFieldLoadBehavior, (NativeBehavior behavior) {
+ sink.writeMemberMap(nativeFieldLoadBehavior,
+ (MemberEntity member, NativeBehavior behavior) {
behavior.writeToDataSink(sink);
});
- sink.writeMemberMap(nativeFieldStoreBehavior, (NativeBehavior behavior) {
+ sink.writeMemberMap(nativeFieldStoreBehavior,
+ (MemberEntity member, NativeBehavior behavior) {
behavior.writeToDataSink(sink);
});
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
new file mode 100644
index 0000000..4135d60
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -0,0 +1,381 @@
+// 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.
+
+library js_backend.runtime_types_new;
+
+import 'package:js_runtime/shared/recipe_syntax.dart';
+
+import '../common_elements.dart' show JCommonElements, JElementEnvironment;
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../js_model/type_recipe.dart';
+import '../js_emitter/js_emitter.dart' show ModularEmitter;
+import '../universe/class_hierarchy.dart';
+import '../world.dart';
+import 'namer.dart';
+import 'native_data.dart';
+
+import 'runtime_types.dart' show RuntimeTypesNeed, RuntimeTypesSubstitutions;
+
+abstract class RecipeEncoder {
+ /// Returns a [jsAst.Expression] representing the given [recipe] to be
+ /// evaluated against a type environment with shape [structure].
+ jsAst.Expression encodeRecipe(ModularEmitter emitter,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
+
+ jsAst.Expression encodeGroundRecipe(
+ ModularEmitter emitter, TypeRecipe recipe);
+
+ // TODO(sra): Still need a $signature function when the function type is a
+ // function of closed type variables. See if the $signature method can always
+ // be generated through SSA in those cases.
+ jsAst.Expression encodeSignature(ModularNamer namer, ModularEmitter emitter,
+ DartType type, jsAst.Expression this_);
+}
+
+class RecipeEncoderImpl implements RecipeEncoder {
+ final JClosedWorld _closedWorld;
+ final RuntimeTypesSubstitutions _rtiSubstitutions;
+ final NativeBasicData _nativeData;
+ final JElementEnvironment _elementEnvironment;
+ final JCommonElements commonElements;
+ final RuntimeTypesNeed _rtiNeed;
+
+ RecipeEncoderImpl(this._closedWorld, this._rtiSubstitutions, this._nativeData,
+ this._elementEnvironment, this.commonElements, this._rtiNeed);
+
+ @override
+ jsAst.Expression encodeRecipe(ModularEmitter emitter,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
+ return _RecipeGenerator(this, emitter, environmentStructure, recipe).run();
+ }
+
+ @override
+ jsAst.Expression encodeGroundRecipe(
+ ModularEmitter emitter, TypeRecipe recipe) {
+ return _RecipeGenerator(this, emitter, null, recipe).run();
+ }
+
+ @override
+ jsAst.Expression encodeSignature(ModularNamer namer, ModularEmitter emitter,
+ DartType type, jsAst.Expression this_) {
+ // TODO(sra): These inputs (referenced to quell lints) are used by the old
+ // rti signature generator. Do we need them?
+ _rtiNeed;
+ commonElements;
+ _elementEnvironment;
+ throw UnimplementedError('RecipeEncoderImpl.getSignatureEncoding');
+ }
+}
+
+class _RecipeGenerator implements DartTypeVisitor<void, void> {
+ final RecipeEncoderImpl _encoder;
+ final ModularEmitter _emitter;
+ final TypeEnvironmentStructure _environment;
+ final TypeRecipe _recipe;
+
+ final List<FunctionTypeVariable> functionTypeVariables = [];
+
+ // Accumulated recipe.
+ final List<jsAst.Literal> _fragments = [];
+ final List<int> _codes = [];
+
+ _RecipeGenerator(
+ this._encoder, this._emitter, this._environment, this._recipe);
+
+ JClosedWorld get _closedWorld => _encoder._closedWorld;
+ NativeBasicData get _nativeData => _encoder._nativeData;
+ RuntimeTypesSubstitutions get _rtiSubstitutions => _encoder._rtiSubstitutions;
+
+ jsAst.Expression run() {
+ _start(_recipe);
+ assert(functionTypeVariables.isEmpty);
+ if (_fragments.isEmpty) {
+ return js.string(String.fromCharCodes(_codes));
+ }
+ _flushCodes();
+ jsAst.LiteralString quote = jsAst.LiteralString('"');
+ return jsAst.StringConcatenation([quote, ..._fragments, quote]);
+ }
+
+ void _start(TypeRecipe recipe) {
+ if (recipe is TypeExpressionRecipe) {
+ visit(recipe.type, null);
+ } else if (recipe is SingletonTypeEnvironmentRecipe) {
+ visit(recipe.type, null);
+ } else if (recipe is FullTypeEnvironmentRecipe) {
+ _startFullTypeEnvironmentRecipe(recipe, null);
+ }
+ }
+
+ void _startFullTypeEnvironmentRecipe(FullTypeEnvironmentRecipe recipe, _) {
+ if (recipe.classType == null) {
+ _emitCode(Recipe.pushDynamic);
+ assert(recipe.types.isNotEmpty);
+ } else {
+ visit(recipe.classType, null);
+ // TODO(sra): The separator can be omitted when the parser will have
+ // reduced to the top of stack to an Rti value.
+ _emitCode(Recipe.toType);
+ }
+
+ if (recipe.types.isNotEmpty) {
+ _emitCode(Recipe.startTypeArguments);
+ bool first = true;
+ for (DartType type in recipe.types) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ visit(type, _);
+ first = false;
+ }
+ _emitCode(Recipe.endTypeArguments);
+ }
+ }
+
+ void _emitCode(int code) {
+ // TODO(sra): We should permit codes with short escapes (like '\n') for
+ // infrequent operators.
+ assert(code >= 0x20 && code <= 0x7E && code != 0x22);
+ _codes.add(code);
+ }
+
+ void _flushCodes() {
+ if (_codes.isEmpty) return;
+ // TODO(sra): codes need some escaping.
+ _fragments.add(StringBackedName(String.fromCharCodes(_codes)));
+ _codes.clear();
+ }
+
+ void _emitInteger(int value) {
+ if (_codes.isEmpty ? _fragments.isNotEmpty : Recipe.isDigit(_codes.last)) {
+ _emitCode(Recipe.separator);
+ }
+ _emitStringUnescaped('$value');
+ }
+
+ void _emitStringUnescaped(String string) {
+ for (int code in string.codeUnits) {
+ _emitCode(code);
+ }
+ }
+
+ void _emitName(jsAst.Name name) {
+ if (_fragments.isNotEmpty && _codes.isEmpty) {
+ _emitCode(Recipe.separator);
+ }
+ _flushCodes();
+ _fragments.add(name);
+ }
+
+ void _emitExtensionOp(int value) {
+ _emitInteger(value);
+ _emitCode(Recipe.extensionOp);
+ }
+
+ @override
+ void visit(DartType type, _) => type.accept(this, _);
+
+ @override
+ void visitTypeVariableType(TypeVariableType type, _) {
+ TypeEnvironmentStructure environment = _environment;
+ if (environment is SingletonTypeEnvironmentStructure) {
+ if (type == environment.variable) {
+ _emitInteger(0);
+ return;
+ }
+ }
+ if (environment is FullTypeEnvironmentStructure) {
+ int i = environment.bindings.indexOf(type);
+ if (i >= 0) {
+ // Indexes are 1-based since '0' encodes using the entire type for the
+ // singleton structure.
+ _emitInteger(i + 1);
+ return;
+ }
+
+ int index = _indexIntoClassTypeVariables(type);
+ if (index != null) {
+ // Indexed class type variables come after the bound function type
+ // variables.
+ _emitInteger(1 + environment.bindings.length + index);
+ return;
+ }
+ // TODO(sra): Encode type variables names via namer.
+ }
+ // TODO(sra): Handle missing cases. This just emits some readable junk. The
+ // backticks ensure it won't parse at runtime.
+ '`$type`'.codeUnits.forEach(_emitCode);
+ }
+
+ int /*?*/ _indexIntoClassTypeVariables(TypeVariableType variable) {
+ TypeVariableEntity element = variable.element;
+ ClassEntity cls = element.typeDeclaration;
+
+ // 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;
+
+ ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
+ if (classHierarchy.anyStrictSubclassOf(cls, (ClassEntity subclass) {
+ return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
+ })) {
+ return null;
+ }
+ return element.index;
+ }
+
+ @override
+ void visitFunctionTypeVariable(FunctionTypeVariable type, _) {
+ int position = functionTypeVariables.indexOf(type);
+ assert(position >= 0);
+ // See [visitFunctionType] for explanation.
+ _emitInteger(functionTypeVariables.length - position - 1);
+ _emitCode(Recipe.genericFunctionTypeParameterIndex);
+ }
+
+ @override
+ void visitDynamicType(DynamicType type, _) {
+ _emitCode(Recipe.pushDynamic);
+ }
+
+ @override
+ void visitInterfaceType(InterfaceType type, _) {
+ jsAst.Name name = _emitter.typeAccessNewRti(type.element);
+ if (type.typeArguments.isEmpty) {
+ // Push the name, which is later converted by an implicit toType
+ // operation.
+ _emitName(name);
+ } else {
+ _emitName(name);
+ _emitCode(Recipe.startTypeArguments);
+ bool first = true;
+ for (DartType argumentType in type.typeArguments) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ if (_nativeData.isJsInteropClass(type.element)) {
+ // Emit 'any' type.
+ _emitExtensionOp(Recipe.pushAnyExtension);
+ } else {
+ visit(argumentType, _);
+ }
+ first = false;
+ }
+ _emitCode(Recipe.endTypeArguments);
+ }
+ }
+
+ @override
+ void visitFunctionType(FunctionType type, _) {
+ if (type.typeVariables.isNotEmpty) {
+ // Enter generic function scope.
+ //
+ // Function type variables are encoded as a modified de Bruin index. We
+ // count variables from the current scope outwards, counting the variables
+ // in the same scope left-to-right.
+ //
+ // If we push the current scope's variables in reverse, then the index is
+ // the position measured from the end.
+ //
+ // foo<AA,BB>() => ...
+ // //^0 ^1
+ // functionTypeVariables: [BB,AA]
+ //
+ // foo<AA,BB>() => <UU,VV,WW>() => ...
+ // ^3 ^4 ^0 ^1 ^2
+ // functionTypeVariables: [BB,AA,WW,VV,UU]
+ //
+ for (FunctionTypeVariable variable in type.typeVariables.reversed) {
+ functionTypeVariables.add(variable);
+ }
+ }
+
+ visit(type.returnType, _);
+ _emitCode(Recipe.startFunctionArguments);
+
+ bool first = true;
+ for (DartType parameterType in type.parameterTypes) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ visit(parameterType, _);
+ first = false;
+ }
+
+ if (type.optionalParameterTypes.isNotEmpty) {
+ first = true;
+ _emitCode(Recipe.startOptionalGroup);
+ for (DartType parameterType in type.optionalParameterTypes) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ visit(parameterType, _);
+ first = false;
+ }
+ _emitCode(Recipe.endOptionalGroup);
+ }
+
+ void emitNamedGroup(List<String> names, List<DartType> types) {
+ assert(names.length == types.length);
+ first = true;
+ _emitCode(Recipe.startNamedGroup);
+ for (int i = 0; i < names.length; i++) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ _emitStringUnescaped(names[i]);
+ _emitCode(Recipe.nameSeparator);
+ visit(types[i], _);
+ first = false;
+ }
+ _emitCode(Recipe.endNamedGroup);
+ }
+
+ // TODO(sra): These are optional named parameters. Handle required named
+ // parameters the same way when they are implemented.
+ if (type.namedParameterTypes.isNotEmpty) {
+ emitNamedGroup(type.namedParameters, type.namedParameterTypes);
+ }
+
+ _emitCode(Recipe.endFunctionArguments);
+
+ // Emit generic type bounds.
+ if (type.typeVariables.isNotEmpty) {
+ bool first = true;
+ _emitCode(Recipe.startTypeArguments);
+ for (FunctionTypeVariable typeVariable in type.typeVariables) {
+ if (!first) {
+ _emitCode(Recipe.separator);
+ }
+ visit(typeVariable.bound, _);
+ }
+ _emitCode(Recipe.endTypeArguments);
+ }
+
+ if (type.typeVariables.isNotEmpty) {
+ // Exit generic function scope. Remove the type variables pushed at entry.
+ functionTypeVariables.length -= type.typeVariables.length;
+ }
+ }
+
+ @override
+ void visitVoidType(VoidType type, _) {
+ _emitCode(Recipe.pushVoid);
+ }
+
+ @override
+ void visitTypedefType(TypedefType type, _) {
+ visit(type.unaliased, _);
+ }
+
+ @override
+ void visitFutureOrType(FutureOrType type, _) {
+ visit(type.typeArgument, _);
+ _emitCode(Recipe.wrapFutureOr);
+ }
+}
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index c9b0ec1..62e9ab0 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -90,6 +90,7 @@
namer,
closedWorld,
codegen.rtiEncoder,
+ codegen.rtiRecipeEncoder,
_backendStrategy.sourceInformationStrategy,
this,
_generateSourceMap);
@@ -179,6 +180,9 @@
/// Returns the JS expression representing the type [e].
jsAst.Expression typeAccess(Entity e);
+ /// Returns the JS name representing the type [e].
+ jsAst.Name typeAccessNewRti(Entity e);
+
/// Returns the JS code for accessing the embedded [global].
jsAst.Expression generateEmbeddedGlobalAccess(String global);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index c664a0f..8752178 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -17,6 +17,7 @@
import '../../js_backend/constant_emitter.dart';
import '../../js_backend/namer.dart';
import '../../js_backend/runtime_types.dart';
+import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
import '../../options.dart';
import '../../universe/codegen_world_builder.dart' show CodegenWorld;
import '../../world.dart' show JClosedWorld;
@@ -86,6 +87,11 @@
}
@override
+ js.Name typeAccessNewRti(Entity element) {
+ return _namer.globalPropertyNameForType(element);
+ }
+
+ @override
js.Expression staticClosureAccess(FunctionEntity element) {
return new js.Call(
new js.PropertyAccess(_namer.readGlobalObjectForMember(element),
@@ -138,6 +144,7 @@
final DiagnosticReporter _reporter;
final JClosedWorld _closedWorld;
final RuntimeTypesEncoder _rtiEncoder;
+ final RecipeEncoder _rtiRecipeEncoder;
final CompilerTask _task;
ModelEmitter _emitter;
@@ -152,6 +159,7 @@
Namer namer,
this._closedWorld,
this._rtiEncoder,
+ this._rtiRecipeEncoder,
SourceInformationStrategy sourceInformationStrategy,
this._task,
bool shouldGenerateSourceMap)
@@ -167,6 +175,7 @@
this,
sourceInformationStrategy,
_rtiEncoder,
+ _rtiRecipeEncoder,
shouldGenerateSourceMap);
}
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index fd8db9b..e5643a5 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -49,6 +49,7 @@
show Namer, ConstantEmitter, StringBackedName;
import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
import '../../js_backend/runtime_types.dart';
+import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
import '../../options.dart';
import '../../universe/codegen_world_builder.dart' show CodegenWorld;
import '../../world.dart';
@@ -99,6 +100,7 @@
this._emitter,
this._sourceInformationStrategy,
RuntimeTypesEncoder rtiEncoder,
+ RecipeEncoder rtiRecipeEncoder,
this._shouldGenerateSourceMap)
: _constantOrdering = new ConstantOrdering(_closedWorld.sorter) {
this._constantEmitter = new ConstantEmitter(
@@ -107,6 +109,7 @@
_closedWorld.elementEnvironment,
_closedWorld.rtiNeed,
rtiEncoder,
+ rtiRecipeEncoder,
_closedWorld.fieldAnalysis,
_emitter,
this.generateConstantReference,
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 2ee5d5c..32f7f78 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -49,12 +49,13 @@
JsToElementMap elementMap, DataSource source) {
source.begin(tag);
// TODO(johnniwinther): Support shared [ScopeInfo].
- Map<MemberEntity, ScopeInfo> scopeMap =
- source.readMemberMap(() => new ScopeInfo.readFromDataSource(source));
+ Map<MemberEntity, ScopeInfo> scopeMap = source.readMemberMap(
+ (MemberEntity member) => new ScopeInfo.readFromDataSource(source));
Map<ir.TreeNode, CapturedScope> capturedScopesMap = source
.readTreeNodeMap(() => new CapturedScope.readFromDataSource(source));
- Map<MemberEntity, CapturedScope> capturedScopeForSignatureMap = source
- .readMemberMap(() => new CapturedScope.readFromDataSource(source));
+ Map<MemberEntity, CapturedScope> capturedScopeForSignatureMap =
+ source.readMemberMap((MemberEntity member) =>
+ new CapturedScope.readFromDataSource(source));
Map<ir.LocalFunction, ClosureRepresentationInfo>
localClosureRepresentationMap = source.readTreeNodeMap(
() => new ClosureRepresentationInfo.readFromDataSource(source));
@@ -67,13 +68,15 @@
@override
void writeToDataSink(DataSink sink) {
sink.begin(tag);
- sink.writeMemberMap(
- _scopeMap, (ScopeInfo info) => info.writeToDataSink(sink));
+ sink.writeMemberMap(_scopeMap,
+ (MemberEntity member, ScopeInfo info) => info.writeToDataSink(sink));
sink.writeTreeNodeMap(_capturedScopesMap, (CapturedScope scope) {
scope.writeToDataSink(sink);
});
- sink.writeMemberMap(_capturedScopeForSignatureMap,
- (CapturedScope scope) => scope.writeToDataSink(sink));
+ sink.writeMemberMap(
+ _capturedScopeForSignatureMap,
+ (MemberEntity member, CapturedScope scope) =>
+ scope.writeToDataSink(sink));
sink.writeTreeNodeMap(_localClosureRepresentationMap,
(ClosureRepresentationInfo info) {
info.writeToDataSink(sink);
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 3fb71a4..0a88fbe 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -120,11 +120,14 @@
List<DartType> getDartTypes(List<ir.DartType> types);
/// Returns the definition information for [member].
- MemberDefinition getMemberDefinition(covariant MemberEntity member);
+ MemberDefinition getMemberDefinition(MemberEntity member);
+
+ /// Returns the [ir.Member] containing the definition of [member], if any.
+ ir.Member getMemberContextNode(MemberEntity member);
/// Returns the type of `this` in [member], or `null` if member is defined in
/// a static context.
- InterfaceType getMemberThisType(covariant MemberEntity member);
+ InterfaceType getMemberThisType(MemberEntity member);
/// Returns how [member] has access to type variables of the this type
/// returned by [getMemberThisType].
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index e24352c..692c95e 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -138,7 +138,8 @@
AnnotationsData annotations)
: this.options = _elementMap.options {
_elementEnvironment = new JsElementEnvironment(this);
- _commonElements = new CommonElementsImpl(_elementEnvironment);
+ _commonElements =
+ new CommonElementsImpl(_elementEnvironment, _elementMap.options);
_constantEnvironment = new JsConstantEnvironment(this, environment);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
@@ -317,7 +318,7 @@
JsKernelToElementMap.readFromDataSource(this.options, this.reporter,
Environment environment, ir.Component component, DataSource source) {
_elementEnvironment = new JsElementEnvironment(this);
- _commonElements = new CommonElementsImpl(_elementEnvironment);
+ _commonElements = new CommonElementsImpl(_elementEnvironment, options);
_constantEnvironment = new JsConstantEnvironment(this, environment);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
@@ -437,8 +438,8 @@
source.end(typeVariableDataTag);
source.begin(nestedClosuresTag);
- _nestedClosureMap.addAll(
- source.readMemberMap(() => source.readMembers<IndexedFunction>()));
+ _nestedClosureMap.addAll(source.readMemberMap(
+ (MemberEntity member) => source.readMembers<IndexedFunction>()));
source.end(nestedClosuresTag);
source.end(tag);
@@ -548,7 +549,10 @@
sink.end(typeVariableDataTag);
sink.begin(nestedClosuresTag);
- sink.writeMemberMap(_nestedClosureMap, sink.writeMembers);
+ sink.writeMemberMap(
+ _nestedClosureMap,
+ (MemberEntity member, List<IndexedFunction> functions) =>
+ sink.writeMembers(functions));
sink.end(nestedClosuresTag);
sink.end(tag);
@@ -1673,6 +1677,33 @@
}
@override
+ ir.Member getMemberContextNode(MemberEntity member) {
+ ir.Member getParentMember(ir.TreeNode node) {
+ while (node != null) {
+ if (node is ir.Member) {
+ return node;
+ }
+ node = node.parent;
+ }
+ return null;
+ }
+
+ MemberDefinition definition = getMemberDefinition(member);
+ switch (definition.kind) {
+ case MemberKind.regular:
+ case MemberKind.constructor:
+ case MemberKind.constructorBody:
+ return definition.node;
+ case MemberKind.closureCall:
+ case MemberKind.closureField:
+ case MemberKind.signature:
+ case MemberKind.generatorBody:
+ return getParentMember(definition.node);
+ }
+ throw new UnsupportedError('Unexpected member kind ${definition}');
+ }
+
+ @override
ClassDefinition getClassDefinition(ClassEntity cls) {
return getClassDefinitionInternal(cls);
}
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 9017330..ac096b1 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -678,7 +678,7 @@
MemberDefinition definition =
new MemberDefinition.readFromDataSource(source);
StaticTypeCache staticTypes =
- new StaticTypeCache.readFromDataSource(source);
+ new StaticTypeCache.readFromDataSource(source, node);
source.end(tag);
return new FunctionDataImpl(node, functionNode, definition, staticTypes);
}
@@ -689,7 +689,7 @@
sink.begin(tag);
sink.writeMemberNode(node);
definition.writeToDataSink(sink);
- staticTypes.writeToDataSink(sink);
+ staticTypes.writeToDataSink(sink, node);
sink.end(tag);
}
@@ -877,7 +877,7 @@
MemberDefinition definition =
new MemberDefinition.readFromDataSource(source);
StaticTypeCache staticTypes =
- new StaticTypeCache.readFromDataSource(source);
+ new StaticTypeCache.readFromDataSource(source, node);
source.end(tag);
return new JConstructorDataImpl(
node, functionNode, definition, staticTypes);
@@ -890,7 +890,7 @@
sink.writeMemberNode(node);
definition.writeToDataSink(sink);
assert(constructorBody == null);
- staticTypes.writeToDataSink(sink);
+ staticTypes.writeToDataSink(sink, node);
sink.end(tag);
}
@@ -940,7 +940,7 @@
MemberDefinition definition =
new MemberDefinition.readFromDataSource(source);
StaticTypeCache staticTypes =
- new StaticTypeCache.readFromDataSource(source);
+ new StaticTypeCache.readFromDataSource(source, node);
source.end(tag);
return new ConstructorBodyDataImpl(
node, functionNode, definition, staticTypes);
@@ -952,7 +952,7 @@
sink.begin(tag);
sink.writeMemberNode(node);
definition.writeToDataSink(sink);
- staticTypes.writeToDataSink(sink);
+ staticTypes.writeToDataSink(sink, node);
sink.end(tag);
}
@@ -988,7 +988,7 @@
MemberDefinition definition =
new MemberDefinition.readFromDataSource(source);
StaticTypeCache staticTypes =
- new StaticTypeCache.readFromDataSource(source);
+ new StaticTypeCache.readFromDataSource(source, node);
source.end(tag);
return new JFieldDataImpl(node, definition, staticTypes);
}
@@ -999,7 +999,7 @@
sink.begin(tag);
sink.writeMemberNode(node);
definition.writeToDataSink(sink);
- staticTypes.writeToDataSink(sink);
+ staticTypes.writeToDataSink(sink, node);
sink.end(tag);
}
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 2c0c686..f794857 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -34,6 +34,8 @@
import '../js_backend/interceptor_data.dart';
import '../js_backend/namer.dart';
import '../js_backend/runtime_types.dart';
+import '../js_backend/runtime_types_new.dart'
+ show RecipeEncoder, RecipeEncoderImpl;
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
import '../js/js.dart' as js;
@@ -202,6 +204,7 @@
closedWorld.elementEnvironment,
closedWorld.commonElements,
closedWorld.rtiNeed);
+
RuntimeTypesSubstitutions rtiSubstitutions;
if (_compiler.options.disableRtiOptimization) {
rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(closedWorld);
@@ -213,8 +216,18 @@
rtiSubstitutions = runtimeTypesImpl;
}
- CodegenInputs codegen = new CodegenInputsImpl(
- rtiSubstitutions, rtiEncoder, tracer, rtiTags, fixedNames);
+ RecipeEncoder rtiRecipeEncoder = _compiler.options.experimentNewRti
+ ? new RecipeEncoderImpl(
+ closedWorld,
+ rtiSubstitutions,
+ closedWorld.nativeData,
+ closedWorld.elementEnvironment,
+ closedWorld.commonElements,
+ closedWorld.rtiNeed)
+ : null;
+
+ CodegenInputs codegen = new CodegenInputsImpl(rtiSubstitutions, rtiEncoder,
+ rtiRecipeEncoder, tracer, rtiTags, fixedNames);
functionCompiler.initialize(globalTypeInferenceResults, codegen);
return codegen;
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 3515770..b1beeb8 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -173,8 +173,8 @@
elementMap.lateOutputUnitDataBuilder =
new LateOutputUnitDataBuilder(outputUnitData);
- Map<MemberEntity, MemberAccess> memberAccess =
- source.readMemberMap(() => new MemberAccess.readFromDataSource(source));
+ Map<MemberEntity, MemberAccess> memberAccess = source.readMemberMap(
+ (MemberEntity member) => new MemberAccess.readFromDataSource(source));
source.end(tag);
@@ -228,7 +228,9 @@
closureDataLookup.writeToDataSink(sink);
outputUnitData.writeToDataSink(sink);
sink.writeMemberMap(
- memberAccess, (MemberAccess access) => access.writeToDataSink(sink));
+ memberAccess,
+ (MemberEntity member, MemberAccess access) =>
+ access.writeToDataSink(sink));
sink.end(tag);
}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index ce5aed9..eba6bd9 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -122,7 +122,7 @@
KernelToElementMapImpl(
this.reporter, this._environment, this._frontendStrategy, this.options) {
_elementEnvironment = new KernelElementEnvironment(this);
- _commonElements = new CommonElementsImpl(_elementEnvironment);
+ _commonElements = new CommonElementsImpl(_elementEnvironment, options);
_constantEnvironment = new KernelConstantEnvironment(this, _environment);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index fe6d512..1b22344 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -403,6 +403,9 @@
// `Mixin.method` is inherited by `Class`.
return;
}
+ if (member.isForwardingStub && cls.isAnonymousMixin) {
+ return;
+ }
if (!includeStatic && member.isStatic) return;
if (member.isNoSuchMethodForwarder) {
// TODO(sigmund): remove once #33732 is fixed.
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index acce37c..74bf19a 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -120,6 +120,9 @@
/// Sets a combination of flags for benchmarking 'production' mode.
bool benchmarkingProduction = false;
+ /// Sets a combination of flags for benchmarking 'experiment' mode.
+ bool benchmarkingExperiment = false;
+
/// ID associated with this sdk build.
String buildId = _UNDETERMINED_BUILD_ID;
@@ -359,6 +362,8 @@
..allowMockCompilation = _hasOption(options, Flags.allowMockCompilation)
..benchmarkingProduction =
_hasOption(options, Flags.benchmarkingProduction)
+ ..benchmarkingExperiment =
+ _hasOption(options, Flags.benchmarkingExperiment)
..buildId =
_extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
..compileForServer = _hasOption(options, Flags.serverMode)
@@ -462,6 +467,11 @@
omitImplicitChecks = true;
}
+ if (benchmarkingExperiment) {
+ // TODO(sra): Set flags implied by '--benchmarking-x'. Initially this will
+ // be --experiment-new-rti, and later NNBD.
+ }
+
if (optimizationLevel != null) {
if (optimizationLevel == 0) {
disableInlining = true;
diff --git a/pkg/compiler/lib/src/serialization/abstract_sink.dart b/pkg/compiler/lib/src/serialization/abstract_sink.dart
index a1af8e8..484d24f 100644
--- a/pkg/compiler/lib/src/serialization/abstract_sink.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_sink.dart
@@ -39,6 +39,9 @@
final Map<String, int> tagFrequencyMap;
+ ir.Member _currentMemberContext;
+ _MemberData _currentMemberData;
+
AbstractDataSink({this.useDataKinds: false, this.tagFrequencyMap}) {
_dartTypeWriter = new DartTypeWriter(this);
_dartTypeNodeWriter = new DartTypeNodeWriter(this);
@@ -73,6 +76,24 @@
}
@override
+ void inMemberContext(ir.Member context, void f()) {
+ ir.Member oldMemberContext = _currentMemberContext;
+ _MemberData oldMemberData = _currentMemberData;
+ _currentMemberContext = context;
+ _currentMemberData = null;
+ f();
+ _currentMemberData = oldMemberData;
+ _currentMemberContext = oldMemberContext;
+ }
+
+ _MemberData get currentMemberData {
+ assert(_currentMemberContext != null,
+ "DataSink has no current member context.");
+ return _currentMemberData ??= _memberData[_currentMemberContext] ??=
+ new _MemberData(_currentMemberContext);
+ }
+
+ @override
void writeCached<E>(E value, void f(E value)) {
IndexedSink sink = _generalCaches[E] ??= new IndexedSink<E>(this);
sink.write(value, (v) => f(v));
@@ -221,10 +242,58 @@
@override
void writeTreeNode(ir.TreeNode value) {
_writeDataKind(DataKind.treeNode);
- _writeTreeNode(value);
+ _writeTreeNode(value, null);
}
- void _writeTreeNode(ir.TreeNode value) {
+ @override
+ void writeTreeNodeInContext(ir.TreeNode value) {
+ writeTreeNodeInContextInternal(value, currentMemberData);
+ }
+
+ void writeTreeNodeInContextInternal(
+ ir.TreeNode value, _MemberData memberData) {
+ _writeDataKind(DataKind.treeNode);
+ _writeTreeNode(value, memberData);
+ }
+
+ @override
+ void writeTreeNodeOrNullInContext(ir.TreeNode value) {
+ writeBool(value != null);
+ if (value != null) {
+ writeTreeNodeInContextInternal(value, currentMemberData);
+ }
+ }
+
+ @override
+ void writeTreeNodesInContext(Iterable<ir.TreeNode> values,
+ {bool allowNull: false}) {
+ if (values == null) {
+ assert(allowNull);
+ writeInt(0);
+ } else {
+ writeInt(values.length);
+ for (ir.TreeNode value in values) {
+ writeTreeNodeInContextInternal(value, currentMemberData);
+ }
+ }
+ }
+
+ @override
+ void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V> map, void f(V value),
+ {bool allowNull: false}) {
+ if (map == null) {
+ assert(allowNull);
+ writeInt(0);
+ } else {
+ writeInt(map.length);
+ map.forEach((ir.TreeNode key, V value) {
+ writeTreeNodeInContextInternal(key, currentMemberData);
+ f(value);
+ });
+ }
+ }
+
+ void _writeTreeNode(ir.TreeNode value, _MemberData memberData) {
if (value is ir.Class) {
_writeEnumInternal(_TreeNodeKind.cls);
_writeClassNode(value);
@@ -234,39 +303,43 @@
} else if (value is ir.VariableDeclaration &&
value.parent is ir.FunctionDeclaration) {
_writeEnumInternal(_TreeNodeKind.functionDeclarationVariable);
- _writeTreeNode(value.parent);
+ _writeTreeNode(value.parent, memberData);
} else if (value is ir.FunctionNode) {
_writeEnumInternal(_TreeNodeKind.functionNode);
- _writeFunctionNode(value);
+ _writeFunctionNode(value, memberData);
} else if (value is ir.TypeParameter) {
_writeEnumInternal(_TreeNodeKind.typeParameter);
- _writeTypeParameter(value);
+ _writeTypeParameter(value, memberData);
} else if (value is ConstantReference) {
_writeEnumInternal(_TreeNodeKind.constant);
- _writeTreeNode(value.expression);
+ _writeTreeNode(value.expression, memberData);
_ConstantNodeIndexerVisitor indexer = new _ConstantNodeIndexerVisitor();
value.expression.constant.accept(indexer);
_writeIntInternal(indexer.getIndex(value.constant));
} else {
_writeEnumInternal(_TreeNodeKind.node);
- ir.TreeNode member = value;
- while (member is! ir.Member) {
- if (member == null) {
- throw new UnsupportedError("No enclosing member of TreeNode "
- "$value (${value.runtimeType})");
+ if (memberData == null) {
+ ir.TreeNode member = value;
+ while (member is! ir.Member) {
+ if (member == null) {
+ throw new UnsupportedError("No enclosing member of TreeNode "
+ "$value (${value.runtimeType})");
+ }
+ member = member.parent;
}
- member = member.parent;
+ _writeMemberNode(member);
+ memberData = _memberData[member] ??= new _MemberData(member);
}
- _writeMemberNode(member);
- _MemberData memberData = _memberData[member] ??= new _MemberData(member);
int index = memberData.getIndexByTreeNode(value);
assert(
- index != null, "No TreeNode index found for ${value.runtimeType}.");
+ index != null,
+ "No TreeNode index found for ${value.runtimeType} "
+ "found in ${memberData}.");
_writeIntInternal(index);
}
}
- void _writeFunctionNode(ir.FunctionNode value) {
+ void _writeFunctionNode(ir.FunctionNode value, _MemberData memberData) {
ir.TreeNode parent = value.parent;
if (parent is ir.Procedure) {
_writeEnumInternal(_FunctionNodeKind.procedure);
@@ -276,10 +349,10 @@
_writeMemberNode(parent);
} else if (parent is ir.FunctionExpression) {
_writeEnumInternal(_FunctionNodeKind.functionExpression);
- _writeTreeNode(parent);
+ _writeTreeNode(parent, memberData);
} else if (parent is ir.FunctionDeclaration) {
_writeEnumInternal(_FunctionNodeKind.functionDeclaration);
- _writeTreeNode(parent);
+ _writeTreeNode(parent, memberData);
} else {
throw new UnsupportedError(
"Unsupported FunctionNode parent ${parent.runtimeType}");
@@ -289,10 +362,10 @@
@override
void writeTypeParameterNode(ir.TypeParameter value) {
_writeDataKind(DataKind.typeParameterNode);
- _writeTypeParameter(value);
+ _writeTypeParameter(value, null);
}
- void _writeTypeParameter(ir.TypeParameter value) {
+ void _writeTypeParameter(ir.TypeParameter value, _MemberData memberData) {
ir.TreeNode parent = value.parent;
if (parent is ir.Class) {
_writeEnumInternal(_TypeParameterKind.cls);
@@ -300,7 +373,7 @@
_writeIntInternal(parent.typeParameters.indexOf(value));
} else if (parent is ir.FunctionNode) {
_writeEnumInternal(_TypeParameterKind.functionNode);
- _writeFunctionNode(parent);
+ _writeFunctionNode(parent, memberData);
_writeIntInternal(parent.typeParameters.indexOf(value));
} else {
throw new UnsupportedError(
@@ -438,7 +511,8 @@
case ConstantValueKind.CONSTRUCTED:
ConstructedConstantValue constant = value;
writeDartType(constant.type);
- writeMemberMap(constant.fields, writeConstant);
+ writeMemberMap(constant.fields,
+ (MemberEntity member, ConstantValue value) => writeConstant(value));
break;
case ConstantValueKind.TYPE:
TypeConstantValue constant = value;
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index a2fa583..a69e834 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -22,6 +22,9 @@
Map<Type, IndexedSource> _generalCaches = {};
+ ir.Member _currentMemberContext;
+ _MemberData _currentMemberData;
+
AbstractDataSource({this.useDataKinds: false}) {
_stringIndex = new IndexedSource<String>(this);
_uriIndex = new IndexedSource<Uri>(this);
@@ -92,6 +95,24 @@
}
@override
+ T inMemberContext<T>(ir.Member context, T f()) {
+ ir.Member oldMemberContext = _currentMemberContext;
+ _MemberData oldMemberData = _currentMemberData;
+ _currentMemberContext = context;
+ _currentMemberData = null;
+ T result = f();
+ _currentMemberData = oldMemberData;
+ _currentMemberContext = oldMemberContext;
+ return result;
+ }
+
+ _MemberData get currentMemberData {
+ assert(_currentMemberContext != null,
+ "DataSink has no current member context.");
+ return _currentMemberData ??= _getMemberData(_currentMemberContext);
+ }
+
+ @override
E readCached<E>(E f()) {
IndexedSource source = _generalCaches[E] ??= new IndexedSource<E>(this);
return source.read(f);
@@ -322,11 +343,11 @@
case MemberContextKind.cls:
_ClassData cls = _readClassData();
String name = _readString();
- return cls.lookupMember(name);
+ return cls.lookupMemberDataByName(name);
case MemberContextKind.library:
_LibraryData library = _readLibraryData();
String name = _readString();
- return library.lookupMember(name);
+ return library.lookupMemberDataByName(name);
}
throw new UnsupportedError("Unsupported _MemberKind $kind");
}
@@ -340,7 +361,7 @@
_ClassData _readClassData() {
_LibraryData library = _readLibraryData();
String name = _readString();
- return library.lookupClass(name);
+ return library.lookupClassByName(name);
}
@override
@@ -419,7 +440,64 @@
@override
ir.TreeNode readTreeNode() {
_checkDataKind(DataKind.treeNode);
- return _readTreeNode();
+ return _readTreeNode(null);
+ }
+
+ _MemberData _getMemberData(ir.Member node) {
+ _LibraryData libraryData =
+ componentLookup.getLibraryDataByUri(node.enclosingLibrary.importUri);
+ if (node.enclosingClass != null) {
+ _ClassData classData = libraryData.lookupClassByNode(node.enclosingClass);
+ return classData.lookupMemberDataByNode(node);
+ } else {
+ return libraryData.lookupMemberDataByNode(node);
+ }
+ }
+
+ @override
+ ir.TreeNode readTreeNodeInContext() {
+ return readTreeNodeInContextInternal(currentMemberData);
+ }
+
+ ir.TreeNode readTreeNodeInContextInternal(_MemberData memberData) {
+ _checkDataKind(DataKind.treeNode);
+ return _readTreeNode(memberData);
+ }
+
+ @override
+ ir.TreeNode readTreeNodeOrNullInContext() {
+ bool hasValue = readBool();
+ if (hasValue) {
+ return readTreeNodeInContextInternal(currentMemberData);
+ }
+ return null;
+ }
+
+ @override
+ List<E> readTreeNodesInContext<E extends ir.TreeNode>(
+ {bool emptyAsNull: false}) {
+ int count = readInt();
+ if (count == 0 && emptyAsNull) return null;
+ List<E> list = new List<E>(count);
+ for (int i = 0; i < count; i++) {
+ ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
+ list[i] = node;
+ }
+ return list;
+ }
+
+ @override
+ Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f(),
+ {bool emptyAsNull: false}) {
+ int count = readInt();
+ if (count == 0 && emptyAsNull) return null;
+ Map<K, V> map = {};
+ for (int i = 0; i < count; i++) {
+ ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
+ V value = f();
+ map[node] = value;
+ }
+ return map;
}
@override
@@ -493,7 +571,8 @@
case ConstantValueKind.CONSTRUCTED:
InterfaceType type = readDartType();
Map<FieldEntity, ConstantValue> fields =
- readMemberMap<FieldEntity, ConstantValue>(() => readConstant());
+ readMemberMap<FieldEntity, ConstantValue>(
+ (MemberEntity member) => readConstant());
return new ConstructedConstantValue(type, fields);
case ConstantValueKind.TYPE:
DartType representedType = readDartType();
@@ -524,7 +603,7 @@
throw new UnsupportedError("Unexpexted constant value kind ${kind}.");
}
- ir.TreeNode _readTreeNode() {
+ ir.TreeNode _readTreeNode(_MemberData memberData) {
_TreeNodeKind kind = _readEnumInternal(_TreeNodeKind.values);
switch (kind) {
case _TreeNodeKind.cls:
@@ -532,32 +611,34 @@
case _TreeNodeKind.member:
return _readMemberData().node;
case _TreeNodeKind.functionDeclarationVariable:
- ir.FunctionDeclaration functionDeclaration = _readTreeNode();
+ ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
return functionDeclaration.variable;
case _TreeNodeKind.functionNode:
- return _readFunctionNode();
+ return _readFunctionNode(memberData);
case _TreeNodeKind.typeParameter:
- return _readTypeParameter();
+ return _readTypeParameter(memberData);
case _TreeNodeKind.constant:
// TODO(johnniwinther): Support serialization within a member context
// and use this to temporarily cache constant node indices.
- ir.ConstantExpression expression = _readTreeNode();
+ ir.ConstantExpression expression = _readTreeNode(memberData);
_ConstantNodeIndexerVisitor indexer = new _ConstantNodeIndexerVisitor();
expression.constant.accept(indexer);
ir.Constant constant = indexer.getConstant(_readIntInternal());
return new ConstantReference(expression, constant);
case _TreeNodeKind.node:
- _MemberData data = _readMemberData();
+ if (memberData == null) {
+ memberData = _readMemberData();
+ }
int index = _readIntInternal();
- ir.TreeNode treeNode = data.getTreeNodeByIndex(index);
+ ir.TreeNode treeNode = memberData.getTreeNodeByIndex(index);
assert(treeNode != null,
- "No TreeNode found for index $index in ${data.node}.$_errorContext");
+ "No TreeNode found for index $index in ${memberData.node}.$_errorContext");
return treeNode;
}
throw new UnsupportedError("Unexpected _TreeNodeKind $kind");
}
- ir.FunctionNode _readFunctionNode() {
+ ir.FunctionNode _readFunctionNode(_MemberData memberData) {
_FunctionNodeKind kind = _readEnumInternal(_FunctionNodeKind.values);
switch (kind) {
case _FunctionNodeKind.procedure:
@@ -567,10 +648,10 @@
ir.Constructor constructor = _readMemberData().node;
return constructor.function;
case _FunctionNodeKind.functionExpression:
- ir.FunctionExpression functionExpression = _readTreeNode();
+ ir.FunctionExpression functionExpression = _readTreeNode(memberData);
return functionExpression.function;
case _FunctionNodeKind.functionDeclaration:
- ir.FunctionDeclaration functionDeclaration = _readTreeNode();
+ ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
return functionDeclaration.function;
}
throw new UnsupportedError("Unexpected _FunctionNodeKind $kind");
@@ -579,17 +660,17 @@
@override
ir.TypeParameter readTypeParameterNode() {
_checkDataKind(DataKind.typeParameterNode);
- return _readTypeParameter();
+ return _readTypeParameter(null);
}
- ir.TypeParameter _readTypeParameter() {
+ ir.TypeParameter _readTypeParameter(_MemberData memberData) {
_TypeParameterKind kind = _readEnumInternal(_TypeParameterKind.values);
switch (kind) {
case _TypeParameterKind.cls:
ir.Class cls = _readClassData().node;
return cls.typeParameters[_readIntInternal()];
case _TypeParameterKind.functionNode:
- ir.FunctionNode functionNode = _readFunctionNode();
+ ir.FunctionNode functionNode = _readFunctionNode(memberData);
return functionNode.typeParameters[_readIntInternal()];
}
throw new UnsupportedError("Unexpected _TypeParameterKind kind $kind");
diff --git a/pkg/compiler/lib/src/serialization/member_data.dart b/pkg/compiler/lib/src/serialization/member_data.dart
index f088210..867a271 100644
--- a/pkg/compiler/lib/src/serialization/member_data.dart
+++ b/pkg/compiler/lib/src/serialization/member_data.dart
@@ -55,27 +55,46 @@
final ir.Library node;
/// Cache of [_ClassData] for classes in this library.
- Map<String, _ClassData> _classes;
+ Map<String, _ClassData> _classesByName;
+ Map<ir.Class, _ClassData> _classesByNode;
/// Cache of [ir.Typedef] nodes for typedefs in this library.
Map<String, ir.Typedef> _typedefs;
/// Cache of [_MemberData] for members in this library.
- Map<String, _MemberData> _members;
+ Map<String, _MemberData> _membersByName;
+ Map<ir.Member, _MemberData> _membersByNode;
_LibraryData(this.node);
- /// Returns the [_ClassData] for the class [name] in this library.
- _ClassData lookupClass(String name) {
- if (_classes == null) {
- _classes = {};
+ void _ensureClasses() {
+ if (_classesByName == null) {
+ _classesByName = {};
+ _classesByNode = {};
for (ir.Class cls in node.classes) {
- assert(!_classes.containsKey(cls.name),
- "Duplicate class '${cls.name}' in $_classes trying to add $cls.");
- _classes[cls.name] = new _ClassData(cls);
+ assert(
+ !_classesByName.containsKey(cls.name),
+ "Duplicate class '${cls.name}' in $_classesByName "
+ "trying to add $cls.");
+ assert(
+ !_classesByNode.containsKey(cls),
+ "Duplicate class '${cls.name}' in $_classesByNode "
+ "trying to add $cls.");
+ _classesByNode[cls] = _classesByName[cls.name] = new _ClassData(cls);
}
}
- return _classes[name];
+ }
+
+ /// Returns the [_ClassData] for the class [name] in this library.
+ _ClassData lookupClassByName(String name) {
+ _ensureClasses();
+ return _classesByName[name];
+ }
+
+ /// Returns the [_ClassData] for the class [node] in this library.
+ _ClassData lookupClassByNode(ir.Class node) {
+ _ensureClasses();
+ return _classesByNode[node];
}
ir.Typedef lookupTypedef(String name) {
@@ -92,20 +111,37 @@
return _typedefs[name];
}
- /// Returns the [_MemberData] for the member uniquely identified by [name] in
- /// this library.
- _MemberData lookupMember(String name) {
- if (_members == null) {
- _members = {};
+ void _ensureMembers() {
+ if (_membersByName == null) {
+ _membersByName = {};
+ _membersByNode = {};
for (ir.Member member in node.members) {
String name = _computeMemberName(member);
if (name == null) continue;
- assert(!_members.containsKey(name),
- "Duplicate member '$name' in $_members trying to add $member.");
- _members[name] = new _MemberData(member);
+ assert(
+ !_membersByName.containsKey(name),
+ "Duplicate member '$name' in $_membersByName "
+ "trying to add $member.");
+ assert(
+ !_membersByNode.containsKey(member),
+ "Duplicate member '$name' in $_membersByNode "
+ "trying to add $member.");
+ _membersByNode[member] = _membersByName[name] = new _MemberData(member);
}
}
- return _members[name];
+ }
+
+ /// Returns the [_MemberData] for the member uniquely identified by [name] in
+ /// this library.
+ _MemberData lookupMemberDataByName(String name) {
+ _ensureMembers();
+ return _membersByName[name];
+ }
+
+ /// Returns the [_MemberData] for the member [node] in this library.
+ _MemberData lookupMemberDataByNode(ir.Member node) {
+ _ensureMembers();
+ return _membersByNode[node];
}
@override
@@ -118,24 +154,42 @@
final ir.Class node;
/// Cache of [_MemberData] for members in this class.
- Map<String, _MemberData> _members;
+ Map<String, _MemberData> _membersByName;
+ Map<ir.Member, _MemberData> _membersByNode;
_ClassData(this.node);
- /// Returns the [_MemberData] for the member uniquely identified by [name] in
- /// this class.
- _MemberData lookupMember(String name) {
- if (_members == null) {
- _members = {};
+ void _ensureMembers() {
+ if (_membersByName == null) {
+ _membersByName = {};
+ _membersByNode = {};
for (ir.Member member in node.members) {
String name = _computeMemberName(member);
if (name == null) continue;
- assert(!_members.containsKey(name),
- "Duplicate member '$name' in $_members trying to add $member.");
- _members[name] = new _MemberData(member);
+ assert(
+ !_membersByName.containsKey(name),
+ "Duplicate member '$name' in $_membersByName "
+ "trying to add $member.");
+ assert(
+ !_membersByNode.containsKey(member),
+ "Duplicate member '$name' in $_membersByNode "
+ "trying to add $member.");
+ _membersByNode[member] = _membersByName[name] = new _MemberData(member);
}
}
- return _members[name];
+ }
+
+ /// Returns the [_MemberData] for the member uniquely identified by [name] in
+ /// this class.
+ _MemberData lookupMemberDataByName(String name) {
+ _ensureMembers();
+ return _membersByName[name];
+ }
+
+ /// Returns the [_MemberData] for the member [node] in this class.
+ _MemberData lookupMemberDataByNode(ir.Member node) {
+ _ensureMembers();
+ return _membersByNode[node];
}
@override
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 2de3e8a..c65a05c 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -142,14 +142,14 @@
}
@override
- Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(),
+ Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member),
{bool emptyAsNull: false}) {
int count = readInt();
if (count == 0 && emptyAsNull) return null;
Map<K, V> map = {};
for (int i = 0; i < count; i++) {
MemberEntity member = readMember();
- V value = f();
+ V value = f(member);
map[member] = value;
}
return map;
@@ -516,7 +516,8 @@
}
@override
- void writeMemberMap<V>(Map<MemberEntity, V> map, void f(V value),
+ void writeMemberMap<V>(
+ Map<MemberEntity, V> map, void f(MemberEntity member, V value),
{bool allowNull: false}) {
if (map == null) {
assert(allowNull);
@@ -525,7 +526,7 @@
writeInt(map.length);
map.forEach((MemberEntity member, V value) {
writeMember(member);
- f(value);
+ f(member, value);
});
}
}
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 92e6ad0..425f6d2 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -187,6 +187,35 @@
void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value),
{bool allowNull: false});
+ /// Writes a reference to the kernel tree node [value] in the known [context]
+ /// to this data sink.
+ void writeTreeNodeInContext(ir.TreeNode value);
+
+ /// Writes a reference to the potentially `null` kernel tree node [value] in
+ /// the known [context] to this data sink.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSource.readTreeNodeOrNullInContext].
+ void writeTreeNodeOrNullInContext(ir.TreeNode value);
+
+ /// Writes references to the kernel tree node [values] in the known [context]
+ /// to this data sink. If [allowNull] is `true`, [values] is allowed to be
+ /// `null`.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSource.readTreeNodesInContext].
+ void writeTreeNodesInContext(Iterable<ir.TreeNode> values,
+ {bool allowNull: false});
+
+ /// Writes the [map] from references to kernel tree nodes to [V] values in the
+ /// known [context] to this data sink, calling [f] to write each value to the
+ /// data sink. If [allowNull] is `true`, [map] is allowed to be `null`.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSource.readTreeNodeMapInContext].
+ void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V> map, void f(V value),
+ {bool allowNull: false});
+
/// Writes a reference to the kernel type parameter node [value] to this data
/// sink.
void writeTypeParameterNode(ir.TypeParameter value);
@@ -297,7 +326,8 @@
///
/// This is a convenience method to be used together with
/// [DataSource.readMemberMap].
- void writeMemberMap<V>(Map<MemberEntity, V> map, void f(V value),
+ void writeMemberMap<V>(
+ Map<MemberEntity, V> map, void f(MemberEntity member, V value),
{bool allowNull: false});
/// Writes a reference to the local [value] to this data sink.
@@ -406,6 +436,11 @@
/// Register a [CodegenWriter] with this data sink to support serialization
/// of codegen only data.
void registerCodegenWriter(CodegenWriter writer);
+
+ /// Invoke [f] in the context of [member]. This sets up support for
+ /// serialization of `ir.TreeNode`s using the `writeTreeNode*InContext`
+ /// methods.
+ void inMemberContext(ir.Member member, void f());
}
/// Interface for deserialization.
@@ -446,6 +481,11 @@
/// for deserialization of codegen only data.
void deregisterCodegenReader(CodegenReader reader);
+ /// Invoke [f] in the context of [member]. This sets up support for
+ /// deserialization of `ir.TreeNode`s using the `readTreeNode*InContext`
+ /// methods.
+ T inMemberContext<T>(ir.Member member, T f());
+
/// Reads a reference to an [E] value from this data source. If the value has
/// not yet been deserialized, [f] is called to deserialize the value itself.
E readCached<E>(E f());
@@ -577,6 +617,33 @@
Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f(),
{bool emptyAsNull: false});
+ /// Reads a reference to a kernel tree node in the known [context] from this
+ /// data source.
+ ir.TreeNode readTreeNodeInContext();
+
+ /// Reads a reference to a potentially `null` kernel tree node in the known
+ /// [context] from this data source.
+ ir.TreeNode readTreeNodeOrNullInContext();
+
+ /// Reads a list of references to kernel tree nodes in the known [context]
+ /// from this data source. If [emptyAsNull] is `true`, `null` is returned
+ /// instead of an empty list.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSink.writeTreeNodesInContext].
+ List<E> readTreeNodesInContext<E extends ir.TreeNode>(
+ {bool emptyAsNull: false});
+
+ /// Reads a map from kernel tree nodes to [V] values in the known [context]
+ /// from this data source, calling [f] to read each value from the data
+ /// source. If [emptyAsNull] is `true`, `null` is returned instead of an empty
+ /// map.
+ ///
+ /// This is a convenience method to be used together with
+ /// [DataSink.writeTreeNodeMapInContext].
+ Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f(),
+ {bool emptyAsNull: false});
+
/// Reads a reference to a kernel type parameter node from this data source.
ir.TypeParameter readTypeParameterNode();
@@ -668,7 +735,7 @@
///
/// This is a convenience method to be used together with
/// [DataSink.writeMemberMap].
- Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(),
+ Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member),
{bool emptyAsNull: false});
/// Reads a reference to a local from this data source.
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 61771d5..f9affee 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -29,7 +29,7 @@
InferredData inferredData = results.inferredData;
closedWorld.writeToDataSink(sink);
inferredData.writeToDataSink(sink);
- results.writeToDataSink(sink);
+ results.writeToDataSink(sink, closedWorld.elementMap);
sink.close();
}
@@ -45,7 +45,7 @@
InferredData newInferredData =
new InferredData.readFromDataSource(source, newClosedWorld);
return new GlobalTypeInferenceResults.readFromDataSource(
- source, newClosedWorld, newInferredData);
+ source, newClosedWorld.elementMap, newClosedWorld, newInferredData);
}
class SerializationTask extends CompilerTask {
@@ -134,7 +134,9 @@
sink.registerEntityWriter(entityWriter);
sink.registerCodegenWriter(new CodegenWriterImpl(closedWorld));
sink.writeMemberMap(
- results, (CodegenResult result) => result.writeToDataSink(sink));
+ results,
+ (MemberEntity member, CodegenResult result) =>
+ result.writeToDataSink(sink));
sink.close();
});
}
@@ -155,7 +157,7 @@
DataSource source = new BinarySourceImpl(dataInput.data);
backendStrategy.prepareCodegenReader(source);
Map<MemberEntity, CodegenResult> codegenResults =
- source.readMemberMap(() {
+ source.readMemberMap((MemberEntity member) {
List<ModularName> modularNames = [];
List<ModularExpression> modularExpressions = [];
CodegenReader reader = new CodegenReaderImpl(
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 257c019..2fa3bac 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -789,25 +789,31 @@
bool needsTypeArguments =
closedWorld.rtiNeed.classNeedsTypeArguments(cls);
if (needsTypeArguments) {
- // Read the values of the type arguments and create a
- // HTypeInfoExpression to set on the newly created object.
- List<HInstruction> typeArguments = <HInstruction>[];
- InterfaceType thisType = _elementEnvironment.getThisType(cls);
- for (DartType typeVariable in thisType.typeArguments) {
- HInstruction argument = localsHandler
- .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
- typeArguments.add(argument);
+ if (options.experimentNewRti) {
+ InterfaceType thisType = _elementEnvironment.getThisType(cls);
+ HInstruction typeArgument =
+ _typeBuilder.analyzeTypeArgumentNewRti(thisType, sourceElement);
+ constructorArguments.add(typeArgument);
+ } else {
+ // Read the values of the type arguments and create a
+ // HTypeInfoExpression to set on the newly created object.
+ List<HInstruction> typeArguments = <HInstruction>[];
+ InterfaceType thisType = _elementEnvironment.getThisType(cls);
+ for (DartType typeVariable in thisType.typeArguments) {
+ HInstruction argument = localsHandler
+ .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
+ typeArguments.add(argument);
+ }
+
+ HInstruction typeInfo = new HTypeInfoExpression(
+ TypeInfoExpressionKind.INSTANCE,
+ thisType,
+ typeArguments,
+ _abstractValueDomain.dynamicType);
+ add(typeInfo);
+ constructorArguments.add(typeInfo);
}
-
- HInstruction typeInfo = new HTypeInfoExpression(
- TypeInfoExpressionKind.INSTANCE,
- thisType,
- typeArguments,
- _abstractValueDomain.dynamicType);
- add(typeInfo);
- constructorArguments.add(typeInfo);
}
-
newObject = new HCreate(cls, constructorArguments,
_abstractValueDomain.createNonNullExact(cls), sourceInformation,
instantiatedTypes: instantiatedTypes,
@@ -1454,12 +1460,16 @@
if (!bound.isDynamic &&
!bound.isVoid &&
bound != _commonElements.objectType) {
- _assertIsType(
- newParameter,
- bound,
- "The type argument '",
- "' is not a subtype of the type variable bound '",
- "' of type variable '${local.name}' in '${method.name}'.");
+ if (options.experimentNewRti) {
+ _checkTypeBound(newParameter, bound, local.name);
+ } else {
+ _assertIsType(
+ newParameter,
+ bound,
+ "The type argument '",
+ "' is not a subtype of the type variable bound '",
+ "' of type variable '${local.name}' in '${method.name}'.");
+ }
}
}
}
@@ -3048,6 +3058,17 @@
if (!_rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
return object;
}
+ if (options.experimentNewRti) {
+ // [type] could be `List<T>`, so ensure it is `JSArray<T>`.
+ InterfaceType arrayType =
+ InterfaceType(_commonElements.jsArrayClass, type.typeArguments);
+ HInstruction rti =
+ _typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
+
+ // TODO(15489): Register at codegen.
+ registry?.registerInstantiation(type);
+ return _callSetRuntimeTypeInfo(rti, object, sourceInformation);
+ }
List<HInstruction> arguments = <HInstruction>[];
for (DartType argument in type.typeArguments) {
arguments.add(_typeBuilder.analyzeTypeArgument(argument, sourceElement));
@@ -4030,6 +4051,8 @@
_handleJsInterceptorConstant(invocation);
} else if (name == 'getInterceptor') {
_handleForeignGetInterceptor(invocation);
+ } else if (name == 'getJSArrayInteropRti') {
+ _handleForeignGetJSArrayInteropRti(invocation);
} else if (name == 'JS_STRING_CONCAT') {
_handleJsStringConcat(invocation);
} else if (name == '_createInvocationMirror') {
@@ -4592,6 +4615,24 @@
stack.add(instruction);
}
+ void _handleForeignGetJSArrayInteropRti(ir.StaticInvocation invocation) {
+ if (_unexpectedForeignArguments(invocation,
+ minPositional: 0, maxPositional: 0) ||
+ !options.experimentNewRti) {
+ // Result expected on stack.
+ stack.add(graph.addConstantNull(closedWorld));
+ return;
+ }
+ // TODO(sra): Introduce 'any' type.
+ InterfaceType interopType =
+ InterfaceType(_commonElements.jsArrayClass, [DynamicType()]);
+ SourceInformation sourceInformation =
+ _sourceInformationBuilder.buildCall(invocation, invocation);
+ HInstruction rti = HLoadType(interopType, _abstractValueDomain.dynamicType)
+ ..sourceInformation = sourceInformation;
+ push(rti);
+ }
+
void _handleForeignJs(ir.StaticInvocation invocation) {
if (_unexpectedForeignArguments(invocation,
minPositional: 2, maxPositional: null, typeArgumentCount: 1)) {
@@ -5212,6 +5253,24 @@
add(assertIsSubtype);
}
+ void _checkTypeBound(
+ HInstruction typeInstruction, DartType bound, String variableName) {
+ HInstruction boundInstruction = _typeBuilder.analyzeTypeArgumentNewRti(
+ localsHandler.substInContext(bound), sourceElement);
+
+ HInstruction variableNameInstruction =
+ graph.addConstantString(variableName, closedWorld);
+ FunctionEntity element = _commonElements.checkTypeBound;
+ var inputs = <HInstruction>[
+ typeInstruction,
+ boundInstruction,
+ variableNameInstruction
+ ];
+ HInstruction checkBound = new HInvokeStatic(
+ element, inputs, typeInstruction.instructionType, const <DartType>[]);
+ add(checkBound);
+ }
+
@override
void visitConstructorInvocation(ir.ConstructorInvocation node) {
SourceInformation sourceInformation =
@@ -5290,6 +5349,13 @@
return;
}
+ if (options.experimentNewRti) {
+ HInstruction rti =
+ _typeBuilder.analyzeTypeArgumentNewRti(typeValue, sourceElement);
+ push(HIsTest(typeValue, expression, rti, _abstractValueDomain.boolType));
+ return;
+ }
+
if (typeValue is FunctionType) {
HInstruction representation =
_typeBuilder.analyzeTypeArgument(typeValue, sourceElement);
@@ -6876,6 +6942,12 @@
}
@override
+ visitConstantExpression(ir.ConstantExpression node) {
+ registerRegularNode();
+ registerReductiveNode();
+ }
+
+ @override
visitReturnStatement(ir.ReturnStatement node) {
registerRegularNode();
node.visitChildren(this);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index a80a7a6..6c5154c 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -26,8 +26,10 @@
import '../js_backend/native_data.dart';
import '../js_backend/namer.dart' show ModularNamer;
import '../js_backend/runtime_types.dart';
+import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
import '../js_model/elements.dart' show JGeneratorBody;
+import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
import '../native/behavior.dart';
import '../options.dart';
import '../tracer.dart';
@@ -114,6 +116,7 @@
codegen.checkedModeHelpers,
codegen.rtiSubstitutions,
codegen.rtiEncoder,
+ codegen.rtiRecipeEncoder,
namer,
codegen.tracer,
closedWorld,
@@ -143,6 +146,7 @@
codegen.checkedModeHelpers,
codegen.rtiSubstitutions,
codegen.rtiEncoder,
+ codegen.rtiRecipeEncoder,
namer,
codegen.tracer,
closedWorld,
@@ -180,6 +184,7 @@
final CheckedModeHelpers _checkedModeHelpers;
final RuntimeTypesSubstitutions _rtiSubstitutions;
final RuntimeTypesEncoder _rtiEncoder;
+ final RecipeEncoder _rtiRecipeEncoder;
final ModularNamer _namer;
final Tracer _tracer;
final JClosedWorld _closedWorld;
@@ -234,6 +239,7 @@
this._checkedModeHelpers,
this._rtiSubstitutions,
this._rtiEncoder,
+ this._rtiRecipeEncoder,
this._namer,
this._tracer,
this._closedWorld,
@@ -3334,6 +3340,8 @@
@override
visitIsTest(HIsTest node) {
+ _registry.registerTypeUse(new TypeUse.isCheck(node.dartType));
+
use(node.typeInput);
js.Expression first = pop();
use(node.checkedInput);
@@ -3372,20 +3380,36 @@
FunctionEntity helperElement = _commonElements.findType;
_registry.registerStaticUse(
new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
- // TODO(sra): Encode recipe.
- js.Expression recipe = js.string('${node.typeExpression}');
+ js.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
+ _emitter, TypeExpressionRecipe(node.typeExpression));
js.Expression helper = _emitter.staticFunctionAccess(helperElement);
push(js.js(r'#(#)', [helper, recipe]).withSourceInformation(
node.sourceInformation));
}
@override
+ visitInstanceEnvironment(HInstanceEnvironment node) {
+ use(node.inputs.single);
+ js.Expression receiver = pop();
+ // TODO(sra): Optimize to direct field access where possible.
+ //
+ // push(js.js(r'#.#', [receiver, _namer.rtiFieldJsName]));
+
+ FunctionEntity helperElement = _commonElements.instanceType;
+ _registry.registerStaticUse(
+ new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
+ js.Expression helper = _emitter.staticFunctionAccess(helperElement);
+ push(js.js(r'#(#)', [helper, receiver]).withSourceInformation(
+ node.sourceInformation));
+ }
+
+ @override
visitTypeEval(HTypeEval node) {
// Call `env._eval("recipe")`.
use(node.inputs[0]);
js.Expression environment = pop();
- // TODO(sra): Encode recipe.
- js.Expression recipe = js.string('${node.typeExpression}');
+ js.Expression recipe = _rtiRecipeEncoder.encodeRecipe(
+ _emitter, node.envStructure, node.typeExpression);
MemberEntity method = _commonElements.rtiEvalMethod;
Selector selector = Selector.fromElement(method);
@@ -3409,7 +3433,7 @@
use(node.inputs[1]);
js.Expression extensions = pop();
- MemberEntity method = _commonElements.rtiEvalMethod;
+ MemberEntity method = _commonElements.rtiBindMethod;
Selector selector = Selector.fromElement(method);
js.Name methodLiteral = _namer.invocationName(selector);
push(js.js('#.#(#)', [
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index ac8f779..a7d0316 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -110,6 +110,7 @@
R visitAsCheck(HAsCheck node);
R visitSubtypeCheck(HSubtypeCheck node);
R visitLoadType(HLoadType node);
+ R visitInstanceEnvironment(HInstanceEnvironment node);
R visitTypeEval(HTypeEval node);
R visitTypeBind(HTypeBind node);
}
@@ -606,6 +607,8 @@
@override
visitLoadType(HLoadType node) => visitInstruction(node);
@override
+ visitInstanceEnvironment(HInstanceEnvironment node) => visitInstruction(node);
+ @override
visitTypeEval(HTypeEval node) => visitInstruction(node);
@override
visitTypeBind(HTypeBind node) => visitInstruction(node);
@@ -1091,8 +1094,9 @@
static const int AS_CHECK_TYPECODE = 48;
static const int SUBTYPE_CHECK_TYPECODE = 49;
static const int LOAD_TYPE_TYPECODE = 50;
- static const int TYPE_EVAL_TYPECODE = 51;
- static const int TYPE_BIND_TYPECODE = 52;
+ static const int INSTANCE_ENVIRONMENT_TYPECODE = 51;
+ static const int TYPE_EVAL_TYPECODE = 52;
+ static const int TYPE_BIND_TYPECODE = 53;
HInstruction(this.inputs, this.instructionType)
: id = idCounter++,
@@ -2903,6 +2907,7 @@
@override
ThisLocal get sourceElement => super.sourceElement;
+
@override
void set sourceElement(covariant ThisLocal local) {
super.sourceElement = local;
@@ -4343,7 +4348,10 @@
/// lowered to other instructions, so this instruction remains for types that
/// depend on type variables and complex types.
class HIsTest extends HInstruction {
- HIsTest(HInstruction checked, HInstruction rti, AbstractValue type)
+ final DartType dartType;
+
+ HIsTest(
+ this.dartType, HInstruction checked, HInstruction rti, AbstractValue type)
: super([rti, checked], type) {
setUseGvn();
}
@@ -4464,6 +4472,33 @@
String toString() => 'HLoadType($typeExpression)';
}
+/// The reified Rti environment stored on a class instance.
+///
+/// Classes with reified type arguments have the type environment stored on the
+/// instance. The reified environment is typically stored as the instance type,
+/// e.g. "UnmodifiableListView<int>".
+class HInstanceEnvironment extends HRtiInstruction {
+ HInstanceEnvironment(HInstruction instance, AbstractValue type)
+ : super([instance], type) {
+ setUseGvn();
+ }
+
+ @override
+ accept(HVisitor visitor) => visitor.visitInstanceEnvironment(this);
+
+ @override
+ int typeCode() => HInstruction.INSTANCE_ENVIRONMENT_TYPECODE;
+
+ @override
+ bool typeEquals(HInstruction other) => other is HInstanceEnvironment;
+
+ @override
+ bool dataEquals(HInstanceEnvironment other) => true;
+
+ @override
+ String toString() => 'HInstanceEnvironment()';
+}
+
/// Evaluates an Rti type recipe in an Rti environment.
class HTypeEval extends HRtiInstruction {
TypeEnvironmentStructure envStructure;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 1a27e5b..865c0ff 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -636,6 +636,8 @@
return splitInstruction;
}
+ // TODO(sra): Implement tagging with `JSArray<String>` for new rti.
+
node.block.addBefore(node, splitInstruction);
HInstruction stringTypeInfo = new HTypeInfoExpression(
@@ -1639,20 +1641,50 @@
for (HInstruction argument in node.inputs) {
if (argument is HTypeInfoReadVariable) {
+ ClassEntity context = DartTypes.getClassContext(argument.variable);
HInstruction nextSource = argument.object;
+ if (nextSource is HRef) {
+ HRef ref = nextSource;
+ nextSource = ref.value;
+ }
if (nextSource is HThis) {
if (source == null) {
source = nextSource;
- ClassEntity contextClass =
- nextSource.sourceElement.enclosingClass;
- if (node.inputs.length !=
- _closedWorld.elementEnvironment
- .getThisType(contextClass)
- .typeArguments
- .length) {
+ ClassEntity thisClass = nextSource.sourceElement.enclosingClass;
+ InterfaceType thisType =
+ _closedWorld.elementEnvironment.getThisType(thisClass);
+ if (node.inputs.length != thisType.typeArguments.length) {
return null;
}
- if (needsSubstitutionForTypeVariableAccess(contextClass)) {
+ if (needsSubstitutionForTypeVariableAccess(thisClass)) {
+ return null;
+ }
+ if (context != null &&
+ !_rtiSubstitutions.isTrivialSubstitution(
+ thisClass, context)) {
+ // If inlining, the [context] is not the same as [thisClass].
+ // If this is the case, then the substitution must be trivial.
+ // Consider this:
+ //
+ // class A {
+ // final Object value;
+ // A(this.value);
+ // }
+ // class B<T> extends A {
+ // B(T value) : super(value);
+ // T get value => super.value as T;
+ // }
+ // class C<S> extends B<List<S>> {
+ // C(List<S> value) : super(value);
+ // S get first => value.first;
+ // }
+ //
+ // If `B.value` is inlined into `C.first` the type info
+ // expression is the list `[B.T]` on a `this` of type `C<S>`.
+ // Since the substitution from C to B is not trivial
+ // (S -> List<S>) this type info expression cannot be replaced
+ // with the type arguments `C<S>` (it would yield [S] instead of
+ // [List<S>]).
return null;
}
}
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 539261d..7ca5ee2 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -675,38 +675,44 @@
}
@override
- visitIsTest(HIsTest node) {
+ String visitIsTest(HIsTest node) {
var inputs = node.inputs.map(temporaryId).join(', ');
return "IsTest: $inputs";
}
@override
- visitAsCheck(HAsCheck node) {
+ String visitAsCheck(HAsCheck node) {
var inputs = node.inputs.map(temporaryId).join(', ');
String error = node.isTypeError ? 'TypeError' : 'CastError';
return "AsCheck: $error $inputs";
}
@override
- visitSubtypeCheck(HSubtypeCheck node) {
+ String visitSubtypeCheck(HSubtypeCheck node) {
var inputs = node.inputs.map(temporaryId).join(', ');
return "SubtypeCheck: $inputs";
}
@override
- visitLoadType(HLoadType node) {
+ String visitLoadType(HLoadType node) {
var inputs = node.inputs.map(temporaryId).join(', ');
return "LoadType: ${node.typeExpression} $inputs";
}
@override
- visitTypeEval(HTypeEval node) {
+ String visitInstanceEnvironment(HInstanceEnvironment node) {
+ var inputs = node.inputs.map(temporaryId).join(', ');
+ return "InstanceEnvironment: $inputs";
+ }
+
+ @override
+ String visitTypeEval(HTypeEval node) {
var inputs = node.inputs.map(temporaryId).join(', ');
return "TypeEval: ${node.typeExpression} $inputs";
}
@override
- visitTypeBind(HTypeBind node) {
+ String visitTypeBind(HTypeBind node) {
var inputs = node.inputs.map(temporaryId).join(', ');
return "TypeBind: $inputs";
}
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 11c31ec..03ad305 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -247,6 +247,10 @@
HInstruction analyzeTypeArgument(
DartType argument, MemberEntity sourceElement,
{SourceInformation sourceInformation}) {
+ if (builder.options.experimentNewRti) {
+ return analyzeTypeArgumentNewRti(argument, sourceElement,
+ sourceInformation: sourceInformation);
+ }
argument = argument.unaliased;
if (argument.treatAsDynamic) {
// Represent [dynamic] as [null].
@@ -279,25 +283,136 @@
{SourceInformation sourceInformation}) {
argument = argument.unaliased;
- if (argument.containsFreeTypeVariables) {
- // TODO(sra): Locate type environment.
- HInstruction environment =
- builder.graph.addConstantString("env", _closedWorld);
- // TODO(sra): Determine environment structure from context.
- TypeEnvironmentStructure structure = null;
- HInstruction rti = HTypeEval(environment, structure,
- TypeExpressionRecipe(argument), _abstractValueDomain.dynamicType)
+ if (!argument.containsTypeVariables) {
+ HInstruction rti = HLoadType(argument, _abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
builder.add(rti);
return rti;
}
+ // TODO(sra): Locate type environment.
+ _EnvironmentExpressionAndStructure environmentAccess =
+ _buildEnvironmentForType(argument, sourceElement,
+ sourceInformation: sourceInformation);
- HInstruction rti = HLoadType(argument, _abstractValueDomain.dynamicType)
+ HInstruction rti = HTypeEval(
+ environmentAccess.expression,
+ environmentAccess.structure,
+ TypeExpressionRecipe(argument),
+ _abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
builder.add(rti);
return rti;
}
+ _EnvironmentExpressionAndStructure _buildEnvironmentForType(
+ DartType type, MemberEntity member,
+ {SourceInformation sourceInformation}) {
+ assert(type.containsTypeVariables);
+ // Build the environment for each access, and hope GVN reduces the larger
+ // number of expressions. Another option is to precompute the environment at
+ // procedure entry and optimize early-exits by sinking the precomputed
+ // environment.
+
+ // Split the type variables into class-scope and function-scope(s).
+ bool usesInstanceParameters = false;
+ InterfaceType interfaceType;
+ Set<TypeVariableType> parameters = Set();
+
+ void processTypeVariable(TypeVariableType type) {
+ ClassTypeVariableAccess typeVariableAccess;
+ if (type.element.typeDeclaration is ClassEntity) {
+ typeVariableAccess = computeTypeVariableAccess(member);
+ interfaceType = _closedWorld.elementEnvironment
+ .getThisType(type.element.typeDeclaration);
+ } else {
+ typeVariableAccess = ClassTypeVariableAccess.parameter;
+ }
+ switch (typeVariableAccess) {
+ case ClassTypeVariableAccess.parameter:
+ parameters.add(type);
+ return;
+ case ClassTypeVariableAccess.instanceField:
+ if (member != builder.targetElement) {
+ // When [member] is a field, we can either be generating a checked
+ // setter or inlining its initializer in a constructor. An
+ // initializer is never built standalone, so in that case [target]
+ // is not the [member] itself.
+ parameters.add(type);
+ return;
+ }
+ usesInstanceParameters = true;
+ return;
+ case ClassTypeVariableAccess.property:
+ usesInstanceParameters = true;
+ return;
+ default:
+ builder.reporter.internalError(
+ type.element, 'Unexpected type variable in static context.');
+ }
+ }
+
+ type.forEachTypeVariable(processTypeVariable);
+
+ HInstruction environment;
+ TypeEnvironmentStructure structure;
+
+ if (usesInstanceParameters) {
+ HInstruction target =
+ builder.localsHandler.readThis(sourceInformation: sourceInformation);
+ // TODO(sra): HInstanceEnvironment should probably take an interceptor to
+ // allow the getInterceptor call to be reused.
+ environment =
+ HInstanceEnvironment(target, _abstractValueDomain.dynamicType)
+ ..sourceInformation = sourceInformation;
+ builder.add(environment);
+ structure = FullTypeEnvironmentStructure(classType: interfaceType);
+ }
+
+ // TODO(sra): Visit parameters in source-order.
+ for (TypeVariableType parameter in parameters) {
+ Local typeVariableLocal =
+ builder.localsHandler.getTypeVariableAsLocal(parameter);
+ HInstruction access = builder.localsHandler
+ .readLocal(typeVariableLocal, sourceInformation: sourceInformation);
+
+ if (environment == null) {
+ environment = access;
+ structure = SingletonTypeEnvironmentStructure(parameter);
+ } else if (structure is SingletonTypeEnvironmentStructure) {
+ SingletonTypeEnvironmentStructure singletonStructure = structure;
+ // Convert a singleton environment into a singleton tuple and extend it
+ // via 'bind'. i.e. generate `env1._eval("@<0>")._bind(env2)` TODO(sra):
+ // Have a bind1 instruction.
+ // TODO(sra): Add a 'Rti._bind1' method to shorten and accelerate this
+ // common case.
+ HInstruction singletonTuple = HTypeEval(
+ environment,
+ structure,
+ FullTypeEnvironmentRecipe(types: [singletonStructure.variable]),
+ _abstractValueDomain.dynamicType)
+ ..sourceInformation = sourceInformation;
+ builder.add(singletonTuple);
+ environment =
+ HTypeBind(singletonTuple, access, _abstractValueDomain.dynamicType);
+ builder.add(environment);
+ structure = FullTypeEnvironmentStructure(
+ bindings: [singletonStructure.variable, parameter]);
+ } else if (structure is FullTypeEnvironmentStructure) {
+ FullTypeEnvironmentStructure fullStructure = structure;
+ environment =
+ HTypeBind(environment, access, _abstractValueDomain.dynamicType);
+ builder.add(environment);
+ structure = FullTypeEnvironmentStructure(
+ classType: fullStructure.classType,
+ bindings: [...fullStructure.bindings, parameter]);
+ } else {
+ builder.reporter.internalError(parameter.element, 'Unexpected');
+ }
+ }
+
+ return _EnvironmentExpressionAndStructure(environment, structure);
+ }
+
/// Build a [HTypeConversion] for converting [original] to type [type].
///
/// Invariant: [type] must be valid in the context.
@@ -357,8 +472,9 @@
if (type.isVoid) return original;
if (type == _closedWorld.commonElements.objectType) return original;
- HInstruction reifiedType =
- analyzeTypeArgumentNewRti(type, builder.sourceElement);
+ HInstruction reifiedType = analyzeTypeArgumentNewRti(
+ type, builder.sourceElement,
+ sourceInformation: sourceInformation);
if (type is InterfaceType) {
// TODO(sra): Under NNDB opt-in, this will be NonNullable.
AbstractValue subtype =
@@ -374,3 +490,9 @@
}
}
}
+
+class _EnvironmentExpressionAndStructure {
+ final HInstruction expression;
+ final TypeEnvironmentStructure structure;
+ _EnvironmentExpressionAndStructure(this.expression, this.structure);
+}
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 9a15238..89bb3d6 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
name: dart_internal
-version: 0.1.4
+version: 0.1.5
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.4.0"
+ sdk: ">=2.0.0-dev.12.0 <2.5.0"
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 249dc5d..efc01ff 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -1,3 +1,5 @@
+include: package:pedantic/analysis_options.1.8.0.yaml
+
analyzer:
strong-mode:
implicit-casts: false
@@ -14,27 +16,3 @@
linter:
rules:
- annotate_overrides
- - avoid_empty_else
- - avoid_init_to_null
- - avoid_relative_lib_imports
- - avoid_return_types_on_setters
- - avoid_shadowing_type_parameters
- - avoid_types_as_parameter_names
- - curly_braces_in_flow_control_structures
- - empty_catches
- - empty_constructor_bodies
- - library_names
- - library_prefixes
- - no_duplicate_case_values
- - null_closures
- - prefer_contains
- - prefer_equal_for_default_values
- - prefer_is_empty
- - prefer_is_not_empty
- - recursive_getters
- - type_init_formals
- - unawaited_futures
- - unnecessary_null_in_if_null_operators
- - unrelated_type_equality_checks
- - use_rethrow_when_possible
- - valid_regexps
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index db2f7b8..4d4ac46 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -23,8 +23,8 @@
if (parsedArgs.isWorker) {
var workerConnection = sendPort == null
- ? new StdAsyncWorkerConnection()
- : new SendPortAsyncWorkerConnection(sendPort);
+ ? StdAsyncWorkerConnection()
+ : SendPortAsyncWorkerConnection(sendPort);
await _CompilerWorker(parsedArgs, workerConnection).run();
} else if (parsedArgs.isBatch) {
await runBatch(parsedArgs);
@@ -52,7 +52,16 @@
var args = _startupArgs.merge(request.arguments);
var output = StringBuffer();
var context = args.reuseResult ? lastResult : null;
- lastResult = await runZoned(() => compile(args, previousResult: context),
+
+ /// Build a map of uris to digests.
+ final inputDigests = <Uri, List<int>>{};
+ for (var input in request.inputs) {
+ inputDigests[Uri.base.resolve(input.path)] = input.digest;
+ }
+
+ lastResult = await runZoned(
+ () =>
+ compile(args, previousResult: context, inputDigests: inputDigests),
zoneSpecification:
ZoneSpecification(print: (self, parent, zone, message) {
output.writeln(message.toString());
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 3d4d114..519cd8b 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -15,7 +15,6 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/token.dart' show StringToken;
-import 'package:analyzer/src/dart/ast/utilities.dart' show UIAsCodeVisitorMixin;
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -68,7 +67,6 @@
// (which result in (JS.Statement).
class CodeGenerator extends Object
with
- UIAsCodeVisitorMixin<js_ast.Node>,
NullableTypeInference,
SharedCompiler<LibraryElement, ClassElement, InterfaceType,
FunctionBody>
@@ -5500,7 +5498,7 @@
variable = forParts.loopVariable.identifier;
init = js.call('let # = #.current', [_emitVariableDef(variable), iter]);
} else {
- throw new StateError('Unrecognized for loop parts');
+ throw StateError('Unrecognized for loop parts');
}
return js.statement(
'{'
@@ -6518,7 +6516,7 @@
} else if (forParts is ForPartsWithDeclarations) {
init = visitVariableDeclarationList(forParts.variables);
} else {
- throw new StateError('Unrecognized for loop parts');
+ throw StateError('Unrecognized for loop parts');
}
js_ast.Expression update;
if (forParts.updaters != null && forParts.updaters.isNotEmpty) {
@@ -6550,7 +6548,7 @@
]);
}
} else {
- throw new StateError('Unrecognized for loop parts');
+ throw StateError('Unrecognized for loop parts');
}
return js_ast.ForOf(jsLeftExpression, jsIterable, jsBody);
}
@@ -6620,7 +6618,7 @@
} else if (forParts is ForEachPartsWithDeclaration) {
variable = forParts.loopVariable.identifier;
} else {
- throw new StateError('Unrecognized for loop parts');
+ throw StateError('Unrecognized for loop parts');
}
var castType = getImplicitCast(variable);
if (castType != null) {
@@ -6748,6 +6746,9 @@
@override
visitExtensionDeclaration(ExtensionDeclaration node) => _unreachable(node);
+
+ @override
+ visitExtensionOverride(ExtensionOverride node) => _unreachable(node);
}
// TODO(jacobr): we would like to do something like the following
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 02e108e..b3f4d3f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -14,7 +14,7 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart' hide CustomUriResolver;
import 'package:analyzer/src/summary/package_bundle_reader.dart'
- show InSummaryUriResolver, SummaryDataStore;
+ show InSummarySource, InSummaryUriResolver, SummaryDataStore;
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:cli_util/cli_util.dart' show getSdkPath;
import 'package:path/path.dart' as path;
@@ -40,10 +40,14 @@
/// The default analysis root.
String analysisRoot = path.current;
+ // May be null.
+ final DependencyTracker dependencyTracker;
+
AnalyzerOptions._(
{this.contextBuilderOptions,
String dartSdkPath,
- this.customUrlMappings = const {}})
+ this.customUrlMappings = const {},
+ this.dependencyTracker})
: dartSdkPath = dartSdkPath ?? getSdkPath() {
contextBuilderOptions.declaredVariables ??= const {};
}
@@ -69,12 +73,16 @@
// For building the SDK, we explicitly set the path to none.
if (dartSdkSummaryPath == 'build') dartSdkSummaryPath = null;
contextOpts.dartSdkSummaryPath = dartSdkSummaryPath;
+ var summaryDepsOutput = args['summary-deps-output'] as String;
+ var dependencyTracker =
+ summaryDepsOutput != null ? DependencyTracker(summaryDepsOutput) : null;
return AnalyzerOptions._(
contextBuilderOptions: contextOpts,
dartSdkPath: dartSdkPath,
customUrlMappings:
- _parseUrlMappings(args['url-mapping'] as List<String>));
+ _parseUrlMappings(args['url-mapping'] as List<String>),
+ dependencyTracker: dependencyTracker);
}
static void addArguments(ArgParser parser, {bool hide = true}) {
@@ -126,7 +134,14 @@
.add(CustomUriResolver(resourceProvider, options.customUrlMappings));
}
if (summaryData != null) {
- resolvers.add(InSummaryUriResolver(resourceProvider, summaryData));
+ UriResolver summaryResolver =
+ InSummaryUriResolver(resourceProvider, summaryData);
+ if (options.dependencyTracker != null) {
+ // Wrap summaryResolver.
+ summaryResolver = TrackingInSummaryUriResolver(
+ summaryResolver, options.dependencyTracker);
+ }
+ resolvers.add(summaryResolver);
}
var fileResolvers = options.fileResolvers ?? createFileResolvers(options);
@@ -160,3 +175,34 @@
}
return mappings;
}
+
+/// A set of path strings read during the build.
+class DependencyTracker {
+ final _dependencies = Set<String>();
+
+ /// The path to the file to create once tracking is done.
+ final String outputPath;
+
+ DependencyTracker(this.outputPath);
+
+ Iterable<String> get dependencies => _dependencies;
+
+ void record(String path) => _dependencies.add(path);
+}
+
+/// Wrapper for [UriResolver] that tracks accesses to summaries.
+class TrackingInSummaryUriResolver extends UriResolver {
+ final UriResolver _summaryResolver;
+ final DependencyTracker _dependencyTracker;
+
+ TrackingInSummaryUriResolver(this._summaryResolver, this._dependencyTracker);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ var source = _summaryResolver.resolveAbsolute(uri, actualUri);
+ if (source != null && source is InSummarySource) {
+ _dependencyTracker.record(source.summaryPath);
+ }
+ return source;
+ }
+}
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index 70bdc0a..0ce3e60 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -117,6 +117,12 @@
}
}
+ if (analyzerOptions.dependencyTracker != null) {
+ var file = File(analyzerOptions.dependencyTracker.outputPath);
+ file.writeAsStringSync(
+ (analyzerOptions.dependencyTracker.dependencies.toList()..sort()).join('\n'));
+ }
+
var jsModule = JSModuleFile(
errors.formattedErrors.toList(), options, jsProgram, driver.summaryBytes);
return jsModule;
@@ -205,6 +211,9 @@
hide: hide)
..addOption('summary-out',
help: 'location to write the summary file', hide: hide)
+ ..addOption('summary-deps-output',
+ help: 'Path to a file to dump summary dependency info to.',
+ hide: hide)
..addOption('module-root',
help: '(deprecated) used to determine the default module name and\n'
'summary import name if those are not provided.',
diff --git a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
index 885172f..ecb118f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
@@ -369,7 +369,7 @@
_nullableLocals.add(element);
}
} else {
- throw new StateError('Unrecognized for loop parts');
+ throw StateError('Unrecognized for loop parts');
}
}
super.visitForStatement(node);
diff --git a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
index 94f1c2edb..dd81f22 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
@@ -292,9 +292,8 @@
T tree, Map<MetaLetVariable, Expression> substitutions) {
var generator = InstantiatorGeneratorVisitor(/*forceCopy:*/ false);
var instantiator = generator.compile(tree);
- var nodes = List<MetaLetVariable>.from(generator
- .analysis.containsInterpolatedNode
- .where((n) => n is MetaLetVariable));
+ var nodes = List<MetaLetVariable>.from(
+ generator.analysis.containsInterpolatedNode.whereType<MetaLetVariable>());
if (nodes.isEmpty) return tree;
return instantiator(Map.fromIterable(nodes,
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index 0388456..fbbf31d 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:collection';
import 'dart:io';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
import 'package:args/args.dart';
@@ -263,8 +262,8 @@
List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
if (!args.contains('--ignore-unrecognized-flags')) return args;
- var knownOptions = new HashSet<String>();
- var knownAbbreviations = new HashSet<String>();
+ var knownOptions = <String>{};
+ var knownAbbreviations = <String>{};
parser.options.forEach((String name, Option option) {
knownOptions.add(name);
var abbreviation = option.abbr;
@@ -400,7 +399,7 @@
/// The result may also contain a [previousResult], which can be passed back in
/// for batch/worker executions to attempt to existing state.
Future<CompilerResult> compile(ParsedArguments args,
- {CompilerResult previousResult}) {
+ {CompilerResult previousResult, Map<Uri, List<int>> inputDigests}) {
if (previousResult != null && !args.isBatchOrWorker) {
throw ArgumentError(
'previousResult requires --batch or --bazel_worker mode/');
@@ -408,7 +407,8 @@
if (args.isKernel) {
return kernel_compiler.compile(args.rest,
compilerState: previousResult?.kernelState,
- useIncrementalCompiler: args.useIncrementalCompiler);
+ useIncrementalCompiler: args.useIncrementalCompiler,
+ inputDigests: inputDigests);
} else {
var result = analyzer_compiler.compile(args.rest,
compilerState: previousResult?.analyzerState);
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index 2d0dd51..a03424d 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/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.
+// ignore_for_file: slash_for_doc_comments, unnecessary_new
+
// Utilities for building JS ASTs at runtime. Contains a builder class
// and a parser that parses part of the language.
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 36d2368..219e99a 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.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.
+// ignore_for_file: slash_for_doc_comments
+
part of js_ast;
abstract class NodeVisitor<T> {
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index f4a9717..0349ce9 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.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.
+// ignore_for_file: slash_for_doc_comments, unnecessary_const
+
part of js_ast;
class JavaScriptPrintingOptions {
@@ -1018,7 +1020,7 @@
spaceOut();
// Object initializers require parenthesis to disambiguate
// AssignmentExpression from FunctionBody. See:
- // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-function-definitions
+ // https://tc39.github.io/ecma262/#sec-arrow-function-definitions
var needsParen = fun.body is ObjectInitializer;
if (needsParen) out("(");
visitNestedExpression(body, ASSIGNMENT,
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index 6363cd6..4fe7042 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.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.
+// ignore_for_file: slash_for_doc_comments
+
part of js_ast;
class TemplateManager {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index ca85c12..22da1ec 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -37,11 +37,13 @@
/// Returns `true` if the program compiled without any fatal errors.
Future<CompilerResult> compile(List<String> args,
{fe.InitializedCompilerState compilerState,
- bool useIncrementalCompiler = false}) async {
+ bool useIncrementalCompiler = false,
+ Map<Uri, List<int>> inputDigests}) async {
try {
return await _compile(args,
compilerState: compilerState,
- useIncrementalCompiler: useIncrementalCompiler);
+ useIncrementalCompiler: useIncrementalCompiler,
+ inputDigests: inputDigests);
} catch (error, stackTrace) {
print('''
We're sorry, you've found a bug in our compiler.
@@ -68,7 +70,8 @@
Future<CompilerResult> _compile(List<String> args,
{fe.InitializedCompilerState compilerState,
- bool useIncrementalCompiler = false}) async {
+ bool useIncrementalCompiler = false,
+ Map<Uri, List<int>> inputDigests}) async {
// TODO(jmesserly): refactor options to share code with dartdevc CLI.
var argParser = ArgParser(allowTrailingOptions: true)
..addFlag('help',
@@ -214,7 +217,9 @@
var experiments = <fe.ExperimentalFlag, bool>{};
for (var name in options.experiments.keys) {
var flag = fe.parseExperimentalFlag(name);
- if (flag != null) {
+ if (flag == fe.ExperimentalFlag.expiredFlag) {
+ stderr.writeln("Flag '$name' is no longer required.");
+ } else if (flag != null) {
experiments[flag] = options.experiments[name];
} else {
stderr.writeln("Unknown experiment flag '$name'.");
@@ -243,7 +248,7 @@
fileSystem: fileSystem,
experiments: experiments);
} else {
- doneInputSummaries = new List<Component>(summaryModules.length);
+ doneInputSummaries = List<Component>(summaryModules.length);
compilerState = await fe.initializeIncrementalCompiler(
oldCompilerState,
doneInputSummaries,
@@ -253,6 +258,7 @@
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
summaryModules.keys.toList(),
+ inputDigests,
DevCompilerTarget(
TargetFlags(trackWidgetCreation: trackWidgetCreation)),
fileSystem: fileSystem,
@@ -286,7 +292,7 @@
Component incrementalComponent = await incrementalCompiler.computeDelta(
entryPoints: inputs, fullComponent: true);
hierarchy = incrementalCompiler.userCode.loader.hierarchy;
- result = new fe.DdcResult(incrementalComponent, doneInputSummaries);
+ result = fe.DdcResult(incrementalComponent, doneInputSummaries);
// Workaround for DDC relying on isExternal being set to true.
for (var lib in cachedSdkInput.component.libraries) {
@@ -329,7 +335,7 @@
outFiles.add(sink.flush().then((_) => sink.close()));
}
if (argResults['summarize-text'] as bool) {
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = StringBuffer();
kernel.Printer(sb, showExternal: false).writeComponentFile(component);
outFiles.add(File(output + '.txt').writeAsString(sb.toString()));
}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 9971f7c..76c8c53 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -39,7 +39,7 @@
ExpressionVisitor<js_ast.Expression>,
DartTypeVisitor<js_ast.Expression>,
ConstantVisitor<js_ast.Expression> {
- final SharedCompilerOptions options;
+ final SharedCompilerOptions _options;
/// Maps a library URI import, that is not in [_libraries], to the
/// corresponding Kernel summary module we imported it with.
@@ -98,11 +98,11 @@
// TODO(jmesserly): rename to `_nativeTypes`
final NativeTypeSet _extensionTypes;
- final CoreTypes coreTypes;
+ final CoreTypes _coreTypes;
- final TypeEnvironment types;
+ final TypeEnvironment _types;
- final ClassHierarchy hierarchy;
+ final ClassHierarchy _hierarchy;
/// Information about virtual and overridden fields/getters/setters in the
/// class we're currently compiling, or `null` if we aren't compiling a class.
@@ -110,7 +110,7 @@
/// Information about virtual fields for all libraries in the current build
/// unit.
- final virtualFields = VirtualFieldModel();
+ final _virtualFields = VirtualFieldModel();
final JSTypeRep _typeRep;
@@ -183,17 +183,17 @@
/// continue statements and are used to simulate "jumping" to case statements.
/// State variables hold the next constant case expression, while labels act
/// as targets for continue and break.
- final _switchLabelStates = HashMap<Statement, SwitchLabelState>();
+ final _switchLabelStates = HashMap<Statement, _SwitchLabelState>();
final Class _jsArrayClass;
- final Class privateSymbolClass;
- final Class linkedHashMapImplClass;
- final Class identityHashMapImplClass;
- final Class linkedHashSetClass;
- final Class linkedHashSetImplClass;
- final Class identityHashSetImplClass;
- final Class syncIterableClass;
- final Class asyncStarImplClass;
+ final Class _privateSymbolClass;
+ final Class _linkedHashMapImplClass;
+ final Class _identityHashMapImplClass;
+ final Class _linkedHashSetClass;
+ final Class _linkedHashSetImplClass;
+ final Class _identityHashSetImplClass;
+ final Class _syncIterableClass;
+ final Class _asyncStarImplClass;
/// The dart:async `StreamIterator<T>` type.
final Class _asyncStreamIteratorClass;
@@ -214,28 +214,28 @@
}
ProgramCompiler._(
- this.coreTypes,
+ this._coreTypes,
LibraryIndex sdk,
this._extensionTypes,
this._constants,
- this.types,
- this.hierarchy,
+ this._types,
+ this._hierarchy,
this._typeRep,
this._nullableInference,
- this.options)
+ this._options)
: _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
_asyncStreamIteratorClass =
sdk.getClass('dart:async', 'StreamIterator'),
- privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
- linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
- identityHashMapImplClass =
+ _privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
+ _linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
+ _identityHashMapImplClass =
sdk.getClass('dart:_js_helper', 'IdentityMap'),
- linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'),
- linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
- identityHashSetImplClass =
+ _linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'),
+ _linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
+ _identityHashSetImplClass =
sdk.getClass('dart:collection', '_IdentityHashSet'),
- syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable'),
- asyncStarImplClass = sdk.getClass('dart:async', '_AsyncStarImpl');
+ _syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable'),
+ _asyncStarImplClass = sdk.getClass('dart:async', '_AsyncStarImpl');
@override
Uri get currentLibraryUri => _currentLibrary.importUri;
@@ -244,18 +244,17 @@
Library get currentLibrary => _currentLibrary;
@override
- Library get coreLibrary => coreTypes.coreLibrary;
+ Library get coreLibrary => _coreTypes.coreLibrary;
@override
FunctionNode get currentFunction => _currentFunction;
@override
- InterfaceType get privateSymbolType => privateSymbolClass.rawType;
+ InterfaceType get privateSymbolType => _privateSymbolClass.rawType;
@override
- InterfaceType get internalSymbolType => coreTypes.internalSymbolClass.rawType;
-
- bool get emitMetadata => options.emitMetadata;
+ InterfaceType get internalSymbolType =>
+ _coreTypes.internalSymbolClass.rawType;
js_ast.Program emitModule(Component component, List<Component> summaries,
List<Uri> summaryUris, Map<Uri, String> moduleImportForSummary) {
@@ -289,7 +288,7 @@
}
// Add implicit dart:core dependency so it is first.
- emitLibraryName(coreTypes.coreLibrary);
+ emitLibraryName(_coreTypes.coreLibrary);
// Visit each library and emit its code.
//
@@ -311,7 +310,7 @@
// hoisted definitions.
items.addAll(_typeTable.discharge());
- return finishModule(items, options.moduleName);
+ return finishModule(items, _options.moduleName);
}
@override
@@ -440,14 +439,14 @@
var savedLibrary = _currentLibrary;
var savedUri = _currentUri;
_currentClass = c;
- types.thisType = c.thisType;
+ _types.thisType = c.thisType;
_currentLibrary = c.enclosingLibrary;
_currentUri = c.fileUri;
moduleItems.add(_emitClassDeclaration(c));
_currentClass = savedClass;
- types.thisType = savedClass?.thisType;
+ _types.thisType = savedClass?.thisType;
_currentLibrary = savedLibrary;
_currentUri = savedUri;
}
@@ -487,7 +486,7 @@
var savedClassProperties = _classProperties;
_classProperties =
- ClassPropertyModel.build(types, _extensionTypes, virtualFields, c);
+ ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c);
var jsCtors = _defineConstructors(c, className);
var jsMethods = _emitClassMethods(c);
@@ -644,7 +643,7 @@
List<js_ast.Method> methods,
List<js_ast.Statement> body,
List<js_ast.Statement> deferredSupertypes) {
- if (c == coreTypes.objectClass) {
+ if (c == _coreTypes.objectClass) {
body.add(_emitClassStatement(c, className, null, methods));
return;
}
@@ -663,7 +662,7 @@
if (t is InterfaceType) {
var tc = t.classNode;
if (c == tc) return true;
- if (tc == coreTypes.objectClass || !visited.add(t)) return false;
+ if (tc == _coreTypes.objectClass || !visited.add(t)) return false;
if (t.typeArguments.any(defer)) return true;
var mixin = tc.mixedInType;
return mixin != null && defer(mixin.asInterfaceType) ||
@@ -706,10 +705,10 @@
var superclass = getSuperclassAndMixins(c, mixinClasses);
var supertype = identical(c.superclass, superclass)
? c.supertype.asInterfaceType
- : hierarchy.getClassAsInstanceOf(c, superclass).asInterfaceType;
+ : _hierarchy.getClassAsInstanceOf(c, superclass).asInterfaceType;
mixinClasses = mixinClasses.reversed.toList();
var mixins = mixinClasses
- .map((m) => hierarchy.getClassAsInstanceOf(c, m).asInterfaceType)
+ .map((m) => _hierarchy.getClassAsInstanceOf(c, m).asInterfaceType)
.toList();
var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass);
@@ -872,8 +871,8 @@
Class c, js_ast.Expression className, List<js_ast.Statement> body) {
js_ast.Expression getInterfaceSymbol(Class interface) {
var library = interface.enclosingLibrary;
- if (library == coreTypes.coreLibrary ||
- library == coreTypes.asyncLibrary) {
+ if (library == _coreTypes.coreLibrary ||
+ library == _coreTypes.asyncLibrary) {
switch (interface.name) {
case 'List':
case 'Map':
@@ -899,8 +898,8 @@
// TODO(jmesserly): share these hand coded type checks with the old back
// end, perhaps by factoring them into a common file, or move them to be
// static methdos in the SDK. (Or wait until we delete the old back end.)
- if (c.enclosingLibrary == coreTypes.coreLibrary) {
- if (c == coreTypes.objectClass) {
+ if (c.enclosingLibrary == _coreTypes.coreLibrary) {
+ if (c == _coreTypes.objectClass) {
// Everything is an Object.
body.add(js.statement(
'#.is = function is_Object(o) { return true; }', [className]));
@@ -910,7 +909,7 @@
'#._check = function check_Object(o) { return o; }', [className]));
return null;
}
- if (c == coreTypes.stringClass) {
+ if (c == _coreTypes.stringClass) {
body.add(js.statement(
'#.is = function is_String(o) { return typeof o == "string"; }',
className));
@@ -928,7 +927,7 @@
[className, runtimeModule, className]));
return null;
}
- if (c == coreTypes.functionClass) {
+ if (c == _coreTypes.functionClass) {
body.add(js.statement(
'#.is = function is_Function(o) { return typeof o == "function"; }',
className));
@@ -946,7 +945,7 @@
[className, runtimeModule, className]));
return null;
}
- if (c == coreTypes.intClass) {
+ if (c == _coreTypes.intClass) {
body.add(js.statement(
'#.is = function is_int(o) {'
' return typeof o == "number" && Math.floor(o) == o;'
@@ -968,7 +967,7 @@
[className, runtimeModule, className]));
return null;
}
- if (c == coreTypes.nullClass) {
+ if (c == _coreTypes.nullClass) {
body.add(js.statement(
'#.is = function is_Null(o) { return o == null; }', className));
body.add(js.statement(
@@ -985,7 +984,7 @@
[className, runtimeModule, className]));
return null;
}
- if (c == coreTypes.numClass || c == coreTypes.doubleClass) {
+ if (c == _coreTypes.numClass || c == _coreTypes.doubleClass) {
body.add(js.statement(
'#.is = function is_num(o) { return typeof o == "number"; }',
className));
@@ -1003,7 +1002,7 @@
[className, runtimeModule, className]));
return null;
}
- if (c == coreTypes.boolClass) {
+ if (c == _coreTypes.boolClass) {
body.add(js.statement(
'#.is = function is_bool(o) { return o === true || o === false; }',
className));
@@ -1022,12 +1021,12 @@
return null;
}
}
- if (c.enclosingLibrary == coreTypes.asyncLibrary) {
- if (c == coreTypes.futureOrClass) {
+ if (c.enclosingLibrary == _coreTypes.asyncLibrary) {
+ if (c == _coreTypes.futureOrClass) {
var typeParam = TypeParameterType(c.typeParameters[0]);
var typeT = visitTypeParameterType(typeParam);
var futureOfT = visitInterfaceType(
- InterfaceType(coreTypes.futureClass, [typeParam]));
+ InterfaceType(_coreTypes.futureClass, [typeParam]));
body.add(js.statement('''
#.is = function is_FutureOr(o) {
return #.is(o) || #.is(o);
@@ -1123,7 +1122,7 @@
void _emitClassMetadata(List<Expression> metadata,
js_ast.Expression className, List<js_ast.Statement> body) {
// Metadata
- if (emitMetadata && metadata.isNotEmpty) {
+ if (_options.emitMetadata && metadata.isNotEmpty) {
body.add(js.statement('#[#.metadata] = #;', [
className,
runtimeModule,
@@ -1135,7 +1134,7 @@
/// Ensure `dartx.` symbols we will use are present.
void _initExtensionSymbols(Class c) {
- if (_extensionTypes.hasNativeSubtype(c) || c == coreTypes.objectClass) {
+ if (_extensionTypes.hasNativeSubtype(c) || c == _coreTypes.objectClass) {
for (var m in c.procedures) {
if (!m.isAbstract && !m.isStatic && !m.name.isPrivate) {
_declareMemberName(m, useExtension: true);
@@ -1187,7 +1186,7 @@
if (elements.isEmpty) return;
if (!name.startsWith('Static')) {
- var proto = c == coreTypes.objectClass
+ var proto = c == _coreTypes.objectClass
? js.call('Object.create(null)')
: runtimeCall('get${name}s(#.__proto__)', [className]);
elements.insert(0, js_ast.Property(propertyName('__proto__'), proto));
@@ -1230,7 +1229,7 @@
for (var member in classProcedures) {
// Static getters/setters/methods cannot be called with dynamic dispatch,
// nor can they be torn off.
- if (!emitMetadata && member.isStatic) continue;
+ if (!_options.emitMetadata && member.isStatic) continue;
var name = member.name.name;
var reifiedType = _getMemberRuntimeType(member, c) as FunctionType;
@@ -1241,7 +1240,7 @@
// emit a signature on this class. Otherwise we will inherit the
// signature from the superclass.
var memberOverride = c.superclass != null
- ? hierarchy.getDispatchTarget(c.superclass, member.name,
+ ? _hierarchy.getDispatchTarget(c.superclass, member.name,
setter: member.isSetter)
: null;
@@ -1289,7 +1288,7 @@
for (var field in classFields) {
// Only instance fields need to be saved for dynamic dispatch.
var isStatic = field.isStatic;
- if (!emitMetadata && isStatic) continue;
+ if (!_options.emitMetadata && isStatic) continue;
var memberName = _declareMemberName(field);
var fieldSig = _emitFieldSignature(field, c);
@@ -1299,7 +1298,7 @@
emitSignature('Field', instanceFields);
emitSignature('StaticField', staticFields);
- if (emitMetadata) {
+ if (_options.emitMetadata) {
var constructors = <js_ast.Property>[];
var allConstructors = [
...c.constructors,
@@ -1316,9 +1315,9 @@
// Add static property dart._runtimeType to Object.
// All other Dart classes will (statically) inherit this property.
- if (c == coreTypes.objectClass) {
+ if (c == _coreTypes.objectClass) {
body.add(runtimeStatement('lazyFn(#, () => #.#)',
- [className, emitLibraryName(coreTypes.coreLibrary), 'Type']));
+ [className, emitLibraryName(_coreTypes.coreLibrary), 'Type']));
}
_classEmittingSignatures = savedClass;
@@ -1328,7 +1327,9 @@
var type = _getTypeFromClass(field.type, field.enclosingClass, fromClass);
var args = [_emitType(type)];
var annotations = field.annotations;
- if (emitMetadata && annotations != null && annotations.isNotEmpty) {
+ if (_options.emitMetadata &&
+ annotations != null &&
+ annotations.isNotEmpty) {
var savedUri = _currentUri;
_currentUri = field.enclosingClass.fileUri;
args.add(js_ast.ArrayInitializer(
@@ -1350,7 +1351,7 @@
result = f.functionType;
} else {
reifyParameter(VariableDeclaration p) =>
- isCovariantParameter(p) ? coreTypes.objectClass.thisType : p.type;
+ isCovariantParameter(p) ? _coreTypes.objectClass.thisType : p.type;
reifyNamedParameter(VariableDeclaration p) =>
NamedType(p.name, reifyParameter(p));
@@ -1370,7 +1371,7 @@
DartType _getTypeFromClass(DartType type, Class superclass, Class subclass) {
if (identical(superclass, subclass)) return type;
return Substitution.fromSupertype(
- hierarchy.getClassAsInstanceOf(subclass, superclass))
+ _hierarchy.getClassAsInstanceOf(subclass, superclass))
.substituteType(type);
}
@@ -1457,7 +1458,7 @@
js_ast.Statement _emitSuperConstructorCallIfNeeded(
Class c, js_ast.Expression className,
[SuperInitializer superInit]) {
- if (c == coreTypes.objectClass) return null;
+ if (c == _coreTypes.objectClass) return null;
Constructor ctor;
List<js_ast.Expression> args;
@@ -1494,7 +1495,7 @@
}
bool _hasUnnamedConstructor(Class c) {
- if (c == null || c == coreTypes.objectClass) return false;
+ if (c == null || c == _coreTypes.objectClass) return false;
var ctor = unnamedConstructor(c);
if (ctor != null && !ctor.isSynthetic) return true;
return c.fields.any((f) => !f.isStatic);
@@ -1611,7 +1612,7 @@
bool hasJsPeer = _extensionTypes.isNativeClass(c);
bool hasIterator = false;
- if (c == coreTypes.objectClass) {
+ if (c == _coreTypes.objectClass) {
// Dart does not use ES6 constructors.
// Add an error to catch any invalid usage.
jsMethods.add(
@@ -1746,7 +1747,7 @@
}
js_ast.Fun _emitNativeFunctionBody(Procedure node) {
- String name = getAnnotationName(node, isJSAnnotation) ?? node.name.name;
+ String name = _annotationName(node, isJSAnnotation) ?? node.name.name;
if (node.isGetter) {
return js_ast.Fun([], js.block('{ return this.#; }', [name]));
} else if (node.isSetter) {
@@ -1787,7 +1788,7 @@
return const [];
}
var setterType = substituteType(superMember.setterType);
- if (types.isTop(setterType)) return const [];
+ if (_types.isTop(setterType)) return const [];
return [
js_ast.Method(
name,
@@ -1922,7 +1923,7 @@
var jsMethods = <js_ast.Method>[];
assert(!field.isStatic);
- var name = getAnnotationName(field, isJSName) ?? field.name.name;
+ var name = _annotationName(field, isJSName) ?? field.name.name;
// Generate getter
var fn = js_ast.Fun([], js.block('{ return this.#; }', [name]));
var method = js_ast.Method(_declareMemberName(field), fn, isGetter: true);
@@ -1979,21 +1980,21 @@
/// otherwise it returns the adapter code.
// TODO(jmesserly): should we adapt `Iterator` too?
js_ast.Method _emitIterable(Class c) {
- var iterable = hierarchy.getClassAsInstanceOf(c, coreTypes.iterableClass);
+ var iterable = _hierarchy.getClassAsInstanceOf(c, _coreTypes.iterableClass);
if (iterable == null) return null;
// If a parent had an `iterator` (concrete or abstract) or implements
// Iterable, we know the adapter is already there, so we can skip it as a
// simple code size optimization.
- var parent = hierarchy.getDispatchTarget(c.superclass, Name('iterator'));
+ var parent = _hierarchy.getDispatchTarget(c.superclass, Name('iterator'));
if (parent != null) return null;
var parentIterable =
- hierarchy.getClassAsInstanceOf(c.superclass, coreTypes.iterableClass);
+ _hierarchy.getClassAsInstanceOf(c.superclass, _coreTypes.iterableClass);
if (parentIterable != null) return null;
if (c.enclosingLibrary.importUri.scheme == 'dart' &&
- c.procedures.any((m) => getJSExportName(m) == 'Symbol.iterator')) {
+ c.procedures.any((m) => _jsExportName(m) == 'Symbol.iterator')) {
return null;
}
@@ -2003,7 +2004,7 @@
js.call('Symbol.iterator'),
js.call('function() { return new #.JsIterator(this.#); }', [
runtimeModule,
- _emitMemberName('iterator', memberClass: coreTypes.iterableClass)
+ _emitMemberName('iterator', memberClass: _coreTypes.iterableClass)
]) as js_ast.Fun);
}
@@ -2184,7 +2185,7 @@
// SDK code. These renames need to be included at every declaration,
// including overrides in subclasses.
if (member != null) {
- var runtimeName = getJSExportName(member);
+ var runtimeName = _jsExportName(member);
if (runtimeName != null) {
var parts = runtimeName.split('.');
if (parts.length < 2) return propertyName(runtimeName);
@@ -2224,7 +2225,7 @@
/// one without renaming.
bool _isSymbolizedMember(Class c, String name) {
if (c == null) {
- return isObjectMember(name);
+ return _isObjectMember(name);
}
c = _typeRep.getImplementationClass(c.rawType) ?? c;
if (_extensionTypes.isNativeClass(c)) {
@@ -2233,7 +2234,7 @@
// Fields on a native class are implicitly native.
// Methods/getters/setters are marked external/native.
if (member is Field || member is Procedure && member.isExternal) {
- var jsName = getAnnotationName(member, isJSName);
+ var jsName = _annotationName(member, isJSName);
return jsName != null && jsName != name;
} else {
// Non-external members must be symbolized.
@@ -2258,8 +2259,8 @@
return map.putIfAbsent(
name,
() =>
- hierarchy.getDispatchTarget(c, Name(name)) ??
- hierarchy.getDispatchTarget(c, Name(name), setter: true));
+ _hierarchy.getDispatchTarget(c, Name(name)) ??
+ _hierarchy.getDispatchTarget(c, Name(name), setter: true));
}
js_ast.Expression _emitStaticMemberName(String name, [NamedNode member]) {
@@ -2296,7 +2297,7 @@
js_ast.Expression _emitJSInteropStaticMemberName(NamedNode n) {
if (!usesJSInterop(n)) return null;
- var name = getAnnotationName(n, isPublicJSAnnotation);
+ var name = _annotationName(n, isPublicJSAnnotation);
if (name != null) {
if (name.contains('.')) {
throw UnsupportedError(
@@ -2320,15 +2321,14 @@
/// NOTE: usually you should use [_emitTopLevelName] instead of this. This
/// function does not handle JS interop.
js_ast.Expression _emitTopLevelMemberName(NamedNode n, {String suffix = ''}) {
- var name = getJSExportName(n) ?? getTopLevelName(n);
+ var name = _jsExportName(n) ?? getTopLevelName(n);
return propertyName(name + suffix);
}
String _getJSNameWithoutGlobal(NamedNode n) {
if (!usesJSInterop(n)) return null;
- var libraryJSName = getAnnotationName(getLibrary(n), isPublicJSAnnotation);
- var jsName =
- getAnnotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
+ var libraryJSName = _annotationName(getLibrary(n), isPublicJSAnnotation);
+ var jsName = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
}
@@ -2402,7 +2402,7 @@
// dart:mirrors is enabled.
// TODO(jmesserly): do we even need this for mirrors, since statics are not
// commonly reflected on?
- if (emitMetadata && _reifyFunctionType(p.function)) {
+ if (_options.emitMetadata && _reifyFunctionType(p.function)) {
body.add(
_emitFunctionTagged(nameExpr, p.function.functionType, topLevel: true)
.toStatement());
@@ -2593,7 +2593,7 @@
/// Kernel represents `<T>` as `<T extends Object = dynamic>`. We can find
/// explicit bounds by looking for anything *except* that.
typeParameterHasExplicitBound(TypeParameter t) =>
- t.bound != types.objectType || t.defaultType != const DynamicType();
+ t.bound != _types.objectType || t.defaultType != const DynamicType();
// If any explicit bounds were passed, emit them.
if (typeFormals.any(typeParameterHasExplicitBound)) {
@@ -2629,7 +2629,7 @@
var result = visitFunctionType(type, member: member);
var annotations = member.annotations;
- if (emitMetadata && annotations.isNotEmpty) {
+ if (_options.emitMetadata && annotations.isNotEmpty) {
// TODO(jmesserly): should we disable source info for annotations?
var savedUri = _currentUri;
_currentUri = member.enclosingClass.fileUri;
@@ -2661,7 +2661,7 @@
// responsible for unpacking this.
js_ast.Expression _emitAnnotatedResult(
js_ast.Expression result, List<Expression> metadata, Member member) {
- if (emitMetadata && metadata.isNotEmpty) {
+ if (_options.emitMetadata && metadata.isNotEmpty) {
// TODO(jmesserly): should we disable source info for annotations?
var savedUri = _currentUri;
_currentUri = member.enclosingClass.fileUri;
@@ -2824,9 +2824,9 @@
}
var returnType =
- _getExpectedReturnType(function, coreTypes.iterableClass);
+ _getExpectedReturnType(function, _coreTypes.iterableClass);
var syncIterable =
- _emitType(InterfaceType(syncIterableClass, [returnType]));
+ _emitType(InterfaceType(_syncIterableClass, [returnType]));
return js.call('new #.new(#)', [syncIterable, gen]);
}
@@ -2840,8 +2840,8 @@
// _AsyncStarImpl has an example of the generated code.
var gen = emitGeneratorFn((_) => [_asyncStarController]);
- var returnType = _getExpectedReturnType(function, coreTypes.streamClass);
- var asyncStarImpl = InterfaceType(asyncStarImplClass, [returnType]);
+ var returnType = _getExpectedReturnType(function, _coreTypes.streamClass);
+ var asyncStarImpl = InterfaceType(_asyncStarImplClass, [returnType]);
return js.call('new #.new(#).stream', [_emitType(asyncStarImpl), gen]);
}
@@ -2859,16 +2859,16 @@
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.functionType.returnType);
return js.call('#.async(#, #)',
- [emitLibraryName(coreTypes.asyncLibrary), _emitType(returnType), gen]);
+ [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;
if (type is InterfaceType) {
- var match = hierarchy.getTypeAsInstanceOf(type, expected);
+ var match = _hierarchy.getTypeAsInstanceOf(type, expected);
if (match != null) return match.typeArguments[0];
}
return const DynamicType();
@@ -3021,7 +3021,7 @@
void _emitCovarianceBoundsCheck(
List<TypeParameter> typeFormals, List<js_ast.Statement> body) {
for (var t in typeFormals) {
- if (t.isGenericCovariantImpl && !types.isTop(t.bound)) {
+ if (t.isGenericCovariantImpl && !_types.isTop(t.bound)) {
body.add(runtimeStatement('checkTypeBound(#, #, #)', [
_emitType(TypeParameterType(t)),
_emitType(t.bound),
@@ -3090,7 +3090,7 @@
}
if (node is AsExpression && node.isTypeError) {
- assert(node.getStaticType(types) == types.boolType);
+ assert(node.getStaticType(_types) == _types.boolType);
return runtimeCall('dtest(#)', [_visitExpression(node.operand)]);
}
@@ -3211,12 +3211,12 @@
@override
js_ast.Statement visitAssertStatement(AssertStatement node) {
- if (!options.enableAsserts) return js_ast.EmptyStatement();
+ if (!_options.enableAsserts) return js_ast.EmptyStatement();
var condition = node.condition;
- var conditionType = condition.getStaticType(types);
+ var conditionType = condition.getStaticType(_types);
var jsCondition = _visitExpression(condition);
- var boolType = coreTypes.boolClass.rawType;
+ var boolType = _coreTypes.boolClass.rawType;
if (conditionType is FunctionType &&
conditionType.requiredParameterCount == 0 &&
conditionType.returnType == boolType) {
@@ -3337,7 +3337,7 @@
// (targeting the loop). Find the outermost non-labeled statement starting
// from body and record all the intermediate labeled statements as continue
// targets.
- Statement effectiveBodyOf(Statement loop, Statement body) {
+ Statement _effectiveBodyOf(Statement loop, Statement body) {
// In a loop whose body is not labeled, this list should be empty because
// it is not possible to continue to an outer loop without a label.
_currentContinueTargets = <LabeledStatement>[];
@@ -3350,7 +3350,7 @@
return body;
}
- T translateLoop<T extends js_ast.Statement>(Statement node, T action()) {
+ T _translateLoop<T extends js_ast.Statement>(Statement node, T action()) {
List<LabeledStatement> savedBreakTargets;
if (_currentBreakTargets.isNotEmpty &&
_effectiveTargets[_currentBreakTargets.first] != node) {
@@ -3371,17 +3371,17 @@
@override
js_ast.While visitWhileStatement(WhileStatement node) {
- return translateLoop(node, () {
+ return _translateLoop(node, () {
var condition = _visitTest(node.condition);
- var body = _visitScope(effectiveBodyOf(node, node.body));
+ var body = _visitScope(_effectiveBodyOf(node, node.body));
return js_ast.While(condition, body);
});
}
@override
js_ast.Do visitDoStatement(DoStatement node) {
- return translateLoop(node, () {
- var body = _visitScope(effectiveBodyOf(node, node.body));
+ return _translateLoop(node, () {
+ var body = _visitScope(_effectiveBodyOf(node, node.body));
var condition = _visitTest(node.condition);
return js_ast.Do(body, condition);
});
@@ -3389,7 +3389,7 @@
@override
js_ast.For visitForStatement(ForStatement node) {
- return translateLoop(node, () {
+ return _translateLoop(node, () {
emitForInitializer(VariableDeclaration v) =>
js_ast.VariableInitialization(_emitVariableDef(v),
_visitInitializer(v.initializer, v.annotations));
@@ -3405,7 +3405,7 @@
.toVoidExpression();
}
var condition = _visitTest(node.condition);
- var body = _visitScope(effectiveBodyOf(node, node.body));
+ var body = _visitScope(_effectiveBodyOf(node, node.body));
return js_ast.For(initList, condition, update, body);
});
@@ -3413,13 +3413,13 @@
@override
js_ast.Statement visitForInStatement(ForInStatement node) {
- return translateLoop(node, () {
+ return _translateLoop(node, () {
if (node.isAsync) {
return _emitAwaitFor(node);
}
var iterable = _visitExpression(node.iterable);
- var body = _visitScope(effectiveBodyOf(node, node.body));
+ var body = _visitScope(_effectiveBodyOf(node, node.body));
var init = js.call('let #', _emitVariableDef(node.variable));
if (_annotatedNullCheck(node.variable.annotations)) {
@@ -3500,7 +3500,7 @@
var labelState = js_ast.TemporaryId("labelState");
// TODO(markzipan): Retrieve the real label name with source offsets
var labelName = 'SL${_switchLabelStates.length}';
- _switchLabelStates[node] = SwitchLabelState(labelName, labelState);
+ _switchLabelStates[node] = _SwitchLabelState(labelName, labelState);
for (var c in node.cases) {
var subcases =
@@ -3689,7 +3689,7 @@
var then = js_ast.Block(body);
// Discard following clauses, if any, as they are unreachable.
- if (types.isTop(node.guard)) return then;
+ if (_types.isTop(node.guard)) return then;
var condition =
_emitIsExpression(VariableGet(exceptionParameter), node.guard);
@@ -3856,7 +3856,7 @@
// encoded as a different node, or possibly eliminated?
// (Regardless, we'll still need to handle the callable JS interop classes.)
if (memberName == 'call' &&
- _isDirectCallable(receiver.getStaticType(types))) {
+ _isDirectCallable(receiver.getStaticType(_types))) {
// Tearoff of `call` on a function type is a no-op;
return _visitExpression(receiver);
}
@@ -3866,7 +3866,7 @@
// TODO(jmesserly): we need to mark an end span for property accessors so
// they can be hovered. Unfortunately this is not possible as Kernel does
// not store this data.
- if (isObjectMember(memberName)) {
+ if (_isObjectMember(memberName)) {
if (isNullable(receiver)) {
// If the receiver is nullable, use a helper so calls like
// `null.hashCode` and `null.runtimeType` will work.
@@ -3891,7 +3891,7 @@
// TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
// _emitMemberName would be a nice place to handle it, but we don't have
// access to the target expression there (needed for `dart.replNameLookup`).
- String get _replSuffix => options.replCompile ? 'Repl' : '';
+ String get _replSuffix => _options.replCompile ? 'Repl' : '';
js_ast.Expression _emitPropertySet(
Expression receiver, Member member, Expression value,
@@ -3981,7 +3981,7 @@
target.hasGetter &&
_isDynamicOrFunction(target.getterType);
if (name == 'call') {
- var receiverType = receiver.getStaticType(types);
+ var receiverType = receiver.getStaticType(_types);
if (isCallingDynamicField || _isDynamicOrFunction(receiverType)) {
return _emitDynamicInvoke(jsReceiver, null, args, arguments);
} else if (_isDirectCallable(receiverType)) {
@@ -4060,7 +4060,7 @@
js_ast.Expression _getImplicitCallTarget(InterfaceType from) {
var c = from.classNode;
- var member = hierarchy.getInterfaceMember(c, Name("call"));
+ var member = _hierarchy.getInterfaceMember(c, Name("call"));
if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
return _emitMemberName('call', member: member);
}
@@ -4068,7 +4068,7 @@
}
bool _isDynamicOrFunction(DartType t) =>
- t == coreTypes.functionClass.rawType || t == const DynamicType();
+ t == _coreTypes.functionClass.rawType || t == const DynamicType();
js_ast.Expression _emitUnaryOperator(
Expression expr, Member target, InvocationExpression node) {
@@ -4245,10 +4245,10 @@
if (target != null) {
var targetClass = target.enclosingClass;
var leftType = targetClass.rawType;
- var rightType = right.getStaticType(types);
+ var rightType = right.getStaticType(_types);
if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
- leftType == types.stringType && op == '+') {
+ leftType == _types.stringType && op == '+') {
// Inline operations on primitive types where possible.
// TODO(jmesserly): inline these from dart:core instead of hardcoding
// the implementation details here.
@@ -4343,7 +4343,7 @@
Expression left, Member target, Expression right,
{bool negated = false}) {
var targetClass = target?.enclosingClass;
- var leftType = targetClass?.rawType ?? left.getStaticType(types);
+ var leftType = targetClass?.rawType ?? left.getStaticType(_types);
// Conceptually `x == y` in Dart is defined as:
//
@@ -4433,7 +4433,7 @@
/// [jsTarget].[jsName], replacing `super` if it is not allowed in scope.
js_ast.PropertyAccess _emitSuperTarget(Member member, {bool setter = false}) {
var jsName = _emitMemberName(member.name.name, member: member);
- if (member is Field && !virtualFields.isVirtual(member)) {
+ if (member is Field && !_virtualFields.isVirtual(member)) {
return js_ast.PropertyAccess(js_ast.This(), jsName);
}
if (_superAllowed) return js_ast.PropertyAccess(js_ast.Super(), jsName);
@@ -4497,7 +4497,7 @@
return getExtensionSymbolInternal(firstArg.value);
}
}
- if (target == coreTypes.identicalProcedure) {
+ if (target == _coreTypes.identicalProcedure) {
return _emitCoreIdenticalCall(node.arguments.positional);
}
if (_isDebuggerCall(target)) {
@@ -4561,7 +4561,7 @@
if (target is Procedure && target.isStatic && target.isExternal) {
var nativeName = _extensionTypes.getNativePeers(c);
if (nativeName.isNotEmpty) {
- var memberName = getAnnotationName(target, isJSName) ??
+ var memberName = _annotationName(target, isJSName) ??
_emitStaticMemberName(target.name.name, target);
return runtimeCall('global.#.#', [nativeName[0], memberName]);
}
@@ -4643,7 +4643,7 @@
bool _isNull(Expression expr) =>
expr is NullLiteral ||
- expr.getStaticType(types) == coreTypes.nullClass.rawType;
+ expr.getStaticType(_types) == _coreTypes.nullClass.rawType;
bool _doubleEqIsIdentity(Expression left, Expression right) {
// If we statically know LHS or RHS is null we can use ==.
@@ -4651,7 +4651,7 @@
// If the representation of the two types will not induce conversion in
// JS then we can use == .
return !_typeRep.equalityMayConvert(
- left.getStaticType(types), right.getStaticType(types));
+ left.getStaticType(_types), right.getStaticType(_types));
}
bool _tripleEqIsIdentity(Expression left, Expression right) {
@@ -4697,7 +4697,7 @@
}
var code = negated ? '!#' : '#';
return js.call(code,
- js_ast.Call(_emitTopLevelName(coreTypes.identicalProcedure), jsArgs));
+ js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs));
}
@override
@@ -4722,7 +4722,7 @@
? ctorClass.rawType
: InterfaceType(ctorClass, args.types);
- if (isFromEnvironmentInvocation(coreTypes, node)) {
+ if (isFromEnvironmentInvocation(_coreTypes, node)) {
var value = _constants.evaluate(node);
if (value is PrimitiveConstant) {
return value.accept(this) as js_ast.Expression;
@@ -4779,7 +4779,7 @@
var typeArgs = type.typeArguments;
if (typeArgs.isEmpty) return _emitType(type);
identity ??= _typeRep.isPrimitive(typeArgs[0]);
- var c = identity ? identityHashMapImplClass : linkedHashMapImplClass;
+ var c = identity ? _identityHashMapImplClass : _linkedHashMapImplClass;
return _emitType(InterfaceType(c, typeArgs));
}
@@ -4787,7 +4787,7 @@
var typeArgs = type.typeArguments;
if (typeArgs.isEmpty) return _emitType(type);
identity ??= _typeRep.isPrimitive(typeArgs[0]);
- var c = identity ? identityHashSetImplClass : linkedHashSetImplClass;
+ var c = identity ? _identityHashSetImplClass : _linkedHashSetImplClass;
return _emitType(InterfaceType(c, typeArgs));
}
@@ -4810,7 +4810,7 @@
operand.receiver, operand.target, operand.arguments.positional[0],
negated: true);
} else if (operand is StaticInvocation &&
- operand.target == coreTypes.identicalProcedure) {
+ operand.target == _coreTypes.identicalProcedure) {
return _emitCoreIdenticalCall(operand.arguments.positional,
negated: true);
}
@@ -4845,7 +4845,7 @@
if (jsExpr is js_ast.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
continue;
}
- parts.add(e.getStaticType(types) == types.stringType && !isNullable(e)
+ parts.add(e.getStaticType(_types) == _types.stringType && !isNullable(e)
? jsExpr
: runtimeCall('str(#)', [jsExpr]));
}
@@ -4864,7 +4864,7 @@
node.accept(this);
if (node is ConstantExpression) {
var list = node.constant as ListConstant;
- entries.addAll(list.entries.map(visitConstant));
+ entries.addAll(list.entries.map(_visitConstant));
} else if (node is ListLiteral) {
entries.addAll(node.expressions.map(_visitExpression));
}
@@ -4886,7 +4886,7 @@
node.accept(this);
if (node is ConstantExpression) {
var set = node.constant as SetConstant;
- entries.addAll(set.entries.map(visitConstant));
+ entries.addAll(set.entries.map(_visitConstant));
} else if (node is SetLiteral) {
entries.addAll(node.expressions.map(_visitExpression));
}
@@ -4909,8 +4909,8 @@
if (node is ConstantExpression) {
var map = node.constant as MapConstant;
for (var entry in map.entries) {
- entries.add(visitConstant(entry.key));
- entries.add(visitConstant(entry.value));
+ entries.add(_visitConstant(entry.key));
+ entries.add(_visitConstant(entry.value));
}
} else if (node is MapLiteral) {
for (var entry in node.entries) {
@@ -4928,7 +4928,7 @@
@override
js_ast.Expression visitInstanceCreation(InstanceCreation node) {
// Only occurs inside unevaluated constants.
- throw new UnsupportedError("Instance creation");
+ throw UnsupportedError("Instance creation");
}
@override
@@ -4941,7 +4941,7 @@
var lhs = _visitExpression(operand);
var typeofName = _typeRep.typeFor(type).primitiveTypeOf;
// Inline primitives other than int (which requires a Math.floor check).
- if (typeofName != null && type != types.intType) {
+ if (typeofName != null && type != _types.intType) {
return js.call('typeof # == #', [lhs, js.string(typeofName, "'")]);
} else {
return js.call('#.is(#)', [_emitType(type), lhs]);
@@ -4953,7 +4953,7 @@
Expression fromExpr = node.operand;
var to = node.type;
var jsFrom = _visitExpression(fromExpr);
- var from = fromExpr.getStaticType(types);
+ var from = fromExpr.getStaticType(_types);
// If the check was put here by static analysis to ensure soundness, we
// can't skip it. For example, one could implement covariant generic caller
@@ -4973,13 +4973,13 @@
// }
//
var isTypeError = node.isTypeError;
- if (!isTypeError && types.isSubtypeOf(from, to)) return jsFrom;
+ if (!isTypeError && _types.isSubtypeOf(from, to)) return jsFrom;
// 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.intClass.rawType &&
+ to == _coreTypes.intClass.rawType) {
// TODO(jmesserly): fuse this with notNull check.
// TODO(jmesserly): this does not correctly distinguish user casts from
// required-for-soundness casts.
@@ -4995,7 +4995,7 @@
js_ast.Expression _emitCast(js_ast.Expression expr, DartType type,
{bool implicit = true}) {
- if (types.isTop(type)) return expr;
+ if (_types.isTop(type)) return expr;
var code = implicit ? '#._check(#)' : '#.as(#)';
return js.call(code, [_emitType(type), expr]);
@@ -5066,7 +5066,7 @@
// TODO(markzipan): remove const check when we use front-end const eval
if (!node.isConst) {
var setType = visitInterfaceType(
- InterfaceType(linkedHashSetClass, [node.typeArgument]));
+ InterfaceType(_linkedHashSetClass, [node.typeArgument]));
if (node.expressions.isEmpty) {
return js.call('#.new()', [setType]);
}
@@ -5095,7 +5095,7 @@
// TODO(markzipan): remove const check when we use front-end const eval
if (!node.isConst) {
var mapType =
- _emitMapImplType(node.getStaticType(types) as InterfaceType);
+ _emitMapImplType(node.getStaticType(_types) as InterfaceType);
if (node.entries.isEmpty) {
return js.call('new #.new()', [mapType]);
}
@@ -5118,7 +5118,7 @@
js_ast.Expression visitFunctionExpression(FunctionExpression node) {
var fn = _emitArrowFunction(node);
if (!_reifyFunctionType(node.function)) return fn;
- return _emitFunctionTagged(fn, node.getStaticType(types) as FunctionType);
+ return _emitFunctionTagged(fn, node.getStaticType(_types) as FunctionType);
}
js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) {
@@ -5197,8 +5197,8 @@
jsBlock.accept(finder);
if (finder.hasYield) {
var genFn = js_ast.Fun([], jsBlock, isGenerator: true);
- var asyncLibrary = emitLibraryName(coreTypes.asyncLibrary);
- var returnType = _emitType(node.getStaticType(types));
+ var asyncLibrary = emitLibraryName(_coreTypes.asyncLibrary);
+ var returnType = _emitType(node.getStaticType(_types));
var asyncCall =
js.call('#.async(#, #)', [asyncLibrary, returnType, genFn]);
return js_ast.Yield(asyncCall);
@@ -5254,23 +5254,23 @@
/// Returns the name value of the `JSExportName` annotation (when compiling
/// the SDK), or `null` if there's none. This is used to control the name
/// under which functions are compiled and exported.
- String getJSExportName(NamedNode n) {
+ String _jsExportName(NamedNode n) {
var library = getLibrary(n);
if (library == null || library.importUri.scheme != 'dart') return null;
- return getAnnotationName(n, isJSExportNameAnnotation);
+ return _annotationName(n, isJSExportNameAnnotation);
}
/// If [node] has annotation matching [test] and the first argument is a
/// string, this returns the string value.
///
/// Calls [findAnnotation] followed by [getNameFromAnnotation].
- String getAnnotationName(NamedNode node, bool test(Expression value)) {
+ String _annotationName(NamedNode node, bool test(Expression value)) {
return _constants.getFieldValueFromAnnotation(
findAnnotation(node, test), 'name') as String;
}
- js_ast.Expression visitConstant(Constant node) =>
+ js_ast.Expression _visitConstant(Constant node) =>
node.accept(this) as js_ast.Expression;
@override
js_ast.Expression visitNullConstant(NullConstant node) =>
@@ -5315,8 +5315,8 @@
js_ast.Expression visitMapConstant(MapConstant node) {
var entries = [
for (var e in node.entries) ...[
- visitConstant(e.key),
- visitConstant(e.value),
+ _visitConstant(e.key),
+ _visitConstant(e.value),
],
];
return _emitConstMap(node.keyType, node.valueType, entries);
@@ -5324,11 +5324,11 @@
@override
js_ast.Expression visitListConstant(ListConstant node) => _emitConstList(
- node.typeArgument, node.entries.map(visitConstant).toList());
+ node.typeArgument, node.entries.map(_visitConstant).toList());
@override
js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet(
- node.typeArgument, node.entries.map(visitConstant).toList());
+ node.typeArgument, node.entries.map(_visitConstant).toList());
@override
js_ast.Expression visitInstanceConstant(InstanceConstant node) {
@@ -5339,7 +5339,7 @@
_emitMemberName(member.name.name, member: member), constant);
}
- var type = visitInterfaceType(node.getType(types) as InterfaceType);
+ var type = visitInterfaceType(node.getType(_types) as InterfaceType);
var prototype = js.call("#.prototype", [type]);
var properties = [
js_ast.Property(propertyName("__proto__"), prototype),
@@ -5361,7 +5361,7 @@
js_ast.Expression visitPartialInstantiationConstant(
PartialInstantiationConstant node) =>
runtimeCall('gbind(#, #)', [
- visitConstant(node.tearOffConstant),
+ _visitConstant(node.tearOffConstant),
node.types.map(_emitType).toList()
]);
@@ -5389,7 +5389,7 @@
///
/// Operator == is excluded, as it is handled as part of the equality binary
/// operator.
-bool isObjectMember(String name) {
+bool _isObjectMember(String name) {
// We could look these up on Object, but we have hard coded runtime helpers
// so it's not really providing any benefit.
switch (name) {
@@ -5417,9 +5417,9 @@
return false;
}
-class SwitchLabelState {
+class _SwitchLabelState {
String label;
js_ast.Identifier variable;
- SwitchLabelState(this.label, this.variable);
+ _SwitchLabelState(this.label, this.variable);
}
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 7ca09fb..4dc3d73 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -15,6 +15,7 @@
dev_dependencies:
sourcemap_testing:
path: ../sourcemap_testing
+ pedantic: ^1.8.0
test: any
testing:
path: ../testing
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 62fb349..2442d93 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -23,16 +23,16 @@
sdkRoot.resolve('tests/modular/'),
'tests/modular',
_options,
- new IOPipeline([
+ IOPipeline([
SourceToSummaryDillStep(),
DDKStep(),
RunD8(),
], cacheSharedModules: true));
}
-const dillId = const DataId("dill");
-const jsId = const DataId("js");
-const txtId = const DataId("txt");
+const dillId = DataId("dill");
+const jsId = DataId("js");
+const txtId = DataId("txt");
class SourceToSummaryDillStep implements IOModularStep {
@override
@@ -270,7 +270,7 @@
} else if (Platform.isMacOS) {
return 'third_party/d8/macos/d8';
}
- throw new UnsupportedError('Unsupported platform.');
+ throw UnsupportedError('Unsupported platform.');
}
Future<void> _createPackagesFile(
@@ -287,7 +287,7 @@
// 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 = new StringBuffer();
+ var packagesContents = StringBuffer();
if (module.isPackage) {
packagesContents.write('${module.name}:${module.packageBase}\n');
}
diff --git a/pkg/dev_compiler/test/sourcemap/common.dart b/pkg/dev_compiler/test/sourcemap/common.dart
index 86f1e30..f3e041e 100644
--- a/pkg/dev_compiler/test/sourcemap/common.dart
+++ b/pkg/dev_compiler/test/sourcemap/common.dart
@@ -7,7 +7,7 @@
import 'dart:io';
import 'package:path/path.dart' as path;
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import 'package:sourcemap_testing/src/stepping_helper.dart';
import 'package:testing/testing.dart';
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
index 33f0a99..653b25e 100644
--- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart
+++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -8,8 +8,8 @@
import 'dart:mirrors' show currentMirrorSystem;
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import 'package:path/path.dart' as path;
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
import 'package:sourcemap_testing/src/stacktrace_helper.dart';
import 'package:sourcemap_testing/src/stepping_helper.dart';
import 'package:testing/testing.dart';
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index c890b2e..f6b6a8c 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -9,9 +9,7 @@
import 'dart:io';
import 'dart:math' as math;
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart'
- show parseCompilationUnit, parseDirectives;
+import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -90,7 +88,7 @@
int inputModifyTime = math.max(selfModifyTime,
libraryFile.lastModifiedSync().millisecondsSinceEpoch);
var partFiles = <File>[];
- for (var part in parseDirectives(libraryContents).directives) {
+ for (var part in parseString(content: libraryContents).unit.directives) {
if (part is PartDirective) {
var partPath = part.uri.stringValue;
outPaths.add(path.join(path.dirname(libraryOut), partPath));
@@ -188,7 +186,7 @@
bool failed = false;
for (var partContent in partsContents) {
var partEdits = StringEditBuffer(partContent);
- var partUnit = parseCompilationUnit(partContent);
+ var partUnit = parseString(content: partContent).unit;
var patcher = PatchApplier(partEdits, patchFinder);
partUnit.accept(patcher);
if (!failed) failed = patcher.patchWasMissing;
@@ -229,12 +227,12 @@
int importPos = unit.directives
.lastWhere((d) => d is ImportDirective, orElse: () => libDir)
.end;
- for (var d in patch.unit.directives.where((d) => d is ImportDirective)) {
+ for (var d in patch.unit.directives.whereType<ImportDirective>()) {
_merge(d, importPos);
}
int partPos = unit.directives.last.end;
- for (var d in patch.unit.directives.where((d) => d is PartDirective)) {
+ for (var d in patch.unit.directives.whereType<PartDirective>()) {
_merge(d, partPos);
}
@@ -315,7 +313,7 @@
PatchFinder.parseAndVisit(String contents)
: contents = contents,
- unit = parseCompilationUnit(contents) {
+ unit = parseString(content: contents).unit {
visitCompilationUnit(unit);
}
@@ -482,6 +480,6 @@
// It doesn't understand optional new/const in Dart 2. For now, we keep
// redundant `const` in tool/input_sdk/libraries.dart as a workaround.
var libraryBuilder = SdkLibrariesReader_LibraryBuilder(true);
- parseCompilationUnit(contents).accept(libraryBuilder);
+ parseString(content: contents).unit.accept(libraryBuilder);
return libraryBuilder.librariesMap.sdkLibraries;
}
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 1d75bc5..14a2a0c 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -233,6 +233,8 @@
ExperimentalFlag flag = parseExperimentalFlag(experiment);
if (flag == null) {
onError("Unknown experiment: " + experiment);
+ } else if (flag == ExperimentalFlag.expiredFlag) {
+ print("Experiment flag no longer required: " + experiment);
} else if (flags.containsKey(flag)) {
if (flags[flag] != value) {
onError(
@@ -244,6 +246,7 @@
}
}
for (ExperimentalFlag flag in ExperimentalFlag.values) {
+ if (flag == ExperimentalFlag.expiredFlag) continue;
assert(defaultExperimentalFlags.containsKey(flag),
"No default value for $flag.");
flags[flag] ??= defaultExperimentalFlags[flag];
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 6428f9b..5c2f97e 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -12,9 +12,13 @@
controlFlowCollections,
extensionMethods,
nonNullable,
- setLiterals,
spreadCollections,
tripleShift,
+
+ // A placeholder representing an "expired" flag which has been removed
+ // from the codebase but still needs to be gracefully ignored
+ // when specified on the command line.
+ expiredFlag,
}
ExperimentalFlag parseExperimentalFlag(String flag) {
@@ -27,12 +31,14 @@
return ExperimentalFlag.extensionMethods;
case "non-nullable":
return ExperimentalFlag.nonNullable;
- case "set-literals":
- return ExperimentalFlag.setLiterals;
case "spread-collections":
return ExperimentalFlag.spreadCollections;
case "triple-shift":
return ExperimentalFlag.tripleShift;
+
+ // Expired flags
+ case "set-literals":
+ return ExperimentalFlag.expiredFlag;
}
return null;
}
@@ -42,7 +48,6 @@
ExperimentalFlag.controlFlowCollections: true,
ExperimentalFlag.extensionMethods: false,
ExperimentalFlag.nonNullable: false,
- ExperimentalFlag.setLiterals: true,
ExperimentalFlag.spreadCollections: true,
ExperimentalFlag.tripleShift: false,
};
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index c9969c5..2cd528c 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -105,7 +105,8 @@
..target = target
..fileSystem = fileSystem
..omitPlatform = true
- ..environmentDefines = const {};
+ ..environmentDefines = const {}
+ ..experimentalFlags = experimentalFlags;
processedOpts = new ProcessedOptions(options: options);
cachedSdkInput = WorkerInputComponent(
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 4c2076b..d761b49 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -131,6 +131,7 @@
Uri packagesFile,
Uri librariesSpecificationUri,
List<Uri> inputSummaries,
+ Map<Uri, List<int>> workerInputDigests,
Target target,
{FileSystem fileSystem,
Map<ExperimentalFlag, bool> experiments}) async {
@@ -143,12 +144,19 @@
Map<Uri, WorkerInputComponent> workerInputCache =
oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+ var sdkDigest = workerInputDigests[sdkSummary];
+ if (sdkDigest == null) {
+ throw new StateError("Expected to get sdk digest at $cachedSdkInput");
+ }
+
cachedSdkInput = workerInputCache[sdkSummary];
if (oldState == null ||
oldState.incrementalCompiler == null ||
oldState.options.compileSdk != compileSdk ||
- cachedSdkInput == null) {
+ cachedSdkInput == null ||
+ !digestsEqual(cachedSdkInput.digest, sdkDigest) ||
+ !equalMaps(oldState.options.experimentalFlags, experiments)) {
// No previous state.
options = new CompilerOptions()
..compileSdk = compileSdk
@@ -166,8 +174,8 @@
processedOpts = new ProcessedOptions(options: options);
- cachedSdkInput = new WorkerInputComponent(null /* not compared anyway */,
- await processedOpts.loadSdkSummary(null));
+ cachedSdkInput = new WorkerInputComponent(
+ sdkDigest, await processedOpts.loadSdkSummary(null));
workerInputCache[sdkSummary] = cachedSdkInput;
incrementalCompiler = new IncrementalCompiler.fromComponent(
new CompilerContext(processedOpts), cachedSdkInput.component);
@@ -207,10 +215,13 @@
for (int i = 0; i < inputSummaries.length; i++) {
Uri inputSummary = inputSummaries[i];
WorkerInputComponent cachedInput = workerInputCache[inputSummary];
+ var digest = workerInputDigests[inputSummary];
+ if (digest == null) {
+ throw new StateError("Expected to get digest for $inputSummary");
+ }
if (cachedInput == null ||
cachedInput.component.root != nameRoot ||
- !digestsEqual(await fileSystem.entityForUri(inputSummary).readAsBytes(),
- cachedInput.digest)) {
+ !digestsEqual(digest, cachedInput.digest)) {
loadFromDillIndexes.add(i);
} else {
// Need to reset cached components so they are usable again.
@@ -226,11 +237,15 @@
for (int i = 0; i < loadFromDillIndexes.length; i++) {
int index = loadFromDillIndexes[i];
Uri summary = inputSummaries[index];
- List<int> data = await fileSystem.entityForUri(summary).readAsBytes();
+ List<int> digest = workerInputDigests[summary];
+ if (digest == null) {
+ throw new StateError("Expected to get digest for $summary");
+ }
+ var bytes = await fileSystem.entityForUri(summary).readAsBytes();
WorkerInputComponent cachedInput = WorkerInputComponent(
- data,
+ digest,
await compilerState.processedOpts
- .loadComponent(data, nameRoot, alwaysCreateNewNamedNodes: true));
+ .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
workerInputCache[summary] = cachedInput;
doneInputSummaries[index] = cachedInput.component;
}
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 77ea7b9..5d814c2 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -34,14 +34,19 @@
export '../fasta/fasta_codes.dart'
show
LocatedMessage,
+ messageBytecodeLimitExceededTooManyArguments,
+ noLength,
templateFfiFieldAnnotation,
- templateFfiStructAnnotation,
templateFfiNotStatic,
templateFfiTypeInvalid,
templateFfiTypeMismatch,
templateFfiTypeUnsized,
templateFfiFieldInitializer,
- templateIllegalRecursiveType;
+ templateIllegalRecursiveType,
+ templateFfiDartTypeMismatch,
+ templateFfiExtendsOrImplementsSealedClass,
+ templateFfiStructGeneric,
+ templateFfiWrongStructInheritance;
export '../fasta/hybrid_file_system.dart' show HybridFileSystem;
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 51e0852..a818b67 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -27,6 +27,7 @@
show
ClassBuilder,
Declaration,
+ FieldBuilder,
ModifierBuilder,
NameIterator,
PrefixBuilder,
@@ -237,6 +238,8 @@
void recordAccess(int charOffset, int length, Uri fileUri) {}
void buildOutlineExpressions() {}
+
+ List<FieldBuilder> takeImplicitlyTypedFields() => null;
}
class LibraryLocalDeclarationIterator implements Iterator<Declaration> {
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 0b99bf5..e714210 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -4,6 +4,8 @@
library fasta.member_builder;
+import '../problems.dart' show unsupported;
+
import 'builder.dart'
show ClassBuilder, Declaration, LibraryBuilder, ModifierBuilder;
@@ -41,4 +43,10 @@
@override
String get fullNameForErrors => name;
+
+ void inferType() => unsupported("inferType", charOffset, fileUri);
+
+ void inferCopiedType(covariant Object other) {
+ unsupported("inferType", charOffset, fileUri);
+ }
}
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 b25813b..2055984 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -461,6 +461,15 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeBytecodeLimitExceededTooManyArguments =
+ messageBytecodeLimitExceededTooManyArguments;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageBytecodeLimitExceededTooManyArguments =
+ const MessageCode("BytecodeLimitExceededTooManyArguments",
+ message: r"""Dart bytecode limit exceeded: too many arguments.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeCandidateFound = messageCandidateFound;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -581,6 +590,36 @@
tip: r"""Try specifying the file explicitly with the --packages option.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateCantInferReturnTypeDueToInconsistentOverrides =
+ const Template<Message Function(String name)>(
+ messageTemplate:
+ r"""Can't infer a return type for '#name' as some of the inherited members have different types.""",
+ tipTemplate: r"""Try adding an explicit type.""",
+ withArguments:
+ _withArgumentsCantInferReturnTypeDueToInconsistentOverrides);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+ codeCantInferReturnTypeDueToInconsistentOverrides =
+ const Code<Message Function(String name)>(
+ "CantInferReturnTypeDueToInconsistentOverrides",
+ templateCantInferReturnTypeDueToInconsistentOverrides,
+ analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantInferReturnTypeDueToInconsistentOverrides(
+ String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeCantInferReturnTypeDueToInconsistentOverrides,
+ message:
+ """Can't infer a return type for '${name}' as some of the inherited members have different types.""",
+ tip: """Try adding an explicit type.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String
@@ -777,6 +816,38 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
+ String name,
+ String
+ name2)> templateCombinedMemberSignatureFailed = const Template<
+ Message Function(String name, String name2)>(
+ messageTemplate:
+ r"""Class '#name' inherits multiple members named '#name2' with incompatible signatures.""",
+ tipTemplate: r"""Try adding a declaration of '#name2' to '#name'.""",
+ withArguments: _withArgumentsCombinedMemberSignatureFailed);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String name2)>
+ codeCombinedMemberSignatureFailed =
+ const Code<Message Function(String name, String name2)>(
+ "CombinedMemberSignatureFailed", templateCombinedMemberSignatureFailed,
+ analyzerCodes: <String>["INCONSISTENT_INHERITANCE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCombinedMemberSignatureFailed(String name, String name2) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ return new Message(codeCombinedMemberSignatureFailed,
+ message:
+ """Class '${name}' inherits multiple members named '${name2}' with incompatible signatures.""",
+ tip: """Try adding a declaration of '${name2}' to '${name}'.""",
+ arguments: {'name': name, 'name2': name2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
String string,
String
string2)> templateConflictingModifiers = const Template<
@@ -3571,11 +3642,64 @@
-h Display this message (add -v for information about all options).""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(DartType _type, DartType _type2)>
+ templateFfiDartTypeMismatch =
+ const Template<Message Function(DartType _type, DartType _type2)>(
+ messageTemplate: r"""Expected '#type' to be a subtype of '#type2'.""",
+ withArguments: _withArgumentsFfiDartTypeMismatch);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, DartType _type2)>
+ codeFfiDartTypeMismatch =
+ const Code<Message Function(DartType _type, DartType _type2)>(
+ "FfiDartTypeMismatch",
+ templateFfiDartTypeMismatch,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiDartTypeMismatch(DartType _type, DartType _type2) {
+ TypeLabeler labeler = new TypeLabeler();
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeFfiDartTypeMismatch,
+ message: """Expected '${type}' to be a subtype of '${type2}'.""" +
+ labeler.originMessages,
+ arguments: {'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateFfiExtendsOrImplementsSealedClass =
+ const Template<Message Function(String name)>(
+ messageTemplate:
+ r"""Class '#name' cannot be extended or implemented.""",
+ withArguments: _withArgumentsFfiExtendsOrImplementsSealedClass);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+ codeFfiExtendsOrImplementsSealedClass =
+ const Code<Message Function(String name)>(
+ "FfiExtendsOrImplementsSealedClass",
+ templateFfiExtendsOrImplementsSealedClass,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiExtendsOrImplementsSealedClass(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeFfiExtendsOrImplementsSealedClass,
+ message: """Class '${name}' cannot be extended or implemented.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(String name)> templateFfiFieldAnnotation = const Template<
Message Function(String name)>(
messageTemplate:
- r"""Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+ r"""Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields.""",
withArguments: _withArgumentsFfiFieldAnnotation);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3591,7 +3715,7 @@
name = demangleMixinApplicationName(name);
return new Message(codeFfiFieldAnnotation,
message:
- """Field '${name}' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+ """Field '${name}' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields.""",
arguments: {'name': name});
}
@@ -3646,27 +3770,24 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
- Message Function(String name)> templateFfiStructAnnotation = const Template<
- Message Function(String name)>(
- messageTemplate:
- r"""Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
- withArguments: _withArgumentsFfiStructAnnotation);
+const Template<Message Function(String name)> templateFfiStructGeneric =
+ const Template<Message Function(String name)>(
+ messageTemplate: r"""Struct '#name' should not be generic.""",
+ withArguments: _withArgumentsFfiStructGeneric);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeFfiStructAnnotation =
+const Code<Message Function(String name)> codeFfiStructGeneric =
const Code<Message Function(String name)>(
- "FfiStructAnnotation",
- templateFfiStructAnnotation,
+ "FfiStructGeneric",
+ templateFfiStructGeneric,
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFfiStructAnnotation(String name) {
+Message _withArgumentsFfiStructGeneric(String name) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
- return new Message(codeFfiStructAnnotation,
- message:
- """Class '${name}' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
+ return new Message(codeFfiStructGeneric,
+ message: """Struct '${name}' should not be generic.""",
arguments: {'name': name});
}
@@ -3767,6 +3888,30 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateFfiWrongStructInheritance =
+ const Template<Message Function(String name)>(
+ messageTemplate:
+ r"""Struct '#name' must inherit from 'Struct<#name>'.""",
+ withArguments: _withArgumentsFfiWrongStructInheritance);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiWrongStructInheritance =
+ const Code<Message Function(String name)>(
+ "FfiWrongStructInheritance",
+ templateFfiWrongStructInheritance,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiWrongStructInheritance(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeFfiWrongStructInheritance,
+ message: """Struct '${name}' must inherit from 'Struct<${name}>'.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeFieldInitializedOutsideDeclaringClass =
messageFieldInitializedOutsideDeclaringClass;
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 71c58dc..691cdc7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2412,6 +2412,14 @@
}
@override
+ void endInvalidAwaitExpression(
+ Token keyword, Token endToken, fasta.MessageCode errorCode) {
+ debugEvent("AwaitExpression");
+ popForValue();
+ push(buildProblem(errorCode, keyword.offset, keyword.length));
+ }
+
+ @override
void handleAsyncModifier(Token asyncToken, Token starToken) {
debugEvent("AsyncModifier");
push(asyncMarkerFromTokens(asyncToken, starToken));
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 2593336..0960fca 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
@@ -8,14 +8,19 @@
show
Class,
DartType,
+ Field,
+ FunctionNode,
InterfaceType,
- TypeParameter,
+ InvalidType,
Library,
Member,
Name,
Procedure,
ProcedureKind,
- Supertype;
+ Supertype,
+ TypeParameter,
+ TypeParameterType,
+ VariableDeclaration;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -23,6 +28,8 @@
import 'package:kernel/type_algebra.dart' show Substitution;
+import '../dill/dill_member_builder.dart' show DillMemberBuilder;
+
import '../loader.dart' show Loader;
import '../messages.dart'
@@ -36,15 +43,23 @@
messageInheritedMembersConflictCause2,
messageStaticAndInstanceConflict,
messageStaticAndInstanceConflictCause,
+ templateCantInferReturnTypeDueToInconsistentOverrides,
+ templateCantInferTypeDueToInconsistentOverrides,
+ templateCombinedMemberSignatureFailed,
templateDuplicatedDeclaration,
templateDuplicatedDeclarationCause,
+ templateDuplicatedDeclarationUse,
templateMissingImplementationCause,
templateMissingImplementationNotAbstract;
import '../names.dart' show noSuchMethodName;
+import '../problems.dart' show unhandled;
+
import '../scope.dart' show Scope;
+import '../source/source_loader.dart' show SourceLoader;
+
import '../type_inference/standard_bounds.dart' show StandardBounds;
import '../type_inference/type_constraint_gatherer.dart'
@@ -56,18 +71,35 @@
import '../type_inference/type_schema_environment.dart' show TypeConstraint;
+import 'forwarding_node.dart' show ForwardingNode;
+
import 'kernel_builder.dart'
show
Declaration,
+ FormalParameterBuilder,
+ ImplicitFieldType,
KernelClassBuilder,
+ KernelFieldBuilder,
+ KernelLibraryBuilder,
KernelNamedTypeBuilder,
+ KernelProcedureBuilder,
KernelTypeBuilder,
+ KernelTypeVariableBuilder,
LibraryBuilder,
+ MemberBuilder,
TypeBuilder,
TypeVariableBuilder;
import 'types.dart' show Types;
+const DebugLogger debug =
+ const bool.fromEnvironment("debug.hierarchy") ? const DebugLogger() : null;
+
+class DebugLogger {
+ const DebugLogger();
+ void log(Object message) => print(message);
+}
+
int compareDeclarations(Declaration a, Declaration b) {
return ClassHierarchy.compareMembers(a.target, b.target);
}
@@ -94,6 +126,7 @@
if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
if (a.isSetter) return !(b.isGetter || b.isSetter);
if (b.isSetter) return !(a.isGetter || a.isSetter);
+ if (a is InterfaceConflict || b is InterfaceConflict) return false;
return true;
}
@@ -101,6 +134,68 @@
return declaration.isField && !(declaration.isFinal || declaration.isConst);
}
+bool hasSameSignature(FunctionNode a, FunctionNode b) {
+ List<TypeParameter> aTypeParameters = a.typeParameters;
+ List<TypeParameter> bTypeParameters = b.typeParameters;
+ int typeParameterCount = aTypeParameters.length;
+ if (typeParameterCount != bTypeParameters.length) return false;
+ Substitution substitution;
+ if (typeParameterCount != 0) {
+ List<DartType> types = new List<DartType>(typeParameterCount);
+ for (int i = 0; i < typeParameterCount; i++) {
+ types[i] = new TypeParameterType(aTypeParameters[i]);
+ }
+ substitution = Substitution.fromPairs(bTypeParameters, types);
+ for (int i = 0; i < typeParameterCount; i++) {
+ DartType aBound = aTypeParameters[i].bound;
+ DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+ if (aBound != bBound) return false;
+ }
+ }
+
+ if (a.requiredParameterCount != b.requiredParameterCount) return false;
+ List<VariableDeclaration> aPositionalParameters = a.positionalParameters;
+ List<VariableDeclaration> bPositionalParameters = b.positionalParameters;
+ if (aPositionalParameters.length != bPositionalParameters.length) {
+ return false;
+ }
+ for (int i = 0; i < aPositionalParameters.length; i++) {
+ VariableDeclaration aParameter = aPositionalParameters[i];
+ VariableDeclaration bParameter = bPositionalParameters[i];
+ if (aParameter.isCovariant != bParameter.isCovariant) return false;
+ DartType aType = aParameter.type;
+ DartType bType = bParameter.type;
+ if (substitution != null) {
+ bType = substitution.substituteType(bType);
+ }
+ if (aType != bType) return false;
+ }
+
+ List<VariableDeclaration> aNamedParameters = a.namedParameters;
+ List<VariableDeclaration> bNamedParameters = b.namedParameters;
+ if (aNamedParameters.length != bNamedParameters.length) return false;
+ for (int i = 0; i < aNamedParameters.length; i++) {
+ VariableDeclaration aParameter = aNamedParameters[i];
+ VariableDeclaration bParameter = bNamedParameters[i];
+ if (aParameter.isCovariant != bParameter.isCovariant) return false;
+ if (aParameter.name != bParameter.name) return false;
+ DartType aType = aParameter.type;
+ DartType bType = bParameter.type;
+ if (substitution != null) {
+ bType = substitution.substituteType(bType);
+ }
+ if (aType != bType) return false;
+ }
+
+ DartType aReturnType = a.returnType;
+ DartType bReturnType = b.returnType;
+ if (substitution != null) {
+ bReturnType = substitution.substituteType(bReturnType);
+ }
+
+ return aReturnType == bReturnType;
+}
+
class ClassHierarchyBuilder {
final Map<Class, ClassHierarchyNode> nodes = <Class, ClassHierarchyNode>{};
@@ -118,6 +213,10 @@
final Class nullKernelClass;
+ final List<DelayedOverrideCheck> overrideChecks = <DelayedOverrideCheck>[];
+
+ final List<DelayedMember> delayedMemberChecks = <DelayedMember>[];
+
// TODO(ahe): Remove this.
final CoreTypes coreTypes;
@@ -138,10 +237,8 @@
}
ClassHierarchyNode getNodeFromType(KernelTypeBuilder type) {
- Declaration declaration = type.declaration;
- return declaration is KernelClassBuilder
- ? getNodeFromClass(declaration)
- : null;
+ KernelClassBuilder cls = getClass(type);
+ return cls == null ? null : getNodeFromClass(cls);
}
ClassHierarchyNode getNodeFromKernelClass(Class cls) {
@@ -190,7 +287,9 @@
}
KernelNamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass);
if (supertype == null) return null;
- if (supertype.arguments == null) return superclass.rawType;
+ if (supertype.arguments == null && superclass.typeParameters.isEmpty) {
+ return superclass.rawType;
+ }
return Substitution.fromInterfaceType(type)
.substituteType(supertype.build(null));
}
@@ -232,17 +331,54 @@
return objectKernelClass.rawType;
}
+ Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) {
+ return getNodeFromKernelClass(cls)
+ .getInterfaceMember(name, isSetter)
+ ?.target;
+ }
+
+ Member getDispatchTargetKernel(Class cls, Name name, bool isSetter) {
+ return getNodeFromKernelClass(cls)
+ .getDispatchTarget(name, isSetter)
+ ?.target;
+ }
+
+ Member getCombinedMemberSignatureKernel(Class cls, Name name, bool isSetter,
+ int charOffset, KernelLibraryBuilder library) {
+ Declaration declaration =
+ getNodeFromKernelClass(cls).getInterfaceMember(name, isSetter);
+ if (declaration?.isStatic ?? true) return null;
+ if (declaration.next != null) {
+ library?.addProblem(
+ templateDuplicatedDeclarationUse.withArguments(name.name),
+ charOffset,
+ name.name.length,
+ library.fileUri);
+ return null;
+ }
+ if (declaration is DelayedMember) {
+ return declaration.check(this);
+ } else {
+ return declaration.target;
+ }
+ }
+
static ClassHierarchyBuilder build(
KernelClassBuilder objectClass,
List<KernelClassBuilder> classes,
- Loader<Object> loader,
+ SourceLoader loader,
CoreTypes coreTypes) {
ClassHierarchyBuilder hierarchy =
new ClassHierarchyBuilder(objectClass, loader, coreTypes);
for (int i = 0; i < classes.length; i++) {
KernelClassBuilder cls = classes[i];
- hierarchy.nodes[cls.target] =
- new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+ if (!cls.isPatch) {
+ hierarchy.nodes[cls.target] =
+ new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+ } else {
+ // TODO(ahe): Merge the injected members of patch into the hierarchy
+ // node of `cls.origin`.
+ }
}
return hierarchy;
}
@@ -261,6 +397,8 @@
KernelClassBuilder get objectClass => hierarchy.objectClass;
+ final Map<Class, Substitution> substitutions = <Class, Substitution>{};
+
/// When merging `aList` and `bList`, [a] (from `aList`) and [b] (from
/// `bList`) each have the same name.
///
@@ -271,44 +409,606 @@
///
/// If [mergeKind] is `MergeKind.supertypes`, [a] should implement [b], and
/// [b] is implicitly abstract.
- Declaration handleMergeConflict(KernelClassBuilder cls, Declaration a,
- Declaration b, MergeKind mergeKind) {
+ Declaration handleMergeConflict(
+ Declaration a, Declaration b, MergeKind mergeKind) {
+ debug?.log(
+ "handleMergeConflict: ${fullName(a)} ${fullName(b)} ${mergeKind}");
+ // TODO(ahe): Enable this optimization, but be careful about abstract
+ // methods overriding concrete methods.
+ // if (cls is DillClassBuilder) return a;
if (a == b) return a;
if (a.next != null || b.next != null) {
// Don't check overrides involving duplicated members.
return a;
}
- if (isInheritanceConflict(a, b)) {
- reportInheritanceConflict(cls, a, b);
- }
- Declaration result = a;
- if (mergeKind == MergeKind.accessors) {
- } else if (mergeKind == MergeKind.interfaces) {
- // TODO(ahe): Combine the signatures of a and b. See the section named
- // "Combined Member Signatures" in [Dart Programming Language
- // Specification](
- // ../../../../../../docs/language/dartLangSpec.tex#combinedMemberSignatures).
- } else if (a.target.isAbstract) {
- if (mergeKind == MergeKind.superclass && !b.target.isAbstract) {
- // An abstract method doesn't override an implemention inherited from a
- // superclass.
- result = b;
- } else {
- (abstractMembers ??= <Declaration>[]).add(a);
- }
- }
+ Declaration result = checkInheritanceConflict(a, b);
+ if (result != null) return result;
+ result = a;
+ switch (mergeKind) {
+ case MergeKind.superclassMembers:
+ case MergeKind.superclassSetters:
+ // [a] is a method declared in [cls]. This means it defines the
+ // interface of this class regardless if its abstract.
+ debug?.log(
+ "superclass: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+ checkValidOverride(
+ a, AbstractMemberOverridingImplementation.selectAbstract(b));
- if (mergeKind == MergeKind.superclass &&
- result.fullNameForErrors == noSuchMethodName.name &&
- result.parent != objectClass) {
- hasNoSuchMethod = true;
+ if (isAbstract(a)) {
+ if (isAbstract(b)) {
+ recordAbstractMember(a);
+ } else {
+ if (!cls.isAbstract) {
+ // The interface of this class is [a]. But the implementation is
+ // [b]. So [b] must implement [a], unless [cls] is abstract.
+ checkValidOverride(b, a);
+ }
+ result = new AbstractMemberOverridingImplementation(
+ cls,
+ a,
+ AbstractMemberOverridingImplementation.selectConcrete(b),
+ mergeKind == MergeKind.superclassSetters,
+ cls.library.loader == hierarchy.loader);
+ hierarchy.delayedMemberChecks.add(result);
+ }
+ } else if (cls.isMixinApplication && a.parent != cls) {
+ result = InheritedImplementationInterfaceConflict.combined(
+ cls,
+ a,
+ b,
+ mergeKind == MergeKind.superclassSetters,
+ cls.library.loader == hierarchy.loader,
+ isInheritableConflict: false);
+ if (result is DelayedMember) {
+ hierarchy.delayedMemberChecks.add(result);
+ }
+ }
+
+ Member target = result.target;
+ if (target.enclosingClass != objectClass.cls &&
+ target.name == noSuchMethodName) {
+ hasNoSuchMethod = true;
+ }
+ break;
+
+ case MergeKind.membersWithSetters:
+ case MergeKind.settersWithMembers:
+ if (a.parent == cls && b.parent != cls) {
+ if (a is KernelFieldBuilder) {
+ if (a.isFinal && b.isSetter) {
+ hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+ } else {
+ if (!inferFieldTypes(a, b)) {
+ hierarchy.overrideChecks
+ .add(new DelayedOverrideCheck(cls, a, b));
+ }
+ }
+ } else if (a is KernelProcedureBuilder) {
+ if (!inferMethodTypes(a, b)) {
+ hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+ }
+ }
+ }
+ break;
+
+ case MergeKind.interfacesMembers:
+ result = InterfaceConflict.combined(
+ cls, a, b, false, cls.library.loader == hierarchy.loader);
+ break;
+
+ case MergeKind.interfacesSetters:
+ result = InterfaceConflict.combined(
+ cls, a, b, true, cls.library.loader == hierarchy.loader);
+ break;
+
+ case MergeKind.supertypesMembers:
+ case MergeKind.supertypesSetters:
+ // [b] is inherited from an interface so it is implicitly abstract.
+
+ a = AbstractMemberOverridingImplementation.selectAbstract(a);
+ b = AbstractMemberOverridingImplementation.selectAbstract(b);
+
+ // If [a] is declared in this class, it defines the interface.
+ if (a.parent == cls) {
+ debug?.log(
+ "supertypes: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+ checkValidOverride(a, b);
+ if (a is DelayedMember && !a.isInheritableConflict) {
+ if (b is DelayedMember) {
+ b.addAllDeclarationsTo(a.declarations);
+ } else {
+ addDeclarationIfDifferent(b, a.declarations);
+ }
+ }
+ } else {
+ if (isAbstract(a)) {
+ result = InterfaceConflict.combined(
+ cls,
+ a,
+ b,
+ mergeKind == MergeKind.supertypesSetters,
+ cls.library.loader == hierarchy.loader);
+ } else {
+ result = InheritedImplementationInterfaceConflict.combined(
+ cls,
+ a,
+ b,
+ mergeKind == MergeKind.supertypesSetters,
+ cls.library.loader == hierarchy.loader);
+ }
+ debug?.log("supertypes: ${result}");
+ if (result is DelayedMember) {
+ hierarchy.delayedMemberChecks.add(result);
+ }
+ }
+ break;
}
return result;
}
- void reportInheritanceConflict(
- KernelClassBuilder cls, Declaration a, Declaration b) {
+ Declaration checkInheritanceConflict(Declaration a, Declaration b) {
+ if (a is DelayedMember) {
+ Declaration result;
+ for (int i = 0; i < a.declarations.length; i++) {
+ Declaration d = checkInheritanceConflict(a.declarations[i], b);
+ result ??= d;
+ }
+ return result;
+ }
+ if (b is DelayedMember) {
+ Declaration result;
+ for (int i = 0; i < b.declarations.length; i++) {
+ Declaration d = checkInheritanceConflict(a, b.declarations[i]);
+ result ??= d;
+ }
+ return result;
+ }
+ if (isInheritanceConflict(a, b)) {
+ reportInheritanceConflict(a, b);
+ return a;
+ }
+ return null;
+ }
+
+ bool inferMethodTypes(KernelProcedureBuilder a, Declaration b) {
+ debug?.log(
+ "Trying to infer types for ${fullName(a)} based on ${fullName(b)}");
+ if (b is DelayedMember) {
+ bool hasSameSignature = true;
+ List<Declaration> declarations = b.declarations;
+ for (int i = 0; i < declarations.length; i++) {
+ if (!inferMethodTypes(a, declarations[i])) {
+ hasSameSignature = false;
+ }
+ }
+ return hasSameSignature;
+ }
+ if (a.isGetter) {
+ return inferGetterType(a, b);
+ } else if (a.isSetter) {
+ return inferSetterType(a, b);
+ }
+ bool hadTypesInferred = a.hadTypesInferred;
+ KernelClassBuilder aCls = a.parent;
+ Substitution aSubstitution;
+ if (cls != aCls) {
+ assert(substitutions.containsKey(aCls.target),
+ "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+ aSubstitution = substitutions[aCls.target];
+ debug?.log(
+ "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+ }
+ KernelClassBuilder bCls = b.parent;
+ Substitution bSubstitution;
+ if (cls != bCls) {
+ assert(substitutions.containsKey(bCls.target),
+ "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+ bSubstitution = substitutions[bCls.target];
+ debug?.log(
+ "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+ }
+ Procedure aProcedure = a.target;
+ if (b.target is! Procedure) {
+ debug?.log("Giving up 1");
+ return false;
+ }
+ Procedure bProcedure = b.target;
+ FunctionNode aFunction = aProcedure.function;
+ FunctionNode bFunction = bProcedure.function;
+
+ List<TypeParameter> aTypeParameters = aFunction.typeParameters;
+ List<TypeParameter> bTypeParameters = bFunction.typeParameters;
+ int typeParameterCount = aTypeParameters.length;
+ if (typeParameterCount != bTypeParameters.length) {
+ debug?.log("Giving up 2");
+ return false;
+ }
+ Substitution substitution;
+ if (typeParameterCount != 0) {
+ for (int i = 0; i < typeParameterCount; i++) {
+ copyTypeParameterCovariance(
+ a.parent, aTypeParameters[i], bTypeParameters[i]);
+ }
+ List<DartType> types = new List<DartType>(typeParameterCount);
+ for (int i = 0; i < typeParameterCount; i++) {
+ types[i] = new TypeParameterType(aTypeParameters[i]);
+ }
+ substitution = Substitution.fromPairs(bTypeParameters, types);
+ for (int i = 0; i < typeParameterCount; i++) {
+ DartType aBound = aTypeParameters[i].bound;
+ DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+ if (aBound != bBound) {
+ debug?.log("Giving up 3");
+ return false;
+ }
+ }
+ }
+
+ DartType aReturnType = aFunction.returnType;
+ if (aSubstitution != null) {
+ aReturnType = aSubstitution.substituteType(aReturnType);
+ }
+ DartType bReturnType = bFunction.returnType;
+ if (bSubstitution != null) {
+ bReturnType = bSubstitution.substituteType(bReturnType);
+ }
+ if (substitution != null) {
+ bReturnType = substitution.substituteType(bReturnType);
+ }
+ bool result = true;
+ if (aFunction.requiredParameterCount > bFunction.requiredParameterCount) {
+ debug?.log("Giving up 4");
+ return false;
+ }
+ List<VariableDeclaration> aPositional = aFunction.positionalParameters;
+ List<VariableDeclaration> bPositional = bFunction.positionalParameters;
+ if (aPositional.length < bPositional.length) {
+ debug?.log("Giving up 5");
+ return false;
+ }
+
+ if (aReturnType != bReturnType) {
+ if (a.parent == cls && a.returnType == null) {
+ result =
+ inferReturnType(cls, a, bReturnType, hadTypesInferred, hierarchy);
+ } else {
+ debug?.log("Giving up 6");
+ result = false;
+ }
+ }
+
+ for (int i = 0; i < bPositional.length; i++) {
+ VariableDeclaration aParameter = aPositional[i];
+ VariableDeclaration bParameter = bPositional[i];
+ copyParameterCovariance(a.parent, aParameter, bParameter);
+ DartType aType = aParameter.type;
+ if (aSubstitution != null) {
+ aType = aSubstitution.substituteType(aType);
+ }
+ DartType bType = bParameter.type;
+ if (bSubstitution != null) {
+ bType = bSubstitution.substituteType(bType);
+ }
+ if (substitution != null) {
+ bType = substitution.substituteType(bType);
+ }
+ if (aType != bType) {
+ if (a.parent == cls && a.formals[i].type == null) {
+ result = inferParameterType(
+ cls, a, a.formals[i], bType, hadTypesInferred, hierarchy);
+ } else {
+ debug?.log("Giving up 8");
+ result = false;
+ }
+ }
+ }
+
+ List<VariableDeclaration> aNamed = aFunction.namedParameters;
+ List<VariableDeclaration> bNamed = bFunction.namedParameters;
+ named:
+ if (aNamed.isNotEmpty || bNamed.isNotEmpty) {
+ if (aPositional.length != bPositional.length) {
+ debug?.log("Giving up 9");
+ result = false;
+ break named;
+ }
+ if (aFunction.requiredParameterCount !=
+ bFunction.requiredParameterCount) {
+ debug?.log("Giving up 10");
+ result = false;
+ break named;
+ }
+
+ aNamed = aNamed.toList()..sort(compareNamedParameters);
+ bNamed = bNamed.toList()..sort(compareNamedParameters);
+ int aCount = 0;
+ for (int bCount = 0; bCount < bNamed.length; bCount++) {
+ String name = bNamed[bCount].name;
+ for (; aCount < aNamed.length; aCount++) {
+ if (aNamed[aCount].name == name) break;
+ }
+ if (aCount == aNamed.length) {
+ debug?.log("Giving up 11");
+ result = false;
+ break named;
+ }
+ VariableDeclaration aParameter = aNamed[aCount];
+ VariableDeclaration bParameter = bNamed[bCount];
+ copyParameterCovariance(a.parent, aParameter, bParameter);
+ DartType aType = aParameter.type;
+ if (aSubstitution != null) {
+ aType = aSubstitution.substituteType(aType);
+ }
+ DartType bType = bParameter.type;
+ if (bSubstitution != null) {
+ bType = bSubstitution.substituteType(bType);
+ }
+ if (substitution != null) {
+ bType = substitution.substituteType(bType);
+ }
+ if (aType != bType) {
+ FormalParameterBuilder<KernelTypeBuilder> parameter;
+ for (int i = aPositional.length; i < a.formals.length; ++i) {
+ if (a.formals[i].name == name) {
+ parameter = a.formals[i];
+ break;
+ }
+ }
+ if (a.parent == cls && parameter.type == null) {
+ result = inferParameterType(
+ cls, a, parameter, bType, hadTypesInferred, hierarchy);
+ } else {
+ debug?.log("Giving up 12");
+ result = false;
+ }
+ }
+ }
+ }
+ debug?.log("Inferring types for ${fullName(a)} based on ${fullName(b)} " +
+ (result ? "succeeded." : "failed."));
+ return result;
+ }
+
+ bool inferGetterType(KernelProcedureBuilder a, Declaration b) {
+ debug?.log(
+ "Inferring getter types for ${fullName(a)} based on ${fullName(b)}");
+ Member bTarget = b.target;
+ DartType bType;
+ if (bTarget is Field) {
+ bType = bTarget.type;
+ } else if (bTarget is Procedure) {
+ if (b.isSetter) {
+ VariableDeclaration bParameter =
+ bTarget.function.positionalParameters.single;
+ bType = bParameter.type;
+ if (!hasExplicitlyTypedFormalParameter(b, 0)) {
+ debug?.log("Giving up (type may be inferred)");
+ return false;
+ }
+ } else if (b.isGetter) {
+ bType = bTarget.function.returnType;
+ if (!hasExplicitReturnType(b)) {
+ debug?.log("Giving up (return type may be inferred)");
+ return false;
+ }
+ } else {
+ debug?.log("Giving up (not accessor: ${bTarget.kind})");
+ return false;
+ }
+ } else {
+ debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+ return false;
+ }
+ return a.target.function.returnType == bType;
+ }
+
+ bool inferSetterType(KernelProcedureBuilder a, Declaration b) {
+ debug?.log(
+ "Inferring setter types for ${fullName(a)} based on ${fullName(b)}");
+ Member bTarget = b.target;
+ Procedure aProcedure = a.target;
+ VariableDeclaration aParameter =
+ aProcedure.function.positionalParameters.single;
+ DartType bType;
+ if (bTarget is Field) {
+ bType = bTarget.type;
+ copyParameterCovarianceFromField(a.parent, aParameter, bTarget);
+ }
+ if (bTarget is Procedure) {
+ if (b.isSetter) {
+ VariableDeclaration bParameter =
+ bTarget.function.positionalParameters.single;
+ bType = bParameter.type;
+ copyParameterCovariance(a.parent, aParameter, bParameter);
+ if (!hasExplicitlyTypedFormalParameter(b, 0) ||
+ !hasExplicitlyTypedFormalParameter(a, 0)) {
+ debug?.log("Giving up (type may be inferred)");
+ return false;
+ }
+ } else if (b.isGetter) {
+ bType = bTarget.function.returnType;
+ if (!hasExplicitReturnType(b)) {
+ debug?.log("Giving up (return type may be inferred)");
+ return false;
+ }
+ } else {
+ debug?.log("Giving up (not accessor: ${bTarget.kind})");
+ return false;
+ }
+ } else {
+ debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+ return false;
+ }
+ return aParameter.type == bType;
+ }
+
+ void checkValidOverride(Declaration a, Declaration b) {
+ debug?.log(
+ "checkValidOverride(${fullName(a)}, ${fullName(b)}) ${a.runtimeType}");
+ if (a is KernelProcedureBuilder) {
+ if (inferMethodTypes(a, b)) return;
+ } else if (a.isField) {
+ if (inferFieldTypes(a, b)) return;
+ }
+ Member aTarget = a.target;
+ Member bTarget = b.target;
+ if (aTarget is Procedure && !aTarget.isAccessor && bTarget is Procedure) {
+ if (hasSameSignature(aTarget.function, bTarget.function)) return;
+ }
+
+ if (b is DelayedMember) {
+ for (int i = 0; i < b.declarations.length; i++) {
+ hierarchy.overrideChecks
+ .add(new DelayedOverrideCheck(cls, a, b.declarations[i]));
+ }
+ } else {
+ hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+ }
+ }
+
+ bool inferFieldTypes(MemberBuilder a, Declaration b) {
+ debug?.log(
+ "Trying to infer field types for ${fullName(a)} based on ${fullName(b)}");
+ if (b is DelayedMember) {
+ bool hasSameSignature = true;
+ List<Declaration> declarations = b.declarations;
+ for (int i = 0; i < declarations.length; i++) {
+ if (!inferFieldTypes(a, declarations[i])) {
+ hasSameSignature = false;
+ }
+ }
+ return hasSameSignature;
+ }
+ Member bTarget = b.target;
+ DartType inheritedType;
+ if (bTarget is Procedure) {
+ if (bTarget.isSetter) {
+ VariableDeclaration parameter =
+ bTarget.function.positionalParameters.single;
+ // inheritedType = parameter.type;
+ copyFieldCovarianceFromParameter(a.parent, a.target, parameter);
+ if (!hasExplicitlyTypedFormalParameter(b, 0)) {
+ debug?.log("Giving up (type may be inferred)");
+ return false;
+ }
+ } else if (bTarget.isGetter) {
+ if (!hasExplicitReturnType(b)) return false;
+ inheritedType = bTarget.function.returnType;
+ }
+ } else if (bTarget is Field) {
+ copyFieldCovariance(a.parent, a.target, bTarget);
+ inheritedType = bTarget.type;
+ }
+ if (inheritedType == null) {
+ debug?.log("Giving up (inheritedType == null)\n${StackTrace.current}");
+ return false;
+ }
+ KernelClassBuilder aCls = a.parent;
+ Substitution aSubstitution;
+ if (cls != aCls) {
+ assert(substitutions.containsKey(aCls.target),
+ "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+ aSubstitution = substitutions[aCls.target];
+ debug?.log(
+ "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+ }
+ KernelClassBuilder bCls = b.parent;
+ Substitution bSubstitution;
+ if (cls != bCls) {
+ assert(substitutions.containsKey(bCls.target),
+ "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+ bSubstitution = substitutions[bCls.target];
+ debug?.log(
+ "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+ }
+ if (bSubstitution != null && inheritedType is! ImplicitFieldType) {
+ inheritedType = bSubstitution.substituteType(inheritedType);
+ }
+
+ DartType declaredType = a.target.type;
+ if (aSubstitution != null) {
+ declaredType = aSubstitution.substituteType(declaredType);
+ }
+ if (declaredType == inheritedType) return true;
+
+ bool result = false;
+ if (a is KernelFieldBuilder) {
+ if (a.parent == cls && a.type == null) {
+ if (a.hadTypesInferred) {
+ reportCantInferFieldType(cls, a);
+ inheritedType = const InvalidType();
+ } else {
+ result = true;
+ a.hadTypesInferred = true;
+ }
+ if (inheritedType is ImplicitFieldType) {
+ KernelLibraryBuilder library = cls.library;
+ (library.implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(a);
+ }
+ a.target.type = inheritedType;
+ }
+ }
+ return result;
+ }
+
+ void copyParameterCovariance(Declaration parent,
+ VariableDeclaration aParameter, VariableDeclaration bParameter) {
+ if (parent == cls) {
+ if (bParameter.isCovariant) {
+ aParameter.isCovariant = true;
+ }
+ if (bParameter.isGenericCovariantImpl) {
+ aParameter.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ void copyParameterCovarianceFromField(
+ Declaration parent, VariableDeclaration aParameter, Field bField) {
+ if (parent == cls) {
+ if (bField.isCovariant) {
+ aParameter.isCovariant = true;
+ }
+ if (bField.isGenericCovariantImpl) {
+ aParameter.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ void copyFieldCovariance(Declaration parent, Field aField, Field bField) {
+ if (parent == cls) {
+ if (bField.isCovariant) {
+ aField.isCovariant = true;
+ }
+ if (bField.isGenericCovariantImpl) {
+ aField.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ void copyFieldCovarianceFromParameter(
+ Declaration parent, Field aField, VariableDeclaration bParameter) {
+ if (parent == cls) {
+ if (bParameter.isCovariant) {
+ aField.isCovariant = true;
+ }
+ if (bParameter.isGenericCovariantImpl) {
+ aField.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ void copyTypeParameterCovariance(
+ Declaration parent, TypeParameter aParameter, TypeParameter bParameter) {
+ if (parent == cls) {
+ if (bParameter.isGenericCovariantImpl) {
+ aParameter.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ void reportInheritanceConflict(Declaration a, Declaration b) {
String name = a.fullNameForErrors;
if (a.parent != b.parent) {
if (a.parent == cls) {
@@ -374,8 +1074,17 @@
/// If [mergeKind] is `MergeKind.supertypes`, [member] isn't
/// implementing/overriding anything.
void handleOnlyA(Declaration member, MergeKind mergeKind) {
- if (mergeKind == MergeKind.superclass && member.target.isAbstract) {
- (abstractMembers ??= <Declaration>[]).add(member);
+ if (mergeKind == MergeKind.interfacesMembers ||
+ mergeKind == MergeKind.interfacesSetters) {
+ return;
+ }
+ // TODO(ahe): Enable this optimization:
+ // if (cls is DillClassBuilder) return;
+ // assert(mergeKind == MergeKind.interfaces || member is! InterfaceConflict);
+ if ((mergeKind == MergeKind.superclassMembers ||
+ mergeKind == MergeKind.superclassSetters) &&
+ isAbstract(member)) {
+ recordAbstractMember(member);
}
}
@@ -388,30 +1097,50 @@
///
/// If [mergeKind] is `MergeKind.supertypes`, [member] is implicitly
/// abstract, and not implemented.
- void handleOnlyB(
- KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
+ Declaration handleOnlyB(Declaration member, MergeKind mergeKind) {
+ if (mergeKind == MergeKind.interfacesMembers ||
+ mergeKind == MergeKind.interfacesSetters) {
+ return member;
+ }
+ // TODO(ahe): Enable this optimization:
+ // if (cls is DillClassBuilder) return member;
Member target = member.target;
- if (mergeKind == MergeKind.supertypes ||
- (mergeKind == MergeKind.superclass && target.isAbstract)) {
+ if ((mergeKind == MergeKind.supertypesMembers ||
+ mergeKind == MergeKind.supertypesSetters) ||
+ ((mergeKind == MergeKind.superclassMembers ||
+ mergeKind == MergeKind.superclassSetters) &&
+ target.isAbstract)) {
if (isNameVisibleIn(target.name, cls.library)) {
- (abstractMembers ??= <Declaration>[]).add(member);
+ recordAbstractMember(member);
}
}
- if (member.parent != objectClass &&
- target.name == noSuchMethodName &&
- !target.isAbstract) {
+ if (mergeKind == MergeKind.superclassMembers &&
+ target.enclosingClass != objectClass.cls &&
+ target.name == noSuchMethodName) {
hasNoSuchMethod = true;
}
+ if (mergeKind != MergeKind.membersWithSetters &&
+ mergeKind != MergeKind.settersWithMembers &&
+ member is DelayedMember &&
+ member.isInheritableConflict) {
+ hierarchy.delayedMemberChecks.add(member.withParent(cls));
+ }
+ return member;
+ }
+
+ void recordAbstractMember(Declaration member) {
+ abstractMembers ??= <Declaration>[];
+ if (member is DelayedMember) {
+ abstractMembers.addAll(member.declarations);
+ } else {
+ abstractMembers.add(member);
+ }
}
ClassHierarchyNode build() {
- if (cls.isPatch) {
- // TODO(ahe): What about patch classes. Have we injected patched members
- // into the class-builder's scope?
- return null;
- }
+ assert(!cls.isPatch);
ClassHierarchyNode supernode;
- if (objectClass != cls) {
+ if (objectClass != cls.origin) {
supernode = hierarchy.getNodeFromType(cls.supertype);
if (supernode == null) {
supernode = hierarchy.getNodeFromClass(objectClass);
@@ -423,8 +1152,10 @@
if (cls.isMixinApplication) {
Declaration mixin = cls.mixedInType.declaration;
inferMixinApplication();
+ // recordSupertype(cls.mixedInType);
while (mixin.isNamedMixinApplication) {
KernelClassBuilder named = mixin;
+ // recordSupertype(named.mixedInType);
mixin = named.mixedInType.declaration;
}
if (mixin is KernelClassBuilder) {
@@ -443,7 +1174,7 @@
..sort(compareDeclarations);
// Add implied setters from fields in [localMembers].
- localSetters = mergeAccessors(cls, localMembers, localSetters);
+ localSetters = mergeAccessors(localMembers, localSetters);
/// Members (excluding setters) declared in [cls] or its superclasses. This
/// includes static methods of [cls], but not its superclasses.
@@ -482,23 +1213,9 @@
new List<KernelTypeBuilder>(supernode.superclasses.length + 1);
superclasses.setRange(0, superclasses.length - 1,
substSupertypes(cls.supertype, supernode.superclasses));
- superclasses[superclasses.length - 1] = cls.supertype;
+ superclasses[superclasses.length - 1] = recordSupertype(cls.supertype);
- classMembers = merge(
- cls, localMembers, supernode.classMembers, MergeKind.superclass);
- classSetters = merge(
- cls, localSetters, supernode.classSetters, MergeKind.superclass);
-
- // Check if local members conflict with inherited setters. This check has
- // already been performed in the superclass, so we only need to check the
- // local members.
- merge(cls, localMembers, classSetters, MergeKind.accessors);
-
- // Check if local setters conflict with inherited members. As above, we
- // only need to check the local setters.
- merge(cls, localSetters, classMembers, MergeKind.accessors);
-
- List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+ List<KernelTypeBuilder> directInterfaces = ignoreFunction(cls.interfaces);
if (cls.isMixinApplication) {
if (directInterfaces == null) {
directInterfaces = <KernelTypeBuilder>[cls.mixedInType];
@@ -508,15 +1225,29 @@
}
}
if (directInterfaces != null) {
- MergeResult result = mergeInterfaces(cls, supernode, directInterfaces);
+ for (int i = 0; i < directInterfaces.length; i++) {
+ recordSupertype(directInterfaces[i]);
+ }
+ }
+ List<KernelTypeBuilder> superclassInterfaces = supernode.interfaces;
+ if (superclassInterfaces != null) {
+ superclassInterfaces =
+ substSupertypes(cls.supertype, superclassInterfaces);
+ }
+
+ classMembers = merge(
+ localMembers, supernode.classMembers, MergeKind.superclassMembers);
+ classSetters = merge(
+ localSetters, supernode.classSetters, MergeKind.superclassSetters);
+
+ if (directInterfaces != null) {
+ MergeResult result = mergeInterfaces(supernode, directInterfaces);
interfaceMembers = result.mergedMembers;
interfaceSetters = result.mergedSetters;
interfaces = <KernelTypeBuilder>[];
- if (supernode.interfaces != null) {
- List<KernelTypeBuilder> types =
- substSupertypes(cls.supertype, supernode.interfaces);
- for (int i = 0; i < types.length; i++) {
- addInterface(interfaces, superclasses, types[i]);
+ if (superclassInterfaces != null) {
+ for (int i = 0; i < superclassInterfaces.length; i++) {
+ addInterface(interfaces, superclasses, superclassInterfaces[i]);
}
}
for (int i = 0; i < directInterfaces.length; i++) {
@@ -546,30 +1277,41 @@
} else {
interfaceMembers = supernode.interfaceMembers;
interfaceSetters = supernode.interfaceSetters;
- interfaces = substSupertypes(cls.supertype, supernode.interfaces);
+ interfaces = superclassInterfaces;
}
+
+ // Check if local members conflict with inherited setters. This check has
+ // already been performed in the superclass, so we only need to check the
+ // local members. These checks have to occur late to enable inferring
+ // types between setters and getters, or from a setter to a final field.
+ merge(localMembers, classSetters, MergeKind.membersWithSetters);
+
+ // Check if local setters conflict with inherited members. As above, we
+ // only need to check the local setters.
+ merge(localSetters, classMembers, MergeKind.settersWithMembers);
+
if (interfaceMembers != null) {
interfaceMembers =
- merge(cls, classMembers, interfaceMembers, MergeKind.supertypes);
+ merge(classMembers, interfaceMembers, MergeKind.supertypesMembers);
// Check if class setters conflict with members inherited from
// interfaces.
- merge(cls, classSetters, interfaceMembers, MergeKind.accessors);
+ merge(classSetters, interfaceMembers, MergeKind.settersWithMembers);
}
if (interfaceSetters != null) {
interfaceSetters =
- merge(cls, classSetters, interfaceSetters, MergeKind.supertypes);
+ merge(classSetters, interfaceSetters, MergeKind.supertypesSetters);
// Check if class members conflict with setters inherited from
// interfaces.
- merge(cls, classMembers, interfaceSetters, MergeKind.accessors);
+ merge(classMembers, interfaceSetters, MergeKind.membersWithSetters);
}
}
if (abstractMembers != null && !cls.isAbstract) {
if (!hasNoSuchMethod) {
- reportMissingMembers(cls);
+ reportMissingMembers();
} else {
- installNsmHandlers(cls);
+ installNsmHandlers();
}
}
return new ClassHierarchyNode(
@@ -581,9 +1323,45 @@
superclasses,
interfaces,
maxInheritancePath,
+ hasNoSuchMethod,
);
}
+ KernelTypeBuilder recordSupertype(KernelTypeBuilder supertype) {
+ if (supertype is KernelNamedTypeBuilder) {
+ debug?.log(
+ "In ${this.cls.fullNameForErrors} recordSupertype(${supertype.fullNameForErrors})");
+ Declaration declaration = supertype.declaration;
+ if (declaration is! KernelClassBuilder) return supertype;
+ KernelClassBuilder cls = declaration;
+ if (cls.isMixinApplication) {
+ recordSupertype(cls.mixedInType);
+ }
+ List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
+ cls.typeVariables;
+ if (typeVariables == null) {
+ substitutions[cls.target] = Substitution.empty;
+ assert(cls.target.typeParameters.isEmpty);
+ } else {
+ List<KernelTypeBuilder> arguments =
+ supertype.arguments ?? computeDefaultTypeArguments(supertype);
+ if (arguments.length != typeVariables.length) {
+ arguments = computeDefaultTypeArguments(supertype);
+ }
+ List<DartType> kernelArguments = new List<DartType>(arguments.length);
+ List<TypeParameter> kernelParameters =
+ new List<TypeParameter>(arguments.length);
+ for (int i = 0; i < arguments.length; i++) {
+ kernelParameters[i] = typeVariables[i].target;
+ kernelArguments[i] = arguments[i].build(this.cls.parent);
+ }
+ substitutions[cls.target] =
+ Substitution.fromPairs(kernelParameters, kernelArguments);
+ }
+ }
+ return supertype;
+ }
+
List<KernelTypeBuilder> substSupertypes(
KernelNamedTypeBuilder supertype, List<KernelTypeBuilder> supertypes) {
Declaration declaration = supertype.declaration;
@@ -591,7 +1369,13 @@
KernelClassBuilder cls = declaration;
List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
cls.typeVariables;
- if (typeVariables == null) return supertypes;
+ if (typeVariables == null) {
+ debug?.log("In ${this.cls.fullNameForErrors} $supertypes aren't substed");
+ for (int i = 0; i < supertypes.length; i++) {
+ recordSupertype(supertypes[i]);
+ }
+ return supertypes;
+ }
Map<TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder> substitution =
<TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder>{};
List<KernelTypeBuilder> arguments =
@@ -602,10 +1386,14 @@
List<KernelTypeBuilder> result;
for (int i = 0; i < supertypes.length; i++) {
KernelTypeBuilder supertype = supertypes[i];
- KernelTypeBuilder substed = supertype.subst(substitution);
+ KernelTypeBuilder substed =
+ recordSupertype(supertype.subst(substitution));
if (supertype != substed) {
+ debug?.log("In ${this.cls.fullNameForErrors} $supertype -> $substed");
result ??= supertypes.toList();
result[i] = substed;
+ } else {
+ debug?.log("In ${this.cls.fullNameForErrors} $supertype isn't substed");
}
}
return result ?? supertypes;
@@ -616,7 +1404,9 @@
List<KernelTypeBuilder> result =
new List<KernelTypeBuilder>(cls.typeVariables.length);
for (int i = 0; i < result.length; ++i) {
- result[i] = cls.typeVariables[i].defaultType;
+ KernelTypeVariableBuilder tv = cls.typeVariables[i];
+ result[i] = tv.defaultType ??
+ cls.library.loader.computeTypeBuilder(tv.target.defaultType);
}
return result;
}
@@ -644,8 +1434,10 @@
return null;
}
- MergeResult mergeInterfaces(KernelClassBuilder cls,
+ MergeResult mergeInterfaces(
ClassHierarchyNode supernode, List<KernelTypeBuilder> interfaces) {
+ debug?.log(
+ "mergeInterfaces($cls (${this.cls}) ${supernode.interfaces} ${interfaces}");
List<List<Declaration>> memberLists =
new List<List<Declaration>>(interfaces.length + 1);
List<List<Declaration>> setterLists =
@@ -665,12 +1457,12 @@
interfaceNode.interfaceSetters ?? interfaceNode.classSetters;
}
}
- return new MergeResult(
- mergeLists(cls, memberLists), mergeLists(cls, setterLists));
+ return new MergeResult(mergeLists(memberLists, MergeKind.interfacesMembers),
+ mergeLists(setterLists, MergeKind.interfacesSetters));
}
List<Declaration> mergeLists(
- KernelClassBuilder cls, List<List<Declaration>> input) {
+ List<List<Declaration>> input, MergeKind mergeKind) {
// This is a k-way merge sort (where k is `input.length + 1`). We merge the
// lists pairwise, which reduces the number of lists to merge by half on
// each iteration. Consequently, we perform O(log k) merges.
@@ -684,7 +1476,7 @@
} else if (second == null) {
output.add(first);
} else {
- output.add(merge(cls, first, second, MergeKind.interfaces));
+ output.add(merge(first, second, mergeKind));
}
}
if (input.length.isOdd) {
@@ -698,7 +1490,7 @@
/// Merge [and check] accessors. This entails copying mutable fields to
/// setters to simulate implied setters, and checking that setters don't
/// override regular methods.
- List<Declaration> mergeAccessors(KernelClassBuilder cls,
+ List<Declaration> mergeAccessors(
List<Declaration> members, List<Declaration> setters) {
final List<Declaration> mergedSetters = new List<Declaration>.filled(
members.length + setters.length, null,
@@ -743,7 +1535,7 @@
}
}
- void reportMissingMembers(KernelClassBuilder cls) {
+ void reportMissingMembers() {
Map<String, LocatedMessage> contextMap = <String, LocatedMessage>{};
for (int i = 0; i < abstractMembers.length; i++) {
Declaration declaration = abstractMembers[i];
@@ -773,12 +1565,12 @@
context: context);
}
- void installNsmHandlers(KernelClassBuilder cls) {
+ void installNsmHandlers() {
// TOOD(ahe): Implement this.
}
- List<Declaration> merge(KernelClassBuilder cls, List<Declaration> aList,
- List<Declaration> bList, MergeKind mergeKind) {
+ List<Declaration> merge(
+ List<Declaration> aList, List<Declaration> bList, MergeKind mergeKind) {
final List<Declaration> result = new List<Declaration>.filled(
aList.length + bList.length, null,
growable: true);
@@ -788,7 +1580,9 @@
while (i < aList.length && j < bList.length) {
final Declaration a = aList[i];
final Declaration b = bList[j];
- if (mergeKind == MergeKind.interfaces && a.isStatic) {
+ if ((mergeKind == MergeKind.interfacesMembers ||
+ mergeKind == MergeKind.interfacesSetters) &&
+ a.isStatic) {
i++;
continue;
}
@@ -798,7 +1592,7 @@
}
final int compare = compareDeclarations(a, b);
if (compare == 0) {
- result[storeIndex++] = handleMergeConflict(cls, a, b, mergeKind);
+ result[storeIndex++] = handleMergeConflict(a, b, mergeKind);
i++;
j++;
} else if (compare < 0) {
@@ -806,14 +1600,15 @@
result[storeIndex++] = a;
i++;
} else {
- handleOnlyB(cls, b, mergeKind);
- result[storeIndex++] = b;
+ result[storeIndex++] = handleOnlyB(b, mergeKind);
j++;
}
}
while (i < aList.length) {
final Declaration a = aList[i];
- if (mergeKind != MergeKind.interfaces || !a.isStatic) {
+ if (!(mergeKind == MergeKind.interfacesMembers ||
+ mergeKind == MergeKind.interfacesSetters) ||
+ !a.isStatic) {
handleOnlyA(a, mergeKind);
result[storeIndex++] = a;
}
@@ -822,8 +1617,7 @@
while (j < bList.length) {
final Declaration b = bList[j];
if (!b.isStatic) {
- handleOnlyB(cls, b, mergeKind);
- result[storeIndex++] = b;
+ result[storeIndex++] = handleOnlyB(b, mergeKind);
}
j++;
}
@@ -853,6 +1647,25 @@
KernelNamedTypeBuilder mixedInType = cls.mixedInType;
mixedInType.arguments = inferredArguments;
}
+
+ /// The class Function from dart:core is supposed to be ignored when used as
+ /// an interface.
+ List<KernelTypeBuilder> ignoreFunction(List<KernelTypeBuilder> interfaces) {
+ if (interfaces == null) return null;
+ for (int i = 0; i < interfaces.length; i++) {
+ KernelClassBuilder cls = getClass(interfaces[i]);
+ if (cls != null && cls.target == hierarchy.functionKernelClass) {
+ if (interfaces.length == 1) {
+ return null;
+ } else {
+ interfaces = interfaces.toList();
+ interfaces.removeAt(i);
+ return ignoreFunction(interfaces);
+ }
+ }
+ }
+ return interfaces;
+ }
}
class ClassHierarchyNode {
@@ -893,6 +1706,8 @@
int get depth => superclasses.length;
+ final bool hasNoSuchMethod;
+
ClassHierarchyNode(
this.cls,
this.classMembers,
@@ -901,7 +1716,8 @@
this.interfaceSetters,
this.superclasses,
this.interfaces,
- this.maxInheritancePath);
+ this.maxInheritancePath,
+ this.hasNoSuchMethod);
/// Returns a list of all supertypes of [cls], including this node.
List<ClassHierarchyNode> computeAllSuperNodes(
@@ -980,6 +1796,42 @@
}
}
+ Declaration getInterfaceMember(Name name, bool isSetter) {
+ return findMember(
+ name,
+ isSetter
+ ? interfaceSetters ?? classSetters
+ : interfaceMembers ?? classMembers);
+ }
+
+ Declaration findMember(Name name, List<Declaration> declarations) {
+ // TODO(ahe): Consider creating a map or scope. The obvious choice would be
+ // to use scopes, but they don't handle private names correctly.
+
+ // This is a copy of `ClassHierarchy.findMemberByName`.
+ int low = 0, high = declarations.length - 1;
+ while (low <= high) {
+ int mid = low + ((high - low) >> 1);
+ Declaration pivot = declarations[mid];
+ int comparison = ClassHierarchy.compareNames(name, pivot.target.name);
+ if (comparison < 0) {
+ high = mid - 1;
+ } else if (comparison > 0) {
+ low = mid + 1;
+ } else if (high != mid) {
+ // Ensure we find the first element of the given name.
+ high = mid;
+ } else {
+ return pivot;
+ }
+ }
+ return null;
+ }
+
+ Declaration getDispatchTarget(Name name, bool isSetter) {
+ return findMember(name, isSetter ? classSetters : classMembers);
+ }
+
static int compareMaxInheritancePath(
ClassHierarchyNode a, ClassHierarchyNode b) {
return b.maxInheritancePath.compareTo(a.maxInheritancePath);
@@ -996,17 +1848,28 @@
enum MergeKind {
/// Merging superclass members with the current class.
- superclass,
+ superclassMembers,
- /// Merging two interfaces.
- interfaces,
+ /// Merging superclass setters with the current class.
+ superclassSetters,
+
+ /// Merging members of two interfaces.
+ interfacesMembers,
+
+ /// Merging setters of two interfaces.
+ interfacesSetters,
/// Merging class members with interface members.
- supertypes,
+ supertypesMembers,
- /// Merging members with inherited setters, or setters with inherited
- /// members.
- accessors,
+ /// Merging class setters with interface setters.
+ supertypesSetters,
+
+ /// Merging members with inherited setters.
+ membersWithSetters,
+
+ /// Merging setters with inherited members.
+ settersWithMembers,
}
List<LocatedMessage> inheritedConflictContext(Declaration a, Declaration b) {
@@ -1123,3 +1986,641 @@
return hierarchy.getKernelLegacyLeastUpperBound(type1, type2);
}
}
+
+class DelayedOverrideCheck {
+ final KernelClassBuilder cls;
+ final Declaration a;
+ final Declaration b;
+
+ const DelayedOverrideCheck(this.cls, this.a, this.b);
+
+ void check(ClassHierarchyBuilder hierarchy) {
+ void callback(
+ Member declaredMember, Member interfaceMember, bool isSetter) {
+ cls.checkOverride(
+ hierarchy.types, declaredMember, interfaceMember, isSetter, callback,
+ isInterfaceCheck: !cls.isMixinApplication);
+ }
+
+ Declaration a = this.a;
+ debug?.log(
+ "Delayed override check of ${fullName(a)} ${fullName(b)} wrt. ${cls.fullNameForErrors}");
+ if (cls == a.parent) {
+ if (a is KernelProcedureBuilder) {
+ if (a.isGetter && !hasExplicitReturnType(a)) {
+ DartType type;
+ if (b.isGetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.returnType;
+ } else if (b.isSetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.positionalParameters.single.type;
+ } else if (b.isField) {
+ Field bTarget = b.target;
+ type = bTarget.type;
+ }
+ if (type != null) {
+ type = Substitution.fromInterfaceType(
+ hierarchy.getKernelTypeAsInstanceOf(
+ cls.cls.thisType, b.target.enclosingClass))
+ .substituteType(type);
+ if (!a.hadTypesInferred || !b.isSetter) {
+ inferReturnType(cls, a, type, a.hadTypesInferred, hierarchy);
+ }
+ }
+ } else if (a.isSetter && !hasExplicitlyTypedFormalParameter(a, 0)) {
+ DartType type;
+ if (b.isGetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.returnType;
+ } else if (b.isSetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.positionalParameters.single.type;
+ } else if (b.isField) {
+ Field bTarget = b.target;
+ type = bTarget.type;
+ }
+ if (type != null) {
+ type = Substitution.fromInterfaceType(
+ hierarchy.getKernelTypeAsInstanceOf(
+ cls.cls.thisType, b.target.enclosingClass))
+ .substituteType(type);
+ if (!a.hadTypesInferred || !b.isGetter) {
+ inferParameterType(cls, a, a.formals.single, type,
+ a.hadTypesInferred, hierarchy);
+ }
+ }
+ }
+ a.hadTypesInferred = true;
+ } else if (a is KernelFieldBuilder && a.type == null) {
+ DartType type;
+ if (b.isGetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.returnType;
+ } else if (b.isSetter) {
+ Procedure bTarget = b.target;
+ type = bTarget.function.positionalParameters.single.type;
+ } else if (b.isField) {
+ Field bTarget = b.target;
+ type = bTarget.type;
+ }
+ if (type != null) {
+ type = Substitution.fromInterfaceType(
+ hierarchy.getKernelTypeAsInstanceOf(
+ cls.cls.thisType, b.target.enclosingClass))
+ .substituteType(type);
+ if (type != a.target.type) {
+ if (a.hadTypesInferred) {
+ if (b.isSetter &&
+ (!impliesSetter(a) ||
+ hierarchy.types.isSubtypeOfKernel(type, a.target.type))) {
+ type = a.target.type;
+ } else {
+ reportCantInferFieldType(cls, a);
+ type = const InvalidType();
+ }
+ }
+ debug?.log("Inferred type ${type} for ${fullName(a)}");
+ a.target.type = type;
+ }
+ }
+ a.hadTypesInferred = true;
+ }
+ }
+
+ callback(a.target, b.target, a.isSetter);
+ }
+}
+
+abstract class DelayedMember extends Declaration {
+ /// The class which has inherited [declarations].
+ @override
+ final KernelClassBuilder parent;
+
+ /// Conflicting declarations.
+ final List<Declaration> declarations;
+
+ final isSetter;
+
+ final bool modifyKernel;
+
+ DelayedMember(
+ this.parent, this.declarations, this.isSetter, this.modifyKernel);
+
+ void addAllDeclarationsTo(List<Declaration> declarations) {
+ for (int i = 0; i < this.declarations.length; i++) {
+ addDeclarationIfDifferent(this.declarations[i], declarations);
+ }
+ assert(declarations.toSet().length == declarations.length);
+ }
+
+ Member check(ClassHierarchyBuilder hierarchy);
+
+ DelayedMember withParent(KernelClassBuilder parent);
+
+ @override
+ Uri get fileUri => parent.fileUri;
+
+ @override
+ int get charOffset => parent.charOffset;
+
+ @override
+ String get fullNameForErrors => declarations.map(fullName).join("%");
+
+ bool get isInheritableConflict => true;
+
+ @override
+ Member get target => declarations.first.target;
+}
+
+/// This represents a concrete implementation inherited from a superclass that
+/// has conflicts with methods inherited from an interface. The concrete
+/// implementation is the first element of [declarations].
+class InheritedImplementationInterfaceConflict extends DelayedMember {
+ Member combinedMemberSignatureResult;
+
+ @override
+ final bool isInheritableConflict;
+
+ InheritedImplementationInterfaceConflict(KernelClassBuilder parent,
+ List<Declaration> declarations, bool isSetter, bool modifyKernel,
+ {this.isInheritableConflict = true})
+ : super(parent, declarations, isSetter, modifyKernel);
+
+ @override
+ String toString() {
+ return "InheritedImplementationInterfaceConflict("
+ "${parent.fullNameForErrors}, "
+ "[${declarations.map(fullName).join(', ')}])";
+ }
+
+ @override
+ Member check(ClassHierarchyBuilder hierarchy) {
+ if (combinedMemberSignatureResult != null) {
+ return combinedMemberSignatureResult;
+ }
+ if (!parent.isAbstract) {
+ Declaration concreteImplementation = declarations.first;
+ for (int i = 1; i < declarations.length; i++) {
+ new DelayedOverrideCheck(
+ parent, concreteImplementation, declarations[i])
+ .check(hierarchy);
+ }
+ }
+ return combinedMemberSignatureResult =
+ new InterfaceConflict(parent, declarations, isSetter, modifyKernel)
+ .check(hierarchy);
+ }
+
+ @override
+ DelayedMember withParent(KernelClassBuilder parent) {
+ return parent == this.parent
+ ? this
+ : new InheritedImplementationInterfaceConflict(
+ parent, declarations, isSetter, modifyKernel);
+ }
+
+ static Declaration combined(
+ KernelClassBuilder parent,
+ Declaration concreteImplementation,
+ Declaration other,
+ bool isSetter,
+ bool createForwarders,
+ {bool isInheritableConflict = true}) {
+ List<Declaration> declarations = <Declaration>[];
+ if (concreteImplementation is DelayedMember) {
+ concreteImplementation.addAllDeclarationsTo(declarations);
+ } else {
+ declarations.add(concreteImplementation);
+ }
+ if (other is DelayedMember) {
+ other.addAllDeclarationsTo(declarations);
+ } else {
+ addDeclarationIfDifferent(other, declarations);
+ }
+ if (declarations.length == 1) {
+ return declarations.single;
+ } else {
+ return new InheritedImplementationInterfaceConflict(
+ parent, declarations, isSetter, createForwarders,
+ isInheritableConflict: isInheritableConflict);
+ }
+ }
+}
+
+class InterfaceConflict extends DelayedMember {
+ InterfaceConflict(KernelClassBuilder parent, List<Declaration> declarations,
+ bool isSetter, bool modifyKernel)
+ : super(parent, declarations, isSetter, modifyKernel);
+
+ Member combinedMemberSignatureResult;
+
+ @override
+ String toString() {
+ return "InterfaceConflict(${parent.fullNameForErrors}, "
+ "[${declarations.map(fullName).join(', ')}])";
+ }
+
+ DartType computeMemberType(
+ ClassHierarchyBuilder hierarchy, DartType thisType, Member member) {
+ DartType type;
+ if (member is Procedure) {
+ if (member.isGetter) {
+ type = member.getterType;
+ } else if (member.isSetter) {
+ type = member.setterType;
+ } else {
+ type = member.function.functionType;
+ }
+ } else if (member is Field) {
+ type = member.type;
+ } else {
+ unhandled("${member.runtimeType}", "$member", parent.charOffset,
+ parent.fileUri);
+ }
+ return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+ thisType, member.enclosingClass))
+ .substituteType(type);
+ }
+
+ bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
+ if (isSetter) {
+ return hierarchy.types.isSubtypeOfKernel(b, a);
+ } else {
+ return hierarchy.types.isSubtypeOfKernel(a, b);
+ }
+ }
+
+ @override
+ Member check(ClassHierarchyBuilder hierarchy) {
+ if (combinedMemberSignatureResult != null) {
+ return combinedMemberSignatureResult;
+ }
+ if (parent.library is! KernelLibraryBuilder) {
+ return combinedMemberSignatureResult = declarations.first.target;
+ }
+ DartType thisType = parent.cls.thisType;
+ Declaration bestSoFar;
+ DartType bestTypeSoFar;
+ for (int i = declarations.length - 1; i >= 0; i--) {
+ Declaration candidate = declarations[i];
+ Member target = candidate.target;
+ DartType candidateType = computeMemberType(hierarchy, thisType, target);
+ if (bestSoFar == null) {
+ bestSoFar = candidate;
+ bestTypeSoFar = candidateType;
+ } else {
+ if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
+ debug?.log(
+ "Combined Member Signature: ${fullName(candidate)} ${candidateType} <: ${fullName(bestSoFar)} ${bestTypeSoFar}");
+ bestSoFar = candidate;
+ bestTypeSoFar = candidateType;
+ } else {
+ debug?.log(
+ "Combined Member Signature: ${fullName(candidate)} !<: ${fullName(bestSoFar)}");
+ }
+ }
+ }
+ if (bestSoFar != null) {
+ debug?.log("Combined Member Signature bestSoFar: ${fullName(bestSoFar)}");
+ for (int i = 0; i < declarations.length; i++) {
+ Declaration candidate = declarations[i];
+ Member target = candidate.target;
+ DartType candidateType = computeMemberType(hierarchy, thisType, target);
+ if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+ debug?.log(
+ "Combined Member Signature: ${fullName(bestSoFar)} !<: ${fullName(candidate)}");
+
+ String uri = '${parent.library.uri}';
+ if (uri == 'dart:js' &&
+ parent.fileUri.pathSegments.last == 'js_dart2js.dart' ||
+ uri == 'dart:_interceptors' &&
+ parent.fileUri.pathSegments.last == 'js_number.dart') {
+ // TODO(johnniwinther): Fix the dart2js libraries and remove the
+ // above URIs.
+ } else {
+ bestSoFar = null;
+ bestTypeSoFar = null;
+ }
+ break;
+ }
+ }
+ }
+ if (bestSoFar == null) {
+ String name = parent.fullNameForErrors;
+ int length = parent.isAnonymousMixinApplication ? 1 : name.length;
+ List<LocatedMessage> context = declarations.map((Declaration d) {
+ return messageDeclaredMemberConflictsWithInheritedMemberCause
+ .withLocation(d.fileUri, d.charOffset, d.fullNameForErrors.length);
+ }).toList();
+
+ parent.addProblem(
+ templateCombinedMemberSignatureFailed.withArguments(
+ parent.fullNameForErrors, declarations.first.fullNameForErrors),
+ parent.charOffset,
+ length,
+ context: context);
+ return null;
+ }
+ debug?.log(
+ "Combined Member Signature of ${fullNameForErrors}: ${fullName(bestSoFar)}");
+
+ ProcedureKind kind = ProcedureKind.Method;
+ if (bestSoFar.isField || bestSoFar.isSetter || bestSoFar.isGetter) {
+ kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+ } else if (bestSoFar.target is Procedure &&
+ bestSoFar.target.kind == ProcedureKind.Operator) {
+ kind = ProcedureKind.Operator;
+ }
+
+ if (modifyKernel) {
+ debug?.log(
+ "Combined Member Signature of ${fullNameForErrors}: new ForwardingNode($parent, $bestSoFar, $declarations, $kind)");
+ Member stub =
+ new ForwardingNode(hierarchy, parent, bestSoFar, declarations, kind)
+ .finalize();
+ if (parent.cls == stub.enclosingClass) {
+ parent.cls.addMember(stub);
+ KernelLibraryBuilder library = parent.library;
+ if (bestSoFar.target is Procedure) {
+ library.forwardersOrigins..add(stub)..add(bestSoFar.target);
+ }
+ debug?.log(
+ "Combined Member Signature of ${fullNameForErrors}: added stub $stub");
+ if (parent.isMixinApplication) {
+ return combinedMemberSignatureResult = bestSoFar.target;
+ } else {
+ return combinedMemberSignatureResult = stub;
+ }
+ }
+ }
+
+ debug?.log(
+ "Combined Member Signature of ${fullNameForErrors}: picked bestSoFar");
+ return combinedMemberSignatureResult = bestSoFar.target;
+ }
+
+ @override
+ DelayedMember withParent(KernelClassBuilder parent) {
+ return parent == this.parent
+ ? this
+ : new InterfaceConflict(parent, declarations, isSetter, modifyKernel);
+ }
+
+ static Declaration combined(KernelClassBuilder parent, Declaration a,
+ Declaration b, bool isSetter, bool createForwarders) {
+ List<Declaration> declarations = <Declaration>[];
+ if (a is DelayedMember) {
+ a.addAllDeclarationsTo(declarations);
+ } else {
+ declarations.add(a);
+ }
+ if (b is DelayedMember) {
+ b.addAllDeclarationsTo(declarations);
+ } else {
+ addDeclarationIfDifferent(b, declarations);
+ }
+ if (declarations.length == 1) {
+ return declarations.single;
+ } else {
+ return new InterfaceConflict(
+ parent, declarations, isSetter, createForwarders);
+ }
+ }
+}
+
+class AbstractMemberOverridingImplementation extends DelayedMember {
+ AbstractMemberOverridingImplementation(
+ KernelClassBuilder parent,
+ Declaration abstractMember,
+ Declaration concreteImplementation,
+ bool isSetter,
+ bool modifyKernel)
+ : super(parent, <Declaration>[concreteImplementation, abstractMember],
+ isSetter, modifyKernel);
+
+ Declaration get concreteImplementation => declarations[0];
+
+ Declaration get abstractMember => declarations[1];
+
+ Member check(ClassHierarchyBuilder hierarchy) {
+ if (!parent.isAbstract && !hierarchy.nodes[parent.cls].hasNoSuchMethod) {
+ new DelayedOverrideCheck(parent, concreteImplementation, abstractMember)
+ .check(hierarchy);
+ }
+
+ ProcedureKind kind = ProcedureKind.Method;
+ if (abstractMember.isSetter || abstractMember.isGetter) {
+ kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+ }
+ if (modifyKernel) {
+ // This call will add a body to the abstract method if needed for
+ // isGenericCovariantImpl checks.
+ new ForwardingNode(hierarchy, parent, abstractMember, declarations, kind)
+ .finalize();
+ }
+ return abstractMember.target;
+ }
+
+ @override
+ DelayedMember withParent(KernelClassBuilder parent) {
+ return parent == this.parent
+ ? this
+ : new AbstractMemberOverridingImplementation(parent, abstractMember,
+ concreteImplementation, isSetter, modifyKernel);
+ }
+
+ static Declaration selectAbstract(Declaration declaration) {
+ if (declaration is AbstractMemberOverridingImplementation) {
+ return declaration.abstractMember;
+ } else {
+ return declaration;
+ }
+ }
+
+ static Declaration selectConcrete(Declaration declaration) {
+ if (declaration is AbstractMemberOverridingImplementation) {
+ return declaration.concreteImplementation;
+ } else {
+ return declaration;
+ }
+ }
+}
+
+void addDeclarationIfDifferent(
+ Declaration declaration, List<Declaration> declarations) {
+ Member target = declaration.target;
+ if (target is Procedure) {
+ FunctionNode function = target.function;
+ for (int i = 0; i < declarations.length; i++) {
+ Member other = declarations[i].target;
+ if (other is Procedure) {
+ if (hasSameSignature(function, other.function)) return;
+ }
+ }
+ } else {
+ for (int i = 0; i < declarations.length; i++) {
+ if (declaration == declarations[i]) return;
+ }
+ }
+ declarations.add(declaration);
+}
+
+String fullName(Declaration declaration) {
+ String suffix = declaration.isSetter ? "=" : "";
+ if (declaration is DelayedMember) {
+ return "${declaration.fullNameForErrors}$suffix";
+ }
+ Declaration parent = declaration.parent;
+ return parent == null
+ ? "${declaration.fullNameForErrors}$suffix"
+ : "${parent.fullNameForErrors}.${declaration.fullNameForErrors}$suffix";
+}
+
+int compareNamedParameters(VariableDeclaration a, VariableDeclaration b) {
+ return a.name.compareTo(b.name);
+}
+
+bool isAbstract(Declaration declaration) {
+ return declaration.target.isAbstract || declaration is InterfaceConflict;
+}
+
+bool inferParameterType(
+ KernelClassBuilder cls,
+ KernelProcedureBuilder member,
+ FormalParameterBuilder<KernelTypeBuilder> parameter,
+ DartType type,
+ bool hadTypesInferred,
+ ClassHierarchyBuilder hierarchy) {
+ debug?.log("Inferred type ${type} for ${parameter}");
+ if (type == parameter.target.type) return true;
+ bool result = true;
+ if (hadTypesInferred) {
+ reportCantInferParameterType(cls, member, parameter, hierarchy);
+ type = const InvalidType();
+ result = false;
+ }
+ parameter.target.type = type;
+ member.hadTypesInferred = true;
+ return result;
+}
+
+void reportCantInferParameterType(
+ KernelClassBuilder cls,
+ MemberBuilder member,
+ FormalParameterBuilder<KernelTypeBuilder> parameter,
+ ClassHierarchyBuilder hierarchy) {
+ String name = parameter.name;
+ cls.addProblem(
+ templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+ parameter.charOffset,
+ name.length,
+ wasHandled: true);
+}
+
+bool inferReturnType(KernelClassBuilder cls, KernelProcedureBuilder member,
+ DartType type, bool hadTypesInferred, ClassHierarchyBuilder hierarchy) {
+ if (type == member.target.function.returnType) return true;
+ bool result = true;
+ if (hadTypesInferred) {
+ reportCantInferReturnType(cls, member, hierarchy);
+ type = const InvalidType();
+ result = false;
+ } else {
+ member.hadTypesInferred = true;
+ }
+ member.target.function.returnType = type;
+ return result;
+}
+
+void reportCantInferReturnType(KernelClassBuilder cls, MemberBuilder member,
+ ClassHierarchyBuilder hierarchy) {
+ String name = member.fullNameForErrors;
+ List<LocatedMessage> context;
+ // // TODO(ahe): The following is for debugging, but could be cleaned up and
+ // // used to improve this error message in general.
+ //
+ // context = <LocatedMessage>[];
+ // ClassHierarchyNode supernode = hierarchy.getNodeFromType(cls.supertype);
+ // // TODO(ahe): Wrong template.
+ // Template<Message Function(String)> template =
+ // templateMissingImplementationCause;
+ // if (supernode != null) {
+ // Declaration superMember =
+ // supernode.getInterfaceMember(new Name(name), false);
+ // if (superMember != null) {
+ // context.add(template
+ // .withArguments(name)
+ // .withLocation(
+ // superMember.fileUri, superMember.charOffset, name.length));
+ // }
+ // superMember = supernode.getInterfaceMember(new Name(name), true);
+ // if (superMember != null) {
+ // context.add(template
+ // .withArguments(name)
+ // .withLocation(
+ // superMember.fileUri, superMember.charOffset, name.length));
+ // }
+ // }
+ // List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+ // for (int i = 0; i < directInterfaces.length; i++) {
+ // ClassHierarchyNode supernode =
+ // hierarchy.getNodeFromType(directInterfaces[i]);
+ // if (supernode != null) {
+ // Declaration superMember =
+ // supernode.getInterfaceMember(new Name(name), false);
+ // if (superMember != null) {
+ // context.add(template
+ // .withArguments(name)
+ // .withLocation(
+ // superMember.fileUri, superMember.charOffset, name.length));
+ // }
+ // superMember = supernode.getInterfaceMember(new Name(name), true);
+ // if (superMember != null) {
+ // context.add(template
+ // .withArguments(name)
+ // .withLocation(
+ // superMember.fileUri, superMember.charOffset, name.length));
+ // }
+ // }
+ // }
+ cls.addProblem(
+ templateCantInferReturnTypeDueToInconsistentOverrides.withArguments(name),
+ member.charOffset,
+ name.length,
+ wasHandled: true,
+ context: context);
+}
+
+void reportCantInferFieldType(
+ KernelClassBuilder cls, KernelFieldBuilder member) {
+ String name = member.fullNameForErrors;
+ cls.addProblem(
+ templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+ member.charOffset,
+ name.length,
+ wasHandled: true);
+}
+
+KernelClassBuilder getClass(KernelTypeBuilder type) {
+ Declaration declaration = type.declaration;
+ return declaration is KernelClassBuilder ? declaration : null;
+}
+
+bool hasExplicitReturnType(Declaration declaration) {
+ assert(
+ declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+ "${declaration.runtimeType}");
+ return declaration is KernelProcedureBuilder
+ ? declaration.returnType != null
+ : true;
+}
+
+bool hasExplicitlyTypedFormalParameter(Declaration declaration, int index) {
+ assert(
+ declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+ "${declaration.runtimeType}");
+ return declaration is KernelProcedureBuilder
+ ? declaration.formals[index].type != null
+ : true;
+}
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 d334dac..175f066 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -306,7 +306,12 @@
// If this constant is inlined, remove it.
if (!keepVariables && shouldInline(node.initializer)) {
- return null;
+ if (constant is! UnevaluatedConstant) {
+ // If the constant is unevaluated we need to keep the expression,
+ // so that, in the case the constant contains error but the local
+ // is unused, the error will still be reported.
+ return null;
+ }
}
} else {
node.initializer = node.initializer.accept(this)..parent = node;
@@ -933,6 +938,12 @@
instanceBuilder.setFieldValue(
fieldRef.asField, _evaluateSubexpression(value));
});
+ node.unusedArguments.forEach((Expression value) {
+ Constant constant = _evaluateSubexpression(value);
+ if (constant is UnevaluatedConstant) {
+ instanceBuilder.unusedArguments.add(extract(constant));
+ }
+ });
if (shouldBeUnevaluated) {
return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
}
@@ -1133,6 +1144,10 @@
'"${init.runtimeType}".');
}
}
+
+ for (UnevaluatedConstant constant in env.unevaluatedUnreadConstants) {
+ instanceBuilder.unusedArguments.add(extract(constant));
+ }
});
});
}
@@ -1763,7 +1778,7 @@
final Constant constant = _evaluateSubexpression(node.operand);
if (shouldBeUnevaluated) {
return unevaluated(node,
- new AsExpression(extract(constant), env.subsituteType(node.type)));
+ new AsExpression(extract(constant), env.substituteType(node.type)));
}
return ensureIsSubtype(constant, evaluateDartType(node, node.type), node);
}
@@ -1808,7 +1823,7 @@
return unevaluated(
node,
new Instantiation(extract(constant),
- node.typeArguments.map((t) => env.subsituteType(t)).toList()));
+ node.typeArguments.map((t) => env.substituteType(t)).toList()));
}
if (constant is TearOffConstant) {
if (node.typeArguments.length ==
@@ -1927,7 +1942,7 @@
}
DartType evaluateDartType(TreeNode node, DartType type) {
- final result = env.subsituteType(type);
+ final result = env.substituteType(type);
if (!isInstantiated(result)) {
return report(
@@ -2118,6 +2133,8 @@
final List<AssertStatement> asserts = <AssertStatement>[];
+ final List<Expression> unusedArguments = <Expression>[];
+
InstanceBuilder(this.evaluator, this.klass, this.typeArguments);
void setFieldValue(Field field, Constant constant) {
@@ -2131,6 +2148,7 @@
assert(value is! UnevaluatedConstant);
fieldValues[field.reference] = value;
});
+ assert(unusedArguments.isEmpty);
return new InstanceConstant(klass.reference, typeArguments, fieldValues);
}
@@ -2139,9 +2157,8 @@
fields.forEach((Field field, Constant value) {
fieldValues[field.reference] = evaluator.extract(value);
});
- // TODO(askesc): Put actual unused arguments.
return new InstanceCreation(
- klass.reference, typeArguments, fieldValues, asserts, []);
+ klass.reference, typeArguments, fieldValues, asserts, unusedArguments);
}
}
@@ -2155,6 +2172,13 @@
final Map<VariableDeclaration, Constant> _variables =
<VariableDeclaration, Constant>{};
+ /// The variables that hold unevaluated constants.
+ ///
+ /// Variables are removed from this set when looked up, leaving only the
+ /// unread variables at the end.
+ final Set<VariableDeclaration> _unreadUnevaluatedVariables =
+ new Set<VariableDeclaration>();
+
/// Whether the current environment is empty.
bool get isEmpty => _typeVariables.isEmpty && _variables.isEmpty;
@@ -2165,6 +2189,9 @@
void addVariableValue(VariableDeclaration variable, Constant value) {
_variables[variable] = value;
+ if (value is UnevaluatedConstant) {
+ _unreadUnevaluatedVariables.add(variable);
+ }
}
DartType lookupParameterValue(TypeParameter parameter) {
@@ -2174,10 +2201,21 @@
}
Constant lookupVariable(VariableDeclaration variable) {
- return _variables[variable];
+ Constant value = _variables[variable];
+ if (value is UnevaluatedConstant) {
+ _unreadUnevaluatedVariables.remove(variable);
+ }
+ return value;
}
- DartType subsituteType(DartType type) {
+ /// The unevaluated constants of variables that were never read.
+ Iterable<UnevaluatedConstant> get unevaluatedUnreadConstants {
+ if (_unreadUnevaluatedVariables.isEmpty) return const [];
+ return _unreadUnevaluatedVariables.map<UnevaluatedConstant>(
+ (VariableDeclaration variable) => _variables[variable]);
+ }
+
+ DartType substituteType(DartType type) {
if (_typeVariables.isEmpty) return type;
return substitute(type, _typeVariables);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
new file mode 100644
index 0000000..441c827
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -0,0 +1,416 @@
+// 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:kernel/ast.dart"
+ show
+ Arguments,
+ Class,
+ DartType,
+ Expression,
+ Field,
+ FunctionNode,
+ Member,
+ Name,
+ NamedExpression,
+ Procedure,
+ ProcedureKind,
+ ReturnStatement,
+ SuperMethodInvocation,
+ SuperPropertyGet,
+ SuperPropertySet,
+ TypeParameter,
+ TypeParameterType,
+ VariableDeclaration,
+ VariableGet,
+ VoidType;
+
+import 'package:kernel/transformations/flags.dart' show TransformerFlag;
+
+import "package:kernel/type_algebra.dart" show Substitution;
+
+import "../problems.dart" show unhandled;
+
+import "../type_inference/type_inference_engine.dart"
+ show IncludesTypeParametersCovariantly;
+
+import "../type_inference/type_inferrer.dart" show getNamedFormal;
+
+import "kernel_builder.dart"
+ show ClassHierarchyBuilder, Declaration, DelayedMember, KernelClassBuilder;
+
+class ForwardingNode {
+ final ClassHierarchyBuilder hierarchy;
+
+ final KernelClassBuilder parent;
+
+ final Declaration combinedMemberSignatureResult;
+
+ final ProcedureKind kind;
+
+ /// A list containing the directly implemented and directly inherited
+ /// procedures of the class in question.
+ final List<Declaration> _candidates;
+
+ ForwardingNode(this.hierarchy, this.parent,
+ this.combinedMemberSignatureResult, this._candidates, this.kind);
+
+ Name get name => combinedMemberSignatureResult.target.name;
+
+ Class get enclosingClass => parent.cls;
+
+ /// Finishes handling of this node by propagating covariance and creating
+ /// forwarding stubs if necessary.
+ Member finalize() => _computeCovarianceFixes();
+
+ /// Tag the parameters of [interfaceMember] that need type checks
+ ///
+ /// Parameters can need type checks for calls coming from statically typed
+ /// call sites, due to covariant generics and overrides with explicit
+ /// `covariant` parameters.
+ ///
+ /// Tag parameters of [interfaceMember] that need such checks when the member
+ /// occurs in [enclosingClass]'s interface. If parameters need checks but
+ /// they would not be checked in an inherited implementation, a forwarding
+ /// stub is introduced as a place to put the checks.
+ Member _computeCovarianceFixes() {
+ Member interfaceMember = combinedMemberSignatureResult.target;
+ Substitution substitution =
+ _substitutionFor(interfaceMember, enclosingClass);
+ // We always create a forwarding stub when we've inherited a member from an
+ // interface other than the first override candidate. This is to work
+ // around a bug in the Kernel type checker where it chooses the first
+ // override candidate.
+ //
+ // TODO(kmillikin): Fix the Kernel type checker and stop creating these
+ // extra stubs.
+ Member stub = interfaceMember.enclosingClass == enclosingClass ||
+ interfaceMember == getCandidateAt(0)
+ ? interfaceMember
+ : _createForwardingStub(substitution, interfaceMember);
+
+ FunctionNode interfaceFunction = interfaceMember.function;
+ List<VariableDeclaration> interfacePositionalParameters =
+ getPositionalParameters(interfaceMember);
+ List<VariableDeclaration> interfaceNamedParameters =
+ interfaceFunction?.namedParameters ?? [];
+ List<TypeParameter> interfaceTypeParameters =
+ interfaceFunction?.typeParameters ?? [];
+
+ void createStubIfNeeded() {
+ if (stub != interfaceMember) return;
+ if (interfaceMember.enclosingClass == enclosingClass) return;
+ stub = _createForwardingStub(substitution, interfaceMember);
+ }
+
+ bool isImplCreated = false;
+ void createImplIfNeeded() {
+ if (isImplCreated) return;
+ createStubIfNeeded();
+ _createForwardingImplIfNeeded(stub.function);
+ isImplCreated = true;
+ }
+
+ IncludesTypeParametersCovariantly needsCheckVisitor = enclosingClass
+ .typeParameters.isEmpty
+ ? null
+ // TODO(ahe): It may be necessary to cache this object.
+ : new IncludesTypeParametersCovariantly(enclosingClass.typeParameters);
+ bool needsCheck(DartType type) => needsCheckVisitor == null
+ ? false
+ : substitution.substituteType(type).accept(needsCheckVisitor);
+ for (int i = 0; i < interfacePositionalParameters.length; i++) {
+ VariableDeclaration parameter = interfacePositionalParameters[i];
+ bool isGenericCovariantImpl =
+ parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+ bool isCovariant = parameter.isCovariant;
+ VariableDeclaration superParameter = parameter;
+ for (int j = 0; j < _candidates.length; j++) {
+ Member otherMember = getCandidateAt(j);
+ if (otherMember is ForwardingNode) continue;
+ List<VariableDeclaration> otherPositionalParameters =
+ getPositionalParameters(otherMember);
+ if (otherPositionalParameters.length <= i) continue;
+ VariableDeclaration otherParameter = otherPositionalParameters[i];
+ if (j == 0) superParameter = otherParameter;
+ if (identical(otherMember, interfaceMember)) continue;
+ if (otherParameter.isGenericCovariantImpl) {
+ isGenericCovariantImpl = true;
+ }
+ if (otherParameter.isCovariant) {
+ isCovariant = true;
+ }
+ }
+ if (isGenericCovariantImpl) {
+ if (!superParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.positionalParameters[i].isGenericCovariantImpl = true;
+ }
+ }
+ if (isCovariant) {
+ if (!superParameter.isCovariant) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isCovariant) {
+ createStubIfNeeded();
+ stub.function.positionalParameters[i].isCovariant = true;
+ }
+ }
+ }
+ for (int i = 0; i < interfaceNamedParameters.length; i++) {
+ VariableDeclaration parameter = interfaceNamedParameters[i];
+ bool isGenericCovariantImpl =
+ parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+ bool isCovariant = parameter.isCovariant;
+ VariableDeclaration superParameter = parameter;
+ for (int j = 0; j < _candidates.length; j++) {
+ Member otherMember = getCandidateAt(j);
+ if (otherMember is ForwardingNode) continue;
+ VariableDeclaration otherParameter =
+ getNamedFormal(otherMember.function, parameter.name);
+ if (otherParameter == null) continue;
+ if (j == 0) superParameter = otherParameter;
+ if (identical(otherMember, interfaceMember)) continue;
+ if (otherParameter.isGenericCovariantImpl) {
+ isGenericCovariantImpl = true;
+ }
+ if (otherParameter.isCovariant) {
+ isCovariant = true;
+ }
+ }
+ if (isGenericCovariantImpl) {
+ if (!superParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.namedParameters[i].isGenericCovariantImpl = true;
+ }
+ }
+ if (isCovariant) {
+ if (!superParameter.isCovariant) {
+ createImplIfNeeded();
+ }
+ if (!parameter.isCovariant) {
+ createStubIfNeeded();
+ stub.function.namedParameters[i].isCovariant = true;
+ }
+ }
+ }
+ for (int i = 0; i < interfaceTypeParameters.length; i++) {
+ TypeParameter typeParameter = interfaceTypeParameters[i];
+ bool isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
+ needsCheck(typeParameter.bound);
+ TypeParameter superTypeParameter = typeParameter;
+ for (int j = 0; j < _candidates.length; j++) {
+ Member otherMember = getCandidateAt(j);
+ if (otherMember is ForwardingNode) continue;
+ List<TypeParameter> otherTypeParameters =
+ otherMember.function.typeParameters;
+ if (otherTypeParameters.length <= i) continue;
+ TypeParameter otherTypeParameter = otherTypeParameters[i];
+ if (j == 0) superTypeParameter = otherTypeParameter;
+ if (identical(otherMember, interfaceMember)) continue;
+ if (otherTypeParameter.isGenericCovariantImpl) {
+ isGenericCovariantImpl = true;
+ }
+ }
+ if (isGenericCovariantImpl) {
+ if (!superTypeParameter.isGenericCovariantImpl) {
+ createImplIfNeeded();
+ }
+ if (!typeParameter.isGenericCovariantImpl) {
+ createStubIfNeeded();
+ stub.function.typeParameters[i].isGenericCovariantImpl = true;
+ }
+ }
+ }
+ return stub;
+ }
+
+ void _createForwardingImplIfNeeded(FunctionNode function) {
+ if (function.body != null) {
+ // There is already an implementation; nothing further needs to be done.
+ return;
+ }
+ // Find the concrete implementation in the superclass; this is what we need
+ // to forward to. If we can't find one, then the method is fully abstract
+ // and we don't need to do anything.
+ Class superclass = enclosingClass.superclass;
+ if (superclass == null) return;
+ Procedure procedure = function.parent;
+ Member superTarget = hierarchy.getDispatchTargetKernel(
+ superclass, procedure.name, kind == ProcedureKind.Setter);
+ if (superTarget == null) return;
+ if (superTarget is Procedure && superTarget.isForwardingStub) {
+ superTarget = _getForwardingStubSuperTarget(superTarget);
+ }
+ procedure.isAbstract = false;
+ if (!procedure.isForwardingStub) {
+ // This procedure exists abstractly in the source code; we need to make it
+ // concrete and give it a body that is a forwarding stub. This situation
+ // is called a "forwarding semi-stub".
+ procedure.isForwardingStub = true;
+ procedure.isForwardingSemiStub = true;
+ }
+ List<Expression> positionalArguments = function.positionalParameters
+ .map<Expression>((parameter) => new VariableGet(parameter))
+ .toList();
+ List<NamedExpression> namedArguments = function.namedParameters
+ .map((parameter) =>
+ new NamedExpression(parameter.name, new VariableGet(parameter)))
+ .toList();
+ List<DartType> typeArguments = function.typeParameters
+ .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
+ .toList();
+ Arguments arguments = new Arguments(positionalArguments,
+ types: typeArguments, named: namedArguments);
+ Expression superCall;
+ switch (kind) {
+ case ProcedureKind.Method:
+ case ProcedureKind.Operator:
+ superCall = new SuperMethodInvocation(name, arguments, superTarget);
+ break;
+ case ProcedureKind.Getter:
+ superCall = new SuperPropertyGet(name, superTarget);
+ break;
+ case ProcedureKind.Setter:
+ superCall =
+ new SuperPropertySet(name, positionalArguments[0], superTarget);
+ break;
+ default:
+ unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
+ break;
+ }
+ function.body = new ReturnStatement(superCall)..parent = function;
+ procedure.transformerFlags |= TransformerFlag.superCalls;
+ procedure.forwardingStubSuperTarget = superTarget;
+ }
+
+ /// Creates a forwarding stub based on the given [target].
+ Procedure _createForwardingStub(Substitution substitution, Member target) {
+ VariableDeclaration copyParameter(VariableDeclaration parameter) {
+ return new VariableDeclaration(parameter.name,
+ type: substitution.substituteType(parameter.type),
+ isCovariant: parameter.isCovariant)
+ ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
+ }
+
+ List<TypeParameter> targetTypeParameters =
+ target.function?.typeParameters ?? [];
+ List<TypeParameter> typeParameters;
+ if (targetTypeParameters.isNotEmpty) {
+ typeParameters =
+ new List<TypeParameter>.filled(targetTypeParameters.length, null);
+ Map<TypeParameter, DartType> additionalSubstitution =
+ <TypeParameter, DartType>{};
+ for (int i = 0; i < targetTypeParameters.length; i++) {
+ TypeParameter targetTypeParameter = targetTypeParameters[i];
+ TypeParameter typeParameter = new TypeParameter(
+ targetTypeParameter.name, null)
+ ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
+ typeParameters[i] = typeParameter;
+ additionalSubstitution[targetTypeParameter] =
+ new TypeParameterType(typeParameter);
+ }
+ substitution = Substitution.combine(
+ substitution, Substitution.fromMap(additionalSubstitution));
+ for (int i = 0; i < typeParameters.length; i++) {
+ typeParameters[i].bound =
+ substitution.substituteType(targetTypeParameters[i].bound);
+ }
+ }
+ List<VariableDeclaration> positionalParameters =
+ getPositionalParameters(target).map(copyParameter).toList();
+ List<VariableDeclaration> namedParameters =
+ target.function?.namedParameters?.map(copyParameter)?.toList() ?? [];
+ FunctionNode function = new FunctionNode(null,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters,
+ typeParameters: typeParameters,
+ requiredParameterCount: getRequiredParameterCount(target),
+ returnType: substitution.substituteType(getReturnType(target)));
+ Member finalTarget;
+ if (target is Procedure && target.isForwardingStub) {
+ finalTarget = target.forwardingStubInterfaceTarget;
+ } else {
+ finalTarget = target;
+ }
+ return new Procedure(name, kind, function,
+ isAbstract: true,
+ isForwardingStub: true,
+ fileUri: enclosingClass.fileUri,
+ forwardingStubInterfaceTarget: finalTarget)
+ ..startFileOffset = enclosingClass.fileOffset
+ ..fileOffset = enclosingClass.fileOffset
+ ..parent = enclosingClass;
+ }
+
+ /// Returns the [i]th element of [_candidates], finalizing it if necessary.
+ Member getCandidateAt(int i) {
+ Declaration candidate = _candidates[i];
+ assert(candidate is! DelayedMember);
+ return candidate.target;
+ }
+
+ static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
+ // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
+ // easier.
+ ReturnStatement body = forwardingStub.function.body;
+ Expression expression = body.expression;
+ if (expression is SuperMethodInvocation) {
+ return expression.interfaceTarget;
+ } else if (expression is SuperPropertySet) {
+ return expression.interfaceTarget;
+ } else {
+ return unhandled('${expression.runtimeType}',
+ '_getForwardingStubSuperTarget', -1, null);
+ }
+ }
+
+ Substitution _substitutionFor(Member candidate, Class class_) {
+ return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+ class_.thisType, candidate.enclosingClass));
+ }
+
+ List<VariableDeclaration> getPositionalParameters(Member member) {
+ if (member is Field) {
+ if (kind == ProcedureKind.Setter) {
+ return <VariableDeclaration>[
+ new VariableDeclaration("_",
+ type: member.type, isCovariant: member.isCovariant)
+ ..isGenericCovariantImpl = member.isGenericCovariantImpl
+ ];
+ } else {
+ return <VariableDeclaration>[];
+ }
+ } else {
+ return member.function.positionalParameters;
+ }
+ }
+
+ int getRequiredParameterCount(Member member) {
+ switch (kind) {
+ case ProcedureKind.Getter:
+ return 0;
+ case ProcedureKind.Setter:
+ return 1;
+ default:
+ return member.function.requiredParameterCount;
+ }
+ }
+
+ DartType getReturnType(Member member) {
+ switch (kind) {
+ case ProcedureKind.Getter:
+ return member is Field ? member.type : member.function.returnType;
+ case ProcedureKind.Setter:
+ return const VoidType();
+ default:
+ return member.function.returnType;
+ }
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index c82886b..1074242 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -16,6 +16,10 @@
class ImplicitFieldType extends DartType {
final MemberBuilder member;
Token initializerToken;
+ bool isStarted = false;
+
+ get nullability =>
+ unsupported("nullability", member.charOffset, member.fileUri);
ImplicitFieldType(this.member, this.initializerToken);
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 7195bac..2a35783 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -7,7 +7,7 @@
import 'package:kernel/ast.dart'
show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
-import '../problems.dart' show unhandled;
+import '../problems.dart' show unhandled, unsupported;
/// Marker type used as type argument on list, set and map literals whenever
/// type arguments are omitted in the source.
@@ -18,6 +18,9 @@
const ImplicitTypeArgument();
@override
+ get nullability => unsupported("nullability", -1, null);
+
+ @override
accept(DartTypeVisitor<Object> v) {
unhandled("$runtimeType", "${v.runtimeType}", -1, null);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index 278e742..dedf5ae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -47,14 +47,13 @@
KernelClassBuilder classBuilder,
ModifierBuilder member,
Scope scope,
- Scope parameterScope,
Uri fileUri)
: forest = const Fangorn(),
super(
library,
member,
scope,
- parameterScope,
+ null,
library.loader.hierarchy,
library.loader.coreTypes,
classBuilder,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
index 0206595..146b7b2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
@@ -16,7 +16,8 @@
export '../builder/builder.dart';
-export 'class_hierarchy_builder.dart' show ClassHierarchyBuilder;
+export 'class_hierarchy_builder.dart'
+ show ClassHierarchyBuilder, DelayedMember, DelayedOverrideCheck;
export 'implicit_field_type.dart' show ImplicitFieldType;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index b36770c..cb9eaf8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -123,6 +123,8 @@
import 'kernel_target.dart' show KernelTarget;
+import 'types.dart' show Types;
+
abstract class KernelClassBuilder
extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
KernelClassBuilder actualOrigin;
@@ -233,7 +235,7 @@
}
KernelMetadataBuilder.buildAnnotations(
- isPatch ? origin.target : cls, metadata, library, this, null, null);
+ isPatch ? origin.target : cls, metadata, library, this, null);
constructors.forEach(build);
scope.forEach(build);
}
@@ -538,7 +540,7 @@
}
void handleSeenCovariant(
- ClassHierarchy hierarchy,
+ Types types,
Member declaredMember,
Member interfaceMember,
bool isSetter,
@@ -546,9 +548,8 @@
// When a parameter is covariant we have to check that we also
// override the same member in all parents.
for (Supertype supertype in interfaceMember.enclosingClass.supers) {
- Member m = hierarchy.getInterfaceMember(
- supertype.classNode, interfaceMember.name,
- setter: isSetter);
+ Member m = types.hierarchy.getInterfaceMemberKernel(
+ supertype.classNode, interfaceMember.name, isSetter);
if (m != null) {
callback(declaredMember, m, isSetter);
}
@@ -556,8 +557,7 @@
}
void checkOverride(
- ClassHierarchy hierarchy,
- TypeEnvironment typeEnvironment,
+ Types types,
Member declaredMember,
Member interfaceMember,
bool isSetter,
@@ -573,25 +573,25 @@
if (declaredMember is Procedure && interfaceMember is Procedure) {
if (declaredMember.kind == ProcedureKind.Method &&
interfaceMember.kind == ProcedureKind.Method) {
- bool seenCovariant = checkMethodOverride(hierarchy, typeEnvironment,
- declaredMember, interfaceMember, isInterfaceCheck);
+ bool seenCovariant = checkMethodOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
- hierarchy, declaredMember, interfaceMember, isSetter, callback);
+ types, declaredMember, interfaceMember, isSetter, callback);
}
}
if (declaredMember.kind == ProcedureKind.Getter &&
interfaceMember.kind == ProcedureKind.Getter) {
- checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
- interfaceMember, isInterfaceCheck);
+ checkGetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
}
if (declaredMember.kind == ProcedureKind.Setter &&
interfaceMember.kind == ProcedureKind.Setter) {
- bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
- declaredMember, interfaceMember, isInterfaceCheck);
+ bool seenCovariant = checkSetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
- hierarchy, declaredMember, interfaceMember, isSetter, callback);
+ types, declaredMember, interfaceMember, isSetter, callback);
}
}
} else {
@@ -599,19 +599,24 @@
declaredMember is Procedure && declaredMember.isGetter;
bool interfaceMemberHasGetter = interfaceMember is Field ||
interfaceMember is Procedure && interfaceMember.isGetter;
- bool declaredMemberHasSetter = declaredMember is Field ||
+ bool declaredMemberHasSetter = (declaredMember is Field &&
+ !declaredMember.isFinal &&
+ !declaredMember.isConst) ||
declaredMember is Procedure && declaredMember.isSetter;
- bool interfaceMemberHasSetter = interfaceMember is Field ||
+ bool interfaceMemberHasSetter = (interfaceMember is Field &&
+ !interfaceMember.isFinal &&
+ !interfaceMember.isConst) ||
interfaceMember is Procedure && interfaceMember.isSetter;
if (declaredMemberHasGetter && interfaceMemberHasGetter) {
- checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
- interfaceMember, isInterfaceCheck);
- } else if (declaredMemberHasSetter && interfaceMemberHasSetter) {
- bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
- declaredMember, interfaceMember, isInterfaceCheck);
+ checkGetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
+ }
+ if (declaredMemberHasSetter && interfaceMemberHasSetter) {
+ bool seenCovariant = checkSetterOverride(
+ types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
- hierarchy, declaredMember, interfaceMember, isSetter, callback);
+ types, declaredMember, interfaceMember, isSetter, callback);
}
}
}
@@ -619,85 +624,10 @@
}
void checkOverrides(
- ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
- void overridePairCallback(
- Member declaredMember, Member interfaceMember, bool isSetter) {
- checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
- isSetter, overridePairCallback);
- }
-
- hierarchy.forEachOverridePair(cls, overridePairCallback);
- }
+ ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {}
void checkAbstractMembers(CoreTypes coreTypes, ClassHierarchy hierarchy,
- TypeEnvironment typeEnvironment) {
- // TODO(ahe): Move this to [ClassHierarchyBuilder].
- if (isAbstract) {
- // Unimplemented members allowed
- return;
- }
-
- bool mustHaveImplementation(Member member) {
- // Public member
- if (!member.name.isPrivate) return true;
- // Private member in different library
- if (member.enclosingLibrary != cls.enclosingLibrary) return false;
- // Private member in patch
- if (member.fileUri != member.enclosingClass.fileUri) return false;
- // Private member in same library
- return true;
- }
-
- void overridePairCallback(
- Member declaredMember, Member interfaceMember, bool isSetter) {
- checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
- isSetter, overridePairCallback,
- isInterfaceCheck: true);
- }
-
- void findMissingImplementations({bool setters}) {
- List<Member> dispatchTargets =
- hierarchy.getDispatchTargets(cls, setters: setters);
- int targetIndex = 0;
- for (Member interfaceMember
- in hierarchy.getInterfaceMembers(cls, setters: setters)) {
- if (mustHaveImplementation(interfaceMember)) {
- while (targetIndex < dispatchTargets.length &&
- ClassHierarchy.compareMembers(
- dispatchTargets[targetIndex], interfaceMember) <
- 0) {
- targetIndex++;
- }
- bool foundTarget = targetIndex < dispatchTargets.length &&
- ClassHierarchy.compareMembers(
- dispatchTargets[targetIndex], interfaceMember) <=
- 0;
- if (foundTarget) {
- Member dispatchTarget = dispatchTargets[targetIndex];
- while (dispatchTarget is Procedure &&
- !dispatchTarget.isExternal &&
- dispatchTarget.forwardingStubSuperTarget != null) {
- dispatchTarget =
- (dispatchTarget as Procedure).forwardingStubSuperTarget;
- }
- while (interfaceMember is Procedure &&
- !interfaceMember.isExternal &&
- interfaceMember.forwardingStubInterfaceTarget != null) {
- interfaceMember =
- (interfaceMember as Procedure).forwardingStubInterfaceTarget;
- }
- if (!hierarchy.isSubtypeOf(dispatchTarget.enclosingClass,
- interfaceMember.enclosingClass)) {
- overridePairCallback(dispatchTarget, interfaceMember, setters);
- }
- }
- }
- }
- }
-
- findMissingImplementations(setters: false);
- findMissingImplementations(setters: true);
- }
+ TypeEnvironment typeEnvironment) {}
bool hasUserDefinedNoSuchMethod(
Class klass, ClassHierarchy hierarchy, Class objectClass) {
@@ -924,7 +854,7 @@
}
Substitution _computeInterfaceSubstitution(
- ClassHierarchy hierarchy,
+ Types types,
Member declaredMember,
Member interfaceMember,
FunctionNode declaredFunction,
@@ -932,8 +862,9 @@
bool isInterfaceCheck) {
Substitution interfaceSubstitution = Substitution.empty;
if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
- interfaceSubstitution = Substitution.fromSupertype(
- hierarchy.getClassAsInstanceOf(cls, interfaceMember.enclosingClass));
+ interfaceSubstitution = Substitution.fromInterfaceType(types.hierarchy
+ .getKernelTypeAsInstanceOf(
+ cls.thisType, interfaceMember.enclosingClass));
}
if (declaredFunction?.typeParameters?.length !=
interfaceFunction?.typeParameters?.length) {
@@ -1000,17 +931,18 @@
}
Substitution _computeDeclaredSubstitution(
- ClassHierarchy hierarchy, Member declaredMember) {
+ Types types, Member declaredMember) {
Substitution declaredSubstitution = Substitution.empty;
if (declaredMember.enclosingClass.typeParameters.isNotEmpty) {
- declaredSubstitution = Substitution.fromSupertype(
- hierarchy.getClassAsInstanceOf(cls, declaredMember.enclosingClass));
+ declaredSubstitution = Substitution.fromInterfaceType(types.hierarchy
+ .getKernelTypeAsInstanceOf(
+ cls.thisType, declaredMember.enclosingClass));
}
return declaredSubstitution;
}
- bool _checkTypes(
- TypeEnvironment typeEnvironment,
+ void _checkTypes(
+ Types types,
Substitution interfaceSubstitution,
Substitution declaredSubstitution,
Member declaredMember,
@@ -1021,7 +953,7 @@
VariableDeclaration declaredParameter,
bool isInterfaceCheck,
{bool asIfDeclaredParameter = false}) {
- if (library.loader.target.backendTarget.legacyMode) return false;
+ if (library.loader.target.backendTarget.legacyMode) return;
if (interfaceSubstitution != null) {
interfaceType = interfaceSubstitution.substituteType(interfaceType);
@@ -1034,9 +966,9 @@
DartType subtype = inParameter ? interfaceType : declaredType;
DartType supertype = inParameter ? declaredType : interfaceType;
- if (typeEnvironment.isSubtypeOf(subtype, supertype)) {
+ if (types.isSubtypeOfKernel(subtype, supertype)) {
// No problem--the proper subtyping relation is satisfied.
- } else if (isCovariant && typeEnvironment.isSubtypeOf(supertype, subtype)) {
+ } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
// No problem--the overriding parameter is marked "covariant" and has
// a type which is a subtype of the parameter it overrides.
} else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1074,19 +1006,13 @@
interfaceMember.fileOffset, noLength)
] +
inheritedContext(isInterfaceCheck, declaredMember));
- return true;
}
- return false;
}
/// Returns whether a covariant parameter was seen and more methods thus have
/// to be checked.
- bool checkMethodOverride(
- ClassHierarchy hierarchy,
- TypeEnvironment typeEnvironment,
- Procedure declaredMember,
- Procedure interfaceMember,
- bool isInterfaceCheck) {
+ bool checkMethodOverride(Types types, Procedure declaredMember,
+ Procedure interfaceMember, bool isInterfaceCheck) {
assert(declaredMember.kind == ProcedureKind.Method);
assert(interfaceMember.kind == ProcedureKind.Method);
bool seenCovariant = false;
@@ -1094,7 +1020,7 @@
FunctionNode interfaceFunction = interfaceMember.function;
Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- hierarchy,
+ types,
declaredMember,
interfaceMember,
declaredFunction,
@@ -1102,10 +1028,10 @@
isInterfaceCheck);
Substitution declaredSubstitution =
- _computeDeclaredSubstitution(hierarchy, declaredMember);
+ _computeDeclaredSubstitution(types, declaredMember);
_checkTypes(
- typeEnvironment,
+ types,
interfaceSubstitution,
declaredSubstitution,
declaredMember,
@@ -1160,7 +1086,7 @@
var declaredParameter = declaredFunction.positionalParameters[i];
var interfaceParameter = interfaceFunction.positionalParameters[i];
_checkTypes(
- typeEnvironment,
+ types,
interfaceSubstitution,
declaredSubstitution,
declaredMember,
@@ -1237,7 +1163,7 @@
}
var declaredParameter = declaredNamedParameters.current;
_checkTypes(
- typeEnvironment,
+ types,
interfaceSubstitution,
declaredSubstitution,
declaredMember,
@@ -1252,25 +1178,16 @@
return seenCovariant;
}
- void checkGetterOverride(
- ClassHierarchy hierarchy,
- TypeEnvironment typeEnvironment,
- Member declaredMember,
- Member interfaceMember,
- bool isInterfaceCheck) {
+ void checkGetterOverride(Types types, Member declaredMember,
+ Member interfaceMember, bool isInterfaceCheck) {
Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- hierarchy,
- declaredMember,
- interfaceMember,
- null,
- null,
- isInterfaceCheck);
+ types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
Substitution declaredSubstitution =
- _computeDeclaredSubstitution(hierarchy, declaredMember);
+ _computeDeclaredSubstitution(types, declaredMember);
var declaredType = declaredMember.getterType;
var interfaceType = interfaceMember.getterType;
_checkTypes(
- typeEnvironment,
+ types,
interfaceSubstitution,
declaredSubstitution,
declaredMember,
@@ -1284,29 +1201,25 @@
/// Returns whether a covariant parameter was seen and more methods thus have
/// to be checked.
- bool checkSetterOverride(
- ClassHierarchy hierarchy,
- TypeEnvironment typeEnvironment,
- Member declaredMember,
- Member interfaceMember,
- bool isInterfaceCheck) {
+ bool checkSetterOverride(Types types, Member declaredMember,
+ Member interfaceMember, bool isInterfaceCheck) {
Substitution interfaceSubstitution = _computeInterfaceSubstitution(
- hierarchy,
- declaredMember,
- interfaceMember,
- null,
- null,
- isInterfaceCheck);
+ types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
Substitution declaredSubstitution =
- _computeDeclaredSubstitution(hierarchy, declaredMember);
+ _computeDeclaredSubstitution(types, declaredMember);
var declaredType = declaredMember.setterType;
var interfaceType = interfaceMember.setterType;
var declaredParameter =
declaredMember.function?.positionalParameters?.elementAt(0);
bool isCovariant = declaredParameter?.isCovariant ?? false;
- if (declaredMember is Field) isCovariant = declaredMember.isCovariant;
+ if (!isCovariant && declaredMember is Field) {
+ isCovariant = declaredMember.isCovariant;
+ }
+ if (!isCovariant && interfaceMember is Field) {
+ isCovariant = interfaceMember.isCovariant;
+ }
_checkTypes(
- typeEnvironment,
+ types,
interfaceSubstitution,
declaredSubstitution,
declaredMember,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 484c95e..8ee7d22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -25,8 +25,6 @@
ThisExpression,
VariableGet;
-import 'kernel_shadow_ast.dart' show ShadowClass;
-
import '../fasta_codes.dart'
show
LocatedMessage,
@@ -85,7 +83,7 @@
String name,
Scope scope,
Scope constructors,
- ShadowClass cls,
+ Class cls,
this.enumConstantInfos,
this.intType,
this.listType,
@@ -115,7 +113,7 @@
KernelTypeBuilder stringType = new KernelNamedTypeBuilder("String", null);
KernelNamedTypeBuilder objectType =
new KernelNamedTypeBuilder("Object", null);
- ShadowClass cls = new ShadowClass(name: name);
+ Class cls = new Class(name: name);
Map<String, MemberBuilder> members = <String, MemberBuilder>{};
Map<String, MemberBuilder> constructors = <String, MemberBuilder>{};
KernelNamedTypeBuilder selfType = new KernelNamedTypeBuilder(name, null);
@@ -255,7 +253,6 @@
members.forEach(setParent);
constructors.forEach(setParent);
selfType.bind(enumBuilder);
- ShadowClass.setBuilder(cls, enumBuilder);
return enumBuilder;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index 88a91b4..3a22dbb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -5,13 +5,16 @@
library fasta.kernel_field_builder;
import 'package:kernel/ast.dart'
- show Class, DartType, DynamicType, Expression, Field, Name, NullLiteral;
+ show Class, DartType, Expression, Field, InvalidType, Name, NullLiteral;
import '../constant_context.dart' show ConstantContext;
-import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
+import '../fasta_codes.dart'
+ show
+ messageInternalProblemAlreadyInitialized,
+ templateCantInferTypeDueToCircularity;
-import '../problems.dart' show internalProblem, unsupported;
+import '../problems.dart' show internalProblem;
import '../scanner.dart' show Token;
@@ -22,6 +25,10 @@
import '../type_inference/type_inference_engine.dart'
show IncludesTypeParametersCovariantly;
+import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
import 'kernel_body_builder.dart' show KernelBodyBuilder;
import 'kernel_builder.dart'
@@ -36,18 +43,17 @@
LibraryBuilder,
MetadataBuilder;
-import 'kernel_shadow_ast.dart' show ShadowField;
-
class KernelFieldBuilder extends FieldBuilder<Expression> {
- final ShadowField field;
+ final Field field;
final List<MetadataBuilder> metadata;
final KernelTypeBuilder type;
Token constInitializerToken;
+ bool hadTypesInferred = false;
+
KernelFieldBuilder(this.metadata, this.type, String name, int modifiers,
Declaration compilationUnit, int charOffset, int charEndOffset)
- : field = new ShadowField(null, type == null,
- fileUri: compilationUnit?.fileUri)
+ : field = new Field(null, fileUri: compilationUnit?.fileUri)
..fileOffset = charOffset
..fileEndOffset = charEndOffset,
super(name, modifiers, compilationUnit, charOffset);
@@ -95,10 +101,6 @@
..hasImplicitGetter = isInstanceMember
..hasImplicitSetter = isInstanceMember && !isConst && !isFinal
..isStatic = !isInstanceMember;
- if (isEligibleForInference && !isInstanceMember) {
- library.loader.typeInferenceEngine
- .recordStaticFieldInferenceCandidate(field, library);
- }
return field;
}
@@ -106,12 +108,12 @@
void buildOutlineExpressions(LibraryBuilder library) {
ClassBuilder classBuilder = isClassMember ? parent : null;
KernelMetadataBuilder.buildAnnotations(
- field, metadata, library, classBuilder, this, null);
+ field, metadata, library, classBuilder, this);
if (constInitializerToken != null) {
Scope scope = classBuilder?.scope ?? library.scope;
KernelBodyBuilder bodyBuilder =
new KernelBodyBuilder.forOutlineExpression(
- library, classBuilder, this, scope, null, fileUri);
+ library, classBuilder, this, scope, fileUri);
bodyBuilder.constantContext =
isConst ? ConstantContext.inferred : ConstantContext.none;
initializer = bodyBuilder.parseFieldInitializer(constInitializerToken)
@@ -130,27 +132,75 @@
Field get target => field;
- void prepareTopLevelInference() {
- if (!isEligibleForInference) return;
+ @override
+ void inferType() {
KernelLibraryBuilder library = this.library;
- var typeInferrer = library.loader.typeInferenceEngine
- .createTopLevelTypeInferrer(
- field.enclosingClass?.thisType, field, null);
- if (hasInitializer) {
- if (field.type is! ImplicitFieldType) {
- unsupported(
- "$name has unexpected type ${field.type}", charOffset, fileUri);
- return;
- }
- ImplicitFieldType type = field.type;
- field.type = const DynamicType();
- KernelBodyBuilder bodyBuilder =
- new KernelBodyBuilder.forField(this, typeInferrer);
- bodyBuilder.constantContext =
- isConst ? ConstantContext.inferred : ConstantContext.none;
- initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
- type.initializerToken = null;
+ if (field.type is! ImplicitFieldType) {
+ // We have already inferred a type.
+ return;
}
+ ImplicitFieldType type = field.type;
+ if (type.member != this) {
+ // The implicit type was inherited.
+ KernelFieldBuilder other = type.member;
+ other.inferCopiedType(field);
+ return;
+ }
+ if (type.isStarted) {
+ library.addProblem(
+ templateCantInferTypeDueToCircularity.withArguments(name),
+ charOffset,
+ name.length,
+ fileUri);
+ field.type = const InvalidType();
+ return;
+ }
+ type.isStarted = true;
+ TypeInferrerImpl typeInferrer = library.loader.typeInferenceEngine
+ .createTopLevelTypeInferrer(
+ fileUri, field.enclosingClass?.thisType, null);
+ KernelBodyBuilder bodyBuilder =
+ new KernelBodyBuilder.forField(this, typeInferrer);
+ bodyBuilder.constantContext =
+ isConst ? ConstantContext.inferred : ConstantContext.none;
+ initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
+ type.initializerToken = null;
+
+ DartType inferredType = typeInferrer.inferDeclarationType(typeInferrer
+ .inferExpression(field.initializer, const UnknownType(), true,
+ isVoidAllowed: true));
+
+ if (field.type is ImplicitFieldType) {
+ // `field.type` may have changed if a circularity was detected when
+ // [inferredType] was computed.
+ field.type = inferredType;
+
+ IncludesTypeParametersCovariantly needsCheckVisitor;
+ if (parent is ClassBuilder) {
+ Class enclosingClass = parent.target;
+ if (enclosingClass.typeParameters.isNotEmpty) {
+ needsCheckVisitor = new IncludesTypeParametersCovariantly(
+ enclosingClass.typeParameters);
+ }
+ }
+ if (needsCheckVisitor != null) {
+ if (field.type.accept(needsCheckVisitor)) {
+ field.isGenericCovariantImpl = true;
+ }
+ }
+ }
+
+ // The following is a hack. The outline should contain the compiled
+ // initializers, however, as top-level inference is subtly different from
+ // we need to compile the field initializer again when everything else is
+ // compiled.
+ field.initializer = null;
+ }
+
+ void inferCopiedType(Field other) {
+ inferType();
+ other.type = field.type;
+ other.initializer = null;
}
@override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 91a846a..06303d6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -103,6 +103,8 @@
namedMixinApplicationMask,
staticMask;
+import '../names.dart' show indexSetName;
+
import '../problems.dart' show unexpected, unhandled;
import '../severity.dart' show Severity;
@@ -203,6 +205,8 @@
List<KernelFormalParameterBuilder> untypedInitializingFormals;
+ List<KernelFieldBuilder> implicitlyTypedFields;
+
KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
[Scope scope, Library target])
: library = target ??
@@ -648,6 +652,7 @@
addBuilder(name, field, charOffset);
if (!legacyMode && type == null && initializerToken != null) {
field.target.type = new ImplicitFieldType(field, initializerToken);
+ (implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(field);
}
loader.target.metadataCollector
?.setDocumentationComment(field.target, documentationComment);
@@ -666,9 +671,10 @@
int charOffset,
int charOpenParenOffset,
int charEndOffset,
- String nativeMethodName) {
+ String nativeMethodName,
+ {Token beginInitializers}) {
MetadataCollector metadataCollector = loader.target.metadataCollector;
- ProcedureBuilder procedure = new KernelConstructorBuilder(
+ KernelConstructorBuilder procedure = new KernelConstructorBuilder(
metadata,
modifiers & ~abstractMask,
returnType,
@@ -694,7 +700,12 @@
if (nativeMethodName != null) {
addNativeMethod(procedure);
}
- if (procedure.isConst) currentDeclaration?.hasConstConstructor = true;
+ if (procedure.isConst) {
+ currentDeclaration?.hasConstConstructor = true;
+ // const constructors will have their initializers compiled and written
+ // into the outline.
+ procedure.beginInitializers = beginInitializers;
+ }
}
void addProcedure(
@@ -713,6 +724,14 @@
String nativeMethodName,
{bool isTopLevel}) {
MetadataCollector metadataCollector = loader.target.metadataCollector;
+ if (returnType == null) {
+ if (kind == ProcedureKind.Operator &&
+ identical(name, indexSetName.name)) {
+ returnType = addVoidType(charOffset);
+ } else if (kind == ProcedureKind.Setter) {
+ returnType = addVoidType(charOffset);
+ }
+ }
ProcedureBuilder procedure = new KernelProcedureBuilder(
metadata,
modifiers,
@@ -904,8 +923,7 @@
@override
void buildOutlineExpressions() {
- KernelMetadataBuilder.buildAnnotations(
- library, metadata, this, null, null, null);
+ KernelMetadataBuilder.buildAnnotations(library, metadata, this, null, null);
}
@override
@@ -1361,9 +1379,9 @@
}
@override
- void includePart(
+ bool includePart(
covariant KernelLibraryBuilder part, Set<Uri> usedParts, int partOffset) {
- super.includePart(part, usedParts, partOffset);
+ if (!super.includePart(part, usedParts, partOffset)) return false;
nativeMethods.addAll(part.nativeMethods);
boundlessTypeVariables.addAll(part.boundlessTypeVariables);
// Check that the targets are different. This is not normally a problem
@@ -1372,6 +1390,16 @@
target.problemsAsJson ??= <String>[];
target.problemsAsJson.addAll(part.target.problemsAsJson);
}
+ List<KernelFieldBuilder> partImplicitlyTypedFields =
+ part.takeImplicitlyTypedFields();
+ if (partImplicitlyTypedFields != null) {
+ if (implicitlyTypedFields == null) {
+ implicitlyTypedFields = partImplicitlyTypedFields;
+ } else {
+ implicitlyTypedFields.addAll(partImplicitlyTypedFields);
+ }
+ }
+ return true;
}
@override
@@ -1827,6 +1855,13 @@
untypedInitializingFormals = null;
return count;
}
+
+ @override
+ List<KernelFieldBuilder> takeImplicitlyTypedFields() {
+ List<KernelFieldBuilder> result = implicitlyTypedFields;
+ implicitlyTypedFields = null;
+ return result;
+ }
}
Uri computeLibraryUri(Declaration declaration) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
index 1c9f1f0..81970a0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
@@ -31,15 +31,14 @@
List<MetadataBuilder> metadata,
KernelLibraryBuilder library,
KernelClassBuilder classBuilder,
- MemberBuilder member,
- Scope parameterScope) {
+ MemberBuilder member) {
if (metadata == null) return;
Uri fileUri = member?.fileUri ?? classBuilder?.fileUri ?? library.fileUri;
Scope scope = parent is Library || parent is Class || classBuilder == null
? library.scope
: classBuilder.scope;
KernelBodyBuilder bodyBuilder = new KernelBodyBuilder.forOutlineExpression(
- library, classBuilder, member, scope, parameterScope, fileUri);
+ library, classBuilder, member, scope, fileUri);
for (int i = 0; i < metadata.length; ++i) {
KernelMetadataBuilder annotationBuilder = metadata[i];
parent.addAnnotation(
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index 0e9e42e..8d0df44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -30,11 +30,12 @@
TypeParameter,
TypeParameterType,
VariableDeclaration,
- VoidType,
setParents;
import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
+import '../../scanner/token.dart' show Token;
+
import '../loader.dart' show Loader;
import '../messages.dart'
@@ -74,8 +75,7 @@
TypeVariableBuilder,
isRedirectingGenerativeConstructorImplementation;
-import 'kernel_shadow_ast.dart'
- show ShadowProcedure, VariableDeclarationJudgment;
+import 'kernel_shadow_ast.dart' show VariableDeclarationJudgment;
import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
@@ -275,7 +275,7 @@
}
class KernelProcedureBuilder extends KernelFunctionBuilder {
- final ShadowProcedure procedure;
+ final Procedure procedure;
final int charOpenParenOffset;
AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
@@ -283,6 +283,8 @@
@override
KernelProcedureBuilder actualOrigin;
+ bool hadTypesInferred = false;
+
KernelProcedureBuilder(
List<MetadataBuilder> metadata,
int modifiers,
@@ -297,11 +299,11 @@
this.charOpenParenOffset,
int charEndOffset,
[String nativeMethodName])
- : procedure = new ShadowProcedure(null, kind, null, returnType == null,
- fileUri: compilationUnit?.fileUri)
- ..startFileOffset = startCharOffset
- ..fileOffset = charOffset
- ..fileEndOffset = charEndOffset,
+ : procedure =
+ new Procedure(null, kind, null, fileUri: compilationUnit?.fileUri)
+ ..startFileOffset = startCharOffset
+ ..fileOffset = charOffset
+ ..fileEndOffset = charEndOffset,
super(metadata, modifiers, returnType, name, typeVariables, formals,
compilationUnit, charOffset, nativeMethodName);
@@ -354,24 +356,13 @@
procedure.isConst = isConst;
procedure.name = new Name(name, library.target);
}
- if (!library.loader.target.legacyMode &&
- (isSetter || (isOperator && name == '[]=')) &&
- returnType == null) {
- procedure.function.returnType = const VoidType();
- }
return procedure;
}
@override
void buildOutlineExpressions(LibraryBuilder library) {
- ClassBuilder classBuilder = isClassMember ? parent : null;
KernelMetadataBuilder.buildAnnotations(
- target,
- metadata,
- library,
- classBuilder,
- this,
- computeFormalParameterScope(classBuilder?.scope ?? library.scope));
+ target, metadata, library, isClassMember ? parent : null, this);
}
Procedure get target => origin.procedure;
@@ -426,6 +417,8 @@
RedirectingInitializer redirectingInitializer;
+ Token beginInitializers;
+
@override
KernelConstructorBuilder actualOrigin;
@@ -498,14 +491,9 @@
@override
void buildOutlineExpressions(LibraryBuilder library) {
- ClassBuilder classBuilder = isClassMember ? parent : null;
KernelMetadataBuilder.buildAnnotations(
- target,
- metadata,
- library,
- classBuilder,
- this,
- computeFormalParameterScope(classBuilder?.scope ?? library.scope));
+ target, metadata, library, parent, this);
+ beginInitializers = null;
}
FunctionNode buildFunction(LibraryBuilder library) {
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 e91b0a4..4a5bc98 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
@@ -59,10 +59,8 @@
import '../type_inference/inference_helper.dart' show InferenceHelper;
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
import '../type_inference/type_inference_engine.dart'
- show IncludesTypeParametersCovariantly, InferenceNode, TypeInferenceEngine;
+ show IncludesTypeParametersCovariantly, TypeInferenceEngine;
import '../type_inference/type_inferrer.dart'
show ExpressionInferenceResult, TypeInferrer, TypeInferrerImpl;
@@ -280,59 +278,6 @@
}
}
-/// Shadow object representing a class in kernel form.
-class ShadowClass extends Class {
- ClassInferenceInfo _inferenceInfo;
-
- ShadowClass(
- {String name,
- Supertype supertype,
- Supertype mixedInType,
- List<TypeParameter> typeParameters,
- List<Supertype> implementedTypes,
- List<Procedure> procedures,
- List<Field> fields})
- : super(
- name: name,
- supertype: supertype,
- mixedInType: mixedInType,
- typeParameters: typeParameters,
- implementedTypes: implementedTypes,
- procedures: procedures,
- fields: fields);
-
- /// Resolves all forwarding nodes for this class, propagates covariance
- /// annotations, and creates forwarding stubs as needed.
- void finalizeCovariance(InterfaceResolver interfaceResolver) {
- interfaceResolver.finalizeCovariance(
- this, _inferenceInfo.gettersAndMethods, _inferenceInfo.builder.library);
- interfaceResolver.finalizeCovariance(
- this, _inferenceInfo.setters, _inferenceInfo.builder.library);
- }
-
- /// Creates API members for this class.
- void setupApiMembers(InterfaceResolver interfaceResolver) {
- interfaceResolver.createApiMembers(this, _inferenceInfo.gettersAndMethods,
- _inferenceInfo.setters, _inferenceInfo.builder.library);
- }
-
- static void clearClassInferenceInfo(ShadowClass class_) {
- class_._inferenceInfo = null;
- }
-
- static ClassInferenceInfo getClassInferenceInfo(Class class_) {
- if (class_ is ShadowClass) return class_._inferenceInfo;
- return null;
- }
-
- /// Initializes the class inference information associated with the given
- /// [class_], starting with the fact that it is associated with the given
- /// [builder].
- static void setBuilder(ShadowClass class_, SourceClassBuilder builder) {
- class_._inferenceInfo = new ClassInferenceInfo(builder);
- }
-}
-
/// Abstract shadow object representing a complex assignment in kernel form.
///
/// Since there are many forms a complex assignment might have been desugared
@@ -635,32 +580,6 @@
}
}
-/// Concrete shadow object representing a field in kernel form.
-class ShadowField extends Field implements ShadowMember {
- @override
- InferenceNode inferenceNode;
-
- ShadowTypeInferrer _typeInferrer;
-
- final bool _isImplicitlyTyped;
-
- ShadowField(Name name, this._isImplicitlyTyped, {Uri fileUri})
- : super(name, fileUri: fileUri) {}
-
- @override
- void setInferredType(
- TypeInferenceEngine engine, Uri uri, DartType inferredType) {
- type = inferredType;
- }
-
- static bool isImplicitlyTyped(ShadowField field) => field._isImplicitlyTyped;
-
- static void setInferenceNode(ShadowField field, InferenceNode node) {
- assert(field.inferenceNode == null);
- field.inferenceNode = node;
- }
-}
-
/// Concrete shadow object representing a field initializer in kernel form.
class ShadowFieldInitializer extends FieldInitializer
implements InitializerJudgment {
@@ -1000,18 +919,6 @@
}
}
-/// Abstract shadow object representing a field or procedure in kernel form.
-abstract class ShadowMember implements Member {
- Uri get fileUri;
-
- InferenceNode get inferenceNode;
-
- void set inferenceNode(InferenceNode value);
-
- void setInferredType(
- TypeInferenceEngine engine, Uri uri, DartType inferredType);
-}
-
/// Shadow object for [MethodInvocation].
class MethodInvocationJudgment extends MethodInvocation
implements ExpressionJudgment {
@@ -1110,37 +1017,6 @@
}
}
-/// Concrete shadow object representing a procedure in kernel form.
-class ShadowProcedure extends Procedure implements ShadowMember {
- @override
- InferenceNode inferenceNode;
-
- final bool _hasImplicitReturnType;
-
- ShadowProcedure(Name name, ProcedureKind kind, FunctionNode function,
- this._hasImplicitReturnType,
- {Uri fileUri, bool isAbstract: false})
- : super(name, kind, function, fileUri: fileUri, isAbstract: isAbstract);
-
- @override
- void setInferredType(
- TypeInferenceEngine engine, Uri uri, DartType inferredType) {
- if (isSetter) {
- if (function.positionalParameters.length > 0) {
- function.positionalParameters[0].type = inferredType;
- }
- } else if (isGetter) {
- function.returnType = inferredType;
- } else {
- unhandled("setInferredType", "not accessor", fileOffset, uri);
- }
- }
-
- static bool hasImplicitReturnType(ShadowProcedure procedure) {
- return procedure._hasImplicitReturnType;
- }
-}
-
/// Concrete shadow object representing an assignment to a property.
class PropertyAssignmentJudgment extends ComplexAssignmentJudgmentWithReceiver {
/// If this assignment uses null-aware access (`?.`), the conditional
@@ -1470,14 +1346,8 @@
@override
ShadowTypeInferrer createTopLevelTypeInferrer(
- InterfaceType thisType, ShadowField field, KernelLibraryBuilder library) {
- return field._typeInferrer =
- new TypeInferrer(this, field.fileUri, true, thisType, library);
- }
-
- @override
- ShadowTypeInferrer getFieldTypeInferrer(ShadowField field) {
- return field._typeInferrer;
+ Uri uri, InterfaceType thisType, KernelLibraryBuilder library) {
+ return new TypeInferrer(this, uri, true, thisType, library);
}
}
@@ -1493,7 +1363,7 @@
super.private(engine, uri, topLevel, thisType, library);
@override
- Expression getFieldInitializer(ShadowField field) {
+ Expression getFieldInitializer(Field field) {
return field.initializer;
}
@@ -1536,13 +1406,6 @@
}
@override
- DartType inferFieldTopLevel(ShadowField field) {
- if (field.initializer == null) return const DynamicType();
- return inferExpression(field.initializer, const UnknownType(), true,
- isVoidAllowed: true);
- }
-
- @override
void inferInitializer(
InferenceHelper helper, kernel.Initializer initializer) {
assert(initializer is InitializerJudgment);
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 5d67c40..0128ab2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -87,7 +87,6 @@
import 'kernel_builder.dart'
show
ClassBuilder,
- ClassHierarchyBuilder,
Declaration,
InvalidTypeBuilder,
KernelClassBuilder,
@@ -152,8 +151,6 @@
loader = createLoader();
}
- void set builderHierarchy(ClassHierarchyBuilder o) {}
-
SourceLoader createLoader() =>
new SourceLoader(fileSystem, includeComments, this);
@@ -268,8 +265,7 @@
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
computeCoreTypes();
- builderHierarchy =
- loader.buildClassHierarchy(myClasses, objectClassBuilder);
+ loader.buildClassHierarchy(myClasses, objectClassBuilder);
loader.computeHierarchy();
loader.performTopLevelInference(myClasses);
loader.checkSupertypes(myClasses);
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
index 9f6d5c1..94e0b9b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -14,6 +14,7 @@
InterfaceType,
InvalidType,
NamedType,
+ Nullability,
TypeParameter,
TypeParameterType,
TypedefType,
@@ -30,16 +31,21 @@
/// Returns true if [s] is a subtype of [t].
bool isSubtypeOfKernel(DartType s, DartType t) {
- if (s is BottomType) {
- return true; // Rule 3.
- }
if (s is InvalidType) {
- // InvalidType is also a bottom type.
+ // InvalidType is a bottom type.
return true;
}
if (t is InvalidType) {
return false;
}
+ return isSubtypeOfKernelNullability(s, s.nullability, t, t.nullability);
+ }
+
+ bool isSubtypeOfKernelNullability(
+ DartType s, Nullability sNullability, DartType t, tNullability) {
+ if (s is BottomType) {
+ return true; // Rule 3.
+ }
if (t is DynamicType) {
return true; // Rule 2.
}
@@ -57,121 +63,161 @@
if (cls == hierarchy.futureOrKernelClass) {
const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
} else {
const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
}
} else if (t is FunctionType) {
const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
} else if (t is TypeParameterType) {
if (t.promotedBound == null) {
const IsTypeParameterSubtypeOf relation =
const IsTypeParameterSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
} else {
const IsIntersectionSubtypeOf relation =
const IsIntersectionSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
}
} else if (t is TypedefType) {
const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
if (s is DynamicType) {
- return relation.isDynamicRelated(s, t, this);
+ return relation.isDynamicRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is VoidType) {
- return relation.isVoidRelated(s, t, this);
+ return relation.isVoidRelated(s, sNullability, t, tNullability, this);
} else if (s is InterfaceType) {
return s.classNode == hierarchy.futureOrKernelClass
- ? relation.isFutureOrRelated(s, t, this)
- : relation.isInterfaceRelated(s, t, this);
+ ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
+ : relation.isInterfaceRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is FunctionType) {
- return relation.isFunctionRelated(s, t, this);
+ return relation.isFunctionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypeParameterType) {
return s.promotedBound == null
- ? relation.isTypeParameterRelated(s, t, this)
- : relation.isIntersectionRelated(s, t, this);
+ ? relation.isTypeParameterRelated(
+ s, sNullability, t, tNullability, this)
+ : relation.isIntersectionRelated(
+ s, sNullability, t, tNullability, this);
} else if (s is TypedefType) {
- return relation.isTypedefRelated(s, t, this);
+ return relation.isTypedefRelated(
+ s, sNullability, t, tNullability, this);
}
} else {
throw "Unhandled type: ${t.runtimeType}";
@@ -198,28 +244,45 @@
abstract class TypeRelation<T extends DartType> {
const TypeRelation();
- bool isDynamicRelated(DynamicType s, T t, Types types);
+ bool isDynamicRelated(DynamicType s, Nullability sNullability, T t,
+ Nullability tNullability, Types types);
- bool isVoidRelated(VoidType s, T t, Types types);
+ bool isVoidRelated(VoidType s, Nullability sNullability, T t,
+ Nullability tNullability, Types types);
- bool isInterfaceRelated(InterfaceType s, T t, Types types);
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability, T t,
+ Nullability tNullability, Types types);
- bool isIntersectionRelated(TypeParameterType intersection, T t, Types types);
+ bool isIntersectionRelated(
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ T t,
+ Nullability tNullability,
+ Types types);
- bool isFunctionRelated(FunctionType s, T t, Types types);
+ bool isFunctionRelated(FunctionType s, Nullability sNullability, T t,
+ Nullability tNullability, Types types);
- bool isFutureOrRelated(InterfaceType futureOr, T t, Types types);
+ bool isFutureOrRelated(
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ T t,
+ Nullability tNullability,
+ Types types);
- bool isTypeParameterRelated(TypeParameterType s, T t, Types types);
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ T t, Nullability tNullability, Types types);
- bool isTypedefRelated(TypedefType s, T t, Types types);
+ bool isTypedefRelated(TypedefType s, Nullability sNullability, T t,
+ Nullability tNullability, Types types);
}
class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
const IsInterfaceSubtypeOf();
@override
- bool isInterfaceRelated(InterfaceType s, InterfaceType t, Types types) {
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+ InterfaceType t, Nullability tNullability, Types types) {
if (s.classNode == types.hierarchy.nullKernelClass) {
// This is an optimization, to avoid instantating unnecessary type
// arguments in getKernelTypeAsInstanceOf.
@@ -236,13 +299,18 @@
}
@override
- bool isTypeParameterRelated(
- TypeParameterType s, InterfaceType t, Types types) {
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ InterfaceType t, Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s.parameter.bound, t);
}
@override
- bool isFutureOrRelated(InterfaceType futureOr, InterfaceType t, Types types) {
+ bool isFutureOrRelated(
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ InterfaceType t,
+ Nullability tNullability,
+ Types types) {
List<DartType> arguments = futureOr.typeArguments;
if (!types.isSubtypeOfKernel(arguments.single, t)) {
return false; // Rule 7.1
@@ -256,28 +324,36 @@
@override
bool isIntersectionRelated(
- TypeParameterType intersection, InterfaceType t, Types types) {
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ InterfaceType t,
+ Nullability tNullability,
+ Types types) {
return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
}
@override
- bool isDynamicRelated(DynamicType s, InterfaceType t, Types types) {
+ bool isDynamicRelated(DynamicType s, Nullability sNullability,
+ InterfaceType t, Nullability tNullability, Types types) {
return false;
}
@override
- bool isFunctionRelated(FunctionType s, InterfaceType t, Types types) {
+ bool isFunctionRelated(FunctionType s, Nullability sNullability,
+ InterfaceType t, Nullability tNullability, Types types) {
return t.classNode == types.hierarchy.functionKernelClass; // Rule 14.
}
@override
- bool isTypedefRelated(TypedefType s, InterfaceType t, Types types) {
+ bool isTypedefRelated(TypedefType s, Nullability sNullability,
+ InterfaceType t, Nullability tNullability, Types types) {
// Rule 5.
return types.isSubtypeOfKernel(s.unalias, t);
}
@override
- bool isVoidRelated(VoidType s, InterfaceType t, Types types) {
+ bool isVoidRelated(VoidType s, Nullability sNullability, InterfaceType t,
+ Nullability tNullability, Types types) {
return false;
}
}
@@ -286,7 +362,8 @@
const IsFunctionSubtypeOf();
@override
- bool isFunctionRelated(FunctionType s, FunctionType t, Types types) {
+ bool isFunctionRelated(FunctionType s, Nullability sNullability,
+ FunctionType t, Nullability tNullability, Types types) {
List<TypeParameter> sTypeVariables = s.typeParameters;
List<TypeParameter> tTypeVariables = t.typeParameters;
if (sTypeVariables.length != tTypeVariables.length) return false;
@@ -364,40 +441,55 @@
}
@override
- bool isInterfaceRelated(InterfaceType s, FunctionType t, Types types) {
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+ FunctionType t, Nullability tNullability, Types types) {
return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
}
@override
- bool isDynamicRelated(DynamicType s, FunctionType t, Types types) => false;
+ bool isDynamicRelated(DynamicType s, Nullability sNullability, FunctionType t,
+ Nullability tNullability, Types types) {
+ return false;
+ }
@override
- bool isFutureOrRelated(InterfaceType futureOr, FunctionType t, Types types) {
+ bool isFutureOrRelated(
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ FunctionType t,
+ Nullability tNullability,
+ Types types) {
return false;
}
@override
bool isIntersectionRelated(
- TypeParameterType intersection, FunctionType t, Types types) {
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ FunctionType t,
+ Nullability tNullability,
+ Types types) {
// Rule 12.
return types.isSubtypeOfKernel(intersection.promotedBound, t);
}
@override
- bool isTypeParameterRelated(
- TypeParameterType s, FunctionType t, Types types) {
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ FunctionType t, Nullability tNullability, Types types) {
// Rule 13.
return types.isSubtypeOfKernel(s.parameter.bound, t);
}
@override
- bool isTypedefRelated(TypedefType s, FunctionType t, Types types) {
+ bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
+ Nullability tNullability, Types types) {
// Rule 5.
return types.isSubtypeOfKernel(s.unalias, t);
}
@override
- bool isVoidRelated(VoidType s, FunctionType t, Types types) {
+ bool isVoidRelated(VoidType s, Nullability sNullability, FunctionType t,
+ Nullability tNullability, Types types) {
return false;
}
}
@@ -406,8 +498,8 @@
const IsTypeParameterSubtypeOf();
@override
- bool isTypeParameterRelated(
- TypeParameterType s, TypeParameterType t, Types types) {
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ TypeParameterType t, Nullability tNullability, Types types) {
return s.parameter == t.parameter ||
// Rule 13.
types.isSubtypeOfKernel(s.bound, t);
@@ -415,38 +507,51 @@
@override
bool isIntersectionRelated(
- TypeParameterType intersection, TypeParameterType t, Types types) {
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ TypeParameterType t,
+ Nullability tNullability,
+ Types types) {
return intersection.parameter == t.parameter; // Rule 8.
}
@override
- bool isInterfaceRelated(InterfaceType s, TypeParameterType t, Types types) {
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+ TypeParameterType t, Nullability tNullability, Types types) {
return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
}
@override
- bool isDynamicRelated(DynamicType s, TypeParameterType t, Types types) {
+ bool isDynamicRelated(DynamicType s, Nullability sNullability,
+ TypeParameterType t, Nullability tNullability, Types types) {
return false;
}
@override
- bool isFunctionRelated(FunctionType s, TypeParameterType t, Types types) {
+ bool isFunctionRelated(FunctionType s, Nullability sNullability,
+ TypeParameterType t, Nullability tNullability, Types types) {
return false;
}
@override
bool isFutureOrRelated(
- InterfaceType futureOr, TypeParameterType t, Types types) {
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ TypeParameterType t,
+ Nullability tNullability,
+ Types types) {
return false;
}
@override
- bool isTypedefRelated(TypedefType s, TypeParameterType t, Types types) {
+ bool isTypedefRelated(TypedefType s, Nullability sNullability,
+ TypeParameterType t, Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s.unalias, t);
}
@override
- bool isVoidRelated(VoidType s, TypeParameterType t, Types types) {
+ bool isVoidRelated(VoidType s, Nullability sNullability, TypeParameterType t,
+ Nullability tNullability, Types types) {
return false;
}
}
@@ -455,43 +560,58 @@
const IsTypedefSubtypeOf();
@override
- bool isInterfaceRelated(InterfaceType s, TypedefType t, Types types) {
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+ TypedefType t, Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s, t.unalias);
}
@override
- bool isDynamicRelated(DynamicType s, TypedefType t, Types types) {
+ bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
+ Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s, t.unalias);
}
@override
- bool isFunctionRelated(FunctionType s, TypedefType t, Types types) {
+ bool isFunctionRelated(FunctionType s, Nullability sNullability,
+ TypedefType t, Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s, t.unalias);
}
@override
- bool isFutureOrRelated(InterfaceType futureOr, TypedefType t, Types types) {
+ bool isFutureOrRelated(
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ TypedefType t,
+ Nullability tNullability,
+ Types types) {
return types.isSubtypeOfKernel(futureOr, t.unalias);
}
@override
bool isIntersectionRelated(
- TypeParameterType intersection, TypedefType t, Types types) {
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ TypedefType t,
+ Nullability tNullability,
+ Types types) {
return types.isSubtypeOfKernel(intersection, t.unalias);
}
@override
- bool isTypeParameterRelated(TypeParameterType s, TypedefType t, Types types) {
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ TypedefType t, Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s, t.unalias);
}
@override
- bool isTypedefRelated(TypedefType s, TypedefType t, Types types) {
+ bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
+ Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s.unalias, t.unalias);
}
@override
- bool isVoidRelated(VoidType s, TypedefType t, Types types) {
+ bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
+ Nullability tNullability, Types types) {
return types.isSubtypeOfKernel(s, t.unalias);
}
}
@@ -500,8 +620,8 @@
const IsFutureOrSubtypeOf();
@override
- bool isInterfaceRelated(
- InterfaceType s, InterfaceType futureOr, Types types) {
+ bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
List<DartType> arguments = futureOr.typeArguments;
if (types.isSubtypeOfKernel(s, arguments.single)) {
return true; // Rule 11.
@@ -513,27 +633,33 @@
@override
bool isFutureOrRelated(
- InterfaceType sFutureOr, InterfaceType tFutureOr, Types types) {
+ InterfaceType sFutureOr,
+ Nullability sFutureOrNullability,
+ InterfaceType tFutureOr,
+ Nullability tFutureOrNullability,
+ Types types) {
// This follows from combining rules 7, 10, and 11.
return types.isSubtypeOfKernel(
sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
}
@override
- bool isDynamicRelated(DynamicType s, InterfaceType futureOr, Types types) {
+ bool isDynamicRelated(DynamicType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
}
@override
- bool isVoidRelated(VoidType s, InterfaceType futureOr, Types types) {
+ bool isVoidRelated(VoidType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
}
@override
- bool isTypeParameterRelated(
- TypeParameterType s, InterfaceType futureOr, Types types) {
+ bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
List<DartType> arguments = futureOr.typeArguments;
if (types.isSubtypeOfKernel(s, arguments.single)) {
// Rule 11.
@@ -551,15 +677,21 @@
}
@override
- bool isFunctionRelated(FunctionType s, InterfaceType futureOr, Types types) {
+ bool isFunctionRelated(FunctionType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
}
@override
bool isIntersectionRelated(
- TypeParameterType intersection, InterfaceType futureOr, Types types) {
- if (isTypeParameterRelated(intersection, futureOr, types)) {
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ Types types) {
+ if (isTypeParameterRelated(intersection, intersectionNullability, futureOr,
+ futureOrNullability, types)) {
// Rule 8.
return true;
}
@@ -568,7 +700,8 @@
}
@override
- bool isTypedefRelated(TypedefType s, InterfaceType futureOr, Types types) {
+ bool isTypedefRelated(TypedefType s, Nullability sNullability,
+ InterfaceType futureOr, Nullability futureOrNullability, Types types) {
return types.isSubtypeOfKernel(s.unalias, futureOr);
}
}
@@ -577,51 +710,93 @@
const IsIntersectionSubtypeOf();
@override
- bool isIntersectionRelated(TypeParameterType sIntersection,
- TypeParameterType tIntersection, Types types) {
+ bool isIntersectionRelated(
+ TypeParameterType sIntersection,
+ Nullability sIntersectionNullability,
+ TypeParameterType tIntersection,
+ Nullability tIntersectionNullability,
+ Types types) {
// Rule 9.
- return const IsTypeParameterSubtypeOf()
- .isIntersectionRelated(sIntersection, tIntersection, types) &&
+ return const IsTypeParameterSubtypeOf().isIntersectionRelated(
+ sIntersection,
+ sIntersectionNullability,
+ tIntersection,
+ tIntersectionNullability,
+ types) &&
types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
}
@override
bool isTypeParameterRelated(
- TypeParameterType s, TypeParameterType intersection, Types types) {
+ TypeParameterType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
// Rule 9.
- return const IsTypeParameterSubtypeOf()
- .isTypeParameterRelated(s, intersection, types) &&
+ return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
+ s, sNullability, intersection, intersectionNullability, types) &&
types.isSubtypeOfKernel(s, intersection.promotedBound);
}
@override
bool isInterfaceRelated(
- InterfaceType s, TypeParameterType intersection, Types types) {
+ InterfaceType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
}
+ @override
bool isDynamicRelated(
- DynamicType s, TypeParameterType intersection, Types types) {
+ DynamicType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
return false;
}
+ @override
bool isFunctionRelated(
- FunctionType s, TypeParameterType intersection, Types types) {
+ FunctionType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
return false;
}
+ @override
bool isFutureOrRelated(
- InterfaceType futureOr, TypeParameterType intersection, Types types) {
+ InterfaceType futureOr,
+ Nullability futureOrNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
return false;
}
+ @override
bool isTypedefRelated(
- TypedefType s, TypeParameterType intersection, Types types) {
+ TypedefType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
// Rule 5.
return types.isSubtypeOfKernel(s.unalias, intersection);
}
- bool isVoidRelated(VoidType s, TypeParameterType intersection, Types types) {
+ @override
+ bool isVoidRelated(
+ VoidType s,
+ Nullability sNullability,
+ TypeParameterType intersection,
+ Nullability intersectionNullability,
+ Types types) {
return false;
}
}
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 64ec528..e2471a4 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -480,6 +480,12 @@
}
@override
+ void endInvalidAwaitExpression(
+ Token beginToken, Token endToken, MessageCode errorCode) {
+ listener?.endInvalidAwaitExpression(beginToken, endToken, errorCode);
+ }
+
+ @override
void endBinaryExpression(Token token) {
listener?.endBinaryExpression(token);
}
@@ -774,9 +780,10 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
- listener?.endMethod(getOrSet, beginToken, beginParam, endToken);
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
+ listener?.endMethod(
+ getOrSet, beginToken, beginParam, beginInitializers, endToken);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index e92f6f3..fcedb9b 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -6,7 +6,8 @@
import '../../scanner/token.dart' show Token;
-import '../fasta_codes.dart' show Message, templateExperimentNotEnabled;
+import '../fasta_codes.dart'
+ show Message, MessageCode, templateExperimentNotEnabled;
import '../quote.dart' show UnescapeErrorListener;
@@ -57,6 +58,11 @@
logEvent("AwaitExpression");
}
+ void endInvalidAwaitExpression(
+ Token beginToken, Token endToken, MessageCode errorCode) {
+ logEvent("InvalidAwaitExpression");
+ }
+
void beginBlock(Token token) {}
void endBlock(int count, Token beginToken, Token endToken) {
@@ -747,8 +753,8 @@
/// - initializers
/// - async marker
/// - body
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
logEvent("Method");
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index ed13bfe..d6a0d065 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2516,7 +2516,7 @@
Token parseInitializersOpt(Token token) {
if (optional(':', token.next)) {
- return parseInitializers(token);
+ return parseInitializers(token.next);
} else {
listener.handleNoInitializers();
return token;
@@ -2529,7 +2529,7 @@
/// ;
/// ```
Token parseInitializers(Token token) {
- Token begin = token.next;
+ Token begin = token;
assert(optional(':', begin));
listener.beginInitializers(begin);
int count = 0;
@@ -3241,8 +3241,10 @@
? MemberKind.StaticMethod
: MemberKind.NonStaticMethod;
Token beforeParam = token;
- token = parseGetterOrFormalParameters(token, name, isGetter, kind);
- token = parseInitializersOpt(token);
+ Token beforeInitializers =
+ parseGetterOrFormalParameters(token, name, isGetter, kind);
+ token = parseInitializersOpt(beforeInitializers);
+ if (token == beforeInitializers) beforeInitializers = null;
AsyncModifier savedAsyncModifier = asyncState;
Token asyncToken = token.next;
@@ -3264,7 +3266,8 @@
(staticToken == null || externalToken != null) && inPlainSync);
}
asyncState = savedAsyncModifier;
- listener.endMethod(getOrSet, beforeStart.next, beforeParam.next, token);
+ listener.endMethod(getOrSet, beforeStart.next, beforeParam.next,
+ beforeInitializers?.next, token);
return token;
}
@@ -5741,12 +5744,15 @@
Token awaitToken = token.next;
assert(optional('await', awaitToken));
listener.beginAwaitExpression(awaitToken);
- if (!inAsync) {
- reportRecoverableError(awaitToken, fasta.messageAwaitNotAsync);
- }
token = parsePrecedenceExpression(
awaitToken, POSTFIX_PRECEDENCE, allowCascades);
- listener.endAwaitExpression(awaitToken, token.next);
+ if (inAsync) {
+ listener.endAwaitExpression(awaitToken, token.next);
+ } else {
+ fasta.MessageCode errorCode = fasta.messageAwaitNotAsync;
+ reportRecoverableError(awaitToken, errorCode);
+ listener.endInvalidAwaitExpression(awaitToken, token.next, errorCode);
+ }
return token;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser_main.dart b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
index a282842..0079797 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser_main.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
@@ -36,6 +36,7 @@
Uri uri = Uri.base.resolve(argument.substring(1));
await for (String file in new File.fromUri(uri)
.openRead()
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(const LineSplitter())) {
outLine(uri.resolve(file));
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index c556487..52ee5db 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -575,8 +575,8 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
debugEvent("Method");
// TODO(danrubel): Consider removing the beginParam parameter
// and using bodyToken, but pushing a NullValue on the stack
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 964646f..1ed1f9e 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -754,8 +754,8 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
debugEvent("Method");
MethodBody bodyKind = pop();
if (bodyKind == MethodBody.RedirectingFactoryBody) {
@@ -871,7 +871,8 @@
charOffset,
formalsOffset,
endToken.charOffset,
- nativeMethodName);
+ nativeMethodName,
+ beginInitializers: beginInitializers);
} else {
if (isConst) {
addProblem(messageConstMethod, varFinalOrConstOffset, 5);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 09cd1c9..3adef89 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -41,21 +41,19 @@
TypeVariableBuilder,
compareProcedures;
-import '../kernel/kernel_shadow_ast.dart' show ShadowClass;
-
import '../kernel/type_algorithms.dart' show Variance, computeVariance;
import '../problems.dart' show unexpected, unhandled;
-ShadowClass initializeClass(
- ShadowClass cls,
+Class initializeClass(
+ Class cls,
List<TypeVariableBuilder> typeVariables,
String name,
KernelLibraryBuilder parent,
int startCharOffset,
int charOffset,
int charEndOffset) {
- cls ??= new ShadowClass(
+ cls ??= new Class(
name: name,
typeParameters:
KernelTypeVariableBuilder.kernelTypeParametersFromBuilders(
@@ -105,12 +103,10 @@
: actualCls = initializeClass(cls, typeVariables, name, parent,
startCharOffset, charOffset, charEndOffset),
super(metadata, modifiers, name, typeVariables, supertype, interfaces,
- scope, constructors, parent, charOffset) {
- ShadowClass.setBuilder(this.cls, this);
- }
+ scope, constructors, parent, charOffset);
@override
- ShadowClass get cls => origin.actualCls;
+ Class get cls => origin.actualCls;
@override
KernelLibraryBuilder get library => super.library;
@@ -278,20 +274,6 @@
constructorScopeBuilder.addMember(name, memberBuilder);
}
- void prepareTopLevelInference() {
- scope.forEach((String name, Declaration declaration) {
- do {
- if (declaration is KernelFieldBuilder) {
- declaration.prepareTopLevelInference();
- }
- declaration = declaration.next;
- } while (declaration != null);
- });
- if (!isPatch) {
- cls.setupApiMembers(library.loader.interfaceResolver);
- }
- }
-
@override
int finishPatch() {
if (!isPatch) return 0;
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 89abbb2..77579d0 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
@@ -431,7 +431,8 @@
int charOffset,
int charOpenParenOffset,
int charEndOffset,
- String nativeMethodName);
+ String nativeMethodName,
+ {Token beginInitializers});
void addProcedure(
String documentationComment,
@@ -703,7 +704,7 @@
}
}
- void includePart(
+ bool includePart(
SourceLibraryBuilder<T, R> part, Set<Uri> usedParts, int partOffset) {
if (part.partOfUri != null) {
if (uriIsValid(part.partOfUri) && part.partOfUri != uri) {
@@ -715,7 +716,7 @@
partOffset,
noLength,
fileUri);
- return;
+ return false;
}
} else if (part.partOfName != null) {
if (name != null) {
@@ -728,7 +729,7 @@
partOffset,
noLength,
fileUri);
- return;
+ return false;
}
} else {
// This is an error, but the part is not removed from the list of parts,
@@ -739,7 +740,7 @@
partOffset,
noLength,
fileUri);
- return;
+ return false;
}
} else {
// This is an error, but the part is not removed from the list of parts,
@@ -749,7 +750,7 @@
addProblem(templateMissingPartOf.withArguments(part.fileUri),
partOffset, noLength, fileUri);
}
- return;
+ return false;
}
part.validatePart(this, usedParts);
NameIterator partDeclarations = part.nameIterator;
@@ -798,6 +799,7 @@
part.partOfLibrary = this;
part.scope.becomePartOf(scope);
// TODO(ahe): Include metadata from part?
+ return true;
}
void buildInitialScopes() {
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 3040e27..74fcaa1 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -68,17 +68,18 @@
templateSourceOutlineSummary,
templateUntranslatableUri;
-import '../kernel/kernel_shadow_ast.dart'
- show ShadowClass, ShadowTypeInferenceEngine;
+import '../kernel/kernel_shadow_ast.dart' show ShadowTypeInferenceEngine;
import '../kernel/kernel_builder.dart'
show
ClassBuilder,
ClassHierarchyBuilder,
Declaration,
+ DelayedMember,
+ DelayedOverrideCheck,
EnumBuilder,
+ FieldBuilder,
KernelClassBuilder,
- KernelFieldBuilder,
KernelProcedureBuilder,
KernelTypeBuilder,
LibraryBuilder,
@@ -107,8 +108,6 @@
import '../scanner.dart'
show ErrorToken, ScannerConfiguration, ScannerResult, Token, scan;
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
import 'diet_listener.dart' show DietListener;
import 'diet_parser.dart' show DietParser;
@@ -128,6 +127,8 @@
final Map<Uri, List<int>> sourceBytes = <Uri, List<int>>{};
+ ClassHierarchyBuilder builderHierarchy;
+
// Used when building directly to kernel.
ClassHierarchy hierarchy;
CoreTypes coreTypes;
@@ -138,8 +139,6 @@
ShadowTypeInferenceEngine typeInferenceEngine;
- InterfaceResolver interfaceResolver;
-
Instrumentation instrumentation;
CollectionTransformer collectionTransformer;
@@ -609,6 +608,10 @@
break;
}
}
+ if (allSupertypesProcessed && cls.isPatch) {
+ allSupertypesProcessed =
+ topologicallySortedClasses.contains(cls.origin);
+ }
if (allSupertypesProcessed) {
topologicallySortedClasses.add(cls);
checkClassSupertypes(cls, directSupertypes, blackListedClasses);
@@ -884,27 +887,33 @@
}
void checkOverrides(List<SourceClassBuilder> sourceClasses) {
- assert(hierarchy != null);
- for (SourceClassBuilder builder in sourceClasses) {
- if (builder.library.loader == this && !builder.isPatch) {
- builder.checkOverrides(
- hierarchy, typeInferenceEngine?.typeSchemaEnvironment);
- }
+ List<DelayedOverrideCheck> overrideChecks =
+ builderHierarchy.overrideChecks.toList();
+ builderHierarchy.overrideChecks.clear();
+ for (int i = 0; i < overrideChecks.length; i++) {
+ overrideChecks[i].check(builderHierarchy);
}
- ticker.logMs("Checked overrides");
+ ticker.logMs("Checked ${overrideChecks.length} overrides");
+
+ typeInferenceEngine?.finishTopLevelInitializingFormals();
+ ticker.logMs("Finished initializing formals");
}
void checkAbstractMembers(List<SourceClassBuilder> sourceClasses) {
- // TODO(ahe): Move this to [ClassHierarchyBuilder].
- if (target.legacyMode) return;
- assert(hierarchy != null);
- for (SourceClassBuilder builder in sourceClasses) {
- if (builder.library.loader == this && !builder.isPatch) {
- builder.checkAbstractMembers(
- coreTypes, hierarchy, typeInferenceEngine.typeSchemaEnvironment);
- }
+ List<DelayedMember> delayedMemberChecks =
+ builderHierarchy.delayedMemberChecks.toList();
+ builderHierarchy.delayedMemberChecks.clear();
+ Set<Class> changedClasses = new Set<Class>();
+ for (int i = 0; i < delayedMemberChecks.length; i++) {
+ delayedMemberChecks[i].check(builderHierarchy);
+ changedClasses.add(delayedMemberChecks[i].parent.cls);
}
- ticker.logMs("Checked abstract members");
+ ticker.logMs(
+ "Computed ${delayedMemberChecks.length} combined member signatures");
+
+ hierarchy.applyMemberChanges(changedClasses, findDescendants: false);
+ ticker
+ .logMs("Updated ${changedClasses.length} classes in kernel hierarchy");
}
void checkRedirectingFactories(List<SourceClassBuilder> sourceClasses) {
@@ -968,12 +977,12 @@
});
}
- ClassHierarchyBuilder buildClassHierarchy(
+ void buildClassHierarchy(
List<SourceClassBuilder> sourceClasses, ClassBuilder objectClass) {
- ClassHierarchyBuilder hierarchy = ClassHierarchyBuilder.build(
+ builderHierarchy = ClassHierarchyBuilder.build(
objectClass, sourceClasses, this, coreTypes);
+ typeInferenceEngine?.hierarchyBuilder = builderHierarchy;
ticker.logMs("Built class hierarchy");
- return hierarchy;
}
void createTypeInferenceEngine() {
@@ -989,58 +998,30 @@
/// might be subject to type inference, and records dependencies between
/// them.
typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
- interfaceResolver = new InterfaceResolver(typeInferenceEngine,
- typeInferenceEngine.typeSchemaEnvironment, instrumentation);
+ List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
for (LibraryBuilder library in builders.values) {
if (library.loader == this) {
- Iterator<Declaration> iterator = library.iterator;
- while (iterator.moveNext()) {
- Declaration member = iterator.current;
- if (member is KernelFieldBuilder) {
- member.prepareTopLevelInference();
- }
+ List<FieldBuilder> implicitlyTypedFields =
+ library.takeImplicitlyTypedFields();
+ if (implicitlyTypedFields != null) {
+ allImplicitlyTypedFields.addAll(implicitlyTypedFields);
}
}
}
- for (int i = 0; i < sourceClasses.length; i++) {
- sourceClasses[i].prepareTopLevelInference();
+
+ for (int i = 0; i < allImplicitlyTypedFields.length; i++) {
+ // TODO(ahe): This can cause a crash for parts that failed to get
+ // included, see for example,
+ // tests/standalone_2/io/http_cookie_date_test.dart.
+ allImplicitlyTypedFields[i].inferType();
}
+
typeInferenceEngine.isTypeInferencePrepared = true;
- ticker.logMs("Prepared top level inference");
- /// The second phase of top level initializer inference, which is to visit
- /// fields and top level variables in topologically-sorted order and assign
- /// their types.
- typeInferenceEngine.finishTopLevelFields();
- List<Class> changedClasses = new List<Class>();
- for (var builder in sourceClasses) {
- if (builder.isPatch) continue;
- ShadowClass class_ = builder.target;
- int memberCount = class_.fields.length +
- class_.constructors.length +
- class_.procedures.length +
- class_.redirectingFactoryConstructors.length;
- class_.finalizeCovariance(interfaceResolver);
- ShadowClass.clearClassInferenceInfo(class_);
- int newMemberCount = class_.fields.length +
- class_.constructors.length +
- class_.procedures.length +
- class_.redirectingFactoryConstructors.length;
- if (newMemberCount != memberCount) {
- // The inference potentially adds new members (but doesn't otherwise
- // change the classes), so if the member count has changed we need to
- // update the class in the class hierarchy.
- changedClasses.add(class_);
- }
- }
-
- typeInferenceEngine.finishTopLevelInitializingFormals();
- interfaceResolver = null;
// Since finalization of covariance may have added forwarding stubs, we need
// to recompute the class hierarchy so that method compilation will properly
// target those forwarding stubs.
hierarchy.onAmbiguousSupertypes = ignoreAmbiguousSupertypes;
- hierarchy.applyMemberChanges(changedClasses, findDescendants: true);
ticker.logMs("Performed top level inference");
}
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index 621a14e..a1faa23 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -6,7 +6,7 @@
import '../builder/builder.dart' show Declaration;
-import '../messages.dart' show LocatedMessage, Message;
+import '../messages.dart' show LocatedMessage, Message, MessageCode;
import '../parser.dart'
show Assert, IdentifierContext, FormalParameterKind, Listener, MemberKind;
@@ -210,6 +210,13 @@
}
@override
+ void endInvalidAwaitExpression(
+ Token beginToken, Token endToken, MessageCode errorCode) {
+ debugEvent("InvalidAwaitExpression", beginToken);
+ state.popPushNull(beginToken.lexeme, beginToken); // Expression.
+ }
+
+ @override
void endBinaryExpression(Token token) {
debugEvent("BinaryExpression", token);
state.pop(); // Right-hand side.
@@ -962,8 +969,8 @@
}
@override
- void endMethod(
- Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+ void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+ Token beginInitializers, Token endToken) {
debugEvent("endMethod", endToken);
state.pop(); // Method name.
state.checkEmpty(endToken);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
deleted file mode 100644
index 5c8dbfa..0000000
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ /dev/null
@@ -1,1235 +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.md file.
-
-import 'package:kernel/ast.dart'
- show
- Arguments,
- Class,
- DartType,
- DynamicType,
- Expression,
- Field,
- FunctionNode,
- FunctionType,
- InvalidType,
- Member,
- Name,
- NamedExpression,
- Procedure,
- ProcedureKind,
- ReturnStatement,
- SuperMethodInvocation,
- SuperPropertyGet,
- SuperPropertySet,
- TypeParameter,
- TypeParameterType,
- VariableDeclaration,
- VariableGet,
- VoidType;
-
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
-import 'package:kernel/transformations/flags.dart' show TransformerFlag;
-
-import 'package:kernel/type_algebra.dart' show Substitution;
-
-import 'package:kernel/src/hierarchy_based_type_environment.dart'
- show HierarchyBasedTypeEnvironment;
-
-import '../../base/instrumentation.dart'
- show Instrumentation, InstrumentationValueLiteral;
-
-import '../builder/builder.dart' show LibraryBuilder;
-
-import '../kernel/kernel_library_builder.dart' show KernelLibraryBuilder;
-
-import '../kernel/kernel_shadow_ast.dart'
- show ShadowClass, ShadowField, ShadowProcedure, VariableDeclarationJudgment;
-
-import '../messages.dart'
- show
- noLength,
- templateCantInferTypeDueToCircularity,
- templateCantInferTypeDueToInconsistentOverrides;
-
-import '../names.dart' show indexSetName;
-
-import '../problems.dart' show unhandled;
-
-import 'type_inference_engine.dart'
- show
- FieldInitializerInferenceNode,
- IncludesTypeParametersCovariantly,
- InferenceNode,
- TypeInferenceEngine;
-
-import 'type_inferrer.dart' show getNamedFormal;
-
-import 'type_schema_environment.dart'
- show
- getNamedParameterType,
- getPositionalParameterType,
- substituteTypeParams;
-
-/// Concrete class derived from [InferenceNode] to represent type inference of
-/// getters, setters, and fields based on inheritance.
-class AccessorInferenceNode extends InferenceNode {
- final InterfaceResolver _interfaceResolver;
-
- /// The method whose return type and/or parameter types should be inferred.
- final Procedure _declaredMethod;
-
- /// A list containing the methods overridden by [_declaredMethod], if any.
- final List<Member> _candidates;
-
- /// The index of the first method in [_candidates] overridden by
- /// [_declaredMethod].
- final int _start;
-
- /// The past-the-end index of the last method in [_candidates] overridden by
- /// [_declaredMethod].
- final int _end;
-
- final LibraryBuilder _library;
-
- final Uri _fileUri;
-
- AccessorInferenceNode(this._interfaceResolver, this._declaredMethod,
- this._candidates, this._start, this._end, this._library, this._fileUri);
-
- String get _name {
- if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
- return _declaredMethod.function.positionalParameters[0].name;
- }
- return _declaredMethod.name.name;
- }
-
- int get _offset {
- if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
- return _declaredMethod.function.positionalParameters[0].fileOffset;
- }
- return _declaredMethod.fileOffset;
- }
-
- @override
- void resolveInternal() {
- var declaredMethod = _declaredMethod;
- var kind = declaredMethod.kind;
- var overriddenTypes = _computeAccessorOverriddenTypes();
- DartType inferredType;
- if (isCircular) {
- inferredType = const InvalidType();
- _library.addProblem(
- templateCantInferTypeDueToCircularity.withArguments(_name),
- _offset,
- noLength,
- _fileUri);
- } else {
- inferredType = _interfaceResolver.matchTypes(
- overriddenTypes, _library, _name, _fileUri, _offset);
- }
- if (declaredMethod is SyntheticAccessor) {
- declaredMethod._field.type = inferredType;
- declaredMethod._field.initializer = null;
- } else {
- if (kind == ProcedureKind.Getter) {
- declaredMethod.function.returnType = inferredType;
- } else {
- declaredMethod.function.positionalParameters[0].type = inferredType;
- }
- }
- }
-
- /// Computes the types of the getters and setters overridden by
- /// [_declaredMethod], with appropriate type parameter substitutions.
- List<DartType> _computeAccessorOverriddenTypes() {
- var overriddenTypes = <DartType>[];
- for (int i = _start; i < _end; i++) {
- var candidate = _candidates[i];
- Procedure resolvedCandidate;
- if (candidate is ForwardingNode) {
- resolvedCandidate = candidate.resolve();
- } else {
- resolvedCandidate = candidate;
- }
- DartType overriddenType;
- if (resolvedCandidate is SyntheticAccessor) {
- var field = resolvedCandidate._field;
- TypeInferenceEngine.resolveInferenceNode(field);
- overriddenType = field.type;
- } else if (resolvedCandidate.function != null) {
- switch (resolvedCandidate.kind) {
- case ProcedureKind.Getter:
- overriddenType = resolvedCandidate.function.returnType;
- break;
- case ProcedureKind.Setter:
- overriddenType =
- resolvedCandidate.function.positionalParameters[0].type;
- break;
- default:
- // Illegal override (error will be reported elsewhere). Just skip
- // this override.
- continue;
- }
- } else {
- // This can happen if there are errors. Just skip this override.
- continue;
- }
- overriddenTypes.add(_interfaceResolver
- ._substitutionFor(resolvedCandidate, _declaredMethod.enclosingClass)
- .substituteType(overriddenType));
- }
- return overriddenTypes;
- }
-}
-
-/// A [ForwardingNode] represents a method, getter, or setter within a class's
-/// interface that is either implemented in the class directly or inherited from
-/// a superclass.
-///
-/// This class allows us to defer the determination of exactly which member is
-/// inherited, as well as the propagation of covariance annotations, and
-/// the creation of forwarding stubs, until type inference.
-class ForwardingNode extends Procedure {
- /// The [InterfaceResolver] that created this [ForwardingNode].
- final InterfaceResolver _interfaceResolver;
-
- /// A list containing the directly implemented and directly inherited
- /// procedures of the class in question.
- ///
- /// Note that many [ForwardingNode]s share the same [_candidates] list;
- /// consult [_start] and [_end] to see which entries in this list are relevant
- /// to this [ForwardingNode].
- final List<Member> _candidates;
-
- /// Index of the first entry in [_candidates] relevant to this
- /// [ForwardingNode].
- final int _start;
-
- /// Index just beyond the last entry in [_candidates] relevant to this
- /// [ForwardingNode].
- final int _end;
-
- /// The member this node resolves to (if it has been computed); otherwise
- /// `null`.
- Member _resolution;
-
- /// The result of finalizing this node (if the node has been finalized);
- /// otherwise `null`.
- Member _finalResolution;
-
- /// If this forwarding node represents a member that needs type inference, the
- /// corresponding [InferenceNode]; otherwise `null`.
- InferenceNode _inferenceNode;
-
- ForwardingNode(this._interfaceResolver, this._inferenceNode, Class class_,
- Name name, ProcedureKind kind, this._candidates, this._start, this._end)
- : super(name, kind, null) {
- parent = class_;
- }
-
- /// Finishes handling of this node by propagating covariance and creating
- /// forwarding stubs if necessary.
- Procedure finalize() => _finalResolution ??= _finalize();
-
- /// Returns the declared or inherited member this node resolves to.
- ///
- /// Does not create forwarding stubs.
- Procedure resolve() => _resolution ??= _resolve();
-
- /// Tag the parameters of [interfaceMember] that need type checks
- ///
- /// Parameters can need type checks for calls coming from statically typed
- /// call sites, due to covariant generics and overrides with explicit
- /// `covariant` parameters.
- ///
- /// Tag parameters of [interfaceMember] that need such checks when the member
- /// occurs in [enclosingClass]'s interface. If parameters need checks but
- /// they would not be checked in an inherited implementation, a forwarding
- /// stub is introduced as a place to put the checks.
- Procedure _computeCovarianceFixes(Procedure interfaceMember) {
- var substitution =
- _interfaceResolver._substitutionFor(interfaceMember, enclosingClass);
- // We always create a forwarding stub when we've inherited a member from an
- // interface other than the first override candidate. This is to work
- // around a bug in the Kernel type checker where it chooses the first
- // override candidate.
- //
- // TODO(kmillikin): Fix the Kernel type checker and stop creating these
- // extra stubs.
- var stub = interfaceMember.enclosingClass == enclosingClass ||
- interfaceMember == _resolvedCandidate(_start)
- ? interfaceMember
- : _createForwardingStub(substitution, interfaceMember);
-
- var interfaceFunction = interfaceMember.function;
- var interfacePositionalParameters = interfaceFunction.positionalParameters;
- var interfaceNamedParameters = interfaceFunction.namedParameters;
- var interfaceTypeParameters = interfaceFunction.typeParameters;
-
- void createStubIfNeeded() {
- if (stub != interfaceMember) return;
- if (interfaceMember.enclosingClass == enclosingClass) return;
- stub = _createForwardingStub(substitution, interfaceMember);
- }
-
- bool isImplCreated = false;
- void createImplIfNeeded() {
- if (isImplCreated) return;
- createStubIfNeeded();
- _createForwardingImplIfNeeded(stub.function);
- isImplCreated = true;
- }
-
- IncludesTypeParametersCovariantly needsCheckVisitor =
- enclosingClass.typeParameters.isEmpty
- ? null
- : ShadowClass.getClassInferenceInfo(enclosingClass)
- .needsCheckVisitor ??=
- new IncludesTypeParametersCovariantly(
- enclosingClass.typeParameters);
- bool needsCheck(DartType type) => needsCheckVisitor == null
- ? false
- : substitution.substituteType(type).accept(needsCheckVisitor);
- for (int i = 0; i < interfacePositionalParameters.length; i++) {
- var parameter = interfacePositionalParameters[i];
- var isGenericCovariantImpl =
- parameter.isGenericCovariantImpl || needsCheck(parameter.type);
- var isCovariant = parameter.isCovariant;
- var superParameter = parameter;
- for (int j = _start; j < _end; j++) {
- var otherMember = _finalizedCandidate(j);
- if (otherMember is ForwardingNode) continue;
- var otherPositionalParameters =
- otherMember.function.positionalParameters;
- if (otherPositionalParameters.length <= i) continue;
- var otherParameter = otherPositionalParameters[i];
- if (j == _start) superParameter = otherParameter;
- if (identical(otherMember, interfaceMember)) continue;
- if (otherParameter.isGenericCovariantImpl) {
- isGenericCovariantImpl = true;
- }
- if (otherParameter.isCovariant) {
- isCovariant = true;
- }
- }
- if (isGenericCovariantImpl) {
- if (!superParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
- }
- if (!parameter.isGenericCovariantImpl) {
- createStubIfNeeded();
- stub.function.positionalParameters[i].isGenericCovariantImpl = true;
- }
- }
- if (isCovariant) {
- if (!superParameter.isCovariant) {
- createImplIfNeeded();
- }
- if (!parameter.isCovariant) {
- createStubIfNeeded();
- stub.function.positionalParameters[i].isCovariant = true;
- }
- }
- }
- for (int i = 0; i < interfaceNamedParameters.length; i++) {
- var parameter = interfaceNamedParameters[i];
- var isGenericCovariantImpl =
- parameter.isGenericCovariantImpl || needsCheck(parameter.type);
- var isCovariant = parameter.isCovariant;
- var superParameter = parameter;
- for (int j = _start; j < _end; j++) {
- var otherMember = _finalizedCandidate(j);
- if (otherMember is ForwardingNode) continue;
- var otherParameter =
- getNamedFormal(otherMember.function, parameter.name);
- if (otherParameter == null) continue;
- if (j == _start) superParameter = otherParameter;
- if (identical(otherMember, interfaceMember)) continue;
- if (otherParameter.isGenericCovariantImpl) {
- isGenericCovariantImpl = true;
- }
- if (otherParameter.isCovariant) {
- isCovariant = true;
- }
- }
- if (isGenericCovariantImpl) {
- if (!superParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
- }
- if (!parameter.isGenericCovariantImpl) {
- createStubIfNeeded();
- stub.function.namedParameters[i].isGenericCovariantImpl = true;
- }
- }
- if (isCovariant) {
- if (!superParameter.isCovariant) {
- createImplIfNeeded();
- }
- if (!parameter.isCovariant) {
- createStubIfNeeded();
- stub.function.namedParameters[i].isCovariant = true;
- }
- }
- }
- for (int i = 0; i < interfaceTypeParameters.length; i++) {
- var typeParameter = interfaceTypeParameters[i];
- var isGenericCovariantImpl = typeParameter.isGenericCovariantImpl;
- var superTypeParameter = typeParameter;
- for (int j = _start; j < _end; j++) {
- var otherMember = _finalizedCandidate(j);
- if (otherMember is ForwardingNode) continue;
- var otherTypeParameters = otherMember.function.typeParameters;
- if (otherTypeParameters.length <= i) continue;
- var otherTypeParameter = otherTypeParameters[i];
- if (j == _start) superTypeParameter = otherTypeParameter;
- if (identical(otherMember, interfaceMember)) continue;
- if (otherTypeParameter.isGenericCovariantImpl) {
- isGenericCovariantImpl = true;
- }
- }
- if (isGenericCovariantImpl) {
- if (!superTypeParameter.isGenericCovariantImpl) {
- createImplIfNeeded();
- }
- if (!typeParameter.isGenericCovariantImpl) {
- createStubIfNeeded();
- stub.function.typeParameters[i].isGenericCovariantImpl = true;
- }
- }
- }
- return stub;
- }
-
- void _createForwardingImplIfNeeded(FunctionNode function) {
- if (function.body != null) {
- // There is already an implementation; nothing further needs to be done.
- return;
- }
- // Find the concrete implementation in the superclass; this is what we need
- // to forward to. If we can't find one, then the method is fully abstract
- // and we don't need to do anything.
- var superclass = enclosingClass.superclass;
- if (superclass == null) return;
- Procedure procedure = function.parent;
- var superTarget = _interfaceResolver._typeEnvironment.hierarchy
- .getDispatchTarget(superclass, procedure.name,
- setter: kind == ProcedureKind.Setter);
- if (superTarget == null) return;
- if (superTarget is Procedure && superTarget.isForwardingStub) {
- superTarget = _getForwardingStubSuperTarget(superTarget);
- }
- procedure.isAbstract = false;
- if (!procedure.isForwardingStub) {
- // This procedure exists abstractly in the source code; we need to make it
- // concrete and give it a body that is a forwarding stub. This situation
- // is called a "forwarding semi-stub".
- procedure.isForwardingStub = true;
- procedure.isForwardingSemiStub = true;
- _interfaceResolver._instrumentation?.record(
- procedure.fileUri,
- procedure.fileOffset,
- 'forwardingStub',
- new InstrumentationValueLiteral('semi-stub'));
- }
- var positionalArguments = function.positionalParameters
- .map<Expression>((parameter) => new VariableGet(parameter))
- .toList();
- var namedArguments = function.namedParameters
- .map((parameter) =>
- new NamedExpression(parameter.name, new VariableGet(parameter)))
- .toList();
- var typeArguments = function.typeParameters
- .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
- .toList();
- var arguments = new Arguments(positionalArguments,
- types: typeArguments, named: namedArguments);
- Expression superCall;
- switch (kind) {
- case ProcedureKind.Method:
- case ProcedureKind.Operator:
- superCall = new SuperMethodInvocation(name, arguments, superTarget);
- break;
- case ProcedureKind.Getter:
- superCall = new SuperPropertyGet(
- name,
- superTarget is SyntheticAccessor
- ? superTarget._field
- : superTarget);
- break;
- case ProcedureKind.Setter:
- superCall = new SuperPropertySet(
- name,
- positionalArguments[0],
- superTarget is SyntheticAccessor
- ? superTarget._field
- : superTarget);
- break;
- default:
- unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
- break;
- }
- function.body = new ReturnStatement(superCall)..parent = function;
- procedure.transformerFlags |= TransformerFlag.superCalls;
- procedure.forwardingStubSuperTarget = superTarget;
- }
-
- /// Creates a forwarding stub based on the given [target].
- Procedure _createForwardingStub(Substitution substitution, Procedure target) {
- VariableDeclaration copyParameter(VariableDeclaration parameter) {
- return new VariableDeclaration(parameter.name,
- type: substitution.substituteType(parameter.type),
- isCovariant: parameter.isCovariant)
- ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
- }
-
- var targetTypeParameters = target.function.typeParameters;
- List<TypeParameter> typeParameters;
- if (targetTypeParameters.isNotEmpty) {
- typeParameters =
- new List<TypeParameter>.filled(targetTypeParameters.length, null);
- var additionalSubstitution = <TypeParameter, DartType>{};
- for (int i = 0; i < targetTypeParameters.length; i++) {
- var targetTypeParameter = targetTypeParameters[i];
- var typeParameter = new TypeParameter(targetTypeParameter.name, null)
- ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
- typeParameters[i] = typeParameter;
- additionalSubstitution[targetTypeParameter] =
- new TypeParameterType(typeParameter);
- }
- substitution = Substitution.combine(
- substitution, Substitution.fromMap(additionalSubstitution));
- for (int i = 0; i < typeParameters.length; i++) {
- typeParameters[i].bound =
- substitution.substituteType(targetTypeParameters[i].bound);
- }
- }
- var positionalParameters =
- target.function.positionalParameters.map(copyParameter).toList();
- var namedParameters =
- target.function.namedParameters.map(copyParameter).toList();
- var function = new FunctionNode(null,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- typeParameters: typeParameters,
- requiredParameterCount: target.function.requiredParameterCount,
- returnType: substitution.substituteType(target.function.returnType));
- Member finalTarget;
- if (target is Procedure && target.isForwardingStub) {
- finalTarget = target.forwardingStubInterfaceTarget;
- } else if (target is SyntheticAccessor) {
- finalTarget = target._field;
- } else {
- finalTarget = target;
- }
- return new Procedure(name, kind, function,
- isAbstract: true,
- isForwardingStub: true,
- fileUri: enclosingClass.fileUri,
- forwardingStubInterfaceTarget: finalTarget)
- ..startFileOffset = enclosingClass.fileOffset
- ..fileOffset = enclosingClass.fileOffset
- ..parent = enclosingClass;
- }
-
- /// Creates a forwarding stub for this node if necessary, and propagates
- /// covariance information.
- Procedure _finalize() {
- return _computeCovarianceFixes(resolve());
- }
-
- /// Returns the [i]th element of [_candidates], finalizing it if necessary.
- Procedure _finalizedCandidate(int i) {
- Procedure candidate = _candidates[i];
- return candidate is ForwardingNode &&
- _interfaceResolver.isTypeInferencePrepared
- ? candidate.finalize()
- : candidate;
- }
-
- /// Determines which inherited member this node resolves to, and also performs
- /// type inference.
- Procedure _resolve() {
- Procedure inheritedMember = _candidates[_start];
- bool isDeclaredInThisClass =
- identical(inheritedMember.enclosingClass, enclosingClass);
- if (isDeclaredInThisClass) {
- if (_inferenceNode != null) {
- _inferenceNode.resolve();
- _inferenceNode = null;
- }
- } else {
- // If there are multiple inheritance candidates, the inherited member is
- // the member whose type is a subtype of all the others. We can find it
- // by two passes over the list of members. For the first pass, we step
- // through the candidates, updating inheritedMember each time we find a
- // member whose type is a subtype of the previous inheritedMember. As we
- // do this, we also work out the necessary substitution for matching up
- // type parameters between this class and the corresponding superclass.
- //
- // Since the subtyping relation is reflexive, we will favor the most
- // recently visited candidate in the case where the types are the same.
- // We want to favor earlier candidates, so we visit the candidate list
- // backwards.
- inheritedMember = _resolvedCandidate(_end - 1);
- var inheritedMemberSubstitution =
- _interfaceResolver._substitutionFor(inheritedMember, enclosingClass);
- var inheritedMemberType = inheritedMember is ForwardingNode
- ? const DynamicType()
- : inheritedMemberSubstitution.substituteType(
- kind == ProcedureKind.Setter
- ? inheritedMember.setterType
- : inheritedMember.getterType);
- for (int i = _end - 2; i >= _start; i--) {
- var candidate = _resolvedCandidate(i);
- var substitution =
- _interfaceResolver._substitutionFor(candidate, enclosingClass);
- bool isBetter;
- DartType type;
- if (kind == ProcedureKind.Setter) {
- type = candidate is ForwardingNode
- ? const DynamicType()
- : substitution.substituteType(candidate.setterType);
- // Setters are contravariant in their setter type, so we have to
- // reverse the check.
- isBetter = _interfaceResolver._typeEnvironment
- .isSubtypeOf(inheritedMemberType, type);
- } else {
- type = candidate is ForwardingNode
- ? const DynamicType()
- : substitution.substituteType(candidate.getterType);
- isBetter = _interfaceResolver._typeEnvironment
- .isSubtypeOf(type, inheritedMemberType);
- }
- if (isBetter) {
- inheritedMember = candidate;
- inheritedMemberSubstitution = substitution;
- inheritedMemberType = type;
- }
- }
- // For the second pass, we verify that inheritedMember is a subtype of all
- // the other potentially inherited members.
- // TODO(paulberry): implement this.
- }
- return inheritedMember;
- }
-
- /// Returns the [i]th element of [_candidates], resolving it if necessary.
- Procedure _resolvedCandidate(int i) {
- Procedure candidate = _candidates[i];
- return candidate is ForwardingNode &&
- _interfaceResolver.isTypeInferencePrepared
- ? candidate.resolve()
- : candidate;
- }
-
- static void createForwardingImplIfNeededForTesting(
- ForwardingNode node, FunctionNode function) {
- node._createForwardingImplIfNeeded(function);
- }
-
- /// Public method allowing tests to access [_createForwardingStub].
- ///
- /// This method is static so that it can be easily eliminated by tree shaking
- /// when not needed.
- static Procedure createForwardingStubForTesting(
- ForwardingNode node, Substitution substitution, Procedure target) {
- return node._createForwardingStub(substitution, target);
- }
-
- /// For testing: get the list of candidates relevant to a given node.
- static List<Procedure> getCandidates(ForwardingNode node) {
- return node._candidates.sublist(node._start, node._end);
- }
-
- static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
- // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
- // easier.
- ReturnStatement body = forwardingStub.function.body;
- var expression = body.expression;
- if (expression is SuperMethodInvocation) {
- return expression.interfaceTarget;
- } else if (expression is SuperPropertySet) {
- return expression.interfaceTarget;
- } else {
- return unhandled('${expression.runtimeType}',
- '_getForwardingStubSuperTarget', -1, null);
- }
- }
-}
-
-/// An [InterfaceResolver] keeps track of the information necessary to resolve
-/// method calls, gets, and sets within a chunk of code being compiled, to
-/// infer covariance annotations, and to create forwarwding stubs when necessary
-/// to meet covariance requirements.
-class InterfaceResolver {
- final TypeInferenceEngine _typeInferenceEngine;
-
- final HierarchyBasedTypeEnvironment _typeEnvironment;
-
- final Instrumentation _instrumentation;
-
- InterfaceResolver(
- this._typeInferenceEngine, this._typeEnvironment, this._instrumentation);
-
- /// Indicates whether the "prepare" phase of type inference is complete.
- bool get isTypeInferencePrepared =>
- _typeInferenceEngine.isTypeInferencePrepared;
-
- /// Report an error if all types in [types] are not equal using `==`.
- ///
- /// Returns the type if there is at least one and they are all equal,
- /// otherwise the type `dynamic`. [library], [name], [fileUri], and
- /// [charOffset] are used to report the error.
- DartType matchTypes(Iterable<DartType> types, LibraryBuilder library,
- String name, Uri fileUri, int charOffset) {
- DartType first;
- for (var type in types) {
- if (first == null) {
- first = type;
- } else if (first != type) {
- // Types don't match. Report an error.
- library.addProblem(
- templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
- charOffset,
- noLength,
- fileUri);
- return const DynamicType();
- }
- }
- // If there are no overridden types, infer `dynamic`.
- return first ?? const DynamicType();
- }
-
- /// Computes the types of the methods overridden by [method] in [class_].
- ///
- /// The types have the type parameters of [class_] substituted appropriately.
- ///
- /// [candidates] has the list of inherited interface methods with the same
- /// name as [method] as a sublist from [start] inclusive to [end] exclusive.
- List<FunctionType> _computeMethodOverriddenTypes(Class class_,
- Procedure method, List<Member> candidates, int start, int end) {
- var overriddenTypes = <FunctionType>[];
- var declaredTypeParameters = method.function.typeParameters;
- for (int i = start; i < end; ++i) {
- var candidate = candidates[i];
- if (candidate is SyntheticAccessor) {
- // This can happen if there are errors. Just skip this override.
- continue;
- }
- var candidateFunction = candidate.function;
- if (candidateFunction == null) {
- // This can happen if there are errors. Just skip this override.
- continue;
- }
- var substitution = _substitutionFor(candidate, class_);
- FunctionType overriddenType =
- substitution.substituteType(candidateFunction.functionType);
- var overriddenTypeParameters = overriddenType.typeParameters;
- if (overriddenTypeParameters.length != declaredTypeParameters.length) {
- // Generic arity mismatch. Don't do any inference for this method.
- // TODO(paulberry): report an error.
- overriddenTypes.clear();
- break;
- } else if (overriddenTypeParameters.isNotEmpty) {
- var substitutionMap = <TypeParameter, DartType>{};
- for (int i = 0; i < declaredTypeParameters.length; ++i) {
- substitutionMap[overriddenTypeParameters[i]] =
- new TypeParameterType(declaredTypeParameters[i]);
- }
- overriddenType = substituteTypeParams(
- overriddenType, substitutionMap, declaredTypeParameters);
- }
- overriddenTypes.add(overriddenType);
- }
- return overriddenTypes;
- }
-
- void inferMethodType(LibraryBuilder library, Class class_, Procedure method,
- List<Member> candidates, int start, int end) {
- var overriddenTypes =
- _computeMethodOverriddenTypes(class_, method, candidates, start, end);
- if (ShadowProcedure.hasImplicitReturnType(method) &&
- method.name != indexSetName) {
- method.function.returnType = matchTypes(
- overriddenTypes.map((type) => type.returnType),
- library,
- method.name.name,
- class_.fileUri,
- method.fileOffset);
- }
- var positionalParameters = method.function.positionalParameters;
- for (int i = 0; i < positionalParameters.length; ++i) {
- if (VariableDeclarationJudgment.isImplicitlyTyped(
- positionalParameters[i])) {
- // Note that if the parameter is not present in the overridden method,
- // getPositionalParameterType treats it as dynamic. This is consistent
- // with the behavior called for in the informal top level type inference
- // spec, which says:
- //
- // If there is no corresponding parameter position in the overridden
- // method to infer from and the signatures are compatible, it is
- // treated as dynamic (e.g. overriding a one parameter method with a
- // method that takes a second optional parameter). Note: if there
- // is no corresponding parameter position in the overridden method to
- // infer from and the signatures are incompatible (e.g. overriding a
- // one parameter method with a method that takes a second
- // non-optional parameter), the inference result is not defined and
- // tools are free to either emit an error, or to defer the error to
- // override checking.
- positionalParameters[i].type = matchTypes(
- overriddenTypes.map((type) => getPositionalParameterType(type, i)),
- library,
- positionalParameters[i].name,
- class_.fileUri,
- positionalParameters[i].fileOffset);
- }
- }
- var namedParameters = method.function.namedParameters;
- for (int i = 0; i < namedParameters.length; i++) {
- if (VariableDeclarationJudgment.isImplicitlyTyped(namedParameters[i])) {
- var name = namedParameters[i].name;
- namedParameters[i].type = matchTypes(
- overriddenTypes.map((type) => getNamedParameterType(type, name)),
- library,
- namedParameters[i].name,
- class_.fileUri,
- namedParameters[i].fileOffset);
- }
- }
- }
-
- /// Populates [getters] and [setters] with the members of the given [class_]'s
- /// interface.
- ///
- /// [getters] will contain methods and getters, [setters] will contain
- /// setters. Some members cannot be resolved immediately. For instance,
- /// top-level type inference has not yet inferred field types based on
- /// initializers and so we cannot yet do override based resolution of getters
- /// and setters. Members of the class's interface that need to be resolved
- /// later are represented by a [ForwardingNode] object.
- void createApiMembers(Class class_, List<Member> getters,
- List<Member> setters, LibraryBuilder library) {
- var candidates = ClassHierarchy.mergeSortedLists(
- getCandidates(class_, false), getCandidates(class_, true));
- // Now create getter and perhaps setter forwarding nodes for each unique
- // name.
- getters.length = candidates.length;
- setters.length = candidates.length;
- int getterIndex = 0;
- int setterIndex = 0;
- // To detect conflicts between instance members (possibly inherited ones)
- // and static members, use a map from names to lists of members. There can
- // be more than one static member with a given name, e.g., if there is a
- // getter and a setter. We will report both conflicts.
- forEachApiMember(candidates, (int start, int end, Name name) {
- Procedure member = candidates[start];
- ProcedureKind kind = _kindOf(member);
- if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
- for (int i = start + 1; i < end; ++i) {
- if (_kindOf(candidates[i]) != kind) return;
- }
- if (member.enclosingClass == class_ && _requiresTypeInference(member)) {
- inferMethodType(library, class_, member, candidates, start + 1, end);
- }
- var forwardingNode = new ForwardingNode(
- this, null, class_, name, kind, candidates, start, end);
- getters[getterIndex++] = forwardingNode.finalize();
- if (library is KernelLibraryBuilder &&
- forwardingNode.finalize() != forwardingNode.resolve()) {
- library.forwardersOrigins.add(forwardingNode.finalize());
- library.forwardersOrigins.add(forwardingNode.resolve());
- }
- return;
- }
-
- Procedure declaredGetter;
- int inheritedGetterStart = start;
- int getterEnd = start;
- if (kind == ProcedureKind.Getter) {
- if (member.enclosingClass == class_) {
- declaredGetter = member;
- ++inheritedGetterStart;
- }
- while (++getterEnd < end) {
- ProcedureKind currentKind = _kindOf(candidates[getterEnd]);
- if (currentKind == ProcedureKind.Setter) break;
- if (currentKind != ProcedureKind.Getter) return;
- }
- }
-
- Procedure declaredSetter;
- int inheritedSetterStart = getterEnd;
- if (getterEnd < end) {
- member = candidates[getterEnd];
- if (member.enclosingClass == class_) {
- declaredSetter = member;
- ++inheritedSetterStart;
- }
- }
-
- InferenceNode getterInferenceNode;
- if (start < getterEnd) {
- if (declaredGetter != null) {
- getterInferenceNode = _createInferenceNode(
- class_,
- declaredGetter,
- candidates,
- inheritedGetterStart,
- getterEnd,
- inheritedSetterStart,
- end,
- library,
- class_.fileUri);
- }
- // Getters need to be resolved later, as part of type inference, so just
- // save the forwarding node for now.
- //
- // Choose a representative to use for error reporting, such as if a
- // class inherits this getter and tries to declare a method with the
- // same name.
- Member representative = candidates[start];
- getters[getterIndex++] = new ForwardingNode(this, getterInferenceNode,
- class_, name, ProcedureKind.Getter, candidates, start, getterEnd)
- ..fileUri = representative.fileUri
- ..fileOffset = representative.fileOffset
- ..fileEndOffset = representative.fileEndOffset;
- }
- if (getterEnd < end) {
- InferenceNode setterInferenceNode;
- if (declaredSetter != null) {
- setterInferenceNode = declaredSetter is SyntheticAccessor
- ? getterInferenceNode
- : _createInferenceNode(
- class_,
- declaredSetter,
- candidates,
- inheritedSetterStart,
- end,
- inheritedGetterStart,
- getterEnd,
- library,
- class_.fileUri);
- }
- Member representative = candidates[getterEnd];
- var forwardingNode = new ForwardingNode(this, setterInferenceNode,
- class_, name, ProcedureKind.Setter, candidates, getterEnd, end)
- ..fileUri = representative.fileUri
- ..fileOffset = representative.fileOffset
- ..fileEndOffset = representative.fileEndOffset;
- // Setters need to be resolved later, as part of type inference, so just
- // save the forwarding node for now.
- setters[setterIndex++] = forwardingNode;
- }
- });
- getters.length = getterIndex;
- setters.length = setterIndex;
- }
-
- void finalizeCovariance(
- Class class_, List<Member> apiMembers, LibraryBuilder library) {
- for (int i = 0; i < apiMembers.length; i++) {
- var member = apiMembers[i];
- Member resolution;
- if (member is ForwardingNode) {
- apiMembers[i] = resolution = member.finalize();
- if (library is KernelLibraryBuilder &&
- member.finalize() != member.resolve()) {
- library.forwardersOrigins.add(member.finalize());
- library.forwardersOrigins.add(member.resolve());
- }
- } else {
- resolution = member;
- }
- if (resolution is Procedure &&
- resolution.isSyntheticForwarder &&
- identical(resolution.enclosingClass, class_)) {
- class_.addMember(resolution);
- }
- }
- }
-
- /// Gets a list of members implemented or potentially inherited by [class_],
- /// sorted so that members with the same name are contiguous.
- ///
- /// If [setters] is `true`, setters are reported; otherwise getters, methods,
- /// and operators are reported.
- List<Procedure> getCandidates(Class class_, bool setters) {
- // First create a list of candidates for inheritance based on the members
- // declared directly in the class.
- List<Procedure> candidates = _typeEnvironment.hierarchy
- .getDeclaredMembers(class_, setters: setters)
- .map((member) => makeCandidate(member, setters))
- .toList();
- // Merge in candidates from superclasses.
- if (class_.superclass != null) {
- candidates = _mergeCandidates(candidates, class_.superclass, setters);
- }
- for (var supertype in class_.implementedTypes) {
- candidates = _mergeCandidates(candidates, supertype.classNode, setters);
- }
- return candidates;
- }
-
- /// Creates the appropriate [InferenceNode] for inferring [procedure] in the
- /// context of [class_].
- ///
- /// [candidates] a list containing the procedures overridden by [procedure],
- /// if any. [start] is the index of the first such procedure, and [end] is
- /// the past-the-end index of the last such procedure.
- ///
- /// For getters and setters, [crossStart] and [crossEnd] are the start and end
- /// indices of the corresponding overridden setters/getters, respectively.
- InferenceNode _createInferenceNode(
- Class class_,
- Procedure procedure,
- List<Member> candidates,
- int start,
- int end,
- int crossStart,
- int crossEnd,
- LibraryBuilder library,
- Uri fileUri) {
- InferenceNode node;
- if (procedure.isAccessor && _requiresTypeInference(procedure)) {
- if (start < end) {
- node = new AccessorInferenceNode(
- this, procedure, candidates, start, end, library, fileUri);
- } else if (crossStart < crossEnd) {
- node = new AccessorInferenceNode(this, procedure, candidates,
- crossStart, crossEnd, library, fileUri);
- } else if (procedure is SyntheticAccessor &&
- procedure._field.initializer != null) {
- node = new FieldInitializerInferenceNode(
- _typeInferenceEngine, procedure._field, library);
- }
-
- if (node != null && procedure is SyntheticAccessor) {
- ShadowField.setInferenceNode(procedure._field, node);
- }
- }
- return node;
- }
-
- /// Retrieves a list of the interface members of the given [class_].
- ///
- /// If [setters] is true, setters are retrieved; otherwise getters and methods
- /// are retrieved.
- List<Member> _getInterfaceMembers(Class class_, bool setters) {
- // If class_ is being compiled from source, retrieve its forwarding nodes.
- var inferenceInfo = ShadowClass.getClassInferenceInfo(class_);
- if (inferenceInfo != null) {
- return setters ? inferenceInfo.setters : inferenceInfo.gettersAndMethods;
- } else {
- return _typeEnvironment.hierarchy
- .getInterfaceMembers(class_, setters: setters);
- }
- }
-
- /// Merges together the list of interface inheritance candidates in
- /// [candidates] with interface inheritance candidates from superclass
- /// [class_].
- ///
- /// Any candidates from [class_] are converted into interface inheritance
- /// candidates using [_makeCandidate].
- List<Procedure> _mergeCandidates(
- List<Procedure> candidates, Class class_, bool setters) {
- List<Member> members = _getInterfaceMembers(class_, setters);
- if (candidates.isEmpty) {
- return members.map((member) => makeCandidate(member, setters)).toList();
- }
- if (members.isEmpty) return candidates;
- List<Procedure> result = <Procedure>[]..length =
- candidates.length + members.length;
- int storeIndex = 0;
- int i = 0, j = 0;
- while (i < candidates.length && j < members.length) {
- Procedure candidate = candidates[i];
- Member member = members[j];
- int compare = ClassHierarchy.compareMembers(candidate, member);
- if (compare <= 0) {
- result[storeIndex++] = candidate;
- ++i;
- // If the same member occurs in both lists, skip the duplicate.
- if (identical(candidate, member)) ++j;
- } else {
- result[storeIndex++] = makeCandidate(member, setters);
- ++j;
- }
- }
- while (i < candidates.length) {
- result[storeIndex++] = candidates[i++];
- }
- while (j < members.length) {
- result[storeIndex++] = makeCandidate(members[j++], setters);
- }
- result.length = storeIndex;
- return result;
- }
-
- /// Determines the appropriate substitution to translate type parameters
- /// mentioned in the given [candidate] to type parameters on [class_].
- Substitution _substitutionFor(Procedure candidate, Class class_) {
- return Substitution.fromInterfaceType(_typeEnvironment.getTypeAsInstanceOf(
- class_.thisType, candidate.enclosingClass));
- }
-
- /// Executes [callback] once for each uniquely named member of [candidates].
- ///
- /// The [start] and [end] values passed to [callback] are the start and
- /// past-the-end indices into [candidates] of a group of members having the
- /// same name. The [name] value passed to [callback] is the common name.
- static void forEachApiMember(
- List<Member> candidates, void callback(int start, int end, Name name)) {
- int i = 0;
- while (i < candidates.length) {
- var name = candidates[i].name;
- int j = i + 1;
- while (j < candidates.length && candidates[j].name == name) {
- j++;
- }
- callback(i, j, name);
- i = j;
- }
- }
-
- /// Transforms [member] into a candidate for interface inheritance.
- ///
- /// Fields are transformed into getters and setters; methods are passed
- /// through unchanged.
- static Procedure makeCandidate(Member member, bool setter) {
- if (member is Procedure) return member;
- if (member is Field) {
- // TODO(paulberry): don't set the type or covariance annotations here,
- // since they might not have been inferred yet. Instead, ensure that this
- // information is propagated to the getter/setter during type inference.
- var type = member.type;
- var isGenericCovariantImpl = member.isGenericCovariantImpl;
- var isCovariant = member.isCovariant;
- if (setter) {
- var valueParam = new VariableDeclaration('_', type: type)
- ..isGenericCovariantImpl = isGenericCovariantImpl
- ..isCovariant = isCovariant;
- var function = new FunctionNode(null,
- positionalParameters: [valueParam], returnType: const VoidType());
- return new SyntheticAccessor(
- member.name, ProcedureKind.Setter, function, member)
- ..parent = member.enclosingClass;
- } else {
- var function = new FunctionNode(null, returnType: type);
- return new SyntheticAccessor(
- member.name, ProcedureKind.Getter, function, member)
- ..parent = member.enclosingClass;
- }
- }
- return unhandled('${member.runtimeType}', 'makeCandidate', -1, null);
- }
-
- static ProcedureKind _kindOf(Procedure procedure) => procedure.kind;
-
- /// Determines whether the given [procedure] will require type inference.
- static bool _requiresTypeInference(Procedure procedure) {
- if (procedure is SyntheticAccessor) {
- return ShadowField.isImplicitlyTyped(procedure._field);
- }
- if (procedure.kind != ProcedureKind.Setter &&
- ShadowProcedure.hasImplicitReturnType(procedure)) {
- // Inference of the return type of `[]=` is handled separately by
- // KernelProcedureBuilder.build, since there are no dependencies.
- if (procedure.kind != ProcedureKind.Operator ||
- procedure.name.name != '[]=') {
- return true;
- }
- }
- var function = procedure.function;
- for (var parameter in function.positionalParameters) {
- if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
- }
- for (var parameter in function.namedParameters) {
- if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
- }
- return false;
- }
-}
-
-/// A [SyntheticAccessor] represents the getter or setter implied by a field.
-class SyntheticAccessor extends Procedure {
- /// The field associated with the synthetic accessor.
- final Field _field;
-
- SyntheticAccessor(
- Name name, ProcedureKind kind, FunctionNode function, this._field)
- : super(
- name,
- kind,
- kind == ProcedureKind.Setter
- ? new SyntheticAccessorFunctionNode.setter(_field)
- : new SyntheticAccessorFunctionNode.getter(_field),
- fileUri: _field.fileUri) {
- fileOffset = _field.fileOffset;
- }
-
- @override
- DartType get getterType => _field.type;
-
- static getField(SyntheticAccessor accessor) => accessor._field;
-}
-
-/// A [SyntheticAccessorFunctionNode] represents the [FunctionNode] part of the
-/// getter or setter implied by a field.
-///
-/// For getters, [returnType] maps to the underlying field's type, so that if
-/// type inference fills in the type of the field, the change will automatically
-/// be reflected in the synthetic getter.
-class SyntheticAccessorFunctionNode extends FunctionNode {
- final Field _field;
-
- SyntheticAccessorFunctionNode.getter(this._field)
- : super(new ReturnStatement());
-
- SyntheticAccessorFunctionNode.setter(this._field)
- : super(new ReturnStatement(),
- positionalParameters: [new SyntheticSetterParameter(_field)]);
-
- @override
- DartType get returnType =>
- positionalParameters.isEmpty ? _field.type : const VoidType();
-}
-
-/// A [SyntheticSetterParameter] represents the "value" parameter of the setter
-/// implied by a field.
-///
-/// The getters [isCovariant], [isGenericCovariantImpl],
-/// [isGenericCovariantInterface], and [type] map to the underlying field's
-/// properties, so that if these properties are modified on the field, the
-/// change will automatically be reflected in the synthetic setter. Similarly,
-/// the setters [isCovariant], [isGenericCovariantImpl], and
-/// [isGenericCovariantInterface] update the corresponding properties on the
-/// field, so that covariance propagation logic can act uniformly on [Procedure]
-/// objects without having to have special case handling for fields.
-class SyntheticSetterParameter extends VariableDeclaration {
- final Field _field;
-
- SyntheticSetterParameter(this._field)
- : super('_', isCovariant: _field.isCovariant);
-
- @override
- bool get isCovariant => _field.isCovariant;
-
- @override
- void set isCovariant(bool value) {
- _field.isCovariant = value;
- }
-
- @override
- bool get isGenericCovariantImpl => _field.isGenericCovariantImpl;
-
- @override
- void set isGenericCovariantImpl(bool value) {
- _field.isGenericCovariantImpl = value;
- }
-
- @override
- DartType get type => _field.type;
-}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index bbf090a..b28fc43 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -11,7 +11,6 @@
Field,
FunctionType,
InterfaceType,
- InvalidType,
Member,
TypeParameter,
TypeParameterType,
@@ -25,63 +24,16 @@
import '../../base/instrumentation.dart' show Instrumentation;
import '../kernel/kernel_builder.dart'
- show LibraryBuilder, KernelLibraryBuilder;
+ show
+ ClassHierarchyBuilder,
+ ImplicitFieldType,
+ LibraryBuilder,
+ KernelLibraryBuilder;
-import '../kernel/kernel_shadow_ast.dart' show ShadowField, ShadowMember;
-
-import '../messages.dart' show noLength, templateCantInferTypeDueToCircularity;
-
-import 'type_inferrer.dart' show TypeInferrer, TypeInferrerImpl;
+import 'type_inferrer.dart' show TypeInferrer;
import 'type_schema_environment.dart' show TypeSchemaEnvironment;
-/// Concrete class derived from [InferenceNode] to represent type inference of a
-/// field based on its initializer.
-class FieldInitializerInferenceNode extends InferenceNode {
- final TypeInferenceEngine _typeInferenceEngine;
-
- /// The field whose type should be inferred.
- final ShadowField field;
-
- final LibraryBuilder _library;
-
- FieldInitializerInferenceNode(
- this._typeInferenceEngine, this.field, this._library);
-
- @override
- void resolveInternal() {
- var typeInferrer = _typeInferenceEngine.getFieldTypeInferrer(field);
- // Note: in the event that there is erroneous code, it's possible for
- // typeInferrer to be null. If this happens, just skip type inference for
- // this field.
- if (typeInferrer != null) {
- var inferredType = typeInferrer
- .inferDeclarationType(typeInferrer.inferFieldTopLevel(field));
- if (isCircular) {
- // Report the appropriate error.
- _library.addProblem(
- templateCantInferTypeDueToCircularity
- .withArguments(field.name.name),
- field.fileOffset,
- noLength,
- field.fileUri);
- inferredType = const InvalidType();
- }
- field.setInferredType(
- _typeInferenceEngine, typeInferrer.uri, inferredType);
- // TODO(paulberry): if type != null, then check that the type of the
- // initializer is assignable to it.
- }
- // TODO(paulberry): the following is a hack so that outlines don't contain
- // initializers. But it means that we rebuild the initializers when doing
- // a full compile. There should be a better way.
- field.initializer = null;
- }
-
- @override
- String toString() => field.toString();
-}
-
/// Visitor to check whether a given type mentions any of a class's type
/// parameters in a covariant fashion.
class IncludesTypeParametersCovariantly extends DartTypeVisitor<bool> {
@@ -131,67 +83,6 @@
}
}
-/// Base class for tracking dependencies during top level type inference.
-///
-/// Fields, accessors, and methods can have their types inferred in a variety of
-/// ways; there will a derived class for each kind of inference.
-abstract class InferenceNode {
- /// The node currently being evaluated, or `null` if no node is being
- /// evaluated.
- static InferenceNode _currentNode;
-
- /// Indicates whether the type inference corresponding to this node has been
- /// completed.
- bool _isResolved = false;
-
- /// Indicates whether this node participates in a circularity.
- bool _isCircular = false;
-
- /// If this node is currently being evaluated, and its evaluation caused a
- /// recursive call to another node's [resolve] method, a pointer to the latter
- /// node; otherwise `null`.
- InferenceNode _nextNode;
-
- /// Indicates whether this node participates in a circularity.
- ///
- /// This may be called at the end of [resolveInternal] to check whether a
- /// circularity was detected during evaluation.
- bool get isCircular => _isCircular;
-
- /// Evaluates this node, properly accounting for circularities.
- void resolve() {
- if (_isResolved) return;
- if (_nextNode != null || identical(_currentNode, this)) {
- // An accessor depends on itself (possibly by way of intermediate
- // accessors). Mark all accessors involved as circular.
- var node = this;
- do {
- node._isCircular = true;
- node._isResolved = true;
- node = node._nextNode;
- } while (node != null);
- } else {
- var previousNode = _currentNode;
- assert(previousNode?._nextNode == null);
- _currentNode = this;
- previousNode?._nextNode = this;
- resolveInternal();
- assert(identical(_currentNode, this));
- previousNode?._nextNode = null;
- _currentNode = previousNode;
- _isResolved = true;
- }
- }
-
- /// Evaluates this node, possibly by making recursive calls to the [resolve]
- /// method of this node or other nodes.
- ///
- /// Circularity detection is handled by [resolve], which calls this method.
- /// Once this method has made all recursive calls to [resolve], it may use
- /// [isCircular] to detect whether a circularity has occurred.
- void resolveInternal();
-}
-
/// Keeps track of the global state for the type inference that occurs outside
/// of method bodies and initializers.
///
@@ -201,6 +92,8 @@
abstract class TypeInferenceEngine {
ClassHierarchy classHierarchy;
+ ClassHierarchyBuilder hierarchyBuilder;
+
CoreTypes coreTypes;
/// Indicates whether the "prepare" phase of type inference is complete.
@@ -208,8 +101,6 @@
TypeSchemaEnvironment typeSchemaEnvironment;
- final staticInferenceNodes = <FieldInitializerInferenceNode>[];
-
/// A map containing constructors with initializing formals whose types
/// need to be inferred.
///
@@ -237,21 +128,7 @@
/// Creates a [TypeInferrer] object which is ready to perform type inference
/// on the given [field].
TypeInferrer createTopLevelTypeInferrer(
- InterfaceType thisType, ShadowField field, KernelLibraryBuilder library);
-
- /// Retrieve the [TypeInferrer] for the given [field], which was created by
- /// a previous call to [createTopLevelTypeInferrer].
- TypeInferrerImpl getFieldTypeInferrer(ShadowField field);
-
- /// Performs the second phase of top level initializer inference, which is to
- /// visit all accessors and top level variables that were passed to
- /// [recordAccessor] in topologically-sorted order and assign their types.
- void finishTopLevelFields() {
- for (var node in staticInferenceNodes) {
- node.resolve();
- }
- staticInferenceNodes.clear();
- }
+ Uri uri, InterfaceType thisType, KernelLibraryBuilder library);
/// Performs the third phase of top level inference, which is to visit all
/// constructors still needing inference and infer the types of their
@@ -295,20 +172,17 @@
new TypeSchemaEnvironment(coreTypes, hierarchy);
}
- /// Records that the given static [field] will need top level type inference.
- void recordStaticFieldInferenceCandidate(
- ShadowField field, LibraryBuilder library) {
- var node = new FieldInitializerInferenceNode(this, field, library);
- ShadowField.setInferenceNode(field, node);
- staticInferenceNodes.add(node);
- }
-
- static void resolveInferenceNode(Member member) {
- if (member is ShadowMember) {
- if (member.inferenceNode != null) {
- member.inferenceNode.resolve();
- member.inferenceNode = null;
+ static Member resolveInferenceNode(Member member) {
+ if (member is Field) {
+ DartType type = member.type;
+ if (type is ImplicitFieldType) {
+ if (type.member.target != member) {
+ type.member.inferCopiedType(member);
+ } else {
+ type.member.inferType();
+ }
}
}
+ return member;
}
}
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 bbe6899..6c30926 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
@@ -103,8 +103,6 @@
import '../kernel/kernel_shadow_ast.dart'
show
ExpressionJudgment,
- ShadowClass,
- ShadowField,
ShadowTypeInferenceEngine,
ShadowTypeInferrer,
VariableDeclarationJudgment,
@@ -119,8 +117,6 @@
import 'inference_helper.dart' show InferenceHelper;
-import 'interface_resolver.dart' show ForwardingNode, SyntheticAccessor;
-
import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
import 'type_inference_engine.dart'
@@ -750,7 +746,8 @@
Class classNode = receiverType is InterfaceType
? receiverType.classNode
: coreTypes.objectClass;
- Member interfaceMember = _getInterfaceMember(classNode, name, setter);
+ Member interfaceMember =
+ _getInterfaceMember(classNode, name, setter, fileOffset);
if (instrumented &&
receiverType != const DynamicType() &&
interfaceMember != null) {
@@ -911,7 +908,8 @@
if (calleeType is FunctionType) {
return calleeType;
} else if (followCall && calleeType is InterfaceType) {
- var member = _getInterfaceMember(calleeType.classNode, callName, false);
+ var member =
+ _getInterfaceMember(calleeType.classNode, callName, false, -1);
var callType = getCalleeType(member, calleeType);
if (callType is FunctionType) {
return callType;
@@ -969,7 +967,7 @@
/// Gets the initializer for the given [field], or `null` if there is no
/// initializer.
- Expression getFieldInitializer(ShadowField field);
+ Expression getFieldInitializer(Field field);
/// If the [member] is a forwarding stub, return the target it forwards to.
/// Otherwise return the given [member].
@@ -1160,12 +1158,6 @@
this.helper = null;
}
- /// Performs type inference on the given [field]'s initializer expression.
- ///
- /// Derived classes should provide an implementation that calls
- /// [inferExpression] for the given [field]'s initializer expression.
- DartType inferFieldTopLevel(ShadowField field);
-
@override
void inferFunctionBody(InferenceHelper helper, DartType returnType,
AsyncMarker asyncMarker, Statement body) {
@@ -1454,7 +1446,9 @@
// Let `N'` be `N[T/S]`. The [ClosureContext] constructor will adjust
// accordingly if the closure is declared with `async`, `async*`, or
// `sync*`.
- returnContext = substitution.substituteType(returnContext);
+ if (returnContext is! UnknownType) {
+ returnContext = substitution.substituteType(returnContext);
+ }
// Apply type inference to `B` in return context `N’`, with any references
// to `xi` in `B` having type `Pi`. This produces `B’`.
@@ -1830,25 +1824,16 @@
}
}
- Member _getInterfaceMember(Class class_, Name name, bool setter) {
- if (class_ is ShadowClass) {
- var classInferenceInfo = ShadowClass.getClassInferenceInfo(class_);
- if (classInferenceInfo != null) {
- var member = ClassHierarchy.findMemberByName(
- setter
- ? classInferenceInfo.setters
- : classInferenceInfo.gettersAndMethods,
- name);
- if (member == null) return null;
- member = member is ForwardingNode ? member.resolve() : member;
- member = member is SyntheticAccessor
- ? SyntheticAccessor.getField(member)
- : member;
- TypeInferenceEngine.resolveInferenceNode(member);
- return member;
- }
+ Member _getInterfaceMember(
+ Class class_, Name name, bool setter, int charOffset) {
+ Member member = engine.hierarchyBuilder.getCombinedMemberSignatureKernel(
+ class_, name, setter, charOffset, library);
+ if (member == null && (library?.isPatch ?? false)) {
+ // TODO(dmitryas): Hack for parts.
+ member ??=
+ classHierarchy.getInterfaceMember(class_, name, setter: setter);
}
- return classHierarchy.getInterfaceMember(class_, name, setter: setter);
+ return TypeInferenceEngine.resolveInferenceNode(member);
}
/// Determines if the given [expression]'s type is precisely known at compile
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index e742fd0..01418ae 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -17,6 +17,8 @@
import 'package:kernel/text/ast_to_text.dart'
show Annotator, NameSystem, Printer, globalDebuggingNames;
+import '../problems.dart' show unsupported;
+
/// Determines whether a type schema contains `?` somewhere inside it.
bool isKnown(DartType schema) => schema.accept(new _IsKnownVisitor());
@@ -62,6 +64,9 @@
/// The unknown type cannot appear in programs or in final inferred types: it is
/// purely part of the local inference process.
class UnknownType extends DartType {
+ @override
+ get nullability => unsupported("nullability", -1, null);
+
const UnknownType();
bool operator ==(Object other) {
diff --git a/pkg/sourcemap_testing/lib/src/annotated_code_helper.dart b/pkg/front_end/lib/src/testing/annotated_code_helper.dart
similarity index 100%
rename from pkg/sourcemap_testing/lib/src/annotated_code_helper.dart
rename to pkg/front_end/lib/src/testing/annotated_code_helper.dart
diff --git a/pkg/front_end/lib/src/testing/id.dart b/pkg/front_end/lib/src/testing/id.dart
new file mode 100644
index 0000000..d8b7b77
--- /dev/null
+++ b/pkg/front_end/lib/src/testing/id.dart
@@ -0,0 +1,282 @@
+// 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.
+
+enum IdKind {
+ member,
+ cls,
+ node,
+ invoke,
+ update,
+ iterator,
+ current,
+ moveNext,
+ stmt,
+}
+
+/// Id for a code point or element.
+abstract class Id {
+ IdKind get kind;
+ bool get isGlobal;
+
+ /// Display name for this id.
+ String get descriptor;
+}
+
+class IdValue {
+ final Id id;
+ final String value;
+
+ const IdValue(this.id, this.value);
+
+ @override
+ int get hashCode => id.hashCode * 13 + value.hashCode * 17;
+
+ @override
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! IdValue) return false;
+ return id == other.id && value == other.value;
+ }
+
+ @override
+ String toString() => idToString(id, value);
+
+ static String idToString(Id id, String value) {
+ switch (id.kind) {
+ case IdKind.member:
+ MemberId elementId = id;
+ return '$memberPrefix${elementId.name}:$value';
+ case IdKind.cls:
+ ClassId classId = id;
+ return '$classPrefix${classId.name}:$value';
+ case IdKind.node:
+ return value;
+ case IdKind.invoke:
+ return '$invokePrefix$value';
+ case IdKind.update:
+ return '$updatePrefix$value';
+ case IdKind.iterator:
+ return '$iteratorPrefix$value';
+ case IdKind.current:
+ return '$currentPrefix$value';
+ case IdKind.moveNext:
+ return '$moveNextPrefix$value';
+ case IdKind.stmt:
+ return '$stmtPrefix$value';
+ }
+ throw new UnsupportedError("Unexpected id kind: ${id.kind}");
+ }
+
+ static const String globalPrefix = "global#";
+ static const String memberPrefix = "member: ";
+ static const String classPrefix = "class: ";
+ static const String invokePrefix = "invoke: ";
+ static const String updatePrefix = "update: ";
+ static const String iteratorPrefix = "iterator: ";
+ static const String currentPrefix = "current: ";
+ static const String moveNextPrefix = "moveNext: ";
+ static const String stmtPrefix = "stmt: ";
+
+ static IdValue decode(int offset, String text) {
+ Id id;
+ String expected;
+ if (text.startsWith(memberPrefix)) {
+ text = text.substring(memberPrefix.length);
+ int colonPos = text.indexOf(':');
+ if (colonPos == -1) throw "Invalid element id: '$text'";
+ String name = text.substring(0, colonPos);
+ bool isGlobal = name.startsWith(globalPrefix);
+ if (isGlobal) {
+ name = name.substring(globalPrefix.length);
+ }
+ id = new MemberId(name, isGlobal: isGlobal);
+ expected = text.substring(colonPos + 1);
+ } else if (text.startsWith(classPrefix)) {
+ text = text.substring(classPrefix.length);
+ int colonPos = text.indexOf(':');
+ if (colonPos == -1) throw "Invalid class id: '$text'";
+ String name = text.substring(0, colonPos);
+ bool isGlobal = name.startsWith(globalPrefix);
+ if (isGlobal) {
+ name = name.substring(globalPrefix.length);
+ }
+ id = new ClassId(name, isGlobal: isGlobal);
+ expected = text.substring(colonPos + 1);
+ } else if (text.startsWith(invokePrefix)) {
+ id = new NodeId(offset, IdKind.invoke);
+ expected = text.substring(invokePrefix.length);
+ } else if (text.startsWith(updatePrefix)) {
+ id = new NodeId(offset, IdKind.update);
+ expected = text.substring(updatePrefix.length);
+ } else if (text.startsWith(iteratorPrefix)) {
+ id = new NodeId(offset, IdKind.iterator);
+ expected = text.substring(iteratorPrefix.length);
+ } else if (text.startsWith(currentPrefix)) {
+ id = new NodeId(offset, IdKind.current);
+ expected = text.substring(currentPrefix.length);
+ } else if (text.startsWith(moveNextPrefix)) {
+ id = new NodeId(offset, IdKind.moveNext);
+ expected = text.substring(moveNextPrefix.length);
+ } else if (text.startsWith(stmtPrefix)) {
+ id = new NodeId(offset, IdKind.stmt);
+ expected = text.substring(stmtPrefix.length);
+ } else {
+ id = new NodeId(offset, IdKind.node);
+ expected = text;
+ }
+ // Remove newlines.
+ expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
+ return new IdValue(id, expected);
+ }
+}
+
+/// Id for an member element.
+class MemberId implements Id {
+ final String className;
+ final String memberName;
+ @override
+ final bool isGlobal;
+
+ factory MemberId(String text, {bool isGlobal: false}) {
+ int dotPos = text.indexOf('.');
+ if (dotPos != -1) {
+ return new MemberId.internal(text.substring(dotPos + 1),
+ className: text.substring(0, dotPos), isGlobal: isGlobal);
+ } else {
+ return new MemberId.internal(text, isGlobal: isGlobal);
+ }
+ }
+
+ MemberId.internal(this.memberName, {this.className, this.isGlobal: false});
+
+ @override
+ int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
+
+ @override
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! MemberId) return false;
+ return className == other.className && memberName == other.memberName;
+ }
+
+ @override
+ IdKind get kind => IdKind.member;
+
+ String get name => className != null ? '$className.$memberName' : memberName;
+
+ @override
+ String get descriptor => 'member $name';
+
+ @override
+ String toString() => 'member:$name';
+}
+
+/// Id for a class.
+class ClassId implements Id {
+ final String className;
+ @override
+ final bool isGlobal;
+
+ ClassId(this.className, {this.isGlobal: false});
+
+ @override
+ int get hashCode => className.hashCode * 13;
+
+ @override
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! ClassId) return false;
+ return className == other.className;
+ }
+
+ @override
+ IdKind get kind => IdKind.cls;
+
+ String get name => className;
+
+ @override
+ String get descriptor => 'class $name';
+
+ @override
+ String toString() => 'class:$name';
+}
+
+/// Id for a code point.
+class NodeId implements Id {
+ final int value;
+ @override
+ final IdKind kind;
+
+ const NodeId(this.value, this.kind);
+
+ @override
+ bool get isGlobal => false;
+
+ @override
+ int get hashCode => value.hashCode * 13 + kind.hashCode * 17;
+
+ @override
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! NodeId) return false;
+ return value == other.value && kind == other.kind;
+ }
+
+ @override
+ String get descriptor => 'offset $value ($kind)';
+
+ @override
+ String toString() => '$kind:$value';
+}
+
+class ActualData<T> {
+ final Id id;
+ final T value;
+ final Uri uri;
+ final int _offset;
+ final Object object;
+
+ ActualData(this.id, this.value, this.uri, this._offset, this.object);
+
+ int get offset {
+ if (id is NodeId) {
+ NodeId nodeId = id;
+ return nodeId.value;
+ } else {
+ return _offset;
+ }
+ }
+
+ String get objectText {
+ return 'object `${'$object'.replaceAll('\n', '')}` (${object.runtimeType})';
+ }
+
+ @override
+ String toString() => 'ActualData(id=$id,value=$value,uri=$uri,'
+ 'offset=$offset,object=$objectText)';
+}
+
+abstract class DataRegistry<T> {
+ Map<Id, ActualData<T>> get actualMap;
+
+ void registerValue(Uri uri, int offset, Id id, T value, Object object) {
+ if (actualMap.containsKey(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.");
+ }
+ if (value != null) {
+ actualMap[id] = new ActualData<T>(id, value, uri, offset, object);
+ }
+ }
+
+ void report(Uri uri, int offset, String message);
+
+ void fail(String message);
+}
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
new file mode 100644
index 0000000..83007b5
--- /dev/null
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -0,0 +1,264 @@
+// 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:kernel/ast.dart';
+import 'id.dart';
+
+/// Compute a canonical [Id] for kernel-based nodes.
+Id computeEntityId(Member node) {
+ String className;
+ if (node.enclosingClass != null) {
+ className = node.enclosingClass.name;
+ }
+ String memberName = node.name.name;
+ if (node is Procedure && node.kind == ProcedureKind.Setter) {
+ memberName += '=';
+ }
+ return new MemberId.internal(memberName, className: className);
+}
+
+TreeNode computeTreeNodeWithOffset(TreeNode node) {
+ while (node != null) {
+ if (node.fileOffset != TreeNode.noOffset) {
+ return node;
+ }
+ node = node.parent;
+ }
+ return null;
+}
+
+/// Abstract visitor for computing data corresponding to a node or element,
+/// and record it with a generic [Id]
+abstract class DataExtractor<T> extends Visitor with DataRegistry<T> {
+ @override
+ final Map<Id, ActualData<T>> actualMap;
+
+ /// Implement this to compute the data corresponding to [member].
+ ///
+ /// If `null` is returned, [member] has no associated data.
+ T computeMemberValue(Id id, Member member);
+
+ /// Implement this to compute the data corresponding to [node].
+ ///
+ /// If `null` is returned, [node] has no associated data.
+ T computeNodeValue(Id id, TreeNode node);
+
+ DataExtractor(this.actualMap);
+
+ void computeForMember(Member member) {
+ MemberId id = computeEntityId(member);
+ if (id == null) return;
+ T value = computeMemberValue(id, member);
+ TreeNode nodeWithOffset = computeTreeNodeWithOffset(member);
+ registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+ id, value, member);
+ }
+
+ void computeForNode(TreeNode node, NodeId id) {
+ if (id == null) return;
+ T value = computeNodeValue(id, node);
+ TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+ id, value, node);
+ }
+
+ NodeId computeDefaultNodeId(TreeNode node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on $node (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.node);
+ }
+
+ NodeId createInvokeId(TreeNode node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on ${node} (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.invoke);
+ }
+
+ NodeId createUpdateId(TreeNode node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on ${node} (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.update);
+ }
+
+ NodeId createIteratorId(ForInStatement node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on ${node} (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.iterator);
+ }
+
+ NodeId createCurrentId(ForInStatement node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on ${node} (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.current);
+ }
+
+ NodeId createMoveNextId(ForInStatement node) {
+ assert(node.fileOffset != TreeNode.noOffset,
+ "No fileOffset on ${node} (${node.runtimeType})");
+ return new NodeId(node.fileOffset, IdKind.moveNext);
+ }
+
+ NodeId createLabeledStatementId(LabeledStatement node) =>
+ computeDefaultNodeId(node.body);
+ NodeId createLoopId(TreeNode node) => computeDefaultNodeId(node);
+ NodeId createGotoId(TreeNode node) => computeDefaultNodeId(node);
+ NodeId createSwitchId(SwitchStatement node) => computeDefaultNodeId(node);
+ NodeId createSwitchCaseId(SwitchCase node) =>
+ new NodeId(node.expressionOffsets.first, IdKind.node);
+
+ void run(Node root) {
+ root.accept(this);
+ }
+
+ @override
+ defaultNode(Node node) {
+ node.visitChildren(this);
+ }
+
+ @override
+ defaultMember(Member node) {
+ super.defaultMember(node);
+ computeForMember(node);
+ }
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ TreeNode receiver = node.receiver;
+ if (receiver is VariableGet &&
+ receiver.variable.parent is FunctionDeclaration) {
+ // This is an invocation of a named local function.
+ computeForNode(node, createInvokeId(node.receiver));
+ node.arguments.accept(this);
+ } else if (node.name.name == '==' &&
+ receiver is VariableGet &&
+ receiver.variable.name == null) {
+ // This is a desugared `?.`.
+ } else if (node.name.name == '[]') {
+ computeForNode(node, computeDefaultNodeId(node));
+ super.visitMethodInvocation(node);
+ } else if (node.name.name == '[]=') {
+ computeForNode(node, createUpdateId(node));
+ super.visitMethodInvocation(node);
+ } else {
+ computeForNode(node, createInvokeId(node));
+ super.visitMethodInvocation(node);
+ }
+ }
+
+ @override
+ visitLoadLibrary(LoadLibrary node) {
+ computeForNode(node, createInvokeId(node));
+ }
+
+ @override
+ visitPropertyGet(PropertyGet node) {
+ computeForNode(node, computeDefaultNodeId(node));
+ super.visitPropertyGet(node);
+ }
+
+ @override
+ visitVariableDeclaration(VariableDeclaration node) {
+ if (node.name != null && node.parent is! FunctionDeclaration) {
+ // Skip synthetic variables and function declaration variables.
+ computeForNode(node, computeDefaultNodeId(node));
+ }
+ super.visitVariableDeclaration(node);
+ }
+
+ @override
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ computeForNode(node, computeDefaultNodeId(node));
+ super.visitFunctionDeclaration(node);
+ }
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ computeForNode(node, computeDefaultNodeId(node));
+ super.visitFunctionExpression(node);
+ }
+
+ @override
+ visitVariableGet(VariableGet node) {
+ if (node.variable.name != null && !node.variable.isFieldFormal) {
+ // Skip use of synthetic variables.
+ computeForNode(node, computeDefaultNodeId(node));
+ }
+ super.visitVariableGet(node);
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ computeForNode(node, createUpdateId(node));
+ super.visitPropertySet(node);
+ }
+
+ @override
+ visitVariableSet(VariableSet node) {
+ if (node.variable.name != null) {
+ // Skip use of synthetic variables.
+ computeForNode(node, createUpdateId(node));
+ }
+ super.visitVariableSet(node);
+ }
+
+ @override
+ visitDoStatement(DoStatement node) {
+ computeForNode(node, createLoopId(node));
+ super.visitDoStatement(node);
+ }
+
+ @override
+ visitForStatement(ForStatement node) {
+ computeForNode(node, createLoopId(node));
+ super.visitForStatement(node);
+ }
+
+ @override
+ visitForInStatement(ForInStatement node) {
+ computeForNode(node, createLoopId(node));
+ computeForNode(node, createIteratorId(node));
+ computeForNode(node, createCurrentId(node));
+ computeForNode(node, createMoveNextId(node));
+ super.visitForInStatement(node);
+ }
+
+ @override
+ visitWhileStatement(WhileStatement node) {
+ computeForNode(node, createLoopId(node));
+ super.visitWhileStatement(node);
+ }
+
+ @override
+ visitLabeledStatement(LabeledStatement node) {
+ // TODO(johnniwinther): Call computeForNode for label statements that are
+ // not placeholders for loop and switch targets.
+ super.visitLabeledStatement(node);
+ }
+
+ @override
+ visitBreakStatement(BreakStatement node) {
+ computeForNode(node, createGotoId(node));
+ super.visitBreakStatement(node);
+ }
+
+ @override
+ visitSwitchStatement(SwitchStatement node) {
+ computeForNode(node, createSwitchId(node));
+ super.visitSwitchStatement(node);
+ }
+
+ @override
+ visitSwitchCase(SwitchCase node) {
+ if (node.expressionOffsets.isNotEmpty) {
+ computeForNode(node, createSwitchCaseId(node));
+ }
+ super.visitSwitchCase(node);
+ }
+
+ @override
+ visitContinueSwitchStatement(ContinueSwitchStatement node) {
+ computeForNode(node, createGotoId(node));
+ super.visitContinueSwitchStatement(node);
+ }
+}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 8f99626..f1fc567 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -28,6 +28,8 @@
BadTypeVariableInSupertype/analyzerCode: Fail
BuiltInIdentifierAsType/example: Fail
BuiltInIdentifierInDeclaration/example: Fail
+BytecodeLimitExceededTooManyArguments/analyzerCode: Fail
+BytecodeLimitExceededTooManyArguments/example: Fail
CannotAssignToParenthesizedExpression/example: Fail
CannotAssignToSuper/example: Fail
CannotReadPackagesFile/analyzerCode: Fail
@@ -42,7 +44,6 @@
CantInferPackagesFromPackageUri/analyzerCode: Fail
CantInferPackagesFromPackageUri/example: Fail
CantInferTypeDueToCircularity/example: Fail
-CantInferTypeDueToInconsistentOverrides/example: Fail
CantReadFile/part_wrapped_script: Fail # Importing file in the (now) part.
CantUseControlFlowOrSpreadAsConstant/example: Fail
CantUseDeferredPrefixAsConstant/part_wrapped_script: Fail # Importing file in the (now) part.
@@ -252,6 +253,10 @@
FfiTypeInvalid/analyzerCode: Fail
FfiTypeMismatch/analyzerCode: Fail
FfiTypeUnsized/analyzerCode: Fail
+FfiDartTypeMismatch/analyzerCode: Fail
+FfiExtendsOrImplementsSealedClass/analyzerCode: Fail
+FfiStructGeneric/analyzerCode: Fail
+FfiWrongStructInheritance/analyzerCode: Fail
FieldInitializedOutsideDeclaringClass/part_wrapped_script1: Fail
FieldInitializedOutsideDeclaringClass/script1: Fail
FieldInitializerOutsideConstructor/part_wrapped_script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index d2b0dac..93da19c 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2926,6 +2926,13 @@
template: "Can't infer a type for '#name' as some of the inherited members have different types."
tip: "Try adding an explicit type."
analyzerCode: INVALID_METHOD_OVERRIDE
+ external: testcases/inference/inconsistent_overrides.dart
+
+CantInferReturnTypeDueToInconsistentOverrides:
+ template: "Can't infer a return type for '#name' as some of the inherited members have different types."
+ tip: "Try adding an explicit type."
+ analyzerCode: INVALID_METHOD_OVERRIDE
+ external: testcases/inference/inconsistent_overrides.dart
CantInferTypeDueToCircularity:
template: "Can't infer the type of '#string': circularity found during type inference."
@@ -3452,7 +3459,7 @@
FfiFieldAnnotation:
# Used by dart:ffi
- template: "Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields."
+ template: "Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields."
external: test/ffi_test.dart
FfiNotStatic:
@@ -3465,9 +3472,24 @@
template: "Field '#name' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution."
external: test/ffi_test.dart
-FfiStructAnnotation:
+FfiExtendsOrImplementsSealedClass:
# Used by dart:ffi
- template: "Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields."
+ template: "Class '#name' cannot be extended or implemented."
+ external: test/ffi_test.dart
+
+FfiStructGeneric:
+ # Used by dart:ffi
+ template: "Struct '#name' should not be generic."
+ external: test/ffi_test.dart
+
+FfiWrongStructInheritance:
+ # Used by dart:ffi
+ template: "Struct '#name' must inherit from 'Struct<#name>'."
+ external: test/ffi_test.dart
+
+FfiDartTypeMismatch:
+ # Used by dart:ffi
+ template: "Expected '#type' to be a subtype of '#type2'."
external: test/ffi_test.dart
SpreadTypeMismatch:
@@ -3566,3 +3588,22 @@
script: >
class Base<T> {}
class Derived<T> extends Base<Derived<Derived<T>>> {}
+
+BytecodeLimitExceededTooManyArguments:
+ template: "Dart bytecode limit exceeded: too many arguments."
+
+CombinedMemberSignatureFailed:
+ template: "Class '#name' inherits multiple members named '#name2' with incompatible signatures."
+ tip: "Try adding a declaration of '#name2' to '#name'."
+ analyzerCode: INCONSISTENT_INHERITANCE
+ script:
+ - |
+ abstract class I1 {
+ foo(x);
+ }
+
+ abstract class I2 {
+ foo();
+ }
+
+ abstract class C implements I2, I1 {}
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 64e9958..e4593e7 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,19 +1,19 @@
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.18
+version: 0.1.20
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.1.0-dev.5.0 <3.0.0'
dependencies:
- kernel: 0.3.18
+ kernel: 0.3.20
package_config: '^1.0.1'
path: '^1.3.9'
yaml: '^2.1.12'
dev_dependencies:
- analyzer: 0.36.3
+ analyzer: 0.37.0
args: '>=0.13.0 <2.0.0'
build_integration:
path: ../build_integration
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index c183abd..9d94241 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -10,7 +10,8 @@
import 'dart:io' show File, Platform;
-import 'package:kernel/ast.dart' show Library, Component;
+import 'package:kernel/ast.dart'
+ show AwaitExpression, Component, Library, Node, Visitor;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -111,6 +112,10 @@
"group": "Fail"
},
{
+ "name": "TransformVerificationError",
+ "group": "Fail"
+ },
+ {
"name": "TextSerializationFailure",
"group": "Fail"
}
@@ -368,7 +373,7 @@
UriTranslator uriTranslator = new UriTranslator(
const TargetLibrariesSpecification('vm'),
context.uriTranslator.packages);
- KernelTarget sourceTarget = new KernelTestingTarget(
+ KernelTarget sourceTarget = new KernelTarget(
StandardFileSystem.instance, false, dillTarget, uriTranslator);
sourceTarget.setEntryPoints(<Uri>[description.uri]);
@@ -422,10 +427,41 @@
} finally {
backendTarget.enabled = false;
}
+ List<String> errors = VerifyTransformed.verify(component);
+ if (errors.isNotEmpty) {
+ return new Result<Component>(
+ component,
+ context.expectationSet["TransformVerificationError"],
+ errors.join('\n'),
+ null);
+ }
return pass(component);
}
}
+/// Visitor that checks that the component has been transformed properly.
+// TODO(johnniwinther): Add checks for all nodes that are unsupported after
+// transformation.
+class VerifyTransformed extends Visitor<void> {
+ List<String> errors = [];
+
+ @override
+ void defaultNode(Node node) {
+ node.visitChildren(this);
+ }
+
+ @override
+ void visitAwaitExpression(AwaitExpression node) {
+ errors.add("ERROR: Untransformed await expression: $node");
+ }
+
+ static List<String> verify(Component component) {
+ VerifyTransformed visitor = new VerifyTransformed();
+ component.accept(visitor);
+ return visitor.errors;
+ }
+}
+
class TestVmTarget extends VmTarget {
bool enabled = false;
@@ -463,15 +499,6 @@
}
}
-class KernelTestingTarget extends KernelTarget {
- @override
- ClassHierarchyBuilder builderHierarchy;
-
- KernelTestingTarget(StandardFileSystem fileSystem, bool includeComments,
- DillTarget dillTarget, UriTranslator uriTranslator)
- : super(fileSystem, includeComments, dillTarget, uriTranslator);
-}
-
class MatchHierarchy extends Step<Component, Component, FastaContext> {
const MatchHierarchy();
@@ -481,8 +508,8 @@
Component component, FastaContext context) async {
Uri uri =
component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
- KernelTestingTarget target = context.componentToTarget[component];
- ClassHierarchyBuilder hierarchy = target.builderHierarchy;
+ KernelTarget target = context.componentToTarget[component];
+ ClassHierarchyBuilder hierarchy = target.loader.builderHierarchy;
StringBuffer sb = new StringBuffer();
for (ClassHierarchyNode node in hierarchy.nodes.values) {
node.toString(sb);
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
deleted file mode 100644
index b19a80f..0000000
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ /dev/null
@@ -1,1049 +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.
-
-import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:front_end/src/fasta/type_inference/interface_resolver.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/type_algebra.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(InterfaceResolverTest);
- });
-}
-
-@reflectiveTest
-class InterfaceResolverTest {
- final Library testLib;
-
- final Component component;
-
- final CoreTypes coreTypes;
-
- ClassHierarchy cachedClassHierarchy;
-
- TypeSchemaEnvironment cachedTypeEnvironment;
-
- InterfaceResolver cachedInterfaceResolver;
-
- InterfaceResolverTest()
- : this._(new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib'),
- createMockSdkComponent());
-
- InterfaceResolverTest._(this.testLib, Component component)
- : component = component..libraries.add(testLib..parent = component),
- coreTypes = new CoreTypes(component);
-
- ClassHierarchy get classHierarchy {
- return cachedClassHierarchy ??= new ClassHierarchy(component);
- }
-
- TypeSchemaEnvironment get typeEnvironment {
- return cachedTypeEnvironment ??=
- new TypeSchemaEnvironment(coreTypes, classHierarchy);
- }
-
- InterfaceResolver get interfaceResolver {
- return cachedInterfaceResolver ??=
- new InterfaceResolver(null, typeEnvironment, null);
- }
-
- InterfaceType get intType => coreTypes.intClass.rawType;
-
- Class get listClass => coreTypes.listClass;
-
- InterfaceType get numType => coreTypes.numClass.rawType;
-
- Class get objectClass => coreTypes.objectClass;
-
- InterfaceType get objectType => objectClass.rawType;
-
- void checkCandidate(Procedure procedure, bool setter) {
- var class_ = makeClass(procedures: [procedure]);
- var candidate = getCandidate(class_, setter);
- expect(candidate, same(procedure));
- }
-
- void checkCandidateOrder(Class class_, Member member) {
- // Check that InterfaceResolver prioritizes [member]
- var candidates = getCandidates(class_, false);
- expect(candidates[0], same(member));
-
- // Check that both implementations of [ClassHierarchy] prioritize [member]
- // ahead of [other]
- void check(ClassHierarchy classHierarchy) {
- var interfaceMember =
- classHierarchy.getInterfaceMember(class_, member.name);
- expect(interfaceMember, same(member));
- }
-
- check(new ClassHierarchy(component));
- }
-
- Procedure getCandidate(Class class_, bool setter) {
- var candidates = getCandidates(class_, setter);
- expect(candidates, hasLength(1));
- return candidates[0];
- }
-
- List<Procedure> getCandidates(Class class_, bool setters) =>
- interfaceResolver.getCandidates(class_, setters);
-
- ForwardingNode getForwardingNode(Class class_, bool setter) {
- var forwardingNodes = getForwardingNodes(class_, setter);
- expect(forwardingNodes, hasLength(1));
- return forwardingNodes[0];
- }
-
- List<ForwardingNode> getForwardingNodes(Class class_, bool setters) {
- var forwardingNodes = <ForwardingNode>[];
- var candidates = getCandidates(class_, setters);
- InterfaceResolver.forEachApiMember(candidates,
- (int start, int end, Name name) {
- forwardingNodes.add(new ForwardingNode(interfaceResolver, null, class_,
- name, candidates[start].kind, candidates, start, end));
- });
- return forwardingNodes;
- }
-
- Member getStubTarget(Procedure stub) {
- var body = stub.function.body;
- if (body == null) return null;
- if (body is ReturnStatement) {
- var expression = body.expression;
- if (expression is SuperMethodInvocation) {
- return expression.interfaceTarget;
- } else if (expression is SuperPropertySet) {
- return expression.interfaceTarget;
- } else {
- fail('Unexpected expression type: ${expression.runtimeType}');
- }
- } else {
- fail('Unexpected body type: ${body.runtimeType}');
- }
- }
-
- Class makeClass(
- {String name,
- Supertype supertype,
- Supertype mixedInType,
- List<TypeParameter> typeParameters,
- List<Supertype> implementedTypes,
- List<Procedure> procedures,
- List<Field> fields}) {
- resetInterfaceResolver();
- var class_ = new ShadowClass(
- name: name ?? 'C',
- supertype: supertype ?? objectClass.asThisSupertype,
- mixedInType: mixedInType,
- typeParameters: typeParameters,
- implementedTypes: implementedTypes,
- procedures: procedures,
- fields: fields);
- testLib.addClass(class_);
- return class_;
- }
-
- Procedure makeEmptyMethod(
- {ProcedureKind kind: ProcedureKind.Method,
- String name: 'foo',
- List<TypeParameter> typeParameters,
- List<VariableDeclaration> positionalParameters,
- List<VariableDeclaration> namedParameters,
- int requiredParameterCount,
- DartType returnType: const VoidType(),
- bool isAbstract: false}) {
- var body = isAbstract ? null : new ReturnStatement(new NullLiteral());
- var function = new FunctionNode(body,
- typeParameters: typeParameters,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- requiredParameterCount: requiredParameterCount,
- returnType: returnType);
- return new ShadowProcedure(new Name(name), kind, function, false,
- isAbstract: isAbstract);
- }
-
- Field makeField(
- {String name: 'foo',
- DartType type: const DynamicType(),
- bool isFinal: false}) {
- return new Field(new Name(name), type: type, isFinal: isFinal);
- }
-
- Procedure makeForwardingStub(Procedure method, bool setter,
- {Substitution substitution}) {
- var a = makeClass(name: 'A', procedures: [method]);
- var b = makeClass(name: 'B', supertype: a.asThisSupertype);
- var node = getForwardingNode(b, setter);
- var stub = ForwardingNode.createForwardingStubForTesting(
- node, substitution ?? Substitution.empty, method);
- ForwardingNode.createForwardingImplIfNeededForTesting(node, stub.function);
- return stub;
- }
-
- Procedure makeGetter(
- {String name: 'foo', DartType getterType: const DynamicType()}) {
- var body = new ReturnStatement(new NullLiteral());
- var function = new FunctionNode(body, returnType: getterType);
- return new ShadowProcedure(
- new Name(name), ProcedureKind.Getter, function, false);
- }
-
- Procedure makeSetter(
- {String name: 'foo',
- DartType setterType: const DynamicType(),
- bool isCovariant: false}) {
- var parameter = new VariableDeclarationJudgment('value', 0,
- type: setterType, isCovariant: isCovariant);
- var body = new Block([]);
- var function = new FunctionNode(body,
- positionalParameters: [parameter], returnType: const VoidType());
- return new ShadowProcedure(
- new Name(name), ProcedureKind.Setter, function, false);
- }
-
- void resetInterfaceResolver() {
- cachedClassHierarchy = null;
- cachedTypeEnvironment = null;
- cachedInterfaceResolver = null;
- }
-
- void test_candidate_for_field_getter() {
- var field = makeField();
- var class_ = makeClass(fields: [field]);
- var candidate = getCandidate(class_, false);
- expect(candidate, const TypeMatcher<SyntheticAccessor>());
- expect(candidate.parent, same(class_));
- expect(candidate.name, field.name);
- expect(candidate.kind, ProcedureKind.Getter);
- expect(candidate.function.positionalParameters, isEmpty);
- expect(candidate.function.namedParameters, isEmpty);
- expect(candidate.function.typeParameters, isEmpty);
- }
-
- void test_candidate_for_field_setter() {
- var field = makeField();
- var class_ = makeClass(fields: [field]);
- var candidate = getCandidate(class_, true);
- expect(candidate, const TypeMatcher<SyntheticAccessor>());
- expect(candidate.parent, same(class_));
- expect(candidate.name, field.name);
- expect(candidate.kind, ProcedureKind.Setter);
- expect(candidate.function.positionalParameters, hasLength(1));
- expect(candidate.function.positionalParameters[0].name, '_');
- expect(candidate.function.namedParameters, isEmpty);
- expect(candidate.function.typeParameters, isEmpty);
- expect(candidate.function.returnType, const VoidType());
- }
-
- void test_candidate_for_getter() {
- var function = new FunctionNode(null);
- var getter = new ShadowProcedure(
- new Name('foo'), ProcedureKind.Getter, function, false);
- checkCandidate(getter, false);
- }
-
- void test_candidate_for_method() {
- checkCandidate(makeEmptyMethod(), false);
- }
-
- void test_candidate_for_setter() {
- var parameter = new VariableDeclarationJudgment('value', 0);
- var function = new FunctionNode(null,
- positionalParameters: [parameter], returnType: const VoidType());
- var setter = new ShadowProcedure(
- new Name('foo'), ProcedureKind.Setter, function, false);
- checkCandidate(setter, true);
- }
-
- void test_candidate_from_interface() {
- var method = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [method]);
- var b = makeClass(name: 'B', implementedTypes: [a.asThisSupertype]);
- var candidate = getCandidate(b, false);
- expect(candidate, same(method));
- }
-
- void test_candidate_from_mixin() {
- var method = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [method]);
- var b = makeClass(name: 'B', mixedInType: a.asThisSupertype);
- var candidate = getCandidate(b, false);
- expect(candidate, same(method));
- }
-
- void test_candidate_from_superclass() {
- var method = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [method]);
- var b = makeClass(name: 'B', supertype: a.asThisSupertype);
- var candidate = getCandidate(b, false);
- expect(candidate, same(method));
- }
-
- void test_candidate_order_interfaces() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
- checkCandidateOrder(c, methodA);
- }
-
- void test_candidate_order_mixin_before_superclass() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C',
- supertype: a.asThisSupertype,
- mixedInType: b.asThisSupertype);
- checkCandidateOrder(c, methodB);
- }
-
- void test_candidate_order_superclass_before_interface() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C',
- supertype: a.asThisSupertype,
- implementedTypes: [b.asThisSupertype]);
- checkCandidateOrder(c, methodA);
- }
-
- void test_createForwardingStub_abstract() {
- var method = makeEmptyMethod(isAbstract: true);
- var stub = makeForwardingStub(method, false);
- expect(stub.isAbstract, isTrue);
- expect(stub.function.body, isNull);
- }
-
- void test_createForwardingStub_getter() {
- var getter = makeGetter(getterType: numType);
- var stub = makeForwardingStub(getter, false);
- expect(stub.name, getter.name);
- expect(stub.kind, ProcedureKind.Getter);
- expect(stub.function.positionalParameters, isEmpty);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 0);
- expect(stub.function.returnType, numType);
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperPropertyGet;
- expect(expression.name, getter.name);
- expect(expression.interfaceTarget, same(getter));
- }
-
- void test_createForwardingStub_getter_for_field() {
- var field = makeField(type: numType);
- var stub = makeForwardingStub(
- InterfaceResolver.makeCandidate(field, false), false);
- expect(stub.name, field.name);
- expect(stub.kind, ProcedureKind.Getter);
- expect(stub.function.positionalParameters, isEmpty);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 0);
- expect(stub.function.returnType, numType);
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperPropertyGet;
- expect(expression.name, field.name);
- expect(expression.interfaceTarget, same(field));
- }
-
- void test_createForwardingStub_operator() {
- var operator = makeEmptyMethod(
- kind: ProcedureKind.Operator,
- name: '[]=',
- positionalParameters: [
- new VariableDeclarationJudgment('index', 0, type: intType),
- new VariableDeclarationJudgment('value', 0, type: numType)
- ]);
- var stub = makeForwardingStub(operator, false);
- expect(stub.name, operator.name);
- expect(stub.kind, ProcedureKind.Operator);
- expect(stub.function.positionalParameters, hasLength(2));
- expect(stub.function.positionalParameters[0].name,
- operator.function.positionalParameters[0].name);
- expect(stub.function.positionalParameters[0].type, intType);
- expect(stub.function.positionalParameters[1].name,
- operator.function.positionalParameters[1].name);
- expect(stub.function.positionalParameters[1].type, numType);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 2);
- expect(stub.function.returnType, const VoidType());
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperMethodInvocation;
- expect(expression.name, operator.name);
- expect(expression.interfaceTarget, same(operator));
- var arguments = expression.arguments;
- expect(arguments.positional, hasLength(2));
- expect((arguments.positional[0] as VariableGet).variable,
- same(stub.function.positionalParameters[0]));
- expect((arguments.positional[1] as VariableGet).variable,
- same(stub.function.positionalParameters[1]));
- }
-
- void test_createForwardingStub_optionalNamedParameter() {
- var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
- var method = makeEmptyMethod(namedParameters: [parameter]);
- var stub = makeForwardingStub(method, false);
- expect(stub.function.namedParameters, hasLength(1));
- expect(stub.function.namedParameters[0].name, 'x');
- expect(stub.function.namedParameters[0].type, intType);
- expect(stub.function.requiredParameterCount, 0);
- var arguments = ((stub.function.body as ReturnStatement).expression
- as SuperMethodInvocation)
- .arguments;
- expect(arguments.named, hasLength(1));
- expect(arguments.named[0].name, 'x');
- expect((arguments.named[0].value as VariableGet).variable,
- same(stub.function.namedParameters[0]));
- }
-
- void test_createForwardingStub_optionalPositionalParameter() {
- var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
- var method = makeEmptyMethod(
- positionalParameters: [parameter], requiredParameterCount: 0);
- var stub = makeForwardingStub(method, false);
- expect(stub.function.positionalParameters, hasLength(1));
- expect(stub.function.positionalParameters[0].name, 'x');
- expect(stub.function.positionalParameters[0].type, intType);
- expect(stub.function.requiredParameterCount, 0);
- var arguments = ((stub.function.body as ReturnStatement).expression
- as SuperMethodInvocation)
- .arguments;
- expect(arguments.positional, hasLength(1));
- expect((arguments.positional[0] as VariableGet).variable,
- same(stub.function.positionalParameters[0]));
- }
-
- void test_createForwardingStub_requiredParameter() {
- var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
- var method = makeEmptyMethod(positionalParameters: [parameter]);
- var stub = makeForwardingStub(method, false);
- expect(stub.function.positionalParameters, hasLength(1));
- expect(stub.function.positionalParameters[0].name, 'x');
- expect(stub.function.positionalParameters[0].type, intType);
- expect(stub.function.requiredParameterCount, 1);
- var arguments = ((stub.function.body as ReturnStatement).expression
- as SuperMethodInvocation)
- .arguments;
- expect(arguments.positional, hasLength(1));
- expect((arguments.positional[0] as VariableGet).variable,
- same(stub.function.positionalParameters[0]));
- }
-
- void test_createForwardingStub_setter() {
- var setter = makeSetter(setterType: numType);
- var stub = makeForwardingStub(setter, true);
- expect(stub.name, setter.name);
- expect(stub.kind, ProcedureKind.Setter);
- expect(stub.function.positionalParameters, hasLength(1));
- expect(stub.function.positionalParameters[0].name,
- setter.function.positionalParameters[0].name);
- expect(stub.function.positionalParameters[0].type, numType);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 1);
- expect(stub.function.returnType, const VoidType());
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperPropertySet;
- expect(expression.name, setter.name);
- expect(expression.interfaceTarget, same(setter));
- expect((expression.value as VariableGet).variable,
- same(stub.function.positionalParameters[0]));
- }
-
- void test_createForwardingStub_setter_for_field() {
- var field = makeField(type: numType);
- var stub =
- makeForwardingStub(InterfaceResolver.makeCandidate(field, true), true);
- expect(stub.name, field.name);
- expect(stub.kind, ProcedureKind.Setter);
- expect(stub.function.positionalParameters, hasLength(1));
- expect(stub.function.positionalParameters[0].name, '_');
- expect(stub.function.positionalParameters[0].type, numType);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 1);
- expect(stub.function.returnType, const VoidType());
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperPropertySet;
- expect(expression.name, field.name);
- expect(expression.interfaceTarget, same(field));
- expect((expression.value as VariableGet).variable,
- same(stub.function.positionalParameters[0]));
- }
-
- void test_createForwardingStub_simple() {
- var method = makeEmptyMethod();
- var stub = makeForwardingStub(method, false);
- expect(stub.name, method.name);
- expect(stub.kind, ProcedureKind.Method);
- expect(stub.isAbstract, isFalse);
- expect(stub.function.positionalParameters, isEmpty);
- expect(stub.function.namedParameters, isEmpty);
- expect(stub.function.typeParameters, isEmpty);
- expect(stub.function.requiredParameterCount, 0);
- expect(stub.function.returnType, const VoidType());
- var body = stub.function.body as ReturnStatement;
- var expression = body.expression as SuperMethodInvocation;
- expect(expression.name, method.name);
- expect(expression.interfaceTarget, same(method));
- expect(expression.arguments.positional, isEmpty);
- expect(expression.arguments.named, isEmpty);
- expect(expression.arguments.types, isEmpty);
- }
-
- void test_createForwardingStub_substitute() {
- // class C<T> { T foo(T x, {T y}); }
- var T = new TypeParameter('T', objectType);
- var x =
- new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
- var y =
- new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(T));
- var method = makeEmptyMethod(
- positionalParameters: [x],
- namedParameters: [y],
- returnType: new TypeParameterType(T));
- var substitution = Substitution.fromPairs([T], [intType]);
- var stub = makeForwardingStub(method, false, substitution: substitution);
- expect(stub.function.positionalParameters[0].type, intType);
- expect(stub.function.namedParameters[0].type, intType);
- expect(stub.function.returnType, intType);
- }
-
- void test_createForwardingStub_typeParameter() {
- var typeParameter = new TypeParameter('T', numType);
- var method = makeEmptyMethod(typeParameters: [typeParameter]);
- var stub = makeForwardingStub(method, false);
- expect(stub.function.typeParameters, hasLength(1));
- expect(stub.function.typeParameters[0].name, 'T');
- expect(stub.function.typeParameters[0].bound, numType);
- var arguments = ((stub.function.body as ReturnStatement).expression
- as SuperMethodInvocation)
- .arguments;
- expect(arguments.types, hasLength(1));
- var typeArgument = arguments.types[0] as TypeParameterType;
- expect(typeArgument.parameter, same(stub.function.typeParameters[0]));
- expect(typeArgument.promotedBound, isNull);
- }
-
- void test_createForwardingStub_typeParameter_and_substitution() {
- // class C<T> { void foo<U>(T x, U y); }
- var T = new TypeParameter('T', objectType);
- var U = new TypeParameter('U', objectType);
- var x =
- new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
- var y =
- new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(U));
- var method =
- makeEmptyMethod(typeParameters: [U], positionalParameters: [x, y]);
- var substitution = Substitution.fromPairs([T], [intType]);
- var stub = makeForwardingStub(method, false, substitution: substitution);
- expect(stub.function.positionalParameters[0].type, intType);
- var stubYType =
- stub.function.positionalParameters[1].type as TypeParameterType;
- expect(stubYType.parameter, same(stub.function.typeParameters[0]));
- }
-
- void test_createForwardingStub_typeParameter_substituteUses() {
- // class C { void foo<T>(T x); }
- var typeParameter = new TypeParameter('T', objectType);
- var param = new VariableDeclarationJudgment('x', 0,
- type: new TypeParameterType(typeParameter));
- var method = makeEmptyMethod(
- typeParameters: [typeParameter], positionalParameters: [param]);
- var stub = makeForwardingStub(method, false);
- var stubXType =
- stub.function.positionalParameters[0].type as TypeParameterType;
- expect(stubXType.parameter, same(stub.function.typeParameters[0]));
- }
-
- void test_createForwardingStub_typeParameter_substituteUses_fBounded() {
- // class C { void foo<T extends List<T>>(T x); }
- var typeParameter = new TypeParameter('T', null);
- typeParameter.bound =
- new InterfaceType(listClass, [new TypeParameterType(typeParameter)]);
- var param = new VariableDeclarationJudgment('x', 0,
- type: new TypeParameterType(typeParameter));
- var method = makeEmptyMethod(
- typeParameters: [typeParameter], positionalParameters: [param]);
- var stub = makeForwardingStub(method, false);
- var stubTypeParameter = stub.function.typeParameters[0];
- var stubTypeParameterBound = stubTypeParameter.bound as InterfaceType;
- var stubTypeParameterBoundArg =
- stubTypeParameterBound.typeArguments[0] as TypeParameterType;
- expect(stubTypeParameterBoundArg.parameter, same(stubTypeParameter));
- var stubXType =
- stub.function.positionalParameters[0].type as TypeParameterType;
- expect(stubXType.parameter, same(stubTypeParameter));
- }
-
- void test_direct_isGenericCovariant() {
- var typeParameter = new TypeParameter('T', objectType);
- var u = new TypeParameter('U', new TypeParameterType(typeParameter))
- ..isGenericCovariantImpl = true;
- var x = new VariableDeclarationJudgment('x', 0,
- type: new TypeParameterType(typeParameter));
- var y = new VariableDeclarationJudgment('y', 0,
- type: new TypeParameterType(typeParameter));
- var method = makeEmptyMethod(
- typeParameters: [u], positionalParameters: [x], namedParameters: [y]);
- var class_ =
- makeClass(typeParameters: [typeParameter], procedures: [method]);
- var node = getForwardingNode(class_, false);
- ShadowClass.setBuilder(class_, null);
- var resolvedMethod = node.finalize();
- expect(resolvedMethod, same(method));
- expect(u.isGenericCovariantImpl, isTrue);
- expect(x.isGenericCovariantImpl, isTrue);
- expect(x.isCovariant, isFalse);
- expect(y.isGenericCovariantImpl, isTrue);
- expect(y.isCovariant, isFalse);
- }
-
- void test_direct_isGenericCovariant_field() {
- var typeParameter = new TypeParameter('T', objectType);
- var field = makeField(type: new TypeParameterType(typeParameter));
- var class_ = makeClass(typeParameters: [typeParameter], fields: [field]);
- var node = getForwardingNode(class_, true);
- ShadowClass.setBuilder(class_, null);
- var resolvedAccessor = node.finalize() as SyntheticAccessor;
- expect(SyntheticAccessor.getField(resolvedAccessor), same(field));
- expect(field.isGenericCovariantImpl, isTrue);
- expect(field.isCovariant, isFalse);
- }
-
- void test_field_isCovariant_inherited() {
- var fieldA = makeField(type: numType)..isCovariant = true;
- var fieldB = makeField(type: numType);
- var a = makeClass(name: 'A', fields: [fieldA]);
- var b = makeClass(
- name: 'B', implementedTypes: [a.asThisSupertype], fields: [fieldB]);
- var node = getForwardingNode(b, true);
- var resolvedAccessor = node.finalize() as SyntheticAccessor;
- expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
- expect(fieldB.isGenericCovariantImpl, isFalse);
- expect(fieldB.isCovariant, isTrue);
- }
-
- void test_field_isGenericCovariantImpl_inherited() {
- var typeParameter = new TypeParameter('T', objectType);
- var fieldA = makeField(type: new TypeParameterType(typeParameter))
- ..isGenericCovariantImpl = true;
- var fieldB = makeField(type: numType);
- var a =
- makeClass(name: 'A', typeParameters: [typeParameter], fields: [fieldA]);
- var b = makeClass(name: 'B', implementedTypes: [
- new Supertype(a, [numType])
- ], fields: [
- fieldB
- ]);
- var node = getForwardingNode(b, true);
- var resolvedAccessor = node.finalize() as SyntheticAccessor;
- expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
- expect(fieldB.isGenericCovariantImpl, isTrue);
- expect(fieldB.isCovariant, isFalse);
- }
-
- void test_forwardingNodes_multiple() {
- var methodAf = makeEmptyMethod(name: 'f');
- var methodBf = makeEmptyMethod(name: 'f');
- var methodAg = makeEmptyMethod(name: 'g');
- var methodBg = makeEmptyMethod(name: 'g');
- var a = makeClass(name: 'A', procedures: [methodAf, methodAg]);
- var b = makeClass(
- name: 'B',
- supertype: a.asThisSupertype,
- procedures: [methodBf, methodBg]);
- var forwardingNodes = getForwardingNodes(b, false);
- expect(forwardingNodes, hasLength(2));
- var nodef = ClassHierarchy.findMemberByName(forwardingNodes, methodAf.name);
- var nodeg = ClassHierarchy.findMemberByName(forwardingNodes, methodAg.name);
- expect(nodef, isNot(same(nodeg)));
- expect(nodef.parent, b);
- expect(nodeg.parent, b);
- {
- var candidates = ForwardingNode.getCandidates(nodef);
- expect(candidates, hasLength(2));
- expect(candidates[0], same(methodBf));
- expect(candidates[1], same(methodAf));
- }
- {
- var candidates = ForwardingNode.getCandidates(nodeg);
- expect(candidates, hasLength(2));
- expect(candidates[0], same(methodBg));
- expect(candidates[1], same(methodAg));
- }
- }
-
- void test_forwardingNodes_single() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(
- name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
- var forwardingNodes = getForwardingNodes(b, false);
- expect(forwardingNodes, hasLength(1));
- expect(forwardingNodes[0].parent, b);
- expect(forwardingNodes[0].name, methodA.name);
- var candidates = ForwardingNode.getCandidates(forwardingNodes[0]);
- expect(candidates, hasLength(2));
- expect(candidates[0], same(methodB));
- expect(candidates[1], same(methodA));
- }
-
- void test_forwardingStub_isCovariant_inherited() {
- var methodA = makeEmptyMethod(positionalParameters: [
- new VariableDeclarationJudgment('x', 0, type: numType)
- ], namedParameters: [
- new VariableDeclarationJudgment('y', 0, type: numType)
- ]);
- var methodB = makeEmptyMethod(positionalParameters: [
- new VariableDeclarationJudgment('x', 0, type: intType)..isCovariant = true
- ], namedParameters: [
- new VariableDeclarationJudgment('y', 0, type: intType)..isCovariant = true
- ]);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C',
- supertype: a.asThisSupertype,
- implementedTypes: [b.asThisSupertype]);
- var node = getForwardingNode(c, false);
- var stub = node.finalize();
- var x = stub.function.positionalParameters[0];
- expect(x.isGenericCovariantImpl, isFalse);
- expect(x.isCovariant, isTrue);
- var y = stub.function.namedParameters[0];
- expect(y.isGenericCovariantImpl, isFalse);
- expect(y.isCovariant, isTrue);
- expect(stub.forwardingStubInterfaceTarget, same(methodA));
- expect(getStubTarget(stub), same(methodA));
- }
-
- void test_forwardingStub_isGenericCovariantImpl_inherited() {
- var methodA = makeEmptyMethod(typeParameters: [
- new TypeParameter('U', numType)
- ], positionalParameters: [
- new VariableDeclarationJudgment('x', 0, type: numType)
- ], namedParameters: [
- new VariableDeclarationJudgment('y', 0, type: numType)
- ]);
- var typeParameterB = new TypeParameter('T', objectType);
- var methodB = makeEmptyMethod(typeParameters: [
- new TypeParameter('U', new TypeParameterType(typeParameterB))
- ..isGenericCovariantImpl = true
- ], positionalParameters: [
- new VariableDeclarationJudgment('x', 0,
- type: new TypeParameterType(typeParameterB))
- ..isGenericCovariantImpl = true
- ], namedParameters: [
- new VariableDeclarationJudgment('y', 0,
- type: new TypeParameterType(typeParameterB))
- ..isGenericCovariantImpl = true
- ]);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(
- name: 'B', typeParameters: [typeParameterB], procedures: [methodB]);
- var c =
- makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
- new Supertype(b, [numType])
- ]);
- var node = getForwardingNode(c, false);
- var stub = node.finalize();
- var u = stub.function.typeParameters[0];
- expect(u.isGenericCovariantImpl, isTrue);
- var x = stub.function.positionalParameters[0];
- expect(x.isGenericCovariantImpl, isTrue);
- expect(x.isCovariant, isFalse);
- var y = stub.function.namedParameters[0];
- expect(y.isGenericCovariantImpl, isTrue);
- expect(y.isCovariant, isFalse);
- expect(stub.forwardingStubInterfaceTarget, same(methodA));
- expect(getStubTarget(stub), same(methodA));
- }
-
- void test_interfaceTarget_cascaded() {
- var methodC = makeEmptyMethod(positionalParameters: [
- new VariableDeclaration('x', type: intType),
- new VariableDeclaration('y', type: intType)
- ]);
- var c = makeClass(name: 'C', procedures: [methodC]);
- var t = new TypeParameter('T', objectType);
- var methodI1 = makeEmptyMethod(positionalParameters: [
- new VariableDeclaration('x', type: new TypeParameterType(t))
- ..isGenericCovariantImpl = true,
- new VariableDeclaration('y', type: intType)
- ]);
- var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [methodI1]);
- // Let's say D was previously compiled, so it already has a forwarding stub
- var d =
- makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
- new Supertype(i1, [intType])
- ]);
- var nodeD = getForwardingNode(d, false);
- var methodD = ForwardingNode.createForwardingStubForTesting(
- nodeD, Substitution.empty, methodC);
- d.addMember(methodD);
- ForwardingNode.createForwardingImplIfNeededForTesting(
- nodeD, methodD.function);
- // To ensure that we don't accidentally make use of information that was
- // computed prior to adding the forwarding stub, reset the interface
- // resolver.
- resetInterfaceResolver();
- var u = new TypeParameter('U', objectType);
- var methodI2 = makeEmptyMethod(positionalParameters: [
- new VariableDeclaration('x', type: intType),
- new VariableDeclaration('y', type: new TypeParameterType(u))
- ..isGenericCovariantImpl = true
- ]);
- var i2 = makeClass(name: 'I2', typeParameters: [u], procedures: [methodI2]);
- var e =
- makeClass(name: 'E', supertype: d.asThisSupertype, implementedTypes: [
- new Supertype(i2, [intType])
- ]);
- var nodeE = getForwardingNode(e, false);
- var stub = nodeE.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(methodC));
- expect(getStubTarget(stub), same(methodC));
- }
-
- void test_interfaceTarget_cascaded_setter() {
- var setterC = makeSetter(setterType: intType);
- var c = makeClass(name: 'C', procedures: [setterC]);
- var t = new TypeParameter('T', objectType);
- var setterI1 = makeSetter(setterType: new TypeParameterType(t));
- var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [setterI1]);
- // Let's say D was previously compiled, so it already has a forwarding stub
- var d =
- makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
- new Supertype(i1, [intType])
- ]);
- var nodeD = getForwardingNode(d, true);
- var setterD = ForwardingNode.createForwardingStubForTesting(
- nodeD, Substitution.empty, setterC);
- d.addMember(setterD);
- ForwardingNode.createForwardingImplIfNeededForTesting(
- nodeD, setterD.function);
- // To ensure that we don't accidentally make use of information that was
- // computed prior to adding the forwarding stub, reset the interface
- // resolver.
- resetInterfaceResolver();
- var setterI2 = makeSetter(setterType: intType, isCovariant: true);
- var i2 = makeClass(name: 'I2', procedures: [setterI2]);
- var e = makeClass(
- name: 'E',
- supertype: d.asThisSupertype,
- implementedTypes: [i2.asThisSupertype]);
- var nodeE = getForwardingNode(e, true);
- var stub = nodeE.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(setterC));
- expect(getStubTarget(stub), same(setterC));
- }
-
- void test_interfaceTarget_field() {
- var fieldA = makeField(type: numType, isFinal: true);
- var fieldB = makeField(type: intType, isFinal: true);
- var a = makeClass(name: 'A', fields: [fieldA]);
- var b = makeClass(name: 'B', fields: [fieldB]);
- var c = makeClass(
- name: 'C',
- supertype: a.asThisSupertype,
- implementedTypes: [b.asThisSupertype]);
- var node = getForwardingNode(c, false);
- var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(fieldB));
- }
-
- void test_merge_candidates_including_mixin() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var methodC = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(name: 'C', procedures: [methodC]);
- var d = makeClass(
- name: 'D',
- supertype: a.asThisSupertype,
- mixedInType: b.asThisSupertype,
- implementedTypes: [c.asThisSupertype]);
- var candidates = getCandidates(d, false);
- expect(candidates, hasLength(3));
- expect(candidates[0], same(methodB));
- expect(candidates[1], same(methodA));
- expect(candidates[2], same(methodC));
- }
-
- void test_merge_candidates_not_including_mixin() {
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var methodC = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C',
- supertype: a.asThisSupertype,
- implementedTypes: [b.asThisSupertype],
- procedures: [methodC]);
- var candidates = getCandidates(c, false);
- expect(candidates, hasLength(3));
- expect(candidates[0], same(methodC));
- expect(candidates[1], same(methodA));
- expect(candidates[2], same(methodB));
- }
-
- void test_resolve_directly_declared() {
- var parameterA = new VariableDeclarationJudgment('x', 0,
- type: objectType, isCovariant: true);
- var methodA = makeEmptyMethod(positionalParameters: [parameterA]);
- var parameterB = new VariableDeclarationJudgment('x', 0,
- type: intType, isCovariant: true);
- var methodB = makeEmptyMethod(positionalParameters: [parameterB]);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(
- name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
- var node = getForwardingNode(b, false);
- expect(node.finalize(), same(methodB));
- }
-
- void test_resolve_favor_first() {
- // When multiple methods have equivalent types, favor the first one.
- var methodA = makeEmptyMethod();
- var methodB = makeEmptyMethod();
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
- var node = getForwardingNode(c, false);
- expect(node.finalize(), same(methodA));
- }
-
- void test_resolve_field() {
- var field = makeField();
- var a = makeClass(name: 'A', fields: [field]);
- var b = makeClass(name: 'B', supertype: a.asThisSupertype);
- var node = getForwardingNode(b, false);
- var accessor = node.finalize() as SyntheticAccessor;
- expect(SyntheticAccessor.getField(accessor), same(field));
- }
-
- void test_resolve_first() {
- var methodA = makeEmptyMethod(returnType: intType);
- var methodB = makeEmptyMethod(returnType: numType);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
- var node = getForwardingNode(c, false);
- expect(node.finalize(), same(methodA));
- }
-
- void test_resolve_second() {
- var methodA = makeEmptyMethod(returnType: numType);
- var methodB = makeEmptyMethod(returnType: intType);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(name: 'B', procedures: [methodB]);
- var c = makeClass(
- name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
- var node = getForwardingNode(c, false);
- var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(methodB));
- expect(getStubTarget(stub), isNull);
- expect(stub.function.returnType, intType);
- }
-
- void test_resolve_setters() {
- var setterA = makeSetter(setterType: intType);
- var setterB = makeSetter(setterType: objectType);
- var setterC = makeSetter(setterType: numType);
- var a = makeClass(name: 'A', procedures: [setterA]);
- var b = makeClass(name: 'B', procedures: [setterB]);
- var c = makeClass(name: 'C', procedures: [setterC]);
- var d = makeClass(name: 'D', implementedTypes: [
- a.asThisSupertype,
- b.asThisSupertype,
- c.asThisSupertype
- ]);
- var node = getForwardingNode(d, true);
- var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(setterB));
- expect(getStubTarget(stub), isNull);
- expect(stub.function.positionalParameters[0].type, objectType);
- }
-
- void test_resolve_with_added_implementation() {
- var methodA = makeEmptyMethod(positionalParameters: [
- new VariableDeclarationJudgment('x', 0, type: numType)
- ]);
- var typeParamB = new TypeParameter('T', objectType);
- var methodB = makeEmptyMethod(positionalParameters: [
- new VariableDeclarationJudgment('x', 0,
- type: new TypeParameterType(typeParamB))
- ..isGenericCovariantImpl = true
- ]);
- var methodC = makeEmptyMethod(positionalParameters: [
- new VariableDeclarationJudgment('x', 0, type: numType)
- ], isAbstract: true);
- var a = makeClass(name: 'A', procedures: [methodA]);
- var b = makeClass(
- name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
- var c =
- makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
- new Supertype(b, [numType])
- ], procedures: [
- methodC
- ]);
- var node = getForwardingNode(c, false);
- expect(methodC.function.body, isNull);
- var resolvedMethod = node.finalize();
- expect(resolvedMethod, same(methodC));
- expect(methodC.function.body, isNotNull);
- expect(methodC.forwardingStubInterfaceTarget, isNull);
- expect(getStubTarget(methodC), same(methodA));
- }
-
- void test_resolve_with_substitutions() {
- var typeParamA = new TypeParameter('T', objectType);
- var typeParamB = new TypeParameter('T', objectType);
- var typeParamC = new TypeParameter('T', objectType);
- var methodA =
- makeEmptyMethod(returnType: new TypeParameterType(typeParamA));
- var methodB =
- makeEmptyMethod(returnType: new TypeParameterType(typeParamB));
- var methodC =
- makeEmptyMethod(returnType: new TypeParameterType(typeParamC));
- var a = makeClass(
- name: 'A', typeParameters: [typeParamA], procedures: [methodA]);
- var b = makeClass(
- name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
- var c = makeClass(
- name: 'C', typeParameters: [typeParamC], procedures: [methodC]);
- var d = makeClass(
- name: 'D',
- supertype: new Supertype(a, [objectType]),
- implementedTypes: [
- new Supertype(b, [intType]),
- new Supertype(c, [numType])
- ]);
- var node = getForwardingNode(d, false);
- var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget, same(methodB));
- expect(getStubTarget(stub), isNull);
- expect(stub.function.returnType, intType);
- }
-}
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 6d92bac..128559f 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
@@ -161,14 +161,14 @@
} else if (kernelArguments.length != typeVariables.length) {
throw "Expected ${typeVariables.length} type arguments: $node";
}
- return new InterfaceType(declaration, kernelArguments);
+ return new InterfaceType(declaration, kernelArguments, node.nullability);
} else if (declaration is TypeParameter) {
if (arguments.isNotEmpty) {
throw "Type variable can't have arguments (${node.name})";
}
- return new TypeParameterType(declaration);
+ return new TypeParameterType(declaration, null, node.nullability);
} else if (declaration is Typedef) {
- return new TypedefType(declaration, kernelArguments);
+ return new TypedefType(declaration, kernelArguments, node.nullability);
} else {
throw "Unhandled ${declaration.runtimeType}";
}
@@ -263,7 +263,8 @@
return new FunctionType(positionalParameters, returnType,
namedParameters: namedParameters,
requiredParameterCount: node.arguments.required.length,
- typeParameters: parameterEnvironment.parameters);
+ typeParameters: parameterEnvironment.parameters,
+ nullability: node.nullability);
}
VoidType visitVoidType(ParsedVoidType node, KernelEnvironment environment) {
@@ -280,7 +281,7 @@
TypeParameterType type =
node.a.accept<Node, KernelEnvironment>(this, environment);
DartType bound = node.b.accept<Node, KernelEnvironment>(this, environment);
- return new TypeParameterType(type.parameter, bound);
+ return new TypeParameterType(type.parameter, bound, type.nullability);
}
Supertype toSupertype(InterfaceType type) {
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index 2911257..37a45fd 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -412,5 +412,16 @@
isSubtype("({int c, int b, int a}) -> void", "({int b, int c}) -> void");
isSubtype("({int a, int b, int c}) -> void", "({int c}) -> void");
isSubtype("({int c, int b, int a}) -> void", "({int c}) -> void");
+
+ // Parsing of nullable and legacy types.
+ isSubtype("int?", "int?");
+ isSubtype("int*", "int*");
+ isSubtype("(int) ->? int", "(int) ->? int");
+ isSubtype("(int) ->* int", "(int) ->* int");
+ isSubtype("(int, int*, int?) -> int?", "(int, int*, int?) -> int?");
+ isSubtype("List<int>?", "List<int>?");
+ isSubtype("List<int?>?", "List<int?>?");
+ isSubtype("T & int?", "T & int?", typeParameters: "T extends Object?");
+ isSubtype("T? & int?", "T? & int?", typeParameters: "T extends Object");
}
}
diff --git a/pkg/front_end/test/fasta/types/type_parser.dart b/pkg/front_end/test/fasta/types/type_parser.dart
index 89a21b7..9a6281e 100644
--- a/pkg/front_end/test/fasta/types/type_parser.dart
+++ b/pkg/front_end/test/fasta/types/type_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.
+import "package:kernel/ast.dart" show Nullability;
+
import "package:front_end/src/fasta/scanner.dart" show scanString, Token;
import "package:front_end/src/fasta/parser/type_info_impl.dart"
@@ -16,7 +18,9 @@
final List<ParsedType> arguments;
- ParsedInterfaceType(this.name, this.arguments);
+ final Nullability nullability;
+
+ ParsedInterfaceType(this.name, this.arguments, this.nullability);
String toString() {
StringBuffer sb = new StringBuffer();
@@ -116,7 +120,10 @@
final ParsedArguments arguments;
- ParsedFunctionType(this.typeVariables, this.returnType, this.arguments);
+ final Nullability nullability;
+
+ ParsedFunctionType(
+ this.typeVariables, this.returnType, this.arguments, this.nullability);
String toString() {
StringBuffer sb = new StringBuffer();
@@ -260,6 +267,16 @@
}
}
+ Nullability parseNullability() {
+ Nullability result = Nullability.nonNullable;
+ if (optionalAdvance("?")) {
+ result = Nullability.nullable;
+ } else if (optionalAdvance("*")) {
+ result = Nullability.legacy;
+ }
+ return result;
+ }
+
ParsedType parseType() {
if (optional("class")) return parseClass();
if (optional("typedef")) return parseTypedef();
@@ -269,7 +286,9 @@
if (optional("(") || optional("<")) {
type = parseFunctionType();
} else if (optionalAdvance("void")) {
- type = new ParsedInterfaceType("void", <ParsedType>[]);
+ type = new ParsedInterfaceType(
+ "void", <ParsedType>[], Nullability.nullable);
+ optionalAdvance("?");
} else {
String name = parseName();
List<ParsedType> arguments = <ParsedType>[];
@@ -283,7 +302,8 @@
peek = splitCloser(peek) ?? peek;
expect(">");
}
- type = new ParsedInterfaceType(name, arguments);
+ Nullability nullability = parseNullability();
+ type = new ParsedInterfaceType(name, arguments, nullability);
}
if (result == null) {
result = type;
@@ -304,8 +324,10 @@
ParsedArguments arguments = parseArguments();
expect("-");
expect(">");
+ Nullability nullability = parseNullability();
ParsedType returnType = parseReturnType();
- return new ParsedFunctionType(typeVariables, returnType, arguments);
+ return new ParsedFunctionType(
+ typeVariables, returnType, arguments, nullability);
}
String parseName() {
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
index c39739d..93c39b2 100644
--- a/pkg/front_end/test/incremental_bulk_compiler_full.dart
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -51,7 +51,7 @@
IncrementalCompiler compiler;
}
-CompilerOptions getOptions(bool strong) {
+CompilerOptions getOptions() {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
var options = new CompilerOptions()
..sdkRoot = sdkRoot
@@ -59,13 +59,8 @@
..omitPlatform = true
..onDiagnostic = (DiagnosticMessage message) {
// Ignored.
- }
- ..legacyMode = !strong;
- if (strong) {
- options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
- } else {
- options.sdkSummary = sdkRoot.resolve("vm_platform.dill");
- }
+ };
+ options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
return options;
}
@@ -83,7 +78,7 @@
List<int> oneShotSerialized;
try {
IncrementalCompiler compiler =
- new IncrementalKernelGenerator(getOptions(true), uri);
+ new IncrementalKernelGenerator(getOptions(), uri);
oneShotSerialized = util.postProcess(await compiler.computeDelta());
} catch (e) {
oneShotFailed = true;
@@ -95,8 +90,7 @@
try {
globalDebuggingNames = new NameSystem();
if (context.compiler == null) {
- context.compiler =
- new IncrementalKernelGenerator(getOptions(true), uri);
+ context.compiler = new IncrementalKernelGenerator(getOptions(), uri);
}
Component bulkCompiledComponent = await context.compiler
.computeDelta(entryPoints: [uri], fullComponent: true);
@@ -111,8 +105,7 @@
try {
globalDebuggingNames = new NameSystem();
if (context.compiler == null) {
- context.compiler =
- new IncrementalKernelGenerator(getOptions(true), uri);
+ context.compiler = new IncrementalKernelGenerator(getOptions(), uri);
}
Component bulkCompiledComponent = await context.compiler
.computeDelta(entryPoints: [uri], fullComponent: true);
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 cf270cb..f1469a1 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
@@ -3,16 +3,21 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async' show Future;
+
import 'dart:io' show Directory, File;
import 'package:expect/expect.dart' show Expect;
+
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
+
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+
import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/target/targets.dart';
import 'incremental_load_from_dill_test.dart'
- show normalCompile, initializedCompile, checkIsEqual;
+ show checkIsEqual, getOptions, initializedCompile, normalCompile;
Directory outDir;
@@ -36,13 +41,16 @@
Uri nonexisting = outDir.uri.resolve("dart2js.nonexisting.dill");
// Compile dart2js without initializing from dill.
+ // Note: Use none-target to avoid mismatches in "interface target" caused by
+ // type inference occurring before or after mixin transformation.
Stopwatch stopwatch = new Stopwatch()..start();
- await normalCompile(dart2jsUrl, normalDill);
+ await normalCompile(dart2jsUrl, normalDill,
+ options: getOptions()..target = new NoneTarget(new TargetFlags()));
print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
{
// Check that we don't include the source from files from the sdk.
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
- Uri platformUri = sdkRoot.resolve("vm_platform.dill");
+ Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
Component cSdk = new Component();
new BinaryBuilder(new File.fromUri(platformUri).readAsBytesSync(),
disableLazyReading: false)
@@ -65,7 +73,7 @@
}
// Compile dart2js, initializing from the just-compiled dill,
- // a nonexisting file and a dill file that isn't valid.
+ // a nonexisting file.
for (List<Object> initializationData in [
[normalDill, true],
[nonexisting, false],
@@ -74,7 +82,8 @@
bool initializeExpect = initializationData[1];
stopwatch.reset();
bool initializeResult = await initializedCompile(
- dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri]);
+ dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri],
+ options: getOptions()..target = new NoneTarget(new TargetFlags()));
Expect.equals(initializeResult, initializeExpect);
print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
"took ${stopwatch.elapsedMilliseconds} ms");
@@ -88,7 +97,8 @@
// Also try without invalidating anything.
stopwatch.reset();
initializeResult = await initializedCompile(
- dart2jsUrl, fullDillFromInitialized, initializeWith, []);
+ dart2jsUrl, fullDillFromInitialized, initializeWith, [],
+ options: getOptions()..target = new NoneTarget(new TargetFlags()));
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 a2ec791..3c68a61 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -116,14 +116,12 @@
await basicTest(
map["sources"],
map["entry"],
- map["strong"],
map["invalidate"],
data.outDir,
);
break;
case "newworld":
await newWorldTest(
- map["strong"],
map["worlds"],
map["modules"],
map["omitPlatform"],
@@ -136,7 +134,7 @@
}
}
-Future<Null> basicTest(YamlMap sourceFiles, String entryPoint, bool strong,
+Future<Null> basicTest(YamlMap sourceFiles, String entryPoint,
YamlList invalidate, Directory outDir) async {
Uri entryPointUri = outDir.uri.resolve(entryPoint);
Set<String> invalidateFilenames =
@@ -169,7 +167,7 @@
Uri initializedOutput = outDir.uri.resolve("full_from_initialized.dill");
Stopwatch stopwatch = new Stopwatch()..start();
- CompilerOptions options = getOptions(strong);
+ CompilerOptions options = getOptions();
if (packagesUri != null) {
options.packagesFileUri = packagesUri;
}
@@ -177,7 +175,7 @@
print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
stopwatch.reset();
- options = getOptions(strong);
+ options = getOptions();
if (packagesUri != null) {
options.packagesFileUri = packagesUri;
}
@@ -196,7 +194,7 @@
}
Future<Map<String, List<int>>> createModules(
- Map module, final List<int> sdkSummaryData, bool strong) async {
+ Map module, final List<int> sdkSummaryData) async {
final Uri base = Uri.parse("org-dartlang-test:///");
final Uri sdkSummary = base.resolve("vm_platform.dill");
@@ -227,7 +225,7 @@
moduleSources.add(uri);
}
}
- CompilerOptions options = getOptions(strong);
+ CompilerOptions options = getOptions();
options.fileSystem = fs;
options.sdkRoot = null;
options.sdkSummary = sdkSummary;
@@ -261,18 +259,12 @@
return moduleResult;
}
-Future<Null> newWorldTest(
- bool strong, List worlds, Map modules, bool omitPlatform) async {
+Future<Null> newWorldTest(List worlds, Map modules, bool omitPlatform) async {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
final Uri base = Uri.parse("org-dartlang-test:///");
final Uri sdkSummary = base.resolve("vm_platform.dill");
final Uri initializeFrom = base.resolve("initializeFrom.dill");
- Uri platformUri;
- if (strong) {
- platformUri = sdkRoot.resolve("vm_platform_strong.dill");
- } else {
- platformUri = sdkRoot.resolve("vm_platform.dill");
- }
+ Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
final List<int> sdkSummaryData =
await new File.fromUri(platformUri).readAsBytes();
@@ -287,7 +279,7 @@
Map<String, Component> moduleComponents;
Component sdk;
if (modules != null) {
- moduleData = await createModules(modules, sdkSummaryData, strong);
+ moduleData = await createModules(modules, sdkSummaryData);
sdk = newestWholeComponent = new Component();
new BinaryBuilder(sdkSummaryData, filename: null, disableLazyReading: false)
.readComponent(newestWholeComponent);
@@ -368,7 +360,7 @@
}
if (brandNewWorld) {
- options = getOptions(strong);
+ options = getOptions();
options.fileSystem = fs;
options.sdkRoot = null;
options.sdkSummary = sdkSummary;
@@ -745,11 +737,11 @@
Expect.equals(a.length, b.length);
}
-CompilerOptions getOptions(bool strong) {
+CompilerOptions getOptions() {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
CompilerOptions options = new CompilerOptions()
..sdkRoot = sdkRoot
- ..target = new VmTarget(new TargetFlags(legacyMode: !strong))
+ ..target = new VmTarget(new TargetFlags())
..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
..omitPlatform = true
..onDiagnostic = (DiagnosticMessage message) {
@@ -758,19 +750,14 @@
Expect.fail(
"Unexpected error: ${message.plainTextFormatted.join('\n')}");
}
- }
- ..legacyMode = !strong;
- if (strong) {
- options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
- } else {
- options.sdkSummary = sdkRoot.resolve("vm_platform.dill");
- }
+ };
+ options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
return options;
}
Future<bool> normalCompile(Uri input, Uri output,
{CompilerOptions options}) async {
- options ??= getOptions(false);
+ options ??= getOptions();
TestIncrementalCompiler compiler =
new TestIncrementalCompiler(options, input);
Component component = await compiler.computeDelta();
@@ -783,7 +770,7 @@
Future<bool> initializedCompile(
Uri input, Uri output, Uri initializeWith, List<Uri> invalidateUris,
{CompilerOptions options}) async {
- options ??= getOptions(false);
+ options ??= getOptions();
TestIncrementalCompiler compiler =
new TestIncrementalCompiler(options, input, initializeWith);
for (Uri invalidateUri in invalidateUris) {
diff --git a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
index 0d9a84e..f108317 100644
--- a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
@@ -132,7 +132,7 @@
errorMessages = <DiagnosticMessage>[];
warningMessages = <DiagnosticMessage>[];
fs = new MemoryFileSystem(base);
- options = getOptions(true);
+ options = getOptions();
options.fileSystem = fs;
options.sdkRoot = null;
diff --git a/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
index 231e9e1..99a7137 100644
--- a/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
@@ -288,7 +288,7 @@
Object._simpleInstanceOf
B.bMethod
Object._instanceOf
- MyMock1.noSuchMethod
+ MyMock2.MyMock1.noSuchMethod%MyMock2.noSuchMethod
A.abstractMethod
Object._identityHashCode
Object.hashCode
@@ -308,7 +308,7 @@
Object._simpleInstanceOf
B.bMethod
Object._instanceOf
- MyMock1.noSuchMethod
+ MyMock2.MyMock1.noSuchMethod%MyMock2.noSuchMethod
A.abstractMethod
Interface1.interfaceMethod1
Object._identityHashCode
@@ -338,7 +338,7 @@
Object._simpleInstanceOf
B.bMethod
Object._instanceOf
- Object.noSuchMethod
+ MyMock3.Object.noSuchMethod%MyMock3.noSuchMethod
A.abstractMethod
Object._identityHashCode
Object.hashCode
@@ -358,7 +358,7 @@
Object._simpleInstanceOf
B.bMethod
Object._instanceOf
- Object.noSuchMethod
+ MyMock3.Object.noSuchMethod%MyMock3.noSuchMethod
A.abstractMethod
Interface1.interfaceMethod1
Object._identityHashCode
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
index 5a3c3d0..0322fcb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
@@ -194,7 +194,7 @@
synthetic constructor •() → self::MyMock1
: super self::B::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return null;
no-such-method-forwarder method interfaceMethod2() → void
return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -217,13 +217,13 @@
synthetic constructor •() → self::MyMock2
: super self::MyMock1::•()
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
}
class MyMock3 extends self::B {
synthetic constructor •() → self::MyMock3
: super self::B::•()
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
no-such-method-forwarder get interfaceMethod1() → dynamic
return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
index 5a3c3d0..0322fcb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
@@ -194,7 +194,7 @@
synthetic constructor •() → self::MyMock1
: super self::B::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return null;
no-such-method-forwarder method interfaceMethod2() → void
return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -217,13 +217,13 @@
synthetic constructor •() → self::MyMock2
: super self::MyMock1::•()
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
}
class MyMock3 extends self::B {
synthetic constructor •() → self::MyMock3
: super self::B::•()
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
no-such-method-forwarder get interfaceMethod1() → dynamic
return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_members.dart.outline.expect b/pkg/front_end/testcases/abstract_members.dart.outline.expect
index ad1e730..c54c9fb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.outline.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.outline.expect
@@ -197,7 +197,7 @@
class MyMock1 extends self::B {
synthetic constructor •() → self::MyMock1
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
;
no-such-method-forwarder method interfaceMethod2() → void
return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -219,12 +219,12 @@
class MyMock2 extends self::MyMock1 {
synthetic constructor •() → self::MyMock2
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
}
class MyMock3 extends self::B {
synthetic constructor •() → self::MyMock3
;
- abstract method noSuchMethod(dynamic _) → dynamic;
+ abstract method noSuchMethod(core::Invocation _) → dynamic;
no-such-method-forwarder get interfaceMethod1() → dynamic
return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart
new file mode 100644
index 0000000..7bba23c
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.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.
+
+abstract class A {
+ A foo() => null;
+}
+
+abstract class B extends A {
+ B foo();
+}
+
+class C {
+ noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect
new file mode 100644
index 0000000..344af9a
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect
@@ -0,0 +1,105 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.A.foo%B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+D:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> C
+ interfaces: B, A
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.A.foo%B.foo
+ C.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → self::A
+ return null;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ abstract method foo() → self::B;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation _) → dynamic
+ return null;
+}
+class D extends self::C implements self::B {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ no-such-method-forwarder method foo() → self::B
+ return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → self::A
+ return null;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ abstract method foo() → self::B;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation _) → dynamic
+ return null;
+}
+class D extends self::C implements self::B {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ no-such-method-forwarder method foo() → self::B
+ return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect
new file mode 100644
index 0000000..5430c79
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method foo() → self::A
+ ;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+ abstract method foo() → self::B;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ ;
+ method noSuchMethod(core::Invocation _) → dynamic
+ ;
+}
+class D extends self::C implements self::B {
+ synthetic constructor •() → self::D
+ ;
+ no-such-method-forwarder method foo() → self::B
+ return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → self::A
+ return null;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ abstract method foo() → self::B;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation _) → dynamic
+ return null;
+}
+class D extends self::C implements self::B {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ no-such-method-forwarder method foo() → self::B
+ return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo() → self::A
+ return null;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ abstract method foo() → self::B;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation _) → dynamic
+ return null;
+}
+class D extends self::C implements self::B {
+ synthetic constructor •() → self::D
+ : super self::C::•()
+ ;
+ no-such-method-forwarder method foo() → self::B
+ return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart b/pkg/front_end/testcases/await_in_non_async.dart
new file mode 100644
index 0000000..7cbf642
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.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.
+
+main() {
+ foo();
+}
+
+foo() {
+ // ignore: await_in_wrong_context
+ await foo();
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect b/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+// await foo();
+// ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+ self::foo();
+}
+static method foo() → dynamic {
+ invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+ await foo();
+ ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect b/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+// await foo();
+// ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+ self::foo();
+}
+static method foo() → dynamic {
+ invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+ await foo();
+ ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.outline.expect b/pkg/front_end/testcases/await_in_non_async.dart.outline.expect
new file mode 100644
index 0000000..4c2eb20
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method foo() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.strong.expect b/pkg/front_end/testcases/await_in_non_async.dart.strong.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.strong.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+// await foo();
+// ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+ self::foo();
+}
+static method foo() → dynamic {
+ invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+ await foo();
+ ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect b/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+// await foo();
+// ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+ self::foo();
+}
+static method foo() → dynamic {
+ invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+ await foo();
+ ^^^^^";
+}
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
index e84ce6f..f93d1cb 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
@@ -47,13 +47,13 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set a(dynamic #synthetic) → dynamic {
+ set a(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
set a();
^";
;
}
- set d(dynamic #synthetic) → dynamic {
+ set d(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
set d(x, y);
^";
@@ -68,13 +68,13 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- set a(dynamic #synthetic) → dynamic {
+ set a(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
set a();
^";
;
}
- set d(dynamic #synthetic) → dynamic {
+ set d(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
set d(x, y);
^";
@@ -85,13 +85,13 @@
}
}
}
-static set b(dynamic #synthetic) → dynamic {
+static set b(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
set b();
^";
;
}
-static set c(dynamic #synthetic) → dynamic {
+static set c(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
set c(x, y);
^";
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
index e84ce6f..f93d1cb 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
@@ -47,13 +47,13 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set a(dynamic #synthetic) → dynamic {
+ set a(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
set a();
^";
;
}
- set d(dynamic #synthetic) → dynamic {
+ set d(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
set d(x, y);
^";
@@ -68,13 +68,13 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- set a(dynamic #synthetic) → dynamic {
+ set a(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
set a();
^";
;
}
- set d(dynamic #synthetic) → dynamic {
+ set d(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
set d(x, y);
^";
@@ -85,13 +85,13 @@
}
}
}
-static set b(dynamic #synthetic) → dynamic {
+static set b(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
set b();
^";
;
}
-static set c(dynamic #synthetic) → dynamic {
+static set c(dynamic #synthetic) → void {
invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
set c(x, y);
^";
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
index 68dcc4d..65b27e3 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
@@ -18,22 +18,22 @@
class A extends core::Object {
synthetic constructor •() → self::A
;
- set a(dynamic #synthetic) → dynamic
+ set a(dynamic #synthetic) → void
;
- set d(dynamic #synthetic) → dynamic
+ set d(dynamic #synthetic) → void
;
}
abstract class B extends core::Object {
synthetic constructor •() → self::B
;
- set a(dynamic #synthetic) → dynamic
+ set a(dynamic #synthetic) → void
;
- set d(dynamic #synthetic) → dynamic
+ set d(dynamic #synthetic) → void
;
}
-static set b(dynamic #synthetic) → dynamic
+static set b(dynamic #synthetic) → void
;
-static set c(dynamic #synthetic) → dynamic
+static set c(dynamic #synthetic) → void
;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/bug32866.dart.legacy.expect b/pkg/front_end/testcases/bug32866.dart.legacy.expect
index f62f9f6..5cf6726 100644
--- a/pkg/front_end/testcases/bug32866.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug32866.dart.legacy.expect
@@ -9,7 +9,7 @@
abstract get f() → core::String;
}
class A extends core::Object implements self::B {
- final field dynamic f;
+ final field core::String f;
constructor •(dynamic f) → self::A
: self::A::f = f, super core::Object::•()
;
diff --git a/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
index f62f9f6..5cf6726 100644
--- a/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
abstract get f() → core::String;
}
class A extends core::Object implements self::B {
- final field dynamic f;
+ final field core::String f;
constructor •(dynamic f) → self::A
: self::A::f = f, super core::Object::•()
;
diff --git a/pkg/front_end/testcases/bug32866.dart.outline.expect b/pkg/front_end/testcases/bug32866.dart.outline.expect
index 0b51724..c902755 100644
--- a/pkg/front_end/testcases/bug32866.dart.outline.expect
+++ b/pkg/front_end/testcases/bug32866.dart.outline.expect
@@ -8,7 +8,7 @@
abstract get f() → core::String;
}
class A extends core::Object implements self::B {
- final field dynamic f;
+ final field core::String f;
constructor •(dynamic f) → self::A
;
}
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.expect b/pkg/front_end/testcases/bug33206.dart.legacy.expect
index b0dba95..1d53254 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.expect
@@ -11,7 +11,7 @@
constructor •(dynamic x, dynamic y) → self::X
: self::X::x = x, self::X::y = y, super core::Object::•()
;
- method toString() → dynamic
+ method toString() → core::String
return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
}
class Y extends core::Object {
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
index 2a26c19..f484e4b 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
@@ -11,7 +11,7 @@
constructor •(dynamic x, dynamic y) → self::X
: self::X::x = x, self::X::y = y, super core::Object::•()
;
- method toString() → dynamic
+ method toString() → core::String
return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
}
class Y extends core::Object {
diff --git a/pkg/front_end/testcases/bug33206.dart.outline.expect b/pkg/front_end/testcases/bug33206.dart.outline.expect
index 95d83e8..3dd6634 100644
--- a/pkg/front_end/testcases/bug33206.dart.outline.expect
+++ b/pkg/front_end/testcases/bug33206.dart.outline.expect
@@ -10,7 +10,7 @@
final field dynamic y;
constructor •(dynamic x, dynamic y) → self::X
;
- method toString() → dynamic
+ method toString() → core::String
;
}
class Y extends core::Object {
diff --git a/pkg/front_end/testcases/covariant_generic.dart.outline.expect b/pkg/front_end/testcases/covariant_generic.dart.outline.expect
index 4b44219..da79e5c 100644
--- a/pkg/front_end/testcases/covariant_generic.dart.outline.expect
+++ b/pkg/front_end/testcases/covariant_generic.dart.outline.expect
@@ -12,7 +12,7 @@
;
method method(generic-covariant-impl self::Foo::T x) → void
;
- set setter(generic-covariant-impl self::Foo::T x) → dynamic
+ set setter(generic-covariant-impl self::Foo::T x) → void
;
method withCallback((self::Foo::T) → void callback) → void
;
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart
new file mode 100644
index 0000000..d9a1e90
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.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.
+
+// The test checks that 'covariant' bit is propagated from the superclass of the
+// mixin application to the mixin application and its subclasses.
+
+class A {
+ void foo(covariant num x) {}
+}
+
+class B {
+ void foo(num x) {}
+}
+
+class C {
+ void foo(num x) {}
+}
+
+class D extends A with B implements C {
+ // This member declaration shouldn't result in a compile-time error.
+ void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect
new file mode 100644
index 0000000..d9115a1
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect
@@ -0,0 +1,138 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A with B:
+ superclasses:
+ Object
+ -> A
+ interfaces: B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A with B.B.foo%A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A with B.B.foo%A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D:
+ superclasses:
+ Object
+ -> A
+ -> _D&A&B
+ interfaces: B, C
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect
new file mode 100644
index 0000000..17ddb30
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+abstract class _D&A&B = self::A with self::B {
+ synthetic constructor •() → self::_D&A&B
+ : super self::A::•()
+ ;
+ forwarding-stub method foo(covariant core::num x) → void
+ return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect
new file mode 100644
index 0000000..cec0223
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+abstract class _D&A&B extends self::A implements self::B {
+ synthetic constructor •() → self::_D&A&B
+ : super self::A::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class D extends self::_D&A&B implements self::C {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect
new file mode 100644
index 0000000..241bbe0
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method foo(covariant core::num x) → void
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ method foo(core::num x) → void
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ ;
+ method foo(core::num x) → void
+ ;
+}
+abstract class _D&A&B = self::A with self::B {
+ synthetic constructor •() → self::_D&A&B
+ : super self::A::•()
+ ;
+ forwarding-stub method foo(covariant core::num x) → void
+ return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+ synthetic constructor •() → self::D
+ ;
+ method foo(covariant core::int x) → void
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect
new file mode 100644
index 0000000..17ddb30
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+abstract class _D&A&B = self::A with self::B {
+ synthetic constructor •() → self::_D&A&B
+ : super self::A::•()
+ ;
+ forwarding-stub method foo(covariant core::num x) → void
+ return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect
new file mode 100644
index 0000000..cec0223
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ method foo(core::num x) → void {}
+}
+abstract class _D&A&B extends self::A implements self::B {
+ synthetic constructor •() → self::_D&A&B
+ : super self::A::•()
+ ;
+ method foo(covariant core::num x) → void {}
+}
+class D extends self::_D&A&B implements self::C {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/escape.dart.legacy.expect b/pkg/front_end/testcases/escape.dart.legacy.expect
index 389e93a..ec93320 100644
--- a/pkg/front_end/testcases/escape.dart.legacy.expect
+++ b/pkg/front_end/testcases/escape.dart.legacy.expect
@@ -18,7 +18,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- operator ==(dynamic x) → dynamic
+ operator ==(dynamic x) → core::bool
return false;
}
class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/escape.dart.legacy.transformed.expect b/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
index 389e93a..ec93320 100644
--- a/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- operator ==(dynamic x) → dynamic
+ operator ==(dynamic x) → core::bool
return false;
}
class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/escape.dart.outline.expect b/pkg/front_end/testcases/escape.dart.outline.expect
index e98ed5f..1bccd65 100644
--- a/pkg/front_end/testcases/escape.dart.outline.expect
+++ b/pkg/front_end/testcases/escape.dart.outline.expect
@@ -15,7 +15,7 @@
class C extends core::Object {
synthetic constructor •() → self::C
;
- operator ==(dynamic x) → dynamic
+ operator ==(dynamic x) → core::bool
;
}
class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/extension_methods.dart b/pkg/front_end/testcases/extension_methods.dart
new file mode 100644
index 0000000..51013db
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+
+class C {
+ int get one => 1;
+}
+
+extension E on C {
+ int get two => 2;
+}
+
+main() {
+ C c = C();
+ var result = c.one + c.two;
+ Expect.equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect b/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..af7781c
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect
@@ -0,0 +1,418 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ C.one
+ classSetters:
+
+Expect:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Expect.identical
+ Expect.throwsCastError
+ Expect._fail
+ Expect.notIdentical
+ Expect.isNotNull
+ Expect._getMessage
+ Expect.allIdentical
+ Expect._escapeSubstring
+ Expect.fail
+ Expect._truncateString
+ Expect.isFalse
+ Expect.isTrue
+ Object.toString
+ Expect.subtype
+ Expect.throwsRangeError
+ Expect._stringDifference
+ Expect.throwsArgumentError
+ Expect.stringEquals
+ Object.runtimeType
+ Expect.testError
+ Expect.throwsStateError
+ Object._simpleInstanceOf
+ Expect.isNull
+ Expect.approxEquals
+ Expect.equals
+ Object._instanceOf
+ Expect.allDistinct
+ Expect.throwsTypeError
+ Expect._subtypeAtRuntime
+ Expect.setEquals
+ Object.noSuchMethod
+ Expect.notEquals
+ Expect.listEquals
+ Expect._findEquivalences
+ Expect.mapEquals
+ Object._identityHashCode
+ Expect.throwsUnsupportedError
+ Expect.notType
+ Expect.deepEquals
+ Expect._escapeString
+ Expect.type
+ Object.hashCode
+ Expect.throwsNoSuchMethodError
+ Expect.notSubtype
+ Expect.throws
+ Object._simpleInstanceOfFalse
+ Expect._writeEquivalences
+ Expect.throwsAssertionError
+ Object._simpleInstanceOfTrue
+ Object.==
+ Expect.throwsFormatException
+ classSetters:
+
+Exception:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+ExpectException:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Exception
+ classMembers:
+ ExpectException.message
+ ExpectException.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ ExpectException.message
+ ExpectException.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+Immutable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Immutable.reason
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+Required:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Required.reason
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_AlwaysThrows:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Checked:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Experimental:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Factory:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_IsTest:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_IsTestGroup:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Literal:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_MustCallSuper:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_OptionalTypeArgs:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Protected:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Sealed:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_Virtual:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_VisibleForOverriding:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+_VisibleForTesting:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/extension_methods.dart.legacy.expect b/pkg/front_end/testcases/extension_methods.dart.legacy.expect
new file mode 100644
index 0000000..7fd1230
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.legacy.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+// ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+// int get two => 2;
+// ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// int get two => 2;
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ get one() → core::int
+ return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+ invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+ C c = C();
+ ^".call();
+ dynamic result = c.one.+(c.two);
+ exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect b/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect
new file mode 100644
index 0000000..7fd1230
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+// ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+// int get two => 2;
+// ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// int get two => 2;
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ get one() → core::int
+ return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+ invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+ C c = C();
+ ^".call();
+ dynamic result = c.one.+(c.two);
+ exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.outline.expect b/pkg/front_end/testcases/extension_methods.dart.outline.expect
new file mode 100644
index 0000000..ccb8e3f
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.outline.expect
@@ -0,0 +1,43 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+// ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+// ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ ;
+ get one() → core::int
+ ;
+}
+static field invalid-type E;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extension_methods.dart.strong.expect b/pkg/front_end/testcases/extension_methods.dart.strong.expect
new file mode 100644
index 0000000..b3845b4
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.strong.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+// ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Error: Type 'on' not found.
+// extension E on C {
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+// int get two => 2;
+// ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// int get two => 2;
+// ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+// C c = C();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ get one() → core::int
+ return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+ invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+ C c = C();
+ ^".call() as{TypeError} invalid-type;
+ dynamic result = c.one.+(c.two);
+ exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart b/pkg/front_end/testcases/forwarding_stub_for_operator.dart
new file mode 100644
index 0000000..e604fe0
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.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 A {
+ dynamic operator+(covariant int a) => null;
+}
+
+class B {
+ dynamic operator+(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+//------------------------------------------------------------------------------
+
+class D {
+ dynamic operator+(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator+(covariant int e);
+}
+
+//------------------------------------------------------------------------------
+
+main() {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
new file mode 100644
index 0000000..d5d1da9
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ A.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ B.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: A, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ C.A.+%B.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ D.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+E:
+ superclasses:
+ Object
+ -> D
+ interfaces:
+ classMembers:
+ Object.toString
+ E.D.+%E.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
new file mode 100644
index 0000000..14a8eef
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ operator +(covariant core::int a) → dynamic
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ operator +(dynamic b) → dynamic
+ ;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ ;
+ operator +(dynamic d) → dynamic
+ ;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart b/pkg/front_end/testcases/ignore_function.dart
new file mode 100644
index 0000000..83c33eb
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart
@@ -0,0 +1,21 @@
+// 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" as core;
+
+class A implements core.Function {
+ // No error here: core.Function is ignored.
+ operator ==(other) => false;
+}
+
+class B implements Function {
+ // Error here Object.== and Function.== disagree on the type of other.
+ operator ==(other) => false;
+}
+
+class Function {
+ core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect b/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect
new file mode 100644
index 0000000..329fb74
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ A.==
+ classSetters:
+
+Function:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Function.==
+ classSetters:
+
+B:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Function
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ B.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ B.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/ignore_function.dart.legacy.expect b/pkg/front_end/testcases/ignore_function.dart.legacy.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.legacy.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+// operator ==(other) => false;
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator ==(dynamic other) → core::bool
+ return false;
+}
+class B extends core::Object implements self::Function {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator ==(invalid-type other) → core::bool
+ return false;
+}
+class Function extends core::Object {
+ synthetic constructor •() → self::Function
+ : super core::Object::•()
+ ;
+ operator ==(core::Object other) → core::bool
+ return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect b/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+// operator ==(other) => false;
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator ==(dynamic other) → core::bool
+ return false;
+}
+class B extends core::Object implements self::Function {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator ==(invalid-type other) → core::bool
+ return false;
+}
+class Function extends core::Object {
+ synthetic constructor •() → self::Function
+ : super core::Object::•()
+ ;
+ operator ==(core::Object other) → core::bool
+ return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.outline.expect b/pkg/front_end/testcases/ignore_function.dart.outline.expect
new file mode 100644
index 0000000..a1585c3
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.outline.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+// operator ==(other) => false;
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+ synthetic constructor •() → self::A
+ ;
+ operator ==(dynamic other) → core::bool
+ ;
+}
+class B extends core::Object implements self::Function {
+ synthetic constructor •() → self::B
+ ;
+ operator ==(invalid-type other) → core::bool
+ ;
+}
+class Function extends core::Object {
+ synthetic constructor •() → self::Function
+ ;
+ operator ==(core::Object other) → core::bool
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/ignore_function.dart.strong.expect b/pkg/front_end/testcases/ignore_function.dart.strong.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+// operator ==(other) => false;
+// ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator ==(dynamic other) → core::bool
+ return false;
+}
+class B extends core::Object implements self::Function {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator ==(invalid-type other) → core::bool
+ return false;
+}
+class Function extends core::Object {
+ synthetic constructor •() → self::Function
+ : super core::Object::•()
+ ;
+ operator ==(core::Object other) → core::bool
+ return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml
new file mode 100644
index 0000000..6e1730d
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml
@@ -0,0 +1,33 @@
+# 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.
+
+type: newworld
+omitPlatform: false
+worlds:
+ - entry: main.dart
+ errors: false
+ warnings: false
+ sources:
+ main.dart: |
+ main() {
+ foo();
+ }
+ foo() {}
+ expectedLibraryCount: 1
+ expectsPlatform: true
+ - entry: main.dart
+ errors: true
+ warnings: false
+ expectInitializeFromDill: false
+ fromComponent: true
+ invalidate:
+ - main.dart
+ sources:
+ main.dart: |
+ main() {
+ await foo();
+ }
+ foo() {}
+ expectedLibraryCount: 1
+ expectsPlatform: true
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
index 9b471de..f884677 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
@@ -2,12 +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.
-# Test compiling in non-strong-mode from source and initializing from dill.
+# Test compiling from source and initializing from dill.
# Make sure that any inference if done in the same way.
type: basic
entry: a.dart
-strong: false
invalidate:
- a.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
index ba6a85f..74d1d07 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
@@ -6,7 +6,6 @@
# Compile again with changing modules.
type: newworld
-strong: true
modules:
example_0.1.0:
example_0.1.0/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
index 4d0a193..f2a10a8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
@@ -6,7 +6,6 @@
# Compile again with changing modules.
type: newworld
-strong: true
modules:
example_1:
example_1/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
index 7e64c8c..c009ea1 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
@@ -6,7 +6,6 @@
# Compile again with changing modules.
type: newworld
-strong: true
modules:
foo:
foo/foo.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
index 08f0a4c..8c256a6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
@@ -7,7 +7,6 @@
# also have been removed from the uri to sources.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
index ef7857f..adee8ad 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
@@ -8,7 +8,6 @@
# removed from the uri to sources.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
index 4b1c653..d8ddd8d 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
@@ -5,7 +5,6 @@
# Test that constant set literals works as expected.
type: newworld
-strong: true
worlds:
- entry: "main.dart"
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
index 7ea4cc0..a1d9f4b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
@@ -7,7 +7,6 @@
type: basic
entry: a.dart
-strong: false
invalidate:
sources:
a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
index 2933c37..dea1937 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
@@ -7,7 +7,6 @@
# we should keep getting an error.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
@@ -24,7 +23,6 @@
expectedLibraryCount: 2
- entry: main.dart
errors: true
- warnings: true
invalidate:
- b.dart
sources:
@@ -37,7 +35,6 @@
expectedLibraryCount: 1
- entry: main.dart
errors: true
- warnings: true
checkInvalidatedFiles: false
worldType: updated
invalidate:
@@ -52,7 +49,6 @@
expectedLibraryCount: 1
- entry: main.dart
errors: true
- warnings: true
checkInvalidatedFiles: false
worldType: updated
invalidate:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
index a00341b..75a951b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
@@ -8,7 +8,6 @@
# of the library list --- initializing from the dill with n libraries.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
index 9e236c1..4790a02 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
@@ -8,7 +8,6 @@
# but shouldn't cause trouble, nor be included in the output.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
index 5bd270e..f5ac43a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
@@ -7,7 +7,6 @@
# should still be included in the output.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
index 2360641..828f103 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
@@ -7,7 +7,6 @@
# should still be included in the output - even if there's errors in main.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
index 02a57de..fd5d0d5 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
@@ -7,7 +7,6 @@
# should still be included in the output - even if there's no main.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
index b426a33..9baf55e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
@@ -9,7 +9,6 @@
# error.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
index 1a79746..1e22f39 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
@@ -5,7 +5,6 @@
# Regression test from flutter.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
index e45af03..2efee99 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
@@ -9,7 +9,6 @@
# by the class hierarchy.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
index 85937b6..e34eff2 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
@@ -10,7 +10,6 @@
# hierarchy.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
index 07e5102..768fd3c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
@@ -6,7 +6,6 @@
type: basic
entry: a.dart
-strong: true
invalidate:
- a.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
index 1d8be7f..da20971 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
@@ -6,7 +6,6 @@
# URI.
type: newworld
-strong: false
worlds:
- entry: "package:example/main.dart"
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
index eae0ae4..60327f4 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
@@ -6,7 +6,6 @@
type: basic
entry: "package:example/main.dart"
-strong: false
invalidate:
- pkg/example/b.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
index 19816ca..ccbe383 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
@@ -6,7 +6,6 @@
type: basic
entry: "package:example/main.dart"
-strong: false
invalidate:
- "package:example/b.dart"
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
index d5a757b..15d82ee 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
@@ -7,7 +7,6 @@
type: basic
entry: "package:example/main.dart"
-strong: false
invalidate:
- pkg/example/b.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
index 149b1ae..2bb9c88 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
@@ -7,7 +7,6 @@
type: basic
entry: "package:example/main.dart"
-strong: false
invalidate:
- "package:example/b.dart"
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
index 8ff940e..4b88157 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
@@ -6,7 +6,6 @@
type: basic
entry: a.dart
-strong: true
invalidate:
- b.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
index c627364..2313785 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
@@ -11,7 +11,6 @@
# that it pulled in should be included.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
index 649545e..6b88d9a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
@@ -10,7 +10,6 @@
# the parameter type 'dart.core::String'".
type: newworld
-strong: true
omitPlatform: false
worlds:
- entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
index 30d267a..51be325 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
@@ -8,7 +8,6 @@
type: basic
entry: a.dart
-strong: true
invalidate:
- a.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
index e571850..e760b10 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
@@ -6,7 +6,6 @@
# and now swallowed somewhere when done in the incremental compiler.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
index 83c53a0..0577118 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
@@ -6,7 +6,6 @@
# results in getting both libraries (aka that multiple entry points work).
type: newworld
-strong: true
worlds:
- entry:
- a.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
index d336e98..5f3ac3c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
@@ -7,7 +7,6 @@
type: basic
entry: a.dart
-strong: true
invalidate:
sources:
a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
index e306e5a..8d884a3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
@@ -5,7 +5,6 @@
# Compile a hello world program, check that omit platform works as expected.
type: newworld
-strong: true
omitPlatform: true
worlds:
- entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
index e1a42a8a..071eacd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
@@ -6,7 +6,6 @@
# Omit platform is true by default in tests.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
index b649bbd..450377b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
@@ -7,7 +7,6 @@
# component again etc.
type: newworld
-strong: true
omitPlatform: false
worlds:
- entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
index 5bfb458..59a9e45 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
@@ -5,7 +5,6 @@
# Compile an application with the option of only getting an outline.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
index 0105f44..94b1a83 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
@@ -6,7 +6,6 @@
# This is a reproduction of http://dartbug.com/36498.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
index 5fd397a..b906cba 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
@@ -7,7 +7,6 @@
# exist in the old library.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
index 0be7810..fb57969 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
index 468566d..91ce7a3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
index 5375fd6..1c74c07 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
index 994f2c6..8342cbd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
index c5164e2..65f2282 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
index fb8b511..5965f18 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
@@ -7,7 +7,6 @@
# invalidating a. Compiling this should not result in any errors.
type: newworld
-strong: false
worlds:
- entry: main.dart
errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
index 1981950..f644133 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
@@ -2,13 +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.md file.
-# Compile in strong mode. Invalidate a file so type inferrer starts
+# Compile. Invalidate a file so type inferrer starts
# on something compiled from source and (potentially) goes into
# something loaded from dill.
type: basic
entry: a.dart
-strong: true
invalidate:
- a.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
index 61d783f..9238c66 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
@@ -2,11 +2,10 @@
# 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 in strong mode. Use mixins.
+# Compile. Use mixins.
type: basic
entry: a.dart
-strong: true
invalidate:
- a.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
index a2c5739..e7182de 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
@@ -8,7 +8,6 @@
# but shouldn't cause trouble, nor be included in the output.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
index 7bb3ab1..0a24fa7 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
@@ -8,7 +8,6 @@
# but shouldn't cause trouble, nor be included in the output.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
index 00cd03f..ad7756f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
@@ -8,7 +8,6 @@
# but shouldn't cause trouble, nor be included in the output.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
index 1c79496..ed1f6ab 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
@@ -8,7 +8,6 @@
# The output should not include the old package.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
index c7a7491..5cb7d9c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
@@ -7,7 +7,6 @@
# This should be an error.
type: newworld
-strong: false
worlds:
- entry: main.dart
sources:
@@ -32,5 +31,4 @@
sources:
.packages:
errors: true
- warnings: true
expectedLibraryCount: 1
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
index cf01000..f716e96 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
@@ -7,7 +7,6 @@
# should now be relative to the new .packages file.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
index 14b0a58..9f3b66a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
@@ -7,7 +7,6 @@
# Loading from such a dill is ok too.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
index bbcc110..50f16a6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
@@ -7,7 +7,6 @@
# Loading from such a dill is ok too.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
index 0402343..6d8eb3f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
@@ -7,7 +7,6 @@
# Loading from such a dill is ok too.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
index df8a598..1af29a8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
@@ -8,7 +8,6 @@
# Loading from such a dill is ok too.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
index bd55d81..9aa7ede 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
@@ -7,7 +7,6 @@
# Loading from such a dill is ok too.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=inference*/
library test;
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
var y = /*@returnType=invalid-type*/ () => x;
main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
index 73adfd1..bd67e53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
@@ -2,18 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-// ^
-//
// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
// ^
//
import self as self;
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
index 73adfd1..bd67e53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
@@ -2,18 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-// ^
-//
// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
// ^
//
import self as self;
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=inference*/
library test;
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
var y = /*@returnType=invalid-type*/ () => x;
main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
index 4f81f83..88a970d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
@@ -2,18 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-// ^
-//
// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
// ^
//
import self as self;
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
index 4f81f83..88a970d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
@@ -2,18 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-// ^
-//
// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
// ^
//
import self as self;
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart b/pkg/front_end/testcases/inference/conflicting_fields.dart
index 72edc67..8dacd55 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart
@@ -17,6 +17,8 @@
class B extends A implements I {
get field1 => null;
get field2 => null;
+ set field1(value) {}
+ set field2(value) {}
}
main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
index 058c190..b2b061e 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
@@ -79,8 +79,8 @@
Object._simpleInstanceOfTrue
Object.==
classSetters:
- A.field1
- A.field2
+ B.field1
+ B.field2
interfaceMembers:
B.field1
Object.toString
@@ -95,5 +95,5 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- A.field1
- A.field2
+ B.field1
+ B.field2
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
index 67e1ae7..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
@@ -1,4 +1,17 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field1(value) {}
+// ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field2(value) {}
+// ^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -20,9 +33,11 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- get field1() → dynamic
+ get field1() → core::int
return null;
- get field2() → dynamic
+ get field2() → core::int
return null;
+ set field1(invalid-type value) → void {}
+ set field2(invalid-type value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
index 67e1ae7..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
@@ -1,4 +1,17 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field1(value) {}
+// ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field2(value) {}
+// ^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -20,9 +33,11 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- get field1() → dynamic
+ get field1() → core::int
return null;
- get field2() → dynamic
+ get field2() → core::int
return null;
+ set field1(invalid-type value) → void {}
+ set field2(invalid-type value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
index 6963ff2..57c1e7c 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
@@ -1,4 +1,17 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field1(value) {}
+// ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+// set field2(value) {}
+// ^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -17,9 +30,13 @@
class B extends self::A implements self::I {
synthetic constructor •() → self::B
;
- get field1() → dynamic
+ get field1() → core::int
;
- get field2() → dynamic
+ get field2() → core::int
+ ;
+ set field1(invalid-type value) → void
+ ;
+ set field2(invalid-type value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
index 3f45ef6..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
@@ -2,42 +2,15 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:18:7: Error: Can't infer a type for 'field1' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
// Try adding an explicit type.
-// get field1 => null;
-// ^
+// set field1(value) {}
+// ^^^^^
//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:19:7: Error: Can't infer a type for 'field2' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
// Try adding an explicit type.
-// get field2 => null;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:19:7: Error: The return type of the method 'B.field2' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.field2'.
-// Change to a subtype of 'int'.
-// get field2 => null;
-// ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:9:7: Context: This is the overridden method ('field2').
-// int field2;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:18:7: Error: The return type of the method 'B.field1' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'I.field1'.
-// Change to a subtype of 'int'.
-// get field1 => null;
-// ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:13:7: Context: This is the overridden method ('field1').
-// int field1;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:8:11: Error: The return type of the method 'A.field1' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'I.field1'.
-// Change to a subtype of 'int'.
-// dynamic field1;
-// ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:13:7: Context: This is the overridden method ('field1').
-// int field1;
-// ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:17:7: Context: Both members are inherited by the non-abstract class 'B'.
-// class B extends A implements I {
-// ^
+// set field2(value) {}
+// ^^^^^
//
import self as self;
import "dart:core" as core;
@@ -60,10 +33,11 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- get field1() → dynamic
+ get field1() → core::int
return null;
- get field2() → dynamic
+ get field2() → core::int
return null;
- abstract forwarding-stub set field2(dynamic _) → void;
+ set field1(invalid-type value) → void {}
+ set field2(invalid-type value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
index ae8c8ce..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
@@ -1,4 +1,17 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -30,14 +43,14 @@
synthetic constructor •() → self::C1
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
class C2 extends core::Object implements self::B, self::A {
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
index ae8c8ce..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
@@ -1,4 +1,17 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -30,14 +43,14 @@
synthetic constructor •() → self::C1
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
class C2 extends core::Object implements self::B, self::A {
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
index 6e8c47d..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
@@ -2,52 +2,16 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
// Try adding an explicit type.
// get a => null;
// ^
//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
// Try adding an explicit type.
// get a => null;
// ^
//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-// - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-// final I1 a = null;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-// - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-// final I2 a = null;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-// - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-// final I2 a = null;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-// - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-// final I1 a = null;
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -79,14 +43,14 @@
synthetic constructor •() → self::C1
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
class C2 extends core::Object implements self::B, self::A {
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
index e3d2868..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,7 +52,7 @@
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
index e3d2868..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+// get a => null;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,7 +52,7 @@
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
index 411506a..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
@@ -2,29 +2,11 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
// Try adding an explicit type.
// get a => null;
// ^
//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-// - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I1'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:22:12: Context: This is the overridden method ('a').
-// final I1 a = null;
-// ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-// - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I2'.
-// get a => null;
-// ^
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:26:12: Context: This is the overridden method ('a').
-// final I2 a = null;
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -70,7 +52,7 @@
synthetic constructor •() → self::C2
: super core::Object::•()
;
- get a() → dynamic
+ get a() → invalid-type
return null;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
index 9a63601..ebc33e7 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
@@ -9,7 +9,7 @@
abstract get foo() → core::Iterable<core::String>;
}
class B extends core::Object implements self::A {
- final field dynamic foo = const <dynamic>[];
+ final field core::Iterable<core::String> foo = const <dynamic>[];
synthetic constructor •() → self::B
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
index 9a63601..ebc33e7 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
abstract get foo() → core::Iterable<core::String>;
}
class B extends core::Object implements self::A {
- final field dynamic foo = const <dynamic>[];
+ final field core::Iterable<core::String> foo = const <dynamic>[];
synthetic constructor •() → self::B
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
index 65ee9d5..945a5e0 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
@@ -8,7 +8,7 @@
abstract get foo() → core::Iterable<core::String>;
}
class B extends core::Object implements self::A {
- final field dynamic foo;
+ final field core::Iterable<core::String> foo;
synthetic constructor •() → self::B
;
}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
index d1361ce..a97723a 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class C extends core::Object implements self::B {
- final field dynamic x;
+ final field core::int x;
constructor •() → self::C
: self::C::x = self::f<dynamic>(), super core::Object::•()
;
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
index d1361ce..a97723a 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class C extends core::Object implements self::B {
- final field dynamic x;
+ final field core::int x;
constructor •() → self::C
: self::C::x = self::f<dynamic>(), super core::Object::•()
;
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
index e84a002..eda87a3 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class C extends core::Object implements self::B {
- final field dynamic x;
+ final field core::int x;
constructor •() → self::C
;
}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
index 88b6639..7126780 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
index 4f440e2..0e46318 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
index a91d75e..c555879 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
index 6538f9e..63c4c5c 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
index 2a3484c..075602a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
index 346e77b8..895ce5a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
index c7d577e..8a393fd 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
index c90b143..98c8918 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
index 141e3e7..58d742b 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
index 33b2911..5d553da 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
index cc6a439..0cc6848 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
index 9ad93e8..6d284e6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
index 579d81d..d16fb57 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
index 1ae82f7..37a9eaf 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
index 3fbb4f7..b5e3e79 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
index 9b1db02..e3526c6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
index a38c5ae..dc6b8a1 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
index 364a78a..8031722 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
index 189b93e..ac112f8 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
index 4a5e294..0ebe142 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
index 8b21e2e..f359eff 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
index e5e7c73..d73e7d4 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
index d4392fe..6231476 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
index fecb72e..b10c087 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
index 985e5ba..211f9f3 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
index f3c12bb..a55a43b 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
index c454264..c131aa9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
index c454264..c131aa9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
index e5a534c..68201b4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
index 4c532cc..b418fd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
index 4c532cc..b418fd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
index e5a534c..68201b4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
index 86abe95..93fd95b 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
index 86abe95..93fd95b 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
index 9162c9b..a644d90 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
index aed7501..f9b1dde 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
index 7697712..24f847d 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
index e80eb43..3e05a12 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
index b3989b2..85cc477 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
index 8c463d9..7395c33 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
index e80eb43..3e05a12 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
index c309ae6..3e9e23f 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
index 5fb66a8..86df2a1 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
index 263a94f..6fbd438 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
index a89b874..1f70652 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
index ec5724d..1afd6d8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
index 263a94f..6fbd438 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
index 9b07131..51e5fde 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
index a3884a8..ec3fde4 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
index da18d4d..2d1e70e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
index b27e6d9..ab6a0d3 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
index ca29563..7fc5179 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
: super core::Object::•() {}
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
return null;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
index da18d4d..2d1e70e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
@@ -10,7 +10,7 @@
;
constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
;
- method noSuchMethod(dynamic invocation) → dynamic
+ method noSuchMethod(core::Invocation invocation) → dynamic
;
method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
index 1f86d32..b9c4222 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+ method f<U extends core::Object = dynamic>(self::C::f::U x) → (self::C::f::U) → void {}
}
class D<T extends core::Object = dynamic> extends core::Object {
synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
index 1f86d32..b9c4222 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+ method f<U extends core::Object = dynamic>(self::C::f::U x) → (self::C::f::U) → void {}
}
class D<T extends core::Object = dynamic> extends core::Object {
synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
index 08648c6..c1d63d6 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic g) → dynamic
+ method f<U extends core::Object = dynamic>(() → core::List<self::C::f::U> g) → void
return null;
}
abstract class D<T extends core::Object = dynamic> extends core::Object {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
index 08648c6..c1d63d6 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic g) → dynamic
+ method f<U extends core::Object = dynamic>(() → core::List<self::C::f::U> g) → void
return null;
}
abstract class D<T extends core::Object = dynamic> extends core::Object {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
index 57033a4..c9c76f5 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+ method f<U extends core::Object = dynamic>(self::C::f::U x) → () → self::C::f::U {}
}
class D<T extends core::Object = dynamic> extends core::Object {
synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
index 57033a4..c9c76f5 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
synthetic constructor •() → self::C<self::C::T>
: super self::D::•()
;
- method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+ method f<U extends core::Object = dynamic>(self::C::f::U x) → () → self::C::f::U {}
}
class D<T extends core::Object = dynamic> extends core::Object {
synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
index 29528fb..0500661 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method m<S extends core::Object = dynamic>(dynamic x) → dynamic
+ method m<S extends core::Object = dynamic>(self::D::m::S x) → self::D::m::S
return x;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
index 29528fb..0500661 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method m<S extends core::Object = dynamic>(dynamic x) → dynamic
+ method m<S extends core::Object = dynamic>(self::D::m::S x) → self::D::m::S
return x;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart b/pkg/front_end/testcases/inference/inconsistent_overrides.dart
new file mode 100644
index 0000000..9030aea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.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.
+
+library test;
+
+/*@testedFeatures=inference*/
+
+class A {
+ A f(A x, {A y}) {}
+ A g(A x, {A y}) {}
+ A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+ f(x, {y}) {}
+ g(x, {y}) {}
+ h(x, {y}) {}
+}
+
+class I {
+ I f(I x, {I y}) {}
+ A g(I x, {I y}) {}
+ A h(A x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect
new file mode 100644
index 0000000..ad5bb3a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ A.f
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ A.h
+ Object.hashCode
+ A.g
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+I:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ I.f
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ I.h
+ Object.hashCode
+ I.g
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces: I
+ classMembers:
+ B.f
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ B.h
+ Object.hashCode
+ B.g
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ B.f
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ B.h
+ Object.hashCode
+ B.g
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// h(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method f(self::A x, {self::A y = null}) → self::A {}
+ method g(self::A x, {self::A y = null}) → self::A {}
+ method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+ method g(invalid-type x, {invalid-type y = null}) → self::A {}
+ method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+ synthetic constructor •() → self::I
+ : super core::Object::•()
+ ;
+ method f(self::I x, {self::I y = null}) → self::I {}
+ method g(self::I x, {self::I y = null}) → self::A {}
+ method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// h(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method f(self::A x, {self::A y = null}) → self::A {}
+ method g(self::A x, {self::A y = null}) → self::A {}
+ method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+ method g(invalid-type x, {invalid-type y = null}) → self::A {}
+ method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+ synthetic constructor •() → self::I
+ : super core::Object::•()
+ ;
+ method f(self::I x, {self::I y = null}) → self::I {}
+ method g(self::I x, {self::I y = null}) → self::A {}
+ method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect
new file mode 100644
index 0000000..26eafa0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect
@@ -0,0 +1,69 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// h(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method f(self::A x, {self::A y}) → self::A
+ ;
+ method g(self::A x, {self::A y}) → self::A
+ ;
+ method h(self::A x, {self::A y}) → self::A
+ ;
+}
+class B extends self::A implements self::I {
+ synthetic constructor •() → self::B
+ ;
+ method f(invalid-type x, {invalid-type y}) → invalid-type
+ ;
+ method g(invalid-type x, {invalid-type y}) → self::A
+ ;
+ method h(self::A x, {invalid-type y}) → self::A
+ ;
+}
+class I extends core::Object {
+ synthetic constructor •() → self::I
+ ;
+ method f(self::I x, {self::I y}) → self::I
+ ;
+ method g(self::I x, {self::I y}) → self::A
+ ;
+ method h(self::A x, {self::I y}) → self::A
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// f(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// h(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// g(x, {y}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method f(self::A x, {self::A y = null}) → self::A {}
+ method g(self::A x, {self::A y = null}) → self::A {}
+ method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+ method g(invalid-type x, {invalid-type y = null}) → self::A {}
+ method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+ synthetic constructor •() → self::I
+ : super core::Object::•()
+ ;
+ method f(self::I x, {self::I y = null}) → self::I {}
+ method g(self::I x, {self::I y = null}) → self::A {}
+ method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
index b9f3f55..ba7aef9 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- operator []=(dynamic index, dynamic value) → dynamic {}
+ operator []=(dynamic index, dynamic value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
index b9f3f55..ba7aef9 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- operator []=(dynamic index, dynamic value) → dynamic {}
+ operator []=(dynamic index, dynamic value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
index 431131a..ef008c4 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
@@ -17,7 +17,7 @@
class D extends self::C implements self::I {
synthetic constructor •() → self::D
;
- operator []=(dynamic index, dynamic value) → dynamic
+ operator []=(dynamic index, dynamic value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
index 5ffc002..587faf3 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- operator []=(core::int index, dynamic value) → dynamic {}
+ operator []=(core::int index, dynamic value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
index 5ffc002..587faf3 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- operator []=(core::int index, dynamic value) → dynamic {}
+ operator []=(core::int index, dynamic value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
index e1dc0dc..68f38e5 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
@@ -17,7 +17,7 @@
class D extends self::C implements self::I {
synthetic constructor •() → self::D
;
- operator []=(core::int index, dynamic value) → dynamic
+ operator []=(core::int index, dynamic value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
index 6657368..4b35f0e 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
index 6657368..4b35f0e 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
index 41317cd..b7b8fe3 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
@@ -3,14 +3,14 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::A
;
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
index 67fa407..94de153 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
index 67fa407..94de153 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::A
: super core::Object::•()
;
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
index 9de155a..25d6786 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
@@ -3,14 +3,14 @@
import "dart:core" as core;
class A extends core::Object implements self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::A
;
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
index 34995f9..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
@@ -1,4 +1,22 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,25 +45,25 @@
abstract get x() → core::double;
}
class E extends self::A implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super self::A::•()
;
}
class F extends self::A implements self::C {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::F
: super self::A::•()
;
}
class G extends self::A implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::G
: super self::A::•()
;
}
class H extends self::C implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::H
: super self::C::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
index 34995f9..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
@@ -1,4 +1,22 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,25 +45,25 @@
abstract get x() → core::double;
}
class E extends self::A implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super self::A::•()
;
}
class F extends self::A implements self::C {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::F
: super self::A::•()
;
}
class G extends self::A implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::G
: super self::A::•()
;
}
class H extends self::C implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::H
: super self::C::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
index c55fa65..ac7a863 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
@@ -1,4 +1,22 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -23,22 +41,22 @@
abstract get x() → core::double;
}
class E extends self::A implements self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::E
;
}
class F extends self::A implements self::C {
- field dynamic x;
+ field invalid-type x;
synthetic constructor •() → self::F
;
}
class G extends self::A implements self::D {
- field dynamic x;
+ field invalid-type x;
synthetic constructor •() → self::G
;
}
class H extends self::C implements self::D {
- field dynamic x;
+ field invalid-type x;
synthetic constructor •() → self::H
;
}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
index c24c0bb..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
@@ -17,54 +17,6 @@
// var x;
// ^
//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.x'.
-// Change to a subtype of 'int'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-// int get x;
-// ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type, 'num', of the overridden method, 'C.x'.
-// Change to a subtype of 'num'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-// num get x;
-// ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.x'.
-// Change to a subtype of 'int'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-// int get x;
-// ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type, 'double', of the overridden method, 'D.x'.
-// Change to a subtype of 'double'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-// double get x;
-// ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type, 'num', of the overridden method, 'C.x'.
-// Change to a subtype of 'num'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-// num get x;
-// ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type, 'double', of the overridden method, 'D.x'.
-// Change to a subtype of 'double'.
-// var x;
-// ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-// double get x;
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -99,19 +51,19 @@
;
}
class F extends self::A implements self::C {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::F
: super self::A::•()
;
}
class G extends self::A implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::G
: super self::A::•()
;
}
class H extends self::C implements self::D {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::H
: super self::C::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
index 651b972..f9b40cd 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
@@ -15,7 +15,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
index 651b972..f9b40cd 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
index 07bf8f9..f76fc3b 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
@@ -13,7 +13,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::C
;
}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
index 6e31b6d..c395f30 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
@@ -11,9 +11,9 @@
abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
}
class B extends self::A<core::int> {
- field dynamic x = null;
- field dynamic y = null;
- field dynamic z = null;
+ field core::List<core::int> x = null;
+ generic-covariant-impl field core::List<core::int> y = null;
+ generic-covariant-impl field core::List<core::int> z = null;
synthetic constructor •() → self::B
: super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
index 6e31b6d..c395f30 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
@@ -11,9 +11,9 @@
abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
}
class B extends self::A<core::int> {
- field dynamic x = null;
- field dynamic y = null;
- field dynamic z = null;
+ field core::List<core::int> x = null;
+ generic-covariant-impl field core::List<core::int> y = null;
+ generic-covariant-impl field core::List<core::int> z = null;
synthetic constructor •() → self::B
: super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
index 2fc6225..711058e 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
@@ -10,9 +10,9 @@
abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
}
class B extends self::A<core::int> {
- field dynamic x;
- field dynamic y;
- field dynamic z;
+ field core::List<core::int> x;
+ generic-covariant-impl field core::List<core::int> y;
+ generic-covariant-impl field core::List<core::int> z;
synthetic constructor •() → self::B
;
}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
index 72b90ee..9f9de47 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
@@ -16,25 +16,25 @@
return 0;
}
class C extends self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::A::•()
;
}
class D extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::D
: super self::B::•()
;
}
class E extends core::Object implements self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
}
class F extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::F
: super core::Object::•()
;
@@ -45,7 +45,7 @@
;
}
class G extends self::_G&Object&B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::G
: super self::_G&Object&B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
index 31c9fee..9f7817b 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
@@ -16,25 +16,25 @@
return 0;
}
class C extends self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::A::•()
;
}
class D extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::D
: super self::B::•()
;
}
class E extends core::Object implements self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
}
class F extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::F
: super core::Object::•()
;
@@ -47,7 +47,7 @@
return 0;
}
class G extends self::_G&Object&B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::G
: super self::_G&Object&B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
index b627b29..99e2051 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
@@ -14,22 +14,22 @@
;
}
class C extends self::A {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::C
;
}
class D extends self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::D
;
}
class E extends core::Object implements self::A {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::E
;
}
class F extends core::Object implements self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::F
;
}
@@ -39,7 +39,7 @@
;
}
class G extends self::_G&Object&B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::G
;
}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
index 8baaa28..3c16ce0 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
@@ -15,25 +15,25 @@
set x(core::int value) → void {}
}
class C extends self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::A::•()
;
}
class D extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::D
: super self::B::•()
;
}
class E extends core::Object implements self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
}
class F extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::F
: super core::Object::•()
;
@@ -44,7 +44,7 @@
;
}
class G extends self::_G&Object&B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::G
: super self::_G&Object&B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
index 1a36773..e3da27e 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
@@ -15,25 +15,25 @@
set x(core::int value) → void {}
}
class C extends self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::C
: super self::A::•()
;
}
class D extends self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::D
: super self::B::•()
;
}
class E extends core::Object implements self::A {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
}
class F extends core::Object implements self::B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::F
: super core::Object::•()
;
@@ -45,7 +45,7 @@
set x(core::int value) → void {}
}
class G extends self::_G&Object&B {
- field dynamic x = null;
+ field core::int x = null;
synthetic constructor •() → self::G
: super self::_G&Object&B::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
index 02e0c2b..0ce880d 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
@@ -14,22 +14,22 @@
;
}
class C extends self::A {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::C
;
}
class D extends self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::D
;
}
class E extends core::Object implements self::A {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::E
;
}
class F extends core::Object implements self::B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::F
;
}
@@ -39,7 +39,7 @@
;
}
class G extends self::_G&Object&B {
- field dynamic x;
+ field core::int x;
synthetic constructor •() → self::G
;
}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
index 18097da..e03bb9e 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
@@ -10,7 +10,7 @@
set x(core::double value) → void {}
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
index 18097da..e03bb9e 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
set x(core::double value) → void {}
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
index 96dbb50..4709de3 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
@@ -10,7 +10,7 @@
;
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
;
}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
index 28bd84b..7dea358 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
@@ -9,7 +9,7 @@
abstract get x() → core::int;
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
index 28bd84b..7dea358 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
abstract get x() → core::int;
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
index 11b26c0..5e18eaa 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
@@ -8,7 +8,7 @@
abstract get x() → core::int;
}
class B extends self::A {
- final field dynamic x;
+ final field core::int x;
constructor •(dynamic x) → self::B
;
}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
index d9bfe67..148028f 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
@@ -9,7 +9,7 @@
set x(core::double value) → void {}
}
class B extends self::A {
- final field dynamic x;
+ final field core::double x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
index d9bfe67..148028f 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
set x(core::double value) → void {}
}
class B extends self::A {
- final field dynamic x;
+ final field core::double x;
constructor •(dynamic x) → self::B
: self::B::x = x, super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
index b2085f3..b0206ee 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
@@ -9,7 +9,7 @@
;
}
class B extends self::A {
- final field dynamic x;
+ final field core::double x;
constructor •(dynamic x) → self::B
;
}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
index 3d410db..1bb410b 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::double;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
index 3d410db..1bb410b 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::double;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
index 35c511d..83d3f12 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
@@ -10,7 +10,7 @@
abstract class B extends self::A {
synthetic constructor •() → self::B
;
- abstract get x() → dynamic;
+ abstract get x() → core::double;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
index 69eff1f1..62a80b3 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
@@ -6,14 +6,14 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return self::f();
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
index 69eff1f1..62a80b3 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
@@ -6,14 +6,14 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return self::f();
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
index a346b2f..64fa771 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
@@ -5,13 +5,13 @@
class A extends core::Object implements self::B {
synthetic constructor •() → self::A
;
- get x() → dynamic
+ get x() → core::int
;
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
;
- abstract get x() → dynamic;
+ abstract get x() → core::int;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
index 5337a40..3c40a1e 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
@@ -1,14 +1,4 @@
library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-// f(x, y);
-// ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-// int f(int x);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -32,8 +22,8 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- abstract method f(dynamic x, dynamic y) → dynamic;
- abstract method g(dynamic x, [dynamic y = null]) → dynamic;
- abstract method h(dynamic x, {dynamic y = null}) → dynamic;
+ abstract method f(core::int x, core::int y) → core::int;
+ abstract method g(core::int x, [core::int y = null]) → core::int;
+ abstract method h(core::int x, {core::int y = null}) → core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
index 5337a40..3c40a1e 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
@@ -1,14 +1,4 @@
library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-// f(x, y);
-// ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-// int f(int x);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -32,8 +22,8 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- abstract method f(dynamic x, dynamic y) → dynamic;
- abstract method g(dynamic x, [dynamic y = null]) → dynamic;
- abstract method h(dynamic x, {dynamic y = null}) → dynamic;
+ abstract method f(core::int x, core::int y) → core::int;
+ abstract method g(core::int x, [core::int y = null]) → core::int;
+ abstract method h(core::int x, {core::int y = null}) → core::int;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
index 0ae3513..332234b 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
@@ -1,14 +1,4 @@
library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-// f(x, y);
-// ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-// int f(int x);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -29,9 +19,9 @@
abstract class C extends core::Object implements self::A, self::B {
synthetic constructor •() → self::C
;
- abstract method f(dynamic x, dynamic y) → dynamic;
- abstract method g(dynamic x, [dynamic y]) → dynamic;
- abstract method h(dynamic x, {dynamic y}) → dynamic;
+ abstract method f(core::int x, core::int y) → core::int;
+ abstract method g(core::int x, [core::int y]) → core::int;
+ abstract method h(core::int x, {core::int y}) → core::int;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
index b4be5c0..1b88745 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super self::D::•()
;
- set foo(dynamic x) → dynamic {}
+ set foo(core::int x) → void {}
}
class D extends core::Object {
field core::int foo = null;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
index b4be5c0..1b88745 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super self::D::•()
;
- set foo(dynamic x) → dynamic {}
+ set foo(core::int x) → void {}
}
class D extends core::Object {
field core::int foo = null;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
index 6288aaf..688faaf 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
@@ -6,12 +6,12 @@
synthetic constructor •() → self::C
: super self::D::•()
;
- set foo(dynamic x) → dynamic {}
+ set foo(core::int x) → void {}
}
class D extends core::Object {
synthetic constructor •() → self::D
: super core::Object::•()
;
- set foo(core::int x) → dynamic {}
+ set foo(core::int x) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
index 6288aaf..688faaf 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
@@ -6,12 +6,12 @@
synthetic constructor •() → self::C
: super self::D::•()
;
- set foo(dynamic x) → dynamic {}
+ set foo(core::int x) → void {}
}
class D extends core::Object {
synthetic constructor •() → self::D
: super core::Object::•()
;
- set foo(core::int x) → dynamic {}
+ set foo(core::int x) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
index 24beb1d..6f68db4 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- static set foo(core::int x) → dynamic {}
+ static set foo(core::int x) → void {}
}
-static set bar(core::int x) → dynamic {}
+static set bar(core::int x) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
index 24beb1d..6f68db4 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- static set foo(core::int x) → dynamic {}
+ static set foo(core::int x) → void {}
}
-static set bar(core::int x) → dynamic {}
+static set bar(core::int x) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
index e12c95b..42e1a1a 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
@@ -5,10 +5,10 @@
class C extends core::Object {
synthetic constructor •() → self::C
;
- static set foo(core::int x) → dynamic
+ static set foo(core::int x) → void
;
}
-static set bar(core::int x) → dynamic
+static set bar(core::int x) → void
;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
index db7fb96..849953f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::double value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
index db7fb96..849953f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::double value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
index e80537c..1d8285f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
@@ -10,7 +10,7 @@
abstract class B extends self::A {
synthetic constructor •() → self::B
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::double value) → void;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
index 0c5bffd..d58802b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
@@ -6,13 +6,13 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set x(dynamic value) → void {}
+ set x(core::int value) → void {}
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
index 0c5bffd..d58802b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
@@ -6,13 +6,13 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set x(dynamic value) → void {}
+ set x(core::int value) → void {}
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
index 47cd14e..462e7c5 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
@@ -5,13 +5,13 @@
class A extends core::Object implements self::B {
synthetic constructor •() → self::A
;
- set x(dynamic value) → void
+ set x(core::int value) → void
;
}
abstract class B extends core::Object implements self::C {
synthetic constructor •() → self::B
;
- abstract set x(dynamic value) → void;
+ abstract set x(core::int value) → void;
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
index a8e04fb..670abbd 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- set x(core::Object o) → dynamic {}
+ set x(core::Object o) → void {}
}
static method main() → dynamic {
new self::B::•().x = "hello";
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
index a8e04fb..670abbd 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- set x(core::Object o) → dynamic {}
+ set x(core::Object o) → void {}
}
static method main() → dynamic {
new self::B::•().x = "hello";
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
index 4afa24f..2f2f40b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
@@ -11,7 +11,7 @@
class B extends self::A {
synthetic constructor •() → self::B
;
- set x(core::Object o) → dynamic
+ set x(core::Object o) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
index 26d089c..2f5e471 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
index 26d089c..2f5e471 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
index 1159f05..922bf72 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
index 1159f05..922bf72 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
index 707d09d..601e9bb 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
@@ -9,7 +9,7 @@
synthetic constructor •() → self::C
: super inf::B::•()
;
- get x() → dynamic
+ get x() → core::int
return null;
}
class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
index 707d09d..601e9bb 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
synthetic constructor •() → self::C
: super inf::B::•()
;
- get x() → dynamic
+ get x() → core::int
return null;
}
class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
index f32c8d5..0b1b2b0 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
@@ -22,7 +22,7 @@
synthetic constructor •() → test::C
: super self::B::•()
;
- get x() → dynamic
+ get x() → core::int
return null;
}
class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
index f32c8d5..0b1b2b0 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
@@ -22,7 +22,7 @@
synthetic constructor •() → test::C
: super self::B::•()
;
- get x() → dynamic
+ get x() → core::int
return null;
}
class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
index 927f51d..0360763 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
@@ -13,9 +13,9 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
- get w() → dynamic
+ get w() → core::int
return "hello";
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
index 927f51d..0360763 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
@@ -13,9 +13,9 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- get x() → dynamic
+ get x() → core::int
return 3;
- get w() → dynamic
+ get w() → core::int
return "hello";
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
index 3c624e6..4f44d59 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::B<self::B::E>
: super self::A::•()
;
- get x() → dynamic
+ get x() → self::B::E
return this.{self::B::y};
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
index 3c624e6..4f44d59 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::B<self::B::E>
: super self::A::•()
;
- get x() → dynamic
+ get x() → self::B::E
return this.{self::B::y};
}
static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
index 23fb83d..2a0386f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
@@ -26,7 +26,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, self::B::E) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, self::B::E) → dynamic f) → core::String {}
}
static method foo() → dynamic {
core::int y = new self::B::•<dynamic>().m(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
index 23fb83d..2a0386f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, self::B::E) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, self::B::E) → dynamic f) → core::String {}
}
static method foo() → dynamic {
core::int y = new self::B::•<dynamic>().m(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
index ecee2c6..be1a80f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
@@ -23,7 +23,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, core::int) → dynamic f) → self::A<self::B::E> {}
}
static method foo() → dynamic {
core::int y = new self::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
index ecee2c6..be1a80f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
@@ -23,7 +23,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, core::int) → dynamic f) → self::A<self::B::E> {}
}
static method foo() → dynamic {
core::int y = new self::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
index 54ed9fa..c669cd7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
@@ -38,7 +38,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
}
static method foo() → dynamic {
core::int y = new test::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
index 54ed9fa..c669cd7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
@@ -38,7 +38,7 @@
;
get y() → core::int
return 0;
- method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+ method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
}
static method foo() → dynamic {
core::int y = new test::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
new file mode 100644
index 0000000..ebc84b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
@@ -0,0 +1,15 @@
+// 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<X> {
+ final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+ final foo;
+
+ B(this.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..6bb747c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A<Y>
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ final field dynamic foo = "bar";
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+ final field dynamic foo;
+ constructor •(dynamic foo) → self::B<self::B::Y>
+ : self::B::foo = foo, super self::A::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ final field dynamic foo = "bar";
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+ final field dynamic foo;
+ constructor •(dynamic foo) → self::B<self::B::Y>
+ : self::B::foo = foo, super self::A::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
new file mode 100644
index 0000000..0a5257b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ final field dynamic foo;
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+ final field dynamic foo;
+ constructor •(dynamic foo) → self::B<self::B::Y>
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ final field core::String foo = "bar";
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+ final field core::String foo;
+ constructor •(core::String foo) → self::B<self::B::Y>
+ : self::B::foo = foo, super self::A::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ final field core::String foo = "bar";
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+ final field core::String foo;
+ constructor •(core::String foo) → self::B<self::B::Y>
+ : self::B::foo = foo, super self::A::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart
new file mode 100644
index 0000000..f905aee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.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.
+
+abstract class A<X> {
+ void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+ void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect
new file mode 100644
index 0000000..c985c1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect
@@ -0,0 +1,69 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: A<Y>
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+ method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+ method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect
new file mode 100644
index 0000000..986c56b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+ abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+ synthetic constructor •() → self::B<self::B::Y>
+ ;
+ method foo({generic-covariant-impl core::Iterable<self::B::Y> x}) → void
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+ method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+ method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
index e0cd00f..7e9ace6 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x(dynamic value) → dynamic {}
+ set x(core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
index e0cd00f..7e9ace6 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x(dynamic value) → dynamic {}
+ set x(core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
index 5052808..1ae8232 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
@@ -17,7 +17,7 @@
class D extends self::C implements self::I {
synthetic constructor •() → self::D
;
- set x(dynamic value) → dynamic
+ set x(core::int value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
index b1c6c5f..8793d9b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
@@ -15,7 +15,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- operator []=(core::Object x, core::Object y) → void {}
+ operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void {}
method h() → void {
super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
index b1c6c5f..8793d9b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- operator []=(core::Object x, core::Object y) → void {}
+ operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void {}
method h() → void {
super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
index 80fd653..adfd796 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
@@ -14,7 +14,7 @@
class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
synthetic constructor •() → self::C<self::C::U>
;
- operator []=(core::Object x, core::Object y) → void
+ operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void
;
method h() → void
;
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
index 20df3bc..219fa54 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
@@ -26,7 +26,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- method g(core::Object x) → self::E<asy::Future<self::C::U>>
+ method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
return null;
method h() → void {
dynamic x = super.{self::B::g}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
index 20df3bc..219fa54 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- method g(core::Object x) → self::E<asy::Future<self::C::U>>
+ method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
return null;
method h() → void {
dynamic x = super.{self::B::g}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
index f2b99a5..07019f3 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
@@ -22,7 +22,7 @@
class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
synthetic constructor •() → self::C<self::C::U>
;
- method g(core::Object x) → self::E<asy::Future<self::C::U>>
+ method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
;
method h() → void
;
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
index fd035f1..87b866d 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
@@ -27,7 +27,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
return null;
- set x(core::Object x) → void {}
+ set x(generic-covariant-impl core::Object x) → void {}
method g() → void {
dynamic y = super.{self::B::x};
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
index fd035f1..87b866d 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
return null;
- set x(core::Object x) → void {}
+ set x(generic-covariant-impl core::Object x) → void {}
method g() → void {
dynamic y = super.{self::B::x};
}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
index caa88dc..941b8de 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
@@ -23,7 +23,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
;
- set x(core::Object x) → void
+ set x(generic-covariant-impl core::Object x) → void
;
method g() → void
;
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
index ae129dc..fec3618 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
@@ -27,7 +27,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
return null;
- set x(core::Object x) → void {}
+ set x(generic-covariant-impl core::Object x) → void {}
method g() → void {
super.{self::B::x} = self::f<dynamic>();
}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
index ae129dc..fec3618 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
return null;
- set x(core::Object x) → void {}
+ set x(generic-covariant-impl core::Object x) → void {}
method g() → void {
super.{self::B::x} = self::f<dynamic>();
}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
index 1fa178c..cf71077 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
@@ -23,7 +23,7 @@
;
get x() → self::E<asy::Future<self::C::U>>
;
- set x(core::Object x) → void
+ set x(generic-covariant-impl core::Object x) → void
;
method g() → void
;
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
index 148400f..3a8a7d9 100644
--- a/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
@@ -58,7 +58,7 @@
Object
interfaces:
classMembers:
- Object.toString
+ StackTrace.Object.toString%StackTrace.toString
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -77,7 +77,7 @@
-> StackTrace
interfaces:
classMembers:
- Object.toString
+ StackTrace.Object.toString%StackTrace.toString
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
index 5d9af14..cf441f7 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
@@ -15,8 +15,8 @@
// There's a circularity between b and c because a.f is generic, so the type of
// c is required to infer b, and vice versa.
-var b = /*@returnType=invalid-type*/ () =>
- a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(c);
+var b = /*@returnType=() -> invalid-type*/ () =>
+ a. /*@typeArgs=() -> invalid-type*/ /*@target=A::f*/ f(c);
var c = /*@returnType=invalid-type*/ () =>
a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(b);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
index 1681eb9..2e9f7aa 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
@@ -2,14 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:5: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var c = /*@returnType=invalid-type*/ () =>
-// ^
-//
// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:5: Error: Can't infer the type of 'b': circularity found during type inference.
// Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () =>
+// var b = /*@returnType=() -> invalid-type*/ () =>
// ^
//
import self as self;
@@ -25,8 +20,8 @@
return 0;
}
static field self::A a = new self::A::•();
-static field invalid-type b = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::c)) as{TypeError} invalid-type;
-static field invalid-type c = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::b)) as{TypeError} invalid-type;
+static field invalid-type b = (() → () → invalid-type => self::a.{self::A::f}<() → invalid-type>(self::c)) as{TypeError} invalid-type;
+static field () → invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
static field () → () → core::int d = () → () → core::int => self::a.{self::A::f}<() → core::int>(self::e);
static field () → core::int e = () → core::int => self::a.{self::A::g}(self::d);
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
index 1681eb9..2e9f7aa 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
@@ -2,14 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:5: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var c = /*@returnType=invalid-type*/ () =>
-// ^
-//
// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:5: Error: Can't infer the type of 'b': circularity found during type inference.
// Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () =>
+// var b = /*@returnType=() -> invalid-type*/ () =>
// ^
//
import self as self;
@@ -25,8 +20,8 @@
return 0;
}
static field self::A a = new self::A::•();
-static field invalid-type b = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::c)) as{TypeError} invalid-type;
-static field invalid-type c = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::b)) as{TypeError} invalid-type;
+static field invalid-type b = (() → () → invalid-type => self::a.{self::A::f}<() → invalid-type>(self::c)) as{TypeError} invalid-type;
+static field () → invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
static field () → () → core::int d = () → () → core::int => self::a.{self::A::f}<() → core::int>(self::e);
static field () → core::int e = () → core::int => self::a.{self::A::g}(self::d);
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
index f2657ee..88b2f85 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
@@ -2,11 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:16:5: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var b = a();
-// ^
-//
// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:5: Error: Can't infer the type of 'a': circularity found during type inference.
// Specify the type explicitly.
// var a = /*@returnType=num*/ () => intValue /*@target=num::+*/ + b;
@@ -19,7 +14,7 @@
static field core::num numValue = 0;
static field core::double doubleValue = 0.0;
static field invalid-type a = (() → core::num => self::intValue.{core::num::+}(self::b as{TypeError} core::num)) as{TypeError} invalid-type;
-static field invalid-type b = self::a.call() as{TypeError} invalid-type;
+static field dynamic b = self::a.call();
static field () → core::num c = () → core::num => self::numValue.{core::num::+}(self::d);
static field core::num d = self::c.call();
static field () → core::double e = () → core::double => self::doubleValue.{core::double::+}(self::f);
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
index e436c4f..4f2a4c9 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
@@ -7,11 +7,6 @@
// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
// ^
//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:17:7: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x;
-// ^
-//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
index e436c4f..4f2a4c9 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
@@ -7,11 +7,6 @@
// var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
// ^
//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:17:7: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x;
-// ^
-//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
index 7848afa..cf2893f 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
@@ -56,3 +56,460 @@
Object.==
classSetters:
B.x
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+double:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ double.~/
+ double.minPositive
+ num.<=
+ num._equalToInteger
+ double.maxFinite
+ num.isInfinite
+ num.<
+ double._tryParseDouble
+ double.Object.toString%double.toString
+ double.+
+ double.negativeInfinity
+ num.clamp
+ num.toDouble
+ double._nativeParse
+ double.ceil
+ double.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ double./
+ double.abs
+ double.nan
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ double.remainder
+ double.infinity
+ num.isFinite
+ num.toInt
+ double.%
+ double.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ double.floorToDouble
+ Object._identityHashCode
+ num.>
+ double.roundToDouble
+ double.round
+ double.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ double.truncate
+ double.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ double.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ double.truncateToDouble
+ double.parse
+ double.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ double._parse
+ double.*
+ classSetters:
+ interfaceMembers:
+ double.~/
+ double.minPositive
+ num.<=
+ num._equalToInteger
+ double.maxFinite
+ num.isInfinite
+ num.<
+ double._tryParseDouble
+ double.Object.toString%double.toString
+ double.+
+ double.negativeInfinity
+ num.clamp
+ num.toDouble
+ double._nativeParse
+ double.ceil
+ double.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ double./
+ double.abs
+ double.nan
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ double.remainder
+ double.infinity
+ num.isFinite
+ num.toInt
+ double.%
+ double.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ double.floorToDouble
+ Object._identityHashCode
+ num.>
+ double.roundToDouble
+ double.round
+ double.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ double.truncate
+ double.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ double.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ double.truncateToDouble
+ double.parse
+ double.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ double._parse
+ double.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
index 30f357c..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -10,7 +18,7 @@
abstract set x(core::double value) → void;
}
class B extends self::A {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::B
: super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
index 30f357c..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -10,7 +18,7 @@
abstract set x(core::double value) → void;
}
class B extends self::A {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::B
: super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
index 5006f0f..faa675a 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -9,7 +17,7 @@
abstract set x(core::double value) → void;
}
class B extends self::A {
- field dynamic x;
+ field invalid-type x;
synthetic constructor •() → self::B
;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
index 9a78098..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
@@ -2,13 +2,10 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: The return type of the method 'B.x' is 'int', which does not match the return type, 'double', of the overridden method, 'A.x'.
-// Change to a subtype of 'double'.
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
// var x;
// ^
-// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:10:12: Context: This is the overridden method ('x').
-// void set x(double value);
-// ^
//
import self as self;
import "dart:core" as core;
@@ -21,7 +18,7 @@
abstract set x(core::double value) → void;
}
class B extends self::A {
- field core::int x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::B
: super self::A::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart
new file mode 100644
index 0000000..d6f3096
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.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.
+
+abstract class A {
+ A get x;
+ void set x(B value);
+
+ B get y;
+ void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+ var x;
+ var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect
new file mode 100644
index 0000000..b7417eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ A.y
+ Object.toString
+ A.x
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ A.y
+ A.x
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces:
+ classMembers:
+ A.y
+ Object.toString
+ A.x
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ A.y
+ A.x
+
+C:
+ superclasses:
+ Object
+ -> A
+ -> B
+ interfaces:
+ classMembers:
+ C.y
+ Object.toString
+ C.x
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ C.y
+ C.x
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var y;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract get x() → self::A;
+ abstract set x(self::B value) → void;
+ abstract get y() → self::B;
+ abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ field self::A x = null;
+ field invalid-type y = null;
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var y;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract get x() → self::A;
+ abstract set x(self::B value) → void;
+ abstract get y() → self::B;
+ abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ field self::A x = null;
+ field invalid-type y = null;
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect
new file mode 100644
index 0000000..b6f7118
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var y;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ abstract get x() → self::A;
+ abstract set x(self::B value) → void;
+ abstract get y() → self::B;
+ abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+}
+class C extends self::B {
+ field self::A x;
+ field invalid-type y;
+ synthetic constructor •() → self::C
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var y;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract get x() → self::A;
+ abstract set x(self::B value) → void;
+ abstract get y() → self::B;
+ abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C extends self::B {
+ field self::A x = null;
+ field invalid-type y = null;
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
index 167e1f9..b0e92da 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
@@ -76,3 +76,327 @@
Object.==
classSetters:
C.x
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
index d397440..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -15,7 +23,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
index d397440..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -15,7 +23,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
index c425d73..42cca77 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
@@ -1,4 +1,12 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+// var x;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -13,7 +21,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field dynamic x;
+ field invalid-type x;
synthetic constructor •() → self::C
;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
index 83026ec..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
@@ -2,13 +2,10 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: The return type of the method 'C.x' is 'int', which does not match the return type, 'num', of the overridden method, 'A.x'.
-// Change to a subtype of 'num'.
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
// var x;
// ^
-// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:9:12: Context: This is the overridden method ('x').
-// void set x(num value);
-// ^
//
import self as self;
import "dart:core" as core;
@@ -26,7 +23,7 @@
abstract get x() → core::int;
}
class C extends self::B {
- field core::int x = null;
+ field invalid-type x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
index 3dbfb21..6c951d9 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
@@ -76,3 +76,327 @@
Object.==
classSetters:
C.x
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
index 24c6ed9..eec7015 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
@@ -15,7 +15,7 @@
abstract set x(core::int value) → void;
}
class C extends self::B {
- field dynamic x = null;
+ field core::num x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
index 24c6ed9..eec7015 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
abstract set x(core::int value) → void;
}
class C extends self::B {
- field dynamic x = null;
+ field core::num x = null;
synthetic constructor •() → self::C
: super self::B::•()
;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
index 2d2fda0..ef2b978 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
@@ -13,7 +13,7 @@
abstract set x(core::int value) → void;
}
class C extends self::B {
- field dynamic x;
+ field core::num x;
synthetic constructor •() → self::C
;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
index 9ffd8ea..f24c3f1 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
@@ -8,12 +8,12 @@
// In the code below, there is a circularity between A.b and x.
class A {
- var b = /*@returnType=invalid-type*/ () => x;
- var c = /*@returnType=invalid-type*/ () => x;
+ var b = /*@returnType=() -> invalid-type*/ () => x;
+ var c = /*@returnType=() -> invalid-type*/ () => x;
}
var a = new A();
var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-var y = /*@returnType=() -> invalid-type*/ () => a. /*@target=A::c*/ c;
+var y = /*@returnType=() -> () -> invalid-type*/ () => a. /*@target=A::c*/ c;
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
index 46baf2b..73a2dd9 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
@@ -4,25 +4,20 @@
//
// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:7: Error: Can't infer the type of 'b': circularity found during type inference.
// Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () => x;
+// var b = /*@returnType=() -> invalid-type*/ () => x;
// ^
//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:16:5: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-// ^
-//
import self as self;
import "dart:core" as core;
class A extends core::Object {
- field invalid-type b = (() → invalid-type => self::x) as{TypeError} invalid-type;
- field () → invalid-type c = () → invalid-type => self::x;
+ field invalid-type b = (() → () → invalid-type => self::x) as{TypeError} invalid-type;
+ field () → () → invalid-type c = () → () → invalid-type => self::x;
synthetic constructor •() → self::A
: super core::Object::•()
;
}
static field self::A a = new self::A::•();
-static field invalid-type x = (() → invalid-type => self::a.{self::A::b}) as{TypeError} invalid-type;
-static field () → () → invalid-type y = () → () → invalid-type => self::a.{self::A::c};
+static field () → invalid-type x = () → invalid-type => self::a.{self::A::b};
+static field () → () → () → invalid-type y = () → () → () → invalid-type => self::a.{self::A::c};
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
index 46baf2b..73a2dd9 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
@@ -4,25 +4,20 @@
//
// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:7: Error: Can't infer the type of 'b': circularity found during type inference.
// Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () => x;
+// var b = /*@returnType=() -> invalid-type*/ () => x;
// ^
//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:16:5: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-// ^
-//
import self as self;
import "dart:core" as core;
class A extends core::Object {
- field invalid-type b = (() → invalid-type => self::x) as{TypeError} invalid-type;
- field () → invalid-type c = () → invalid-type => self::x;
+ field invalid-type b = (() → () → invalid-type => self::x) as{TypeError} invalid-type;
+ field () → () → invalid-type c = () → () → invalid-type => self::x;
synthetic constructor •() → self::A
: super core::Object::•()
;
}
static field self::A a = new self::A::•();
-static field invalid-type x = (() → invalid-type => self::a.{self::A::b}) as{TypeError} invalid-type;
-static field () → () → invalid-type y = () → () → invalid-type => self::a.{self::A::c};
+static field () → invalid-type x = () → invalid-type => self::a.{self::A::b};
+static field () → () → () → invalid-type y = () → () → () → invalid-type => self::a.{self::A::c};
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
index f8f9e8f..3493bd8 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
- method f() → dynamic {}
+ method f() → void {}
}
static field dynamic x = new self::C::•().f();
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
index f8f9e8f..3493bd8 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
- method f() → dynamic {}
+ method f() → void {}
}
static field dynamic x = new self::C::•().f();
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
index ac467ff..fbaac00 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
@@ -11,7 +11,7 @@
class C extends self::B {
synthetic constructor •() → self::C
;
- method f() → dynamic
+ method f() → void
;
}
static field dynamic x;
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
index f92d773..5a9daa5 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
@@ -72,7 +72,7 @@
Object.==
classSetters:
interfaceMembers:
- I1.f
+ C.I1.f%I2.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -136,7 +136,7 @@
Object.==
classSetters:
interfaceMembers:
- I2.f
+ E.I2.f%I1.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -181,3 +181,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
index 525f04b..e52d854 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
@@ -18,6 +18,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
+ abstract forwarding-stub method f(core::Object o) → void;
}
class D extends self::C {
synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
index 525f04b..e52d854 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
@@ -18,6 +18,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
+ abstract forwarding-stub method f(core::Object o) → void;
}
class D extends self::C {
synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
index cbba19d..68748a3 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
@@ -15,6 +15,7 @@
abstract class C extends core::Object implements self::I1, self::I2 {
synthetic constructor •() → self::C
;
+ abstract forwarding-stub method f(core::Object o) → void;
}
class D extends self::C {
synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
index 788e92f..d378992 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
@@ -14,7 +14,7 @@
// circularity, and for error recovery their type is set to `dynamic`.
// Thereafter, z infers without problems.
-var x = /*@returnType=invalid-type*/ () => f() ? y : z;
+var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
var y = /*@returnType=invalid-type*/ () => x;
var z = /*@returnType=invalid-type*/ () => x;
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
index 88bfdb0..b228e01 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
@@ -2,22 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:18:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-// ^
-//
// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => f() ? y : z;
+// var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
// ^
//
import self as self;
import "dart:core" as core;
-static field invalid-type x = (() → invalid-type => self::f() ?{invalid-type} self::y : self::z) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
-static field () → dynamic z = () → invalid-type => self::x;
+static field invalid-type x = (() → () → invalid-type => self::f() ?{() → invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
+static field () → invalid-type z = () → invalid-type => self::x;
static method f() → core::bool
return null;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
index 9a54331..b228e01 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
@@ -2,22 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
+// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:5: Error: Can't infer the type of 'x': circularity found during type inference.
// Specify the type explicitly.
-// var /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-// ^
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-// ^
+// var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
+// ^
//
import self as self;
import "dart:core" as core;
-static field dynamic x = () → dynamic => self::f() ?{dynamic} self::y : self::z;
-static field dynamic y = () → dynamic => self::x;
-static field () → dynamic z = () → dynamic => self::x;
+static field invalid-type x = (() → () → invalid-type => self::f() ?{() → invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
+static field () → invalid-type z = () → invalid-type => self::x;
static method f() → core::bool
return null;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
index 0f54c8d..bae8810 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
@@ -26,7 +26,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+ operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
return null;
method h() → void {
dynamic x = super.{self::B::[]}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
index 0f54c8d..bae8810 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
synthetic constructor •() → self::C<self::C::U>
: super self::B::•()
;
- operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+ operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
return null;
method h() → void {
dynamic x = super.{self::B::[]}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
index 12ca495..482f685 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
@@ -22,7 +22,7 @@
class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
synthetic constructor •() → self::C<self::C::U>
;
- operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+ operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
;
method h() → void
;
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
index 00d3da3..59b9ccc 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
@@ -148,7 +148,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- D.foo
+ G.D.foo%E.foo%F.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
index cef6169..869fb78 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
@@ -39,6 +39,7 @@
synthetic constructor •() → self::G
: super core::Object::•()
;
+ abstract forwarding-stub method foo() → self::B;
}
class H extends self::G {
synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
index cef6169..869fb78 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
@@ -39,6 +39,7 @@
synthetic constructor •() → self::G
: super core::Object::•()
;
+ abstract forwarding-stub method foo() → self::B;
}
class H extends self::G {
synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
index 8801b74..b028b33 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
@@ -32,6 +32,7 @@
abstract class G extends core::Object implements self::D, self::E, self::F {
synthetic constructor •() → self::G
;
+ abstract forwarding-stub method foo() → self::B;
}
class H extends self::G {
synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/issue129167943.dart b/pkg/front_end/testcases/issue129167943.dart
new file mode 100644
index 0000000..c7560ea
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.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.
+
+abstract class A {}
+
+abstract class B {
+ void foo(num x);
+}
+
+abstract class C implements B {
+ void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+ void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+ void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+ void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+ void foo(num x);
+}
+
+abstract class E {
+ void set foo(num x);
+}
+
+abstract class G implements E {
+ void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+ void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+ void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+ void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+ void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect b/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect
new file mode 100644
index 0000000..a8b24514
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect
@@ -0,0 +1,778 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D1:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, C, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D2:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, C, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D2.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D2.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D3:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, C, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D3.C.foo%B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D4:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, C, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D4.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D4.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D5:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, C, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D5.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ D5.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+E:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ E.foo
+
+G:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: E
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ G.foo
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ G.foo
+
+H1:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, E, G
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ H1.foo
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ H1.foo
+
+H2:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, E, G
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ H2.foo
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ H2.foo
+
+H3:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, E, G
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ H3.E.foo=%G.foo=
+
+H4:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, E, G
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ H4.foo
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ H4.foo
+
+H5:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ interfaces: A, E, G
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ H5.foo
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+ H5.foo
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/issue129167943.dart.legacy.expect b/pkg/front_end/testcases/issue129167943.dart.legacy.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.legacy.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+abstract class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D1
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D2
+ : super core::Object::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D4
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D5
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+ synthetic constructor •() → self::E
+ : super core::Object::•()
+ ;
+ abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+ synthetic constructor •() → self::G
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H1
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H2
+ : super core::Object::•()
+ ;
+ set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H4
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H5
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+abstract class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D1
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D2
+ : super core::Object::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D4
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D5
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+ synthetic constructor •() → self::E
+ : super core::Object::•()
+ ;
+ abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+ synthetic constructor •() → self::G
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H1
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H2
+ : super core::Object::•()
+ ;
+ set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H4
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H5
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.outline.expect b/pkg/front_end/testcases/issue129167943.dart.outline.expect
new file mode 100644
index 0000000..f6d1af6
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.outline.expect
@@ -0,0 +1,82 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+}
+abstract class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+ synthetic constructor •() → self::C
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D1
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D2
+ ;
+ method foo(covariant core::int x) → void
+ ;
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D3
+ ;
+ abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D4
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D5
+ ;
+ abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+ synthetic constructor •() → self::E
+ ;
+ abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+ synthetic constructor •() → self::G
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H1
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H2
+ ;
+ set foo(covariant core::int x) → void
+ ;
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H3
+ ;
+ abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H4
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H5
+ ;
+ abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/issue129167943.dart.strong.expect b/pkg/front_end/testcases/issue129167943.dart.strong.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.strong.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+abstract class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D1
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D2
+ : super core::Object::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D4
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D5
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+ synthetic constructor •() → self::E
+ : super core::Object::•()
+ ;
+ abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+ synthetic constructor •() → self::G
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H1
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H2
+ : super core::Object::•()
+ ;
+ set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H4
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H5
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect b/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+abstract class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D1
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D2
+ : super core::Object::•()
+ ;
+ method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D4
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+ synthetic constructor •() → self::D5
+ : super core::Object::•()
+ ;
+ abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+ synthetic constructor •() → self::E
+ : super core::Object::•()
+ ;
+ abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+ synthetic constructor •() → self::G
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H1
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H2
+ : super core::Object::•()
+ ;
+ set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H3
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H4
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+ synthetic constructor •() → self::H5
+ : super core::Object::•()
+ ;
+ abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue37381.dart b/pkg/front_end/testcases/issue37381.dart
new file mode 100644
index 0000000..9424045
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// This test checks that the bug reported at http://dartbug.com/37381 is fixed.
+
+class A<X> {
+ R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {
+ A<num> a = A<int>();
+ a.f(<X>(_) => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.hierarchy.expect b/pkg/front_end/testcases/issue37381.dart.hierarchy.expect
new file mode 100644
index 0000000..8f0eb34
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ A.f
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/issue37381.dart.legacy.expect b/pkg/front_end/testcases/issue37381.dart.legacy.expect
new file mode 100644
index 0000000..13d9878
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.legacy.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+ return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+ self::A<core::num> a = new self::A::•<core::int>();
+ a.f(<X extends core::Object = dynamic>(dynamic _) → dynamic => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect
new file mode 100644
index 0000000..13d9878
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+ return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+ self::A<core::num> a = new self::A::•<core::int>();
+ a.f(<X extends core::Object = dynamic>(dynamic _) → dynamic => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.outline.expect b/pkg/front_end/testcases/issue37381.dart.outline.expect
new file mode 100644
index 0000000..74b9165
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+ method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/issue37381.dart.strong.expect b/pkg/front_end/testcases/issue37381.dart.strong.expect
new file mode 100644
index 0000000..4aa8cae
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+ return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+ self::A<core::num> a = new self::A::•<core::int>();
+ a.{self::A::f}<core::int>(<X extends core::Object = dynamic>(self::A<X> _) → core::int => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect b/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect
new file mode 100644
index 0000000..4aa8cae
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+ method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+ return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+ self::A<core::num> a = new self::A::•<core::int>();
+ a.{self::A::f}<core::int>(<X extends core::Object = dynamic>(self::A<X> _) → core::int => 42);
+}
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index b1b1917..45b13a3 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -7,12 +7,14 @@
DeltaBlue: Fail # Fasta and dartk disagree on static initializers
ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
+await_in_non_async: RuntimeError # Expected.
bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
call: Fail # Test can't run.
constructor_const_inference: RuntimeError # Test exercises strong mode semantics. See also Issue #33813.
constructor_initializer_invalid: RuntimeError # Fails execution after recovery
control_flow_collection: RuntimeError
duplicated_field_initializer: RuntimeError
+extension_methods: RuntimeError
external_import: RuntimeError # Expected -- test uses import which doesn't exist.
fallthrough: Fail # Missing FallThroughError.
function_type_recovery: Fail
@@ -37,6 +39,7 @@
micro: Fail # External method marked abstract.
minimum_int: Crash # Min int literal not supported in non-strong mode.
named_parameters: Fail # Missing types and unnecessary default values.
+nnbd/nullable_param: RuntimeError
operator_method_not_found: RuntimeError # Expected
optional: Fail # Unnecessary default values.
rasta/abstract_constructor: Fail
@@ -118,6 +121,7 @@
regress/issue_36647: RuntimeError # Expected
regress/issue_36647_2: RuntimeError # Expected
regress/issue_36669: RuntimeError
+regress/issue_37285: RuntimeError
reject_generic_function_types_in_bounds: RuntimeError # Expected
runtime_checks/implicit_downcast_constructor_initializer: RuntimeError # Test exercises strong mode semantics
runtime_checks/implicit_downcast_do: RuntimeError # Test exercises strong mode semantics
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
index 8351797..2d41275 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
@@ -115,7 +115,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A0.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -128,7 +128,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A0.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -180,7 +180,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A1.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -193,7 +193,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A1.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -279,7 +279,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A2.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -292,7 +292,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ A2.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -311,7 +311,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -324,7 +324,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -344,7 +344,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -357,7 +357,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -409,7 +409,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -422,7 +422,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -443,7 +443,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -456,7 +456,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -542,7 +542,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -555,7 +555,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -577,7 +577,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -590,7 +590,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _A2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -609,7 +609,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -622,7 +622,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -642,7 +642,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -655,7 +655,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -707,7 +707,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -720,7 +720,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -741,7 +741,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -754,7 +754,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -840,7 +840,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -853,7 +853,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -875,7 +875,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -888,7 +888,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -907,7 +907,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -920,7 +920,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -940,7 +940,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -953,7 +953,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -974,7 +974,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -987,7 +987,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ S with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1039,7 +1039,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1052,7 +1052,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1073,7 +1073,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1086,7 +1086,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1108,7 +1108,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1121,7 +1121,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B1X&S&M1 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1207,7 +1207,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1220,7 +1220,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1242,7 +1242,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1255,7 +1255,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1278,7 +1278,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -1291,7 +1291,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- M.foo
+ _B2X&S&M1&M2 with M.M.foo%S.foo
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
index b5c4a61..6856ac8 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
@@ -156,6 +156,7 @@
synthetic constructor •() → self::A0
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A1&S&M1 = self::S with self::M1 {
synthetic constructor •() → self::_A1&S&M1
@@ -166,6 +167,7 @@
synthetic constructor •() → self::A1
: super self::_A1&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A2&S&M1 = self::S with self::M1 {
synthetic constructor •() → self::_A2&S&M1
@@ -181,11 +183,13 @@
synthetic constructor •() → self::A2
: super self::_A2&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A0X&S&M = self::S with self::M {
synthetic constructor •() → self::_A0X&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A0X = self::_A0X&S&M with self::MX {
synthetic constructor •() → self::A0X
@@ -201,6 +205,7 @@
synthetic constructor •() → self::_A1X&S&M1&M
: super self::_A1X&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A1X = self::_A1X&S&M1&M with self::MX {
synthetic constructor •() → self::A1X
@@ -221,6 +226,7 @@
synthetic constructor •() → self::_A2X&S&M1&M2&M
: super self::_A2X&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A2X = self::_A2X&S&M1&M2&M with self::MX {
synthetic constructor •() → self::A2X
@@ -231,6 +237,7 @@
synthetic constructor •() → self::_B0&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B0 extends self::_B0&S&M {
synthetic constructor •() → self::B0
@@ -246,6 +253,7 @@
synthetic constructor •() → self::_B1&S&M1&M
: super self::_B1&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B1 extends self::_B1&S&M1&M {
synthetic constructor •() → self::B1
@@ -266,6 +274,7 @@
synthetic constructor •() → self::_B2&S&M1&M2&M
: super self::_B2&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B2 extends self::_B2&S&M1&M2&M {
synthetic constructor •() → self::B2
@@ -276,6 +285,7 @@
synthetic constructor •() → self::_B0X&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B0X&S&M&MX = self::_B0X&S&M with self::MX {
synthetic constructor •() → self::_B0X&S&M&MX
@@ -296,6 +306,7 @@
synthetic constructor •() → self::_B1X&S&M1&M
: super self::_B1X&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B1X&S&M1&M&MX = self::_B1X&S&M1&M with self::MX {
synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -321,6 +332,7 @@
synthetic constructor •() → self::_B2X&S&M1&M2&M
: super self::_B2X&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B2X&S&M1&M2&M&MX = self::_B2X&S&M1&M2&M with self::MX {
synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
index c5a8827..f59920c 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
@@ -156,7 +156,7 @@
synthetic constructor •() → self::A0
: super self::S::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A1&S&M1 extends self::S implements self::M1 {
synthetic constructor •() → self::_A1&S&M1
@@ -167,7 +167,7 @@
synthetic constructor •() → self::A1
: super self::_A1&S&M1::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A2&S&M1 extends self::S implements self::M1 {
synthetic constructor •() → self::_A2&S&M1
@@ -183,13 +183,13 @@
synthetic constructor •() → self::A2
: super self::_A2&S&M1&M2::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _A0X&S&M extends self::S implements self::M {
synthetic constructor •() → self::_A0X&S&M
: super self::S::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A0X extends self::_A0X&S&M implements self::MX {
synthetic constructor •() → self::A0X
@@ -205,7 +205,7 @@
synthetic constructor •() → self::_A1X&S&M1&M
: super self::_A1X&S&M1::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A1X extends self::_A1X&S&M1&M implements self::MX {
synthetic constructor •() → self::A1X
@@ -226,7 +226,7 @@
synthetic constructor •() → self::_A2X&S&M1&M2&M
: super self::_A2X&S&M1&M2::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class A2X extends self::_A2X&S&M1&M2&M implements self::MX {
synthetic constructor •() → self::A2X
@@ -237,7 +237,7 @@
synthetic constructor •() → self::_B0&S&M
: super self::S::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B0 extends self::_B0&S&M {
synthetic constructor •() → self::B0
@@ -253,7 +253,7 @@
synthetic constructor •() → self::_B1&S&M1&M
: super self::_B1&S&M1::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B1 extends self::_B1&S&M1&M {
synthetic constructor •() → self::B1
@@ -274,7 +274,7 @@
synthetic constructor •() → self::_B2&S&M1&M2&M
: super self::_B2&S&M1&M2::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
class B2 extends self::_B2&S&M1&M2&M {
synthetic constructor •() → self::B2
@@ -285,7 +285,7 @@
synthetic constructor •() → self::_B0X&S&M
: super self::S::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B0X&S&M&MX extends self::_B0X&S&M implements self::MX {
synthetic constructor •() → self::_B0X&S&M&MX
@@ -306,7 +306,7 @@
synthetic constructor •() → self::_B1X&S&M1&M
: super self::_B1X&S&M1::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B1X&S&M1&M&MX extends self::_B1X&S&M1&M implements self::MX {
synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -332,7 +332,7 @@
synthetic constructor •() → self::_B2X&S&M1&M2&M
: super self::_B2X&S&M1&M2::•()
;
- method foo() → dynamic {}
+ abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
}
abstract class _B2X&S&M1&M2&M&MX extends self::_B2X&S&M1&M2&M implements self::MX {
synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
index 9983cfb..a241bd6 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
@@ -153,6 +153,7 @@
synthetic constructor •() → self::A0
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _A1&S&M1 = self::S with self::M1 {
synthetic constructor •() → self::_A1&S&M1
@@ -163,6 +164,7 @@
synthetic constructor •() → self::A1
: super self::_A1&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _A2&S&M1 = self::S with self::M1 {
synthetic constructor •() → self::_A2&S&M1
@@ -178,11 +180,13 @@
synthetic constructor •() → self::A2
: super self::_A2&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _A0X&S&M = self::S with self::M {
synthetic constructor •() → self::_A0X&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class A0X = self::_A0X&S&M with self::MX {
synthetic constructor •() → self::A0X
@@ -198,6 +202,7 @@
synthetic constructor •() → self::_A1X&S&M1&M
: super self::_A1X&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class A1X = self::_A1X&S&M1&M with self::MX {
synthetic constructor •() → self::A1X
@@ -218,6 +223,7 @@
synthetic constructor •() → self::_A2X&S&M1&M2&M
: super self::_A2X&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class A2X = self::_A2X&S&M1&M2&M with self::MX {
synthetic constructor •() → self::A2X
@@ -228,6 +234,7 @@
synthetic constructor •() → self::_B0&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class B0 extends self::_B0&S&M {
synthetic constructor •() → self::B0
@@ -242,6 +249,7 @@
synthetic constructor •() → self::_B1&S&M1&M
: super self::_B1&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class B1 extends self::_B1&S&M1&M {
synthetic constructor •() → self::B1
@@ -261,6 +269,7 @@
synthetic constructor •() → self::_B2&S&M1&M2&M
: super self::_B2&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
class B2 extends self::_B2&S&M1&M2&M {
synthetic constructor •() → self::B2
@@ -270,6 +279,7 @@
synthetic constructor •() → self::_B0X&S&M
: super self::S::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _B0X&S&M&MX = self::_B0X&S&M with self::MX {
synthetic constructor •() → self::_B0X&S&M&MX
@@ -289,6 +299,7 @@
synthetic constructor •() → self::_B1X&S&M1&M
: super self::_B1X&S&M1::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _B1X&S&M1&M&MX = self::_B1X&S&M1&M with self::MX {
synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -313,6 +324,7 @@
synthetic constructor •() → self::_B2X&S&M1&M2&M
: super self::_B2X&S&M1&M2::•()
;
+ abstract forwarding-stub method foo([dynamic x]) → dynamic;
}
abstract class _B2X&S&M1&M2&M&MX = self::_B2X&S&M1&M2&M with self::MX {
synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/native_as_name.dart.legacy.expect b/pkg/front_end/testcases/native_as_name.dart.legacy.expect
index 52a151a..b2691b8 100644
--- a/pkg/front_end/testcases/native_as_name.dart.legacy.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.legacy.expect
@@ -34,7 +34,7 @@
synthetic constructor •() → self::Z
: super core::Object::•()
;
- set native(core::String s) → dynamic
+ set native(core::String s) → void
return this.{self::Z::f} = s;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
index 52a151a..b2691b8 100644
--- a/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
@@ -34,7 +34,7 @@
synthetic constructor •() → self::Z
: super core::Object::•()
;
- set native(core::String s) → dynamic
+ set native(core::String s) → void
return this.{self::Z::f} = s;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/native_as_name.dart.outline.expect b/pkg/front_end/testcases/native_as_name.dart.outline.expect
index b78f8ae..c2df01d 100644
--- a/pkg/front_end/testcases/native_as_name.dart.outline.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.outline.expect
@@ -29,7 +29,7 @@
field core::String f;
synthetic constructor •() → self::Z
;
- set native(core::String s) → dynamic
+ set native(core::String s) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart b/pkg/front_end/testcases/nnbd/nullable_param.dart
new file mode 100644
index 0000000..5de460c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.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 Foo {
+ int? field;
+ int? bar(int? x);
+}
+
+main() {
+ Foo foo = new Foo();
+ foo.field = 5;
+ foo.bar(6);
+
+ test_nullable_function_type_formal_param(f: () => 2);
+}
+
+int test_nullable_function_type_formal_param({int f()? : null}) {
+ return f() ?? -1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect
new file mode 100644
index 0000000..2d561e3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+Foo:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Foo.bar
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Foo.field
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ Foo.field
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect
new file mode 100644
index 0000000..f852bba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? field;
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+// - Foo.bar
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+// ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+// int? bar(int? x);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+ field core::int field = null;
+ synthetic constructor •() → self::Foo
+ : super core::Object::•()
+ ;
+ abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+ self::Foo foo = new self::Foo::•();
+ foo.field = 5;
+ foo.bar(6);
+ self::test_nullable_function_type_formal_param(f: () → dynamic => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+ return let final dynamic #t1 = f.call() in #t1.==(null) ? 1.unary-() : #t1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f852bba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? field;
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+// - Foo.bar
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+// ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+// int? bar(int? x);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+ field core::int field = null;
+ synthetic constructor •() → self::Foo
+ : super core::Object::•()
+ ;
+ abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+ self::Foo foo = new self::Foo::•();
+ foo.field = 5;
+ foo.bar(6);
+ self::test_nullable_function_type_formal_param(f: () → dynamic => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+ return let final dynamic #t1 = f.call() in #t1.==(null) ? 1.unary-() : #t1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
new file mode 100644
index 0000000..f909c50
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? field;
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+// - Foo.bar
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+// ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+// int? bar(int? x);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+ field core::int field;
+ synthetic constructor •() → self::Foo
+ ;
+ abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic
+ ;
+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
new file mode 100644
index 0000000..81c9259
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? field;
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+// - Foo.bar
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+// ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+// int? bar(int? x);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+ field core::int field = null;
+ synthetic constructor •() → self::Foo
+ : super core::Object::•()
+ ;
+ abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+ 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);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → 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
new file mode 100644
index 0000000..81c9259
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? field;
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int? bar(int? x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+// ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+// - Foo.bar
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+// ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+// int? bar(int? x);
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+ field core::int field = null;
+ synthetic constructor •() → self::Foo
+ : super core::Object::•()
+ ;
+ abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+ 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);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → 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/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
index 11c8d48..d420935 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
no-such-method-forwarder get foo() → core::int
return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
index 11c8d48..d420935 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
no-such-method-forwarder get foo() → core::int
return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
index 1756340..e7230a4 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
@@ -10,7 +10,7 @@
class A extends core::Object implements self::I {
synthetic constructor •() → self::A
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
no-such-method-forwarder get foo() → core::int
return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
index 2e65c41..8387d6d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
@@ -34,6 +34,6 @@
}
static method main() → dynamic {
self::A a = new self::A::•();
- self::expectTypeError(() → core::int => a.{self::A::foo});
+ self::expectTypeError(() → core::int => a.{self::I::foo});
self::expectTypeError(() → core::String => (a as dynamic).foo = "bar");
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
index 2e65c41..8387d6d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
@@ -34,6 +34,6 @@
}
static method main() → dynamic {
self::A a = new self::A::•();
- self::expectTypeError(() → core::int => a.{self::A::foo});
+ self::expectTypeError(() → core::int => a.{self::I::foo});
self::expectTypeError(() → core::String => (a as dynamic).foo = "bar");
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
index 0e0e756..fa7bf1f 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
self::count = self::count.+(1);
return null;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
index e0f993c..dae5f70 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
self::count = self::count.+(1);
return null;
}
@@ -25,7 +25,7 @@
const synthetic constructor •() → self::_C&Object&B
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
self::count = self::count.+(1);
return null;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
index d92df10..11ba2e6 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
@@ -10,7 +10,7 @@
class B extends core::Object implements self::A {
synthetic constructor •() → self::B
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
no-such-method-forwarder get foo() → core::int
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
index c7fedd2..b172437 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
@@ -14,7 +14,7 @@
;
get foo() → core::int
return 42;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
}
class C extends self::B {
@@ -29,7 +29,7 @@
: super core::Object::•()
;
set foo(core::int value) → void {}
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
index c7fedd2..b172437 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
@@ -14,7 +14,7 @@
;
get foo() → core::int
return 42;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
}
class C extends self::B {
@@ -29,7 +29,7 @@
: super core::Object::•()
;
set foo(core::int value) → void {}
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return "bar";
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
index 523367d..ed38e84 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
@@ -12,7 +12,7 @@
;
get foo() → core::int
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
}
class C extends self::B {
@@ -26,7 +26,7 @@
;
set foo(core::int value) → void
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
index cb4a71e..7417039 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
@@ -51,5 +51,5 @@
self::C c = new self::C::•();
self::expectTypeError(() → core::String => (c as dynamic).foo = "bar");
self::E e = new self::E::•();
- self::expectTypeError(() → core::int => e.{self::E::foo});
+ self::expectTypeError(() → core::int => e.{self::A::foo});
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
index cb4a71e..7417039 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
@@ -51,5 +51,5 @@
self::C c = new self::C::•();
self::expectTypeError(() → core::String => (c as dynamic).foo = "bar");
self::E e = new self::E::•();
- self::expectTypeError(() → core::int => e.{self::E::foo});
+ self::expectTypeError(() → core::int => e.{self::A::foo});
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
index ed949f6..3daf444 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return <dynamic>[];
no-such-method-forwarder get foo() → core::List<core::int>
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
index ed949f6..3daf444 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return <dynamic>[];
no-such-method-forwarder get foo() → core::List<core::int>
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
index 9679fbf..0cdcb88 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
@@ -10,7 +10,7 @@
class B extends core::Object implements self::A<core::int> {
synthetic constructor •() → self::B
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
no-such-method-forwarder get foo() → core::List<core::int>
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
index 0b0b415..a705020 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
@@ -29,6 +29,6 @@
}
static method main() → dynamic {
self::B b = new self::B::•();
- self::expectTypeError(() → core::List<core::int> => b.{self::B::foo});
+ self::expectTypeError(() → core::List<core::int> => b.{self::A::foo});
self::expectTypeError(() → core::List<dynamic> => (b as dynamic).foo = <dynamic>[]);
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
index 0b0b415..a705020 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
@@ -29,6 +29,6 @@
}
static method main() → dynamic {
self::B b = new self::B::•();
- self::expectTypeError(() → core::List<core::int> => b.{self::B::foo});
+ self::expectTypeError(() → core::List<core::int> => b.{self::A::foo});
self::expectTypeError(() → core::List<dynamic> => (b as dynamic).foo = <dynamic>[]);
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
index 521bedd..b71a516 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
@@ -18,7 +18,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return null;
no-such-method-forwarder method foo() → dynamic
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
index 528ca88..7cd29a7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
synthetic constructor •() → self::B
: super core::Object::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return null;
no-such-method-forwarder method foo() → dynamic
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -27,7 +27,7 @@
synthetic constructor •() → self::_C&A&B
: super self::A::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return null;
}
class C extends self::_C&A&B {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
index 8007c45..f04505e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
@@ -16,7 +16,7 @@
class B extends core::Object implements self::I {
synthetic constructor •() → self::B
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
;
no-such-method-forwarder method foo() → dynamic
return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
index 5f6f35b..075405d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
@@ -31,10 +31,10 @@
static method main() → dynamic {
self::B b = new self::B::•();
dynamic value;
- if(!(value = b.{self::B::foo}()).{core::String::==}("baz")) {
+ if(!(value = b.{self::A::foo}()).{core::String::==}("baz")) {
throw "Unexpected value: '${value}'; expected 'baz'.";
}
- if(!(value = b.{self::B::hest}()).{core::num::==}(42)) {
+ if(!(value = b.{self::A::hest}()).{core::num::==}(42)) {
throw "Unexpected value: '${value}'; expected '42'.";
}
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
index 5f6f35b..075405d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
@@ -31,10 +31,10 @@
static method main() → dynamic {
self::B b = new self::B::•();
dynamic value;
- if(!(value = b.{self::B::foo}()).{core::String::==}("baz")) {
+ if(!(value = b.{self::A::foo}()).{core::String::==}("baz")) {
throw "Unexpected value: '${value}'; expected 'baz'.";
}
- if(!(value = b.{self::B::hest}()).{core::num::==}(42)) {
+ if(!(value = b.{self::A::hest}()).{core::num::==}(42)) {
throw "Unexpected value: '${value}'; expected '42'.";
}
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
index f0470a5..f405f12 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return null;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
index f0470a5..f405f12 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return null;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
index 32e8f80..e5f2ba8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
@@ -5,7 +5,7 @@
abstract class A extends core::Object {
synthetic constructor •() → self::A
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
index bf620af..05f2839 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return null;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
index bf620af..05f2839 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
return null;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
index e72d0cf..df83640 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
@@ -5,7 +5,7 @@
abstract class A extends core::Object {
synthetic constructor •() → self::A
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
abstract method foo() → void;
}
diff --git a/pkg/front_end/testcases/operators.dart.legacy.expect b/pkg/front_end/testcases/operators.dart.legacy.expect
index 9760fe2..639223b 100644
--- a/pkg/front_end/testcases/operators.dart.legacy.expect
+++ b/pkg/front_end/testcases/operators.dart.legacy.expect
@@ -18,7 +18,7 @@
return null;
operator /(dynamic other) → dynamic
return null;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return null;
operator >(dynamic other) → dynamic
return null;
diff --git a/pkg/front_end/testcases/operators.dart.legacy.transformed.expect b/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
index 9760fe2..639223b 100644
--- a/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
return null;
operator /(dynamic other) → dynamic
return null;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return null;
operator >(dynamic other) → dynamic
return null;
diff --git a/pkg/front_end/testcases/operators.dart.outline.expect b/pkg/front_end/testcases/operators.dart.outline.expect
index 22aa8c4..68ed1ff 100644
--- a/pkg/front_end/testcases/operators.dart.outline.expect
+++ b/pkg/front_end/testcases/operators.dart.outline.expect
@@ -17,7 +17,7 @@
;
operator /(dynamic other) → dynamic
;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
;
operator >(dynamic other) → dynamic
;
diff --git a/pkg/front_end/testcases/optional.dart.outline.expect b/pkg/front_end/testcases/optional.dart.outline.expect
index 0f681fd..03d2b6e 100644
--- a/pkg/front_end/testcases/optional.dart.outline.expect
+++ b/pkg/front_end/testcases/optional.dart.outline.expect
@@ -22,13 +22,13 @@
class TestListener extends self::Listener {
synthetic constructor •() → self::TestListener
;
- method event(dynamic input, [dynamic x, dynamic y]) → void
+ method event(core::String input, [core::int x, core::int y]) → void
;
}
class ExtendedListener extends self::Listener {
synthetic constructor •() → self::ExtendedListener
;
- method event(dynamic input, [dynamic x, dynamic y, dynamic z]) → void
+ method event(core::String input, [core::int x, core::int y, dynamic z]) → void
;
}
class InvalidListener extends core::Object {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
index cf84a61..b8259ec 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
@@ -24,8 +24,8 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x(dynamic value) → void {}
- get y() → dynamic
+ set x(self::A value) → void {}
+ get y() → self::B
return null;
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
index cf84a61..b8259ec 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
@@ -24,8 +24,8 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x(dynamic value) → void {}
- get y() → dynamic
+ set x(self::A value) → void {}
+ get y() → self::B
return null;
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
index 98a1f1b..f6baaa1 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
@@ -21,9 +21,9 @@
class D extends self::C {
synthetic constructor •() → self::D
;
- set x(dynamic value) → void
+ set x(self::A value) → void
;
- get y() → dynamic
+ get y() → self::B
;
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
index 7a03141..ec9f575 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
@@ -27,7 +27,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x1(self::B value) → void {}
+ set x1(covariant self::B value) → void {}
set x2(covariant self::B value) → void {}
set x3(covariant self::B value) → void {}
set x4(self::B value) → void {}
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
index 7a03141..ec9f575 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- set x1(self::B value) → void {}
+ set x1(covariant self::B value) → void {}
set x2(covariant self::B value) → void {}
set x3(covariant self::B value) → void {}
set x4(self::B value) → void {}
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
index f5ae95c..eb8c429 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
@@ -29,7 +29,7 @@
class D extends self::C {
synthetic constructor •() → self::D
;
- set x1(self::B value) → void
+ set x1(covariant self::B value) → void
;
set x2(covariant self::B value) → void
;
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
index deaf420..adf56f6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
@@ -22,7 +22,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f(dynamic x) → void {}
+ method f(self::A x) → void {}
}
class E extends self::D {
synthetic constructor •() → self::E
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
index deaf420..adf56f6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
@@ -22,7 +22,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f(dynamic x) → void {}
+ method f(self::A x) → void {}
}
class E extends self::D {
synthetic constructor •() → self::E
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect b/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
index 82c9ce4..6f3f1e6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
@@ -19,7 +19,7 @@
class D extends self::C {
synthetic constructor •() → self::D
;
- method f(dynamic x) → void
+ method f(self::A x) → void
;
}
class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
index dd0c4d5..05d92ea 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void {}
+ method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
index dd0c4d5..05d92ea 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
synthetic constructor •() → self::B
: super self::A::•()
;
- method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void {}
+ method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
index e836ac4..713595c 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
@@ -11,7 +11,7 @@
class B extends self::A<core::String> {
synthetic constructor •() → self::B
;
- method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void
+ method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
index bd8f94e..30f268c 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
@@ -27,7 +27,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f1(self::B x) → void {}
+ method f1(covariant self::B x) → void {}
method f2(covariant self::B x) → void {}
method f3(covariant self::B x) → void {}
method f4(self::B x) → void {}
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
index bd8f94e..30f268c 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f1(self::B x) → void {}
+ method f1(covariant self::B x) → void {}
method f2(covariant self::B x) → void {}
method f3(covariant self::B x) → void {}
method f4(self::B x) → void {}
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
index 2d4aa32..5ff196d 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
@@ -29,7 +29,7 @@
class D extends self::C {
synthetic constructor •() → self::D
;
- method f1(self::B x) → void
+ method f1(covariant self::B x) → void
;
method f2(covariant self::B x) → void
;
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart b/pkg/front_end/testcases/override_inference_for_setters.dart
new file mode 100644
index 0000000..0da2cf9
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart
@@ -0,0 +1,14 @@
+// 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 B {
+ num get foo => null;
+ set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+ set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect
new file mode 100644
index 0000000..b1e3c8a
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ B.foo
+
+A:
+ superclasses:
+ Object
+ -> B
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ A.foo
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ get foo() → core::num
+ return null;
+ set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+ synthetic constructor •() → self::A
+ : super self::B::•()
+ ;
+ set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ get foo() → core::num
+ return null;
+ set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+ synthetic constructor •() → self::A
+ : super self::B::•()
+ ;
+ set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect
new file mode 100644
index 0000000..1c22d1f
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ get foo() → core::num
+ ;
+ set foo(dynamic newFoo) → void
+ ;
+}
+class A extends self::B {
+ synthetic constructor •() → self::A
+ ;
+ set foo(dynamic newFoo) → void
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ get foo() → core::num
+ return null;
+ set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+ synthetic constructor •() → self::A
+ : super self::B::•()
+ ;
+ set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ get foo() → core::num
+ return null;
+ set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+ synthetic constructor •() → self::A
+ : super self::B::•()
+ ;
+ set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart
new file mode 100644
index 0000000..d5210c1
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.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.
+
+// The test checks that override-based inference for named parameters isn't
+// affected by the name-based ordering of the parameters.
+
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+// A1, B1, and C1 are similar to A, B, and C, only they have the names of the
+// named parameters swapped, to test that the alternative ordering works.
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
new file mode 100644
index 0000000..9fb9b41
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
@@ -0,0 +1,133 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ -> A
+ -> B
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A1:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B1:
+ superclasses:
+ Object
+ -> A1
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C1:
+ superclasses:
+ Object
+ -> A1
+ -> B1
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
new file mode 100644
index 0000000..7a732b2
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
index 5a47079..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
@@ -15,7 +15,7 @@
C() : field = null;
^^^^^"
;
- set field(dynamic value) → dynamic {}
+ set field(dynamic value) → void {}
}
static method main() → dynamic {
new self::C::•();
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
index 5a47079..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
C() : field = null;
^^^^^"
;
- set field(dynamic value) → dynamic {}
+ set field(dynamic value) → void {}
}
static method main() → dynamic {
new self::C::•();
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
index 97d6cdd..1f58e29 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
@@ -5,7 +5,7 @@
class C extends core::Object {
constructor •() → self::C
;
- set field(dynamic value) → dynamic
+ set field(dynamic value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
index 5fabc15..3be7ccc 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
@@ -4,7 +4,7 @@
static get x() → dynamic
return 42;
-static set x(dynamic val) → dynamic {}
+static set x(dynamic val) → void {}
static method main() → dynamic {
core::print(self::x);
core::print(self::x = 87);
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
index 5fabc15..3be7ccc 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
@@ -4,7 +4,7 @@
static get x() → dynamic
return 42;
-static set x(dynamic val) → dynamic {}
+static set x(dynamic val) → void {}
static method main() → dynamic {
core::print(self::x);
core::print(self::x = 87);
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
index aab1950..8ee979d 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
@@ -3,7 +3,7 @@
static get x() → dynamic
;
-static set x(dynamic val) → dynamic
+static set x(dynamic val) → void
;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
index 6fe92fb..953dad2 100644
--- a/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
@@ -67,7 +67,7 @@
Object.toString
Object.runtimeType
Object._simpleInstanceOf
- M1.v2
+ C.M1.v2%A.v2
Object._instanceOf
Object.noSuchMethod
Object._identityHashCode
@@ -77,13 +77,13 @@
Object._simpleInstanceOfTrue
Object.==
classSetters:
- M1.v2
+ C.M1.v2%A.v2
A.v1
interfaceMembers:
Object.toString
Object.runtimeType
Object._simpleInstanceOf
- M1.v2
+ C.M1.v2%A.v2
Object._instanceOf
Object.noSuchMethod
Object._identityHashCode
@@ -93,5 +93,5 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- M1.v2
+ C.M1.v2%A.v2
A.v1
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
index 230c10b..4dbd973 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return throw "x";
method test() → dynamic {
super.{core::Object::==}(null);
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
index 230c10b..4dbd973 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return throw "x";
method test() → dynamic {
super.{core::Object::==}(null);
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
index bc032b0..f3f1fd5 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
@@ -5,7 +5,7 @@
class C extends core::Object {
synthetic constructor •() → self::C
;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
;
method test() → dynamic
;
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
index cb7bd6b..b12559d 100644
--- a/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
@@ -11,7 +11,7 @@
field core::int _hashCode;
synthetic constructor •() → self::Sub
;
- get hashCode() → dynamic
+ get hashCode() → core::int
;
method foo() → dynamic
;
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
index a7ea25b..fc3831b 100644
--- a/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
@@ -5,7 +5,7 @@
class Bar extends core::Object {
get x() → self::Bar
;
- set x(self::Bar value) → dynamic
+ set x(self::Bar value) → void
;
method f() → dynamic
;
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
index 70d0f8c..b9c1b3e 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
@@ -150,7 +150,7 @@
static method staticFunction() → dynamic {}
static get staticGetter() → dynamic
return null;
- static set staticSetter(dynamic _) → dynamic {}
+ static set staticSetter(dynamic _) → void {}
}
static method use(dynamic x) → dynamic {
if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
index 70d0f8c..b9c1b3e 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
@@ -150,7 +150,7 @@
static method staticFunction() → dynamic {}
static get staticGetter() → dynamic
return null;
- static set staticSetter(dynamic _) → dynamic {}
+ static set staticSetter(dynamic _) → void {}
}
static method use(dynamic x) → dynamic {
if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
diff --git a/pkg/front_end/testcases/rasta/static.dart.outline.expect b/pkg/front_end/testcases/rasta/static.dart.outline.expect
index f9b177a..2e9d362 100644
--- a/pkg/front_end/testcases/rasta/static.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.outline.expect
@@ -11,7 +11,7 @@
;
static get staticGetter() → dynamic
;
- static set staticSetter(dynamic _) → dynamic
+ static set staticSetter(dynamic _) → void
;
}
static method use(dynamic x) → dynamic
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
index 55dfd57..dbd7908 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
@@ -253,24 +253,24 @@
;
get e() → dynamic
return null;
- set g(dynamic _) → dynamic {}
+ set g(dynamic _) → void {}
get h() → dynamic
return null;
- set h(dynamic _) → dynamic {}
+ set h(dynamic _) → void {}
get i() → dynamic
return null;
operator [](dynamic _) → dynamic
return null;
- operator []=(dynamic a, dynamic b) → dynamic {}
+ operator []=(dynamic a, dynamic b) → void {}
operator ~() → dynamic
return 117;
operator unary-() → dynamic
return 117;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return true;
method m() → void {}
method n() → void {}
- set n(dynamic _) → dynamic {}
+ set n(dynamic _) → void {}
}
class B extends self::A {
final field dynamic d = null;
@@ -279,8 +279,8 @@
;
get b() → dynamic
return null;
- set c(dynamic x) → dynamic {}
- set i(dynamic x) → dynamic {}
+ set c(dynamic x) → void {}
+ set i(dynamic x) → void {}
}
class C extends self::B {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
index 55dfd57..dbd7908 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
@@ -253,24 +253,24 @@
;
get e() → dynamic
return null;
- set g(dynamic _) → dynamic {}
+ set g(dynamic _) → void {}
get h() → dynamic
return null;
- set h(dynamic _) → dynamic {}
+ set h(dynamic _) → void {}
get i() → dynamic
return null;
operator [](dynamic _) → dynamic
return null;
- operator []=(dynamic a, dynamic b) → dynamic {}
+ operator []=(dynamic a, dynamic b) → void {}
operator ~() → dynamic
return 117;
operator unary-() → dynamic
return 117;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
return true;
method m() → void {}
method n() → void {}
- set n(dynamic _) → dynamic {}
+ set n(dynamic _) → void {}
}
class B extends self::A {
final field dynamic d = null;
@@ -279,8 +279,8 @@
;
get b() → dynamic
return null;
- set c(dynamic x) → dynamic {}
- set i(dynamic x) → dynamic {}
+ set c(dynamic x) → void {}
+ set i(dynamic x) → void {}
}
class C extends self::B {
synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/rasta/super.dart.outline.expect b/pkg/front_end/testcases/rasta/super.dart.outline.expect
index d668783..9b0da41 100644
--- a/pkg/front_end/testcases/rasta/super.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.outline.expect
@@ -22,29 +22,29 @@
;
get e() → dynamic
;
- set g(dynamic _) → dynamic
+ set g(dynamic _) → void
;
get h() → dynamic
;
- set h(dynamic _) → dynamic
+ set h(dynamic _) → void
;
get i() → dynamic
;
operator [](dynamic _) → dynamic
;
- operator []=(dynamic a, dynamic b) → dynamic
+ operator []=(dynamic a, dynamic b) → void
;
operator ~() → dynamic
;
operator unary-() → dynamic
;
- operator ==(dynamic other) → dynamic
+ operator ==(dynamic other) → core::bool
;
method m() → void
;
method n() → void
;
- set n(dynamic _) → dynamic
+ set n(dynamic _) → void
;
}
class B extends self::A {
@@ -53,9 +53,9 @@
;
get b() → dynamic
;
- set c(dynamic x) → dynamic
+ set c(dynamic x) → void
;
- set i(dynamic x) → dynamic
+ set i(dynamic x) → void
;
}
class C extends self::B {
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect b/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
index d0ecc4d..01e59ad 100644
--- a/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
@@ -9,7 +9,7 @@
;
operator [](dynamic i) → dynamic
;
- operator []=(dynamic i, dynamic val) → dynamic
+ operator []=(dynamic i, dynamic val) → void
;
}
class B extends self::A {
@@ -19,7 +19,7 @@
;
operator [](dynamic i) → dynamic
;
- operator []=(dynamic i, dynamic val) → dynamic
+ operator []=(dynamic i, dynamic val) → void
;
}
class Autobianchi extends core::Object {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
index bba4f23..32a5b17 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
@@ -25,7 +25,7 @@
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
: super self::B::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::C::V},${self::C::S},${self::C::R}";
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
index bba4f23..32a5b17 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
@@ -25,7 +25,7 @@
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
: super self::B::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::C::V},${self::C::S},${self::C::R}";
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
index 3b0ee19..d4a0e63 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
@@ -21,7 +21,7 @@
class C<V extends core::Object = dynamic, S extends core::Object = dynamic, R extends core::Object = dynamic> extends self::B<self::C::V, self::C::S> {
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
;
- method toString() → dynamic
+ method toString() → core::String
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
index cee4e10..09e1d27 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
@@ -25,7 +25,7 @@
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
: super self::B::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::C::V},${self::C::S},${self::C::R}";
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
index cee4e10..09e1d27 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
@@ -25,7 +25,7 @@
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
: super self::B::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::C::V},${self::C::S},${self::C::R}";
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
index 2b481ac..f9db296 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
@@ -21,7 +21,7 @@
class C<V extends core::Object = dynamic, S extends core::Object = dynamic, R extends core::Object = dynamic> extends self::B<self::C::V, self::C::S> {
constructor •() → self::C<self::C::V, self::C::S, self::C::R>
;
- method toString() → dynamic
+ method toString() → core::String
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
index 2fff34d..0dc1e9e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
@@ -17,7 +17,7 @@
const constructor •() → self::B<self::B::T>
: super self::A::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::B::T}";
}
static method main() → void {
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
index 2fff34d..0dc1e9e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
@@ -17,7 +17,7 @@
const constructor •() → self::B<self::B::T>
: super self::A::empty()
;
- method toString() → dynamic
+ method toString() → core::String
return "${self::B::T}";
}
static method main() → void {
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
index 4e65df8..0fcea3e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
@@ -14,7 +14,7 @@
class B<T extends core::Object = dynamic> extends self::A {
const constructor •() → self::B<self::B::T>
;
- method toString() → dynamic
+ method toString() → core::String
;
}
static method main() → void
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
index d90c580..2f3e686 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set A(dynamic v) → dynamic {}
+ set A(dynamic v) → void {}
}
static method main() → dynamic {
dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
index d90c580..2f3e686 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::A
: super core::Object::•()
;
- set A(dynamic v) → dynamic {}
+ set A(dynamic v) → void {}
}
static method main() → dynamic {
dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
index b7a0c48..f48580b 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
@@ -12,7 +12,7 @@
class A extends core::Object {
synthetic constructor •() → self::A
;
- set A(dynamic v) → dynamic
+ set A(dynamic v) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
index 5c7b6fa..3cbcc36 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
@@ -77,7 +77,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- A.foo
+ C.A.foo%B.foo
C.noSuchMethod
Object._identityHashCode
Object.hashCode
@@ -114,7 +114,7 @@
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
- D.foo
+ E.D.foo%E.foo
E.noSuchMethod
Object._identityHashCode
Object.hashCode
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
index 46f8dc2..e4d64d6 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
@@ -1,4 +1,27 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y});
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+// ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y}) => y;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -20,10 +43,11 @@
synthetic constructor •() → self::C
: super self::A::•()
;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
core::print("No such method!");
return 42;
}
+ abstract forwarding-stub method foo(core::int x, {core::int y = null}) → dynamic;
}
class D extends core::Object {
synthetic constructor •() → self::D
@@ -37,7 +61,7 @@
: super self::D::•()
;
abstract method foo(core::int x, {core::int y = null}) → dynamic;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
core::print(i.namedArguments);
return 42;
}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
index 46f8dc2..e4d64d6 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
@@ -1,4 +1,27 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y});
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+// ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y}) => y;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -20,10 +43,11 @@
synthetic constructor •() → self::C
: super self::A::•()
;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
core::print("No such method!");
return 42;
}
+ abstract forwarding-stub method foo(core::int x, {core::int y = null}) → dynamic;
}
class D extends core::Object {
synthetic constructor •() → self::D
@@ -37,7 +61,7 @@
: super self::D::•()
;
abstract method foo(core::int x, {core::int y = null}) → dynamic;
- method noSuchMethod(dynamic i) → dynamic {
+ method noSuchMethod(core::Invocation i) → dynamic {
core::print(i.namedArguments);
return 42;
}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
index 9dc571a..7b9f48b 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
@@ -1,4 +1,27 @@
library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y});
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+// ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y}) => y;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -17,8 +40,9 @@
class C extends self::A implements self::B {
synthetic constructor •() → self::C
;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
+ abstract forwarding-stub method foo(core::int x, {core::int y}) → dynamic;
}
class D extends core::Object {
synthetic constructor •() → self::D
@@ -30,7 +54,7 @@
synthetic constructor •() → self::E
;
abstract method foo(core::int x, {core::int y}) → dynamic;
- method noSuchMethod(dynamic i) → dynamic
+ method noSuchMethod(core::Invocation i) → dynamic
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
index 910fc65..73b1b6a 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
-// foo(int x) => x;
-// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
-// foo(int x, {int y}) => y;
-// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-// ^
-//
// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
// foo(int x) => x;
// ^
@@ -22,6 +12,16 @@
// class E extends D {
// ^
//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y}) => y;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+// ^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
index 910fc65..73b1b6a 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
@@ -2,16 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
-// foo(int x) => x;
-// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
-// foo(int x, {int y}) => y;
-// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-// ^
-//
// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
// foo(int x) => x;
// ^
@@ -22,6 +12,16 @@
// class E extends D {
// ^
//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// foo(int x) => x;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+// foo(int x, {int y}) => y;
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+// ^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
index 24e8a2a..1b764c6 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
@@ -17,13 +17,13 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- static set C(dynamic v) → dynamic {}
+ static set C(dynamic v) → void {}
}
class D extends core::Object {
synthetic constructor •() → self::D
: super core::Object::•()
;
- set D(dynamic v) → dynamic {}
+ set D(dynamic v) → void {}
}
static method main() → dynamic {
dynamic c = new self::C::•();
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
index 24e8a2a..1b764c6 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
@@ -17,13 +17,13 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- static set C(dynamic v) → dynamic {}
+ static set C(dynamic v) → void {}
}
class D extends core::Object {
synthetic constructor •() → self::D
: super core::Object::•()
;
- set D(dynamic v) → dynamic {}
+ set D(dynamic v) → void {}
}
static method main() → dynamic {
dynamic c = new self::C::•();
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
index 4582fae..5cfdb48 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
@@ -16,13 +16,13 @@
class C extends core::Object {
synthetic constructor •() → self::C
;
- static set C(dynamic v) → dynamic
+ static set C(dynamic v) → void
;
}
class D extends core::Object {
synthetic constructor •() → self::D
;
- set D(dynamic v) → dynamic
+ set D(dynamic v) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart b/pkg/front_end/testcases/regress/issue_37285.dart
new file mode 100644
index 0000000..6b5857d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.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 C {
+ C() : super()[];
+}
+
+main () {
+ new C();
+}
+
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+// C() : super()[];
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ constructor •() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+ C() : super()[];
+ ^"
+ ;
+}
+static method main() → dynamic {
+ new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+// C() : super()[];
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ constructor •() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+ C() : super()[];
+ ^"
+ ;
+}
+static method main() → dynamic {
+ new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect b/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect
new file mode 100644
index 0000000..2437d0c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+// C() : super()[];
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ constructor •() → self::C
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect b/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+// C() : super()[];
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ constructor •() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+ C() : super()[];
+ ^"
+ ;
+}
+static method main() → dynamic {
+ new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C() : super()[];
+// ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+// C() : super()[];
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ constructor •() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+ C() : super()[];
+ ^"
+ ;
+}
+static method main() → dynamic {
+ new self::C::•();
+}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
index 96700b1..2092b43 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
@@ -13,15 +13,15 @@
synthetic constructor •() → self::C<self::C::U>
: super core::Object::•()
;
- method f1(core::int x) → void {}
- method f2(core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
+ method f1(generic-covariant-impl core::int x) → void {}
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
}
class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
synthetic constructor •() → self::D<self::D::U>
: super self::C::•()
;
- method f1(core::int x) → void {}
- method f2(core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
+ method f1(generic-covariant-impl core::int x) → void {}
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
}
static method g1(self::C<core::num> c) → void {
c.f1(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
index 96700b1..2092b43 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
@@ -13,15 +13,15 @@
synthetic constructor •() → self::C<self::C::U>
: super core::Object::•()
;
- method f1(core::int x) → void {}
- method f2(core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
+ method f1(generic-covariant-impl core::int x) → void {}
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
}
class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
synthetic constructor •() → self::D<self::D::U>
: super self::C::•()
;
- method f1(core::int x) → void {}
- method f2(core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
+ method f1(generic-covariant-impl core::int x) → void {}
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
}
static method g1(self::C<core::num> c) → void {
c.f1(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
index fe2f698..9779f69 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
@@ -11,17 +11,17 @@
class C<U extends core::Object = dynamic> extends core::Object implements self::I<core::int> {
synthetic constructor •() → self::C<self::C::U>
;
- method f1(core::int x) → void
+ method f1(generic-covariant-impl core::int x) → void
;
- method f2(core::int x, [generic-covariant-impl self::C::U y]) → void
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y]) → void
;
}
class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
synthetic constructor •() → self::D<self::D::U>
;
- method f1(core::int x) → void
+ method f1(generic-covariant-impl core::int x) → void
;
- method f2(core::int x, [generic-covariant-impl self::D::U y]) → void
+ method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y]) → void
;
}
static method g1(self::C<core::num> c) → void
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
index 6ad21c9..eee2991 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
@@ -91,7 +91,7 @@
Object.==
classSetters:
interfaceMembers:
- M.f
+ C.M.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
index 144807a..226d14a 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
@@ -24,6 +24,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
index 20d3a2e..9af26fa 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
@@ -24,7 +24,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
- method f(core::int x) → void {}
+ method f(generic-covariant-impl core::int x) → void {}
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
index 10f6ea9..db72bce 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
@@ -23,6 +23,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
index c6a5468..66e9deb 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
index ca44867..dd05793 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
@@ -18,6 +18,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
index ca44867..dd05793 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
@@ -18,6 +18,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
index ee14e2c..bd1c5ab 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
@@ -16,6 +16,8 @@
class C extends self::B implements self::I<core::int> {
synthetic constructor •() → self::C
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
index 3b034c6..63ed69c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
@@ -90,7 +90,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
index 45abbbf..b31bd2e 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
@@ -23,6 +23,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
index 0e61a92..1fb19f0 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
@@ -23,6 +23,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void {
c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
index 926b281..97f802d 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
@@ -21,6 +21,8 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x) → void
+ return super.{self::B::f}(x);
}
static method g1(self::C c) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
index 31aa1f7..9faa7e3 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
@@ -19,7 +19,7 @@
synthetic constructor •() → self::E
: super self::D::•()
;
- method f(core::int x) → void {}
+ method f(covariant core::int x) → void {}
}
static method g1(self::C c) → void {
c.f(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
index 31aa1f7..9faa7e3 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
@@ -19,7 +19,7 @@
synthetic constructor •() → self::E
: super self::D::•()
;
- method f(core::int x) → void {}
+ method f(covariant core::int x) → void {}
}
static method g1(self::C c) → void {
c.f(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
index 3303a29..dd2a7ad 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
@@ -18,7 +18,7 @@
class E extends self::D {
synthetic constructor •() → self::E
;
- method f(core::int x) → void
+ method f(covariant core::int x) → void
;
}
static method g1(self::C c) → void
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
index 306dd42..1f3710c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
@@ -15,7 +15,7 @@
;
}
class E extends core::Object implements self::D {
- field core::int x = null;
+ covariant field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
index 306dd42..1f3710c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
;
}
class E extends core::Object implements self::D {
- field core::int x = null;
+ covariant field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
index 643c93c..063eafe 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
@@ -13,7 +13,7 @@
;
}
class E extends core::Object implements self::D {
- field core::int x;
+ covariant field core::int x;
synthetic constructor •() → self::E
;
}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
index 4e1a3ad..760a9dc 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
@@ -20,6 +20,6 @@
;
get x() → core::int
return 0;
- set x(core::int value) → void {}
+ set x(covariant core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
index 4e1a3ad..760a9dc 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
@@ -20,6 +20,6 @@
;
get x() → core::int
return 0;
- set x(core::int value) → void {}
+ set x(covariant core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
index 358009c..0bc780e 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
@@ -17,7 +17,7 @@
;
get x() → core::int
;
- set x(core::int value) → void
+ set x(covariant core::int value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
index d5f7a72..cc9e3d7 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::E
: super self::D::•()
;
- set x(core::int value) → void {}
+ set x(covariant core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
index d5f7a72..cc9e3d7 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
synthetic constructor •() → self::E
: super self::D::•()
;
- set x(core::int value) → void {}
+ set x(covariant core::int value) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
index 8f94f9e..840f751 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
@@ -17,7 +17,7 @@
class E extends self::D {
synthetic constructor •() → self::E
;
- set x(core::int value) → void
+ set x(covariant core::int value) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
index 79a95bb..492c9a2 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
@@ -15,7 +15,7 @@
set x(covariant core::int value) → void {}
}
class E extends core::Object implements self::D {
- field core::int x = null;
+ covariant field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
index 79a95bb..492c9a2 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
set x(covariant core::int value) → void {}
}
class E extends core::Object implements self::D {
- field core::int x = null;
+ covariant field core::int x = null;
synthetic constructor •() → self::E
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
index 97331e8..809ec55 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
@@ -15,7 +15,7 @@
;
}
class E extends core::Object implements self::D {
- field core::int x;
+ covariant field core::int x;
synthetic constructor •() → self::E
;
}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
index 2efc919..a6d4f4c 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f1(covariant core::int x) → void {}
+ method f1(covariant generic-covariant-impl core::int x) → void {}
}
static method g1(dynamic d) → void {
d.f1(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
index 2efc919..a6d4f4c 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method f1(covariant core::int x) → void {}
+ method f1(covariant generic-covariant-impl core::int x) → void {}
}
static method g1(dynamic d) → void {
d.f1(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
index 87b6f89..6d8aa4a 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
@@ -13,7 +13,7 @@
class D extends self::C<core::num> {
synthetic constructor •() → self::D
;
- method f1(covariant core::int x) → void
+ method f1(covariant generic-covariant-impl core::int x) → void
;
}
static method g1(dynamic d) → void
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
index 1153bca..7869c3b 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
@@ -77,7 +77,7 @@
C.x
interfaceMembers:
Object.toString
- C.x
+ D.C.x%B.x
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -88,4 +88,4 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- C.x
+ D.C.x%B.x
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
index 084024b..4a50297 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
+ forwarding-stub set x(generic-covariant-impl core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
index 084024b..4a50297 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
+ forwarding-stub set x(generic-covariant-impl core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
index d696974..8bf7b77 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
@@ -15,6 +15,8 @@
class D extends self::C implements self::B<core::num> {
synthetic constructor •() → self::D
;
+ forwarding-stub set x(generic-covariant-impl core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
index 389c831..8993132 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
@@ -82,7 +82,7 @@
classSetters:
B._x
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
B._x
Object.runtimeType
@@ -91,7 +91,7 @@
Object.noSuchMethod
Object._identityHashCode
Object.hashCode
- B.g
+ C.B.g%I.g
B.check
Object._simpleInstanceOfFalse
Object._simpleInstanceOfTrue
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
index 82a32ab..339d3dc 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
@@ -30,6 +30,10 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
+ return super.{self::B::f}(x);
+ forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
+ return super.{self::B::g}(x: x);
}
static method main() → dynamic {
self::C c = new self::C::•();
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
index 82a32ab..339d3dc 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
@@ -30,6 +30,10 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
+ return super.{self::B::f}(x);
+ forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
+ return super.{self::B::g}(x: x);
}
static method main() → dynamic {
self::C c = new self::C::•();
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
index 5998e7f..d95ebff 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
@@ -22,6 +22,10 @@
class C extends self::B implements self::I<core::num> {
synthetic constructor •() → self::C
;
+ forwarding-stub method f([generic-covariant-impl core::num x]) → void
+ return super.{self::B::f}(x);
+ forwarding-stub method g({generic-covariant-impl core::num x}) → void
+ return super.{self::B::g}(x: x);
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
index c6a5468..66e9deb 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
index 5486a15..760fd0e 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
index 5486a15..760fd0e 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
index a0b2b04..32a8732 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
@@ -16,6 +16,8 @@
class C extends self::B implements self::I<core::int> {
synthetic constructor •() → self::C
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
index 121a90b..add41b9 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
@@ -10,8 +10,8 @@
set x(generic-covariant-impl self::C::T t) → void {}
}
class D extends core::Object implements self::C<core::num> {
- field core::num x = null;
- field core::num y = null;
+ generic-covariant-impl field core::num x = null;
+ generic-covariant-impl field core::num y = null;
synthetic constructor •() → self::D
: super core::Object::•()
;
@@ -20,9 +20,9 @@
synthetic constructor •() → self::E
: super core::Object::•()
;
- set x(core::num t) → void {}
+ set x(generic-covariant-impl core::num t) → void {}
get y() → core::num
return null;
- set y(core::num t) → void {}
+ set y(generic-covariant-impl core::num t) → void {}
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
index 121a90b..add41b9 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
@@ -10,8 +10,8 @@
set x(generic-covariant-impl self::C::T t) → void {}
}
class D extends core::Object implements self::C<core::num> {
- field core::num x = null;
- field core::num y = null;
+ generic-covariant-impl field core::num x = null;
+ generic-covariant-impl field core::num y = null;
synthetic constructor •() → self::D
: super core::Object::•()
;
@@ -20,9 +20,9 @@
synthetic constructor •() → self::E
: super core::Object::•()
;
- set x(core::num t) → void {}
+ set x(generic-covariant-impl core::num t) → void {}
get y() → core::num
return null;
- set y(core::num t) → void {}
+ set y(generic-covariant-impl core::num t) → void {}
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
index bf98c8f..53b0ab7 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
@@ -10,19 +10,19 @@
;
}
class D extends core::Object implements self::C<core::num> {
- field core::num x;
- field core::num y;
+ generic-covariant-impl field core::num x;
+ generic-covariant-impl field core::num y;
synthetic constructor •() → self::D
;
}
class E extends core::Object implements self::C<core::num> {
synthetic constructor •() → self::E
;
- set x(core::num t) → void
+ set x(generic-covariant-impl core::num t) → void
;
get y() → core::num
;
- set y(core::num t) → void
+ set y(generic-covariant-impl core::num t) → void
;
}
static method main() → void
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
index fc559f4..d50d07e 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
@@ -9,17 +9,17 @@
abstract set x(covariant core::Object value) → void;
}
class B extends core::Object implements self::A {
- field core::Object x = null;
+ covariant field core::Object x = null;
synthetic constructor •() → self::B
: super core::Object::•()
;
method f(covariant core::Object x) → void {}
}
class C<T extends core::Object = dynamic> extends core::Object implements self::B {
- generic-covariant-impl field self::C::T x = null;
+ covariant generic-covariant-impl field self::C::T x = null;
synthetic constructor •() → self::C<self::C::T>
: super core::Object::•()
;
- method f(generic-covariant-impl self::C::T x) → void {}
+ method f(covariant generic-covariant-impl self::C::T x) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
index fc559f4..d50d07e 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
@@ -9,17 +9,17 @@
abstract set x(covariant core::Object value) → void;
}
class B extends core::Object implements self::A {
- field core::Object x = null;
+ covariant field core::Object x = null;
synthetic constructor •() → self::B
: super core::Object::•()
;
method f(covariant core::Object x) → void {}
}
class C<T extends core::Object = dynamic> extends core::Object implements self::B {
- generic-covariant-impl field self::C::T x = null;
+ covariant generic-covariant-impl field self::C::T x = null;
synthetic constructor •() → self::C<self::C::T>
: super core::Object::•()
;
- method f(generic-covariant-impl self::C::T x) → void {}
+ method f(covariant generic-covariant-impl self::C::T x) → void {}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
index 4ed0cca..037ffa8 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
@@ -8,17 +8,17 @@
abstract set x(covariant core::Object value) → void;
}
class B extends core::Object implements self::A {
- field core::Object x;
+ covariant field core::Object x;
synthetic constructor •() → self::B
;
method f(covariant core::Object x) → void
;
}
class C<T extends core::Object = dynamic> extends core::Object implements self::B {
- generic-covariant-impl field self::C::T x;
+ covariant generic-covariant-impl field self::C::T x;
synthetic constructor •() → self::C<self::C::T>
;
- method f(generic-covariant-impl self::C::T x) → void
+ method f(covariant generic-covariant-impl self::C::T x) → void
;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
index 4b4ea07..47824ee 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
@@ -14,7 +14,7 @@
}
class C extends B implements I<num> {
- void /*@forwardingStub=semi-stub*/ f(num x);
+ void f(num x);
}
main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
index c844506..0bd7033 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
@@ -60,7 +60,7 @@
-> B
interfaces: I<num>
classMembers:
- B.f
+ C.B.f%C.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%C.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
index 95fdf8b..5862850 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
@@ -18,6 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
- abstract method f(core::num x) → void;
+ forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+ return super.{self::B::f}(x);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
index 95fdf8b..5862850 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
@@ -18,6 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
- abstract method f(core::num x) → void;
+ forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+ return super.{self::B::f}(x);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
index 8b7ff11..c8141fe 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
@@ -16,7 +16,8 @@
class C extends self::B implements self::I<core::num> {
synthetic constructor •() → self::C
;
- abstract method f(core::num x) → void;
+ forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+ return super.{self::B::f}(x);
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
index f9eaac1..2a7623e 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
@@ -29,7 +29,7 @@
synthetic constructor •() → self::E
: super self::C::•()
;
- method f(covariant core::int x) → void {}
+ method f(covariant generic-covariant-impl core::int x) → void {}
}
static method test() → dynamic {
dynamic x = new self::D::•().g4() as (core::Object) → dynamic;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
index f9eaac1..2a7623e 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
@@ -29,7 +29,7 @@
synthetic constructor •() → self::E
: super self::C::•()
;
- method f(covariant core::int x) → void {}
+ method f(covariant generic-covariant-impl core::int x) → void {}
}
static method test() → dynamic {
dynamic x = new self::D::•().g4() as (core::Object) → dynamic;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
index 0c9d1ca..1f6aacf 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
@@ -24,7 +24,7 @@
class E extends self::C<core::num> {
synthetic constructor •() → self::E
;
- method f(covariant core::int x) → void
+ method f(covariant generic-covariant-impl core::int x) → void
;
}
static method test() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
index d6381e8..54bc8ea 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
@@ -77,7 +77,7 @@
C.x
interfaceMembers:
Object.toString
- C.x
+ D.C.x%B.x
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -88,4 +88,328 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- C.x
+ D.C.x%B.x
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
index 3f2338c..eea0f36 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
+ forwarding-stub set x(covariant core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
index 3f2338c..eea0f36 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
+ forwarding-stub set x(covariant core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
index 64163de..d8da134 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
@@ -15,6 +15,8 @@
class D extends self::C implements self::B {
synthetic constructor •() → self::D
;
+ forwarding-stub set x(covariant core::num _) → void
+ return super.{self::C::x} = _;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
index a959413..f6be89d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
@@ -10,19 +10,19 @@
;
}
abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
- field dynamic x = null;
+ generic-covariant-impl field core::num x = null;
synthetic constructor •() → self::C<self::C::T>
: super core::Object::•()
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → core::num;
+ abstract set y(generic-covariant-impl core::num value) → void;
}
abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
- field dynamic x = null;
+ generic-covariant-impl field self::D::T x = null;
synthetic constructor •() → self::D<self::D::T>
: super core::Object::•()
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → self::D::T;
+ abstract set y(generic-covariant-impl self::D::T value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
index a959413..f6be89d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
@@ -10,19 +10,19 @@
;
}
abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
- field dynamic x = null;
+ generic-covariant-impl field core::num x = null;
synthetic constructor •() → self::C<self::C::T>
: super core::Object::•()
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → core::num;
+ abstract set y(generic-covariant-impl core::num value) → void;
}
abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
- field dynamic x = null;
+ generic-covariant-impl field self::D::T x = null;
synthetic constructor •() → self::D<self::D::T>
: super core::Object::•()
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → self::D::T;
+ abstract set y(generic-covariant-impl self::D::T value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
index 60525b9..2696bf4 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
@@ -9,18 +9,18 @@
;
}
abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
- field dynamic x;
+ generic-covariant-impl field core::num x;
synthetic constructor •() → self::C<self::C::T>
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → core::num;
+ abstract set y(generic-covariant-impl core::num value) → void;
}
abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
- field dynamic x;
+ generic-covariant-impl field self::D::T x;
synthetic constructor •() → self::D<self::D::T>
;
- abstract get y() → dynamic;
- abstract set y(dynamic value) → dynamic;
+ abstract get y() → self::D::T;
+ abstract set y(generic-covariant-impl self::D::T value) → void;
}
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
index 94c8b5c..9a9e066 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
@@ -87,9 +87,9 @@
-> B
interfaces: M, I<int>
classMembers:
- M.y
+ C.M.y%B.y%I.y
Object.toString
- M.x
+ C.M.x%B.x%I.x
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -100,12 +100,12 @@
Object._simpleInstanceOfTrue
Object.==
classSetters:
- M.y
- M.x
+ C.M.y%B.y=%I.y=
+ C.M.x%B.x=%I.x=
interfaceMembers:
- M.y
+ C.M.y%B.y%I.y
Object.toString
- M.x
+ C.M.x%B.x%I.x
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -116,5 +116,329 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- M.y
- M.x
+ C.M.y%B.y=%I.y=
+ C.M.x%B.x=%I.x=
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
index 4978034..b99aea3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
@@ -32,6 +32,10 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub set y(covariant core::Object value) → void
+ return super.{self::B::y} = value;
+ forwarding-stub set x(generic-covariant-impl core::int _) → void
+ return super.{self::B::x} = _;
}
static method expectTypeError(() → void callback) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
index 94c8b5c..e23589d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
@@ -103,9 +103,9 @@
M.y
M.x
interfaceMembers:
- M.y
+ C.M.y%I.y
Object.toString
- M.x
+ C.M.x%I.x
Object.runtimeType
Object._simpleInstanceOf
Object._instanceOf
@@ -116,5 +116,329 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
- M.y
- M.x
+ C.M.y=%I.y=
+ C.M.x=%I.x=
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
index 4b6371a..782ccf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
@@ -38,6 +38,10 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub set y(covariant core::Object value) → void
+ return super.{self::B::y} = value;
+ forwarding-stub set x(generic-covariant-impl core::int value) → void
+ return super.{self::B::x} = value;
}
static method expectTypeError(() → void callback) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -85,3 +85,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
index 4e4266a..91a76ee 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
@@ -16,6 +16,8 @@
class C extends self::B implements self::I {
synthetic constructor •() → self::C
;
+ forwarding-stub method f(covariant core::Object x) → core::int
+ return super.{self::B::f}(x);
}
static method expectTypeError(() → void callback) → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
index c6a5468..f7b0451 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -85,3 +85,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
index 3334045..082a15f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
index 3334045..082a15f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
index 205776d..5890db1 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
@@ -16,6 +16,8 @@
abstract class C extends self::B implements self::I<core::int> {
synthetic constructor •() → self::C
;
+ forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
index 2defd9d..578a89f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -85,3 +85,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
index 3038f0e..04bbcf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
@@ -18,5 +18,6 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
index 3038f0e..04bbcf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
@@ -18,5 +18,6 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
index 9e7de41..5c37f4b 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
@@ -16,6 +16,7 @@
abstract class C extends self::B<core::int> implements self::I {
synthetic constructor •() → self::C
;
+ abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -85,3 +85,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
index 22a66005..ed5aa28 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(covariant core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
index 22a66005..ed5aa28 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ forwarding-stub method f(covariant core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
index 91a90a9..ac22acd 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
@@ -16,6 +16,8 @@
abstract class C extends self::B implements self::I {
synthetic constructor •() → self::C
;
+ forwarding-stub method f(covariant core::int x, core::Object y) → void
+ return super.{self::B::f}(x, y);
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
Object.==
classSetters:
interfaceMembers:
- B.f
+ C.B.f%I.f
Object.toString
Object.runtimeType
Object._simpleInstanceOf
@@ -85,3 +85,327 @@
Object._simpleInstanceOfTrue
Object.==
interfaceSetters:
+
+Comparable:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Comparable.compareTo
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ Comparable.compare
+ classSetters:
+
+num:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: Comparable<num>
+ classMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ classSetters:
+ interfaceMembers:
+ num.~/
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ num._returnDoubleNull
+ num.Object.toString%num.toString
+ num._returnIntNull
+ num.+
+ num.clamp
+ num.toDouble
+ num.ceil
+ num.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ num.toStringAsExponential
+ num./
+ num.abs
+ num._moduloFromInteger
+ num._subFromInteger
+ num._addFromInteger
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ num.sign
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ num.floorToDouble
+ Object._identityHashCode
+ num.>
+ num.roundToDouble
+ num.round
+ num.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ num.truncate
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ num.ceilToDouble
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ num.truncateToDouble
+ num.parse
+ num.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ num.*
+ interfaceSetters:
+
+int:
+ Longest path to Object: 3
+ superclasses:
+ Object
+ -> num
+ interfaces: Comparable<num>
+ classMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ classSetters:
+ interfaceMembers:
+ int._minInt64
+ num.~/
+ int.toSigned
+ int._shrFromInteger
+ int._throwFormatException
+ int._parseBlock
+ num.<=
+ num._equalToInteger
+ num.isInfinite
+ num.<
+ int._int64OverflowLimits
+ int._parseRadix
+ int.Object.toString%int.toString
+ int._PARSE_LIMITS
+ int._kNull
+ num.+
+ num.clamp
+ num.toDouble
+ int.ceil
+ int.unary-
+ num._mulFromInteger
+ num.>=
+ Object.runtimeType
+ Object._simpleInstanceOf
+ num.isNegative
+ num.isNaN
+ int._initInt64OverflowLimits
+ int.isEven
+ num.toStringAsExponential
+ num./
+ int.abs
+ int._bitAndFromSmi
+ int.|
+ num._moduloFromInteger
+ int.gcd
+ int._int64UnsignedOverflowLimits
+ int.<<
+ num._subFromInteger
+ num._addFromInteger
+ int.toUnsigned
+ int.toRadixString
+ int._int64UnsignedSmiOverflowLimits
+ Object._instanceOf
+ num.remainder
+ num.isFinite
+ num.toInt
+ num.%
+ int._tryParseSmi
+ int.sign
+ int.>>
+ Object.noSuchMethod
+ num.toStringAsPrecision
+ int.modInverse
+ int.floorToDouble
+ Object._identityHashCode
+ num.>
+ int.roundToDouble
+ int.round
+ int._maxInt64
+ int.floor
+ num.compareTo
+ num.Object.hashCode%num.hashCode
+ num._truncDivFromInteger
+ int.truncate
+ int.^
+ int._shlFromInteger
+ int.&
+ num.-
+ Object._simpleInstanceOfFalse
+ num._greaterThanFromInteger
+ int.bitLength
+ int.ceilToDouble
+ int.modPow
+ int.isOdd
+ int._bitAndFromInteger
+ Object._simpleInstanceOfTrue
+ num.Object.==%num.==
+ int._bitOrFromInteger
+ int.truncateToDouble
+ int._bitXorFromInteger
+ int.parse
+ int.tryParse
+ num.toStringAsFixed
+ num._remainderFromInteger
+ int._parse
+ num.*
+ int.~
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
index cf870cc..1ce982c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
@@ -18,5 +18,6 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
index cf870cc..1ce982c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
@@ -18,5 +18,6 @@
synthetic constructor •() → self::C
: super self::B::•()
;
+ abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
index d4b0825..9c7aa8f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
@@ -16,6 +16,7 @@
abstract class C extends self::B implements self::I {
synthetic constructor •() → self::C
;
+ abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
}
static method main() → void
;
diff --git a/pkg/front_end/testcases/static_setter.dart.legacy.expect b/pkg/front_end/testcases/static_setter.dart.legacy.expect
index 05125e5..055ed11 100644
--- a/pkg/front_end/testcases/static_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/static_setter.dart.legacy.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
}
-static set foo(dynamic x) → dynamic {}
+static set foo(dynamic x) → void {}
static method main() → dynamic {
self::foo = new self::Foo::•();
}
diff --git a/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
index 05125e5..055ed11 100644
--- a/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
}
-static set foo(dynamic x) → dynamic {}
+static set foo(dynamic x) → void {}
static method main() → dynamic {
self::foo = new self::Foo::•();
}
diff --git a/pkg/front_end/testcases/static_setter.dart.outline.expect b/pkg/front_end/testcases/static_setter.dart.outline.expect
index 13eaefe..0c46d4c 100644
--- a/pkg/front_end/testcases/static_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/static_setter.dart.outline.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → self::Foo
;
}
-static set foo(dynamic x) → dynamic
+static set foo(dynamic x) → void
;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 79ac736..45003af 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -10,6 +10,7 @@
accessors: RuntimeError
ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
argument_mismatch: InstrumentationMismatch # Test assumes Dart 1.0 semantics
+await_in_non_async: RuntimeError # Expected.
bug21938: TypeCheckError
bug30695: TypeCheckError
bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
@@ -22,13 +23,15 @@
duplicated_field_initializer: RuntimeError
dynamic_and_void: InstrumentationMismatch # Test assumes Dart 1.0 semantics
expressions: RuntimeError
+extension_methods: TypeCheckError
external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
fallthrough: ExpectationFileMismatch
+ignore_function: TypeCheckError
incomplete_field_formal_parameter: RuntimeError
inference/abstract_class_instantiation: InstrumentationMismatch # Issue #30040
inference/conflicting_fields: TypeCheckError
-inference/conflicts_can_happen: TypeCheckError
inference/conflicts_can_happen2: TypeCheckError
+inference/conflicts_can_happen: TypeCheckError
inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
inference/constructors_too_many_positional_arguments: InstrumentationMismatch # Issue #30040
inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
@@ -44,8 +47,10 @@
inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
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
inference/infer_types_on_generic_instantiations_4: RuntimeError
@@ -66,16 +71,18 @@
inference_new/infer_assign_to_index_upwards: TypeCheckError
inference_new/infer_assign_to_property_custom: TypeCheckError
inference_new/infer_field_getter_setter_mismatch: TypeCheckError
+inference_new/infer_field_override_accessors: TypeCheckError
inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
-inference_new/strongly_connected_component: TypeCheckError
instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError # Expected
instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError # Expected
invalid_type: TypeCheckError
invocations: RuntimeError
issue34899: TypeCheckError
micro: RuntimeError
+mixin_application_override: ExpectationFileMismatch # Too many errors.
mixin_application_override: TypeCheckError
+nnbd/nullable_param: RuntimeError
operator_method_not_found: RuntimeError # Expected
optional: TypeCheckError
override_check_accessor_after_inference: TypeCheckError # Issue #31620
@@ -146,6 +153,7 @@
regress/issue_36647: RuntimeError # Expected
regress/issue_36647_2: RuntimeError # Expected
regress/issue_36669: RuntimeError
+regress/issue_37285: RuntimeError
reject_generic_function_types_in_bounds: RuntimeError # Expected
runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
diff --git a/pkg/front_end/testcases/super_nsm.dart.legacy.expect b/pkg/front_end/testcases/super_nsm.dart.legacy.expect
index a0c7a8c..eb7ebeb 100644
--- a/pkg/front_end/testcases/super_nsm.dart.legacy.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.legacy.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return "C";
no-such-method-forwarder method interfaceMethod() → dynamic
return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -21,7 +21,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return "D";
method dMethod() → dynamic
return super.{self::C::interfaceMethod}();
diff --git a/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect b/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
index a0c7a8c..eb7ebeb 100644
--- a/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
synthetic constructor •() → self::C
: super core::Object::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return "C";
no-such-method-forwarder method interfaceMethod() → dynamic
return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -21,7 +21,7 @@
synthetic constructor •() → self::D
: super self::C::•()
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
return "D";
method dMethod() → dynamic
return super.{self::C::interfaceMethod}();
diff --git a/pkg/front_end/testcases/super_nsm.dart.outline.expect b/pkg/front_end/testcases/super_nsm.dart.outline.expect
index de7c531..6ec8595 100644
--- a/pkg/front_end/testcases/super_nsm.dart.outline.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.outline.expect
@@ -10,7 +10,7 @@
class C extends core::Object implements self::I {
synthetic constructor •() → self::C
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
;
no-such-method-forwarder method interfaceMethod() → dynamic
return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -18,7 +18,7 @@
class D extends self::C {
synthetic constructor •() → self::D
;
- method noSuchMethod(dynamic _) → dynamic
+ method noSuchMethod(core::Invocation _) → dynamic
;
method dMethod() → dynamic
;
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 8508fee..74c01f5 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,6 +8,7 @@
DeltaBlue: TextSerializationFailure # Was: Pass
abstract_members: TypeCheckError
+abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
accessors: TextSerializationFailure # Was: RuntimeError
ambiguous_exports: TextSerializationFailure # Was: RuntimeError # Expected, this file exports two main methods.
annotation_eof: TextSerializationFailure # Was: Pass
@@ -23,6 +24,7 @@
async_function: TextSerializationFailure # Was: Pass
async_nested: TextSerializationFailure # Was: Pass
await: TextSerializationFailure # Was: Pass
+await_in_non_async: TextSerializationFailure
bad_setter_abstract: TextSerializationFailure # Was: Pass
bad_store: TextSerializationFailure # Was: Pass
bad_type_variable_uses_in_supertypes: TextSerializationFailure
@@ -71,6 +73,7 @@
control_flow_collection: TextSerializationFailure
control_flow_collection_inference: TextSerializationFailure
covariant_generic: TextSerializationFailure # Was: RuntimeError
+covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
cycles: TextSerializationFailure # Was: Pass
default_values: TextSerializationFailure # Was: Pass
deferred_lib: TextSerializationFailure # Was: Pass
@@ -90,12 +93,14 @@
expression/eval: TextSerializationFailure # Was: Pass
expression/main: TextSerializationFailure # Was: Pass
expressions: TextSerializationFailure # Was: RuntimeError
+extension_methods: TypeCheckError
external: TextSerializationFailure # Was: Pass
external_import: TextSerializationFailure # Was: RuntimeError # The native extension to import doesn't exist. This is ok.
fallthrough: ExpectationFileMismatch
fibonacci: TextSerializationFailure # Was: Pass
for_in_scope: TextSerializationFailure # Was: Pass
for_in_without_declaration: TextSerializationFailure
+forwarding_stub_for_operator: TextSerializationFailure
function_in_field: TextSerializationFailure # Was: Pass
function_type_assignments: TextSerializationFailure # Was: Pass
function_type_default_value: TextSerializationFailure
@@ -103,9 +108,10 @@
function_type_recovery: TextSerializationFailure # Was: Pass
functions: TextSerializationFailure # Was: Pass
future_or_test: TextSerializationFailure # Was: Pass
-hello: TextSerializationFailure # Was: Pass
having_part_with_part_and_annotation: TextSerializationFailure
having_part_with_parts_and_annotation: TextSerializationFailure
+hello: TextSerializationFailure # Was: Pass
+ignore_function: TypeCheckError
illegal_named_function_expression: TextSerializationFailure # Was: Pass
illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
implicit_const_with_static_fields: TextSerializationFailure # Was: Pass
@@ -162,6 +168,7 @@
inference/complex_predecrement: TextSerializationFailure # Was: Pass
inference/conditional_lub: TextSerializationFailure # Was: Pass
inference/conditional_upwards_inference: TextSerializationFailure # Was: Pass
+inference/conflicting_fields: ExpectationFileMismatch
inference/conflicting_fields: TypeCheckError
inference/conflicts_can_happen2: TypeCheckError
inference/conflicts_can_happen: TypeCheckError
@@ -277,6 +284,7 @@
inference/generic_methods_nested_generic_instantiation: TextSerializationFailure # Was: Pass
inference/generic_methods_uses_greatest_lower_bound: TextSerializationFailure # Was: Pass
inference/greatest_closure_multiple_params: TextSerializationFailure # Was: Pass
+inference/inconsistent_overrides: TypeCheckError
inference/index_assign_operator_return_type: TextSerializationFailure # Was: Pass
inference/index_assign_operator_return_type_2: TextSerializationFailure # Was: Pass
inference/infer_accessor_from_later_inferred_field: TextSerializationFailure # Was: Pass
@@ -340,6 +348,7 @@
inference/infer_local_function_referenced_before_declaration: TextSerializationFailure # Was: Pass
inference/infer_local_function_return_type: TextSerializationFailure # Was: Pass
inference/infer_method_function_typed: TextSerializationFailure # Was: Pass
+inference/infer_method_missing_params: ExpectationFileMismatch
inference/infer_method_missing_params: TypeCheckError
inference/infer_parameter_type_setter_from_field: TextSerializationFailure # Was: Pass
inference/infer_parameter_type_setter_from_setter: TextSerializationFailure # Was: Pass
@@ -467,6 +476,8 @@
inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Was: Pass
inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
inference/override_equals: TextSerializationFailure # Was: RuntimeError
+inference/override_inference_depends_on_field_inference: TextSerializationFailure
+inference/override_inference_with_type_parameters: TextSerializationFailure
inference/parameter_defaults_downwards: TextSerializationFailure # Was: Pass
inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
inference/promote_bounds: TextSerializationFailure # Was: Pass
@@ -586,6 +597,7 @@
inference_new/infer_assign_to_static: TextSerializationFailure # Was: Pass
inference_new/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
inference_new/infer_field_getter_setter_mismatch: TypeCheckError
+inference_new/infer_field_override_accessors: TypeCheckError
inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
inference_new/infer_field_override_setter_overrides_getter: TextSerializationFailure # Was: Pass
inference_new/infer_instance_accessor_ref: TextSerializationFailure # Was: Pass
@@ -605,6 +617,7 @@
inference_new/super_index_get: TextSerializationFailure # Was: Pass
inference_new/super_index_get_substitution: TextSerializationFailure # Was: Pass
inference_new/switch: TextSerializationFailure # Was: Pass
+inference_new/top_level_field_depends_on_multiple_inheritance: ExpectationFileMismatch
inference_new/top_level_field_depends_on_multiple_inheritance: TextSerializationFailure # Was: Pass
inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure # Was: Pass
inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure # Was: Pass
@@ -680,10 +693,12 @@
invalid_cast: TextSerializationFailure # Was: Pass
invalid_type: TypeCheckError
invocations: TextSerializationFailure # Was: RuntimeError
+issue129167943: TextSerializationFailure
issue34515: TextSerializationFailure
issue34899: TypeCheckError
issue35875: TextSerializationFailure
issue37027: TextSerializationFailure
+issue37381: TextSerializationFailure
literals: TextSerializationFailure # Was: Pass
local_generic_function: TextSerializationFailure # Was: Pass
magic_const: TextSerializationFailure # Was: Pass
@@ -695,6 +710,7 @@
minimum_int: TextSerializationFailure # Was: Pass
missing_constructor: TextSerializationFailure # Was: Pass
mixin: TextSerializationFailure # Was: Pass
+mixin_application_override: ExpectationFileMismatch
mixin_application_override: TypeCheckError
mixin_conflicts: TextSerializationFailure
mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
@@ -706,6 +722,7 @@
native_as_name: TextSerializationFailure # Was: Pass
nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
new_const_insertion/simple: TextSerializationFailure # Was: Pass
+nnbd/nullable_param: TextSerializationFailure
no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
@@ -742,6 +759,8 @@
override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
override_check_two_substitutions: TextSerializationFailure # Was: Pass
override_check_with_covariant_modifier: TypeCheckError # Issue #31620
+override_inference_for_setters: TextSerializationFailure
+override_inference_named_parameters_ordering: TextSerializationFailure
part_as_entry_point: TextSerializationFailure # Was: Pass
part_as_entry_point_lib: TextSerializationFailure # Was: Pass
part_not_part_of: TextSerializationFailure
@@ -932,6 +951,7 @@
regress/issue_36647_2: TextSerializationFailure
regress/issue_36669: TextSerializationFailure
regress/issue_36793: TextSerializationFailure
+regress/issue_37285: TextSerializationFailure
reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
@@ -964,6 +984,7 @@
runtime_checks/dynamic_invocation: TextSerializationFailure # Was: Pass
runtime_checks/dynamic_invocation_generic: TextSerializationFailure # Was: Pass
runtime_checks/dynamic_invocation_of_getter: TextSerializationFailure # Was: Pass
+runtime_checks/field_forwarding_stub_generic_covariant: ExpectationFileMismatch
runtime_checks/field_forwarding_stub_generic_covariant: TextSerializationFailure # Was: Pass
runtime_checks/forwarding_stub_with_default_values: TextSerializationFailure # Was: Pass
runtime_checks/forwarding_stub_with_non_covariant_param: TextSerializationFailure # Was: Pass
@@ -977,6 +998,7 @@
runtime_checks/implicit_downcast_if: TextSerializationFailure # Was: Pass
runtime_checks/implicit_downcast_not: TextSerializationFailure # Was: Pass
runtime_checks/implicit_downcast_while: TextSerializationFailure # Was: Pass
+runtime_checks_new/abstract_override_becomes_forwarding_stub: ExpectationFileMismatch
runtime_checks_new/abstract_override_becomes_forwarding_stub: TextSerializationFailure # Was: Pass
runtime_checks_new/call_through_this: TextSerializationFailure # Was: Pass
runtime_checks_new/contravariant_combiner: TextSerializationFailure # Was: Pass
@@ -986,12 +1008,15 @@
runtime_checks_new/contravariant_index_get: TextSerializationFailure # Was: Pass
runtime_checks_new/derived_class_typed: TextSerializationFailure # Was: Pass
runtime_checks_new/field_forwarding_stub_abstract_generic_covariant: TextSerializationFailure # Was: Pass
+runtime_checks_new/field_forwarding_stub_explicit_covariant: ExpectationFileMismatch
runtime_checks_new/field_forwarding_stub_explicit_covariant: TextSerializationFailure # Was: Pass
runtime_checks_new/for_in_call_kinds: TextSerializationFailure # Was: Pass
runtime_checks_new/generic_covariance_based_on_inference: TextSerializationFailure # Was: Pass
runtime_checks_new/implicit_downcast_field: TextSerializationFailure # Was: Pass
+runtime_checks_new/mixin_forwarding_stub_field: ExpectationFileMismatch
runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
+runtime_checks_new/mixin_forwarding_stub_setter: ExpectationFileMismatch
runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
diff --git a/pkg/front_end/testcases/void_methods.dart.outline.expect b/pkg/front_end/testcases/void_methods.dart.outline.expect
index b73833b..881f4a6 100644
--- a/pkg/front_end/testcases/void_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/void_methods.dart.outline.expect
@@ -6,9 +6,9 @@
field core::List<dynamic> list;
synthetic constructor •() → self::Foo
;
- set first(dynamic x) → dynamic
+ set first(dynamic x) → void
;
- operator []=(dynamic x, dynamic y) → dynamic
+ operator []=(dynamic x, dynamic y) → void
;
method clear() → void
;
diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
index 355836a..82918cf 100644
--- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
+++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
@@ -51,33 +51,53 @@
enum ExperimentalFlag {
''');
for (var key in keys) {
+ var expired = (yaml[key] as YamlMap)['expired'];
+ if (expired == true) continue;
sb.writeln(' ${keyToIdentifier(key)},');
}
- sb.writeln('}');
-
sb.write('''
+ // A placeholder representing an "expired" flag which has been removed
+ // from the codebase but still needs to be gracefully ignored
+ // when specified on the command line.
+ expiredFlag,
+}
+
ExperimentalFlag parseExperimentalFlag(String flag) {
switch (flag) {
''');
+ var expiredKeys = <String>[];
for (var key in keys) {
+ var expired = (yaml[key] as YamlMap)['expired'];
+ if (expired == true) {
+ expiredKeys.add(key);
+ continue;
+ }
sb.writeln(' case "$key":');
sb.writeln(' return ExperimentalFlag.${keyToIdentifier(key)};');
}
+ if (expiredKeys.isNotEmpty) {
+ sb.write('''
+
+ // Expired flags
+''');
+ for (var key in expiredKeys) {
+ sb.writeln(' case "$key":');
+ sb.writeln(' return ExperimentalFlag.expiredFlag;');
+ }
+ }
sb.write(''' }
return null;
}
-''');
-
- sb.write('''
const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
''');
for (var key in keys) {
+ var expired = (yaml[key] as YamlMap)['expired'];
+ if (expired == true) continue;
bool shipped = (yaml[key] as YamlMap)['enabledIn'] != null;
sb.writeln(' ExperimentalFlag.${keyToIdentifier(key)}: ${shipped},');
if (shipped) {
- var expired = (yaml[key] as YamlMap)['expired'];
if (expired == false) {
throw 'Cannot mark shipped feature as "expired: false"';
}
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index f95564c..31aee1b 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -31,7 +31,7 @@
}
collectLog(DateTime time, HttpRequest request) async {
- String json = await request.transform(utf8.decoder).join();
+ String json = await request.cast<List<int>>().transform(utf8.decoder).join();
var data;
try {
data = jsonDecode(json);
diff --git a/pkg/front_end/tool/fasta.dart b/pkg/front_end/tool/fasta.dart
new file mode 100644
index 0000000..77f1115
--- /dev/null
+++ b/pkg/front_end/tool/fasta.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.
+
+import 'dart:io';
+
+final String repoDir = _computeRepoDir();
+
+final String toolDir = '$repoDir/pkg/front_end/tool/_fasta';
+
+final String kernelBin = '$repoDir/pkg/kernel/bin';
+
+String get dartVm =>
+ Platform.isWindows ? '$repoDir/sdk/bin/dart.bat' : '$repoDir/sdk/bin/dart';
+
+main(List<String> args) async {
+ List<String> extraVmArguments = [];
+ String script;
+ List<String> scriptArguments = [];
+
+ int index = 0;
+ for (; index < args.length; index++) {
+ String arg = args[index];
+ if (arg.startsWith('-')) {
+ extraVmArguments.add(arg);
+ } else {
+ break;
+ }
+ }
+ if (args.length == index) {
+ stop("No command provided.");
+ }
+ String command = args[index++];
+ List<String> remainingArguments = args.skip(index).toList();
+
+ switch (command) {
+ case 'abcompile':
+ script = '${toolDir}/abcompile.dart';
+ break;
+ case 'compile':
+ script = '${toolDir}/compile.dart';
+ break;
+ case 'compile-platform':
+ script = '${toolDir}/compile_platform.dart';
+ break;
+ case 'log':
+ script = '${toolDir}/log_analyzer.dart';
+ break;
+ case 'logd':
+ script = '${toolDir}/log_collector.dart';
+ break;
+ case 'outline':
+ script = '${toolDir}/outline.dart';
+ break;
+ case 'parser':
+ script = '${toolDir}/parser.dart';
+ break;
+ case 'scanner':
+ script = '${toolDir}/scanner.dart';
+ break;
+ case 'dump-partial':
+ script = '${toolDir}/dump_partial.dart';
+ break;
+ case 'dump-ir':
+ script = '${kernelBin}/dump.dart';
+ if (remainingArguments.isEmpty || remainingArguments.length > 2) {
+ stop("Usage: $command dillfile [output]");
+ }
+ break;
+ case 'testing':
+ script = '${repoDir}/pkg/testing/bin/testing.dart';
+ scriptArguments.add('--config=${repoDir}/pkg/front_end/testing.json');
+ break;
+ case 'generate-messages':
+ script = '${toolDir}/generate_messages.dart';
+ break;
+ case 'generate-experimental-flags':
+ script = '${toolDir}/generate_experimental_flags.dart';
+ break;
+ default:
+ stop("'$command' isn't a valid subcommand.");
+ }
+
+ List<String> arguments = [];
+ arguments.addAll(extraVmArguments);
+ arguments.add('--enable-asserts');
+ arguments.add(script);
+ arguments.addAll(remainingArguments);
+ arguments.addAll(scriptArguments);
+
+ print('Running: ${dartVm} ${arguments.join(' ')}');
+ Process process = await Process.start(dartVm, arguments,
+ mode: ProcessStartMode.inheritStdio);
+ exitCode = await process.exitCode;
+}
+
+String _computeRepoDir() {
+ ProcessResult result = Process.runSync(
+ 'git', ['rev-parse', '--show-toplevel'],
+ runInShell: true,
+ workingDirectory: new File.fromUri(Platform.script).parent.path);
+ return (result.stdout as String).trim();
+}
+
+void stop(String message) {
+ stderr.write(message);
+ exit(2);
+}
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 0ba6da6..9bb4e6e 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -8,6 +8,7 @@
import 'dart:async';
import 'dart:io';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/fasta/ast_builder.dart';
import 'package:args/args.dart';
@@ -213,7 +214,8 @@
// Note: AstBuilder doesn't build compilation-units or classes, only method
// bodies. So this listener is not feature complete.
class _PartialAstBuilder extends AstBuilder {
- _PartialAstBuilder(Uri uri) : super(null, null, true, uri);
+ _PartialAstBuilder(Uri uri)
+ : super(null, null, true, FeatureSet.fromEnableFlags([]), uri);
// Note: this method converts the body to kernel, so we skip that here.
@override
diff --git a/pkg/front_end/tool/incremental_perf_test.dart b/pkg/front_end/tool/incremental_perf_test.dart
index 5a97ad8..73e0893 100644
--- a/pkg/front_end/tool/incremental_perf_test.dart
+++ b/pkg/front_end/tool/incremental_perf_test.dart
@@ -12,7 +12,7 @@
main() async {
var sdkOutline = computePlatformBinariesLocation(forceBuildDir: true).resolve(
// TODO(sigmund): switch to `vm_outline.dill` (issue #29881).
- "vm_platform.dill");
+ "vm_platform_strong.dill");
final ikgBenchmarks = Platform.script.resolve('../benchmarks/ikg/');
final helloEntry = ikgBenchmarks.resolve('hello.dart');
@@ -28,7 +28,6 @@
'--no-loop',
'--sdk-summary',
'$sdkOutline',
- '--mode=legacy',
'$helloEntry',
'$helloEdits'
]);
@@ -54,7 +53,6 @@
'--no-loop',
'--sdk-summary',
'$sdkOutline',
- '--mode=legacy',
'--implementation=default',
'$dart2jsEntry',
'$dart2jsEdits'
@@ -63,7 +61,6 @@
'--no-loop',
'--sdk-summary',
'$sdkOutline',
- '--mode=legacy',
'--implementation=minimal',
'$dart2jsEntry',
'$dart2jsEdits'
diff --git a/pkg/js/CHANGELOG.md b/pkg/js/CHANGELOG.md
index a839eb6..800418a 100644
--- a/pkg/js/CHANGELOG.md
+++ b/pkg/js/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.2
+
+* Improved documentation.
+
## 0.6.1+1
* Support Dart 2 final release.
diff --git a/pkg/js/README.md b/pkg/js/README.md
index e95e03e..1aec699 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -1,18 +1,5 @@
Methods and annotations to specify interoperability with JavaScript APIs.
-*This packages requires Dart SDK 1.13.0.*
-
-*This is beta software. Please files [issues].*
-
-### Adding the dependency
-
-Add the following to your `pubspec.yaml`:
-
-```yaml
-dependencies:
- js: ^0.6.0
-```
-
### Example
See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for an
@@ -20,12 +7,20 @@
### Usage
+All Dart code interacting with JavaScript should use the utilities provided with
+`package:js`. Developers should avoid importing `dart:js` directly.
+
#### Calling methods
```dart
+@JS()
+library stringify;
+
+import 'package:js/js.dart';
+
// Calls invoke JavaScript `JSON.stringify(obj)`.
-@JS("JSON.stringify")
-external String stringify(obj);
+@JS('JSON.stringify')
+external String stringify(Object obj);
```
#### Classes and Namespaces
@@ -34,24 +29,24 @@
@JS('google.maps')
library maps;
-import "package:js/js.dart";
+import 'package:js/js.dart';
// Invokes the JavaScript getter `google.maps.map`.
external Map get map;
-// `new Map` invokes JavaScript `new google.maps.Map(location)`
+// The `Map` constructor invokes JavaScript `new google.maps.Map(location)`
@JS()
class Map {
external Map(Location location);
external Location getLocation();
}
-// `new Location(...)` invokes JavaScript `new google.maps.LatLng(...)`
+// The `Location` constructor invokes JavaScript `new google.maps.LatLng(...)`
//
// We recommend against using custom JavaScript names whenever
// possible. It is easier for users if the JavaScript names and Dart names
// are consistent.
-@JS("LatLng")
+@JS('LatLng')
class Location {
external Location(num lat, num lng);
}
@@ -65,17 +60,19 @@
printOptions({responsive: true});
```
-If you want to use `printOptions` from Dart, you cannot simply pass a Dart `Map`
-object – they are "opaque" in JavaScript.
+If you want to use `printOptions` from Dart a `Map<String, dynamic>` would be
+"opaque" in JavaScript.
-
-Instead, create a Dart class with both the `@JS()` and
-`@anonymous` annotations.
+Instead, create a Dart class with both the `@JS()` and `@anonymous` annotations.
```dart
-// Dart
+@JS()
+library print_options;
+
+import 'package:js/js.dart';
+
void main() {
- printOptions(new Options(responsive: true));
+ printOptions(Options(responsive: true));
}
@JS()
@@ -86,26 +83,131 @@
class Options {
external bool get responsive;
+ // Must have an unnamed factory constructor with named arguments.
external factory Options({bool responsive});
}
```
-NB: This _anonymous_ class must have an unnamed _factory constructor_.
+#### Passing functions to JavaScript
-#### Passing functions to JavaScript.
+If you are passing a Dart function to a JavaScript API as an argument , you must
+wrap it using `allowInterop` or `allowInteropCaptureThis`. **Warning** There is
+a behavior difference between the Dart2JS and DDC compilers. When compiled with
+DDC there will be no errors despite missing `allowInterop` calls, because DDC
+uses JS calling semantics by default. When compiling with Dart2JS the
+`allowInterop` utility must be used.
-If you are passing a Dart function to a JavaScript API, you must wrap it using
-`allowInterop` or `allowInteropCaptureThis`.
+#### Making a Dart function callable from JavaScript
-## Contributing and Filing Bugs
+To provide a Dart function callable from JavaScript by name use a setter
+annotated with `@JS()`.
-Please file bugs and features requests on the [Github issue tracker][issues].
+```dart
+@JS()
+library callable_function;
-We also love and accept community contributions, from API suggestions to pull requests.
-Please file an issue before beginning work so we can discuss the design and implementation.
-We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+import 'package:js/js.dart';
-Code contributors must sign the
-[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1).
+/// Allows assigning a function to be callable from `window.functionName()`
+@JS('functionName')
+external set _functionName(void Function() f);
+
+/// Allows calling the assigned function from Dart as well.
+@JS()
+external void functionName();
+
+void _someDartFunction() {
+ print('Hello from Dart!');
+}
+
+void main() {
+ _functionName = allowInterop(_someDartFunction);
+ // JavaScript code may now call `functionName()` or `window.functionName()`.
+}
+```
+
+## Known limitations and bugs
+
+### Differences betwenn Dart2JS and DDC
+
+Dart's production and development JavaScript compilers use different calling
+conventions and type representation, and therefore have different challenges in
+JavaScript interop. There are currently some know differences in behavior and
+bugs in one or both compilers.
+
+#### allowInterop is required in Dart2JS, optional in DDC
+
+DDC uses the same calling conventions as JavaScript and so Dart functions passed
+as callbacks can be invoked without modification. In Dart2JS the calling
+conventions are different and so `allowInterop` or `allowInteropCaptureThis`
+must be used for any callback.
+
+**Workaround:**: Always use `allowInterop` even when not required in DDC.
+
+#### Callbacks allow extra ignored arguments in DDC
+
+In JavaScript a caller may pass any number of "extra" arguments to a function
+and they will be ignored. DDC follows this behavior, Dart2JS will have a runtime
+error if a function is invoked with more arguments than expected.
+
+**Workaround:** Write functions that take the same number of arguments as will
+be passed from JavaScript. If the number is variable use optional positional
+arguments.
+
+#### DDC and Dart2JS have different representation for Maps
+
+Passing a `Map<String, String>` as an argument to a JavaScript function will
+have different behavior depending on the compiler. Calling something like
+`JSON.stringify()` will give different results.
+
+**Workaround:** Only pass object literals instead of Maps as arguments. For json
+specifically use `jsonEncode` in Dart rather than a JS alternative.
+
+#### Missing validation for anonymous factory constructors in DDC
+
+When using an `@anonymous` class to create JavaScript object literals Dart2JS
+will enforce that only named arguments are used, while DDC will allow positional
+arguments but may generate incorrect code.
+
+**Workaround:** Try builds in both development and release mode to get the full
+scope of static validation.
+
+### Sharp Edges
+
+Dart and JavaScript have different semantics and common patterns which makes it
+easy to make some mistakes, and difficult for the tools to provide safety. These
+sharp edges are known pitfalls.
+
+#### Lack of runtime type checking
+
+The return types of methods annotated with `@JS()` are not validated at runtime,
+so an incorrect type may "leak" into other Dart code and violate type system
+guarantees.
+
+**Workaround:** For any calls into JavaScript code that are not known to be safe
+in their return values, validate the results manually with `is` checks.
+
+#### List instances coming from JavaScript will always be `List<dynamic>`
+
+A JavaScript array does not have a reified element type, so an array returned
+from a JavaScript function cannot make guarantees about it's elements without
+inspecting each one. At runtime a check like `result is List` may succeed, while
+`result is List<String>` will always fail.
+
+**Workaround:** Use a `.cast<String>().toList()` call to get a `List` with the
+expected reified type at runtime.
+
+#### The `JsObject` type from `dart:js` can't be used with `@JS()` annotation
+
+`JsObject` and related code in `dart:js` uses a different approach and may not
+be passed as an argument to a method annotated with `@JS()`.
+
+**Workaround:** Avoid importing `dart:js` and only use the `package:js` provided
+approach. To handle object literals use `@anonymous` on an `@JS()` annotated
+class.
+
+## Reporting issues
+
+Please file bugs and features requests on the [SDK issue tracker][issues].
[issues]: https://goo.gl/j3rzs0
diff --git a/pkg/js/lib/js.dart b/pkg/js/lib/js.dart
index 17b1ded..2880c21 100644
--- a/pkg/js/lib/js.dart
+++ b/pkg/js/lib/js.dart
@@ -2,14 +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.
-/// Allows interoperability with Javascript APIs.
+/// Annotations to mark interfaces to JavaScript.
library js;
export 'dart:js' show allowInterop, allowInteropCaptureThis;
-/// A metadata annotation that indicates that a Library, Class, or member is
-/// implemented directly in JavaScript. All external members of a class or
-/// library with this annotation implicitly have it as well.
+/// An annotation that indicates a library, class, or member is implemented
+/// directly in JavaScript.
+///
+/// All external members of a class or library with this annotation implicitly
+/// have it as well.
///
/// Specifying [name] customizes the JavaScript name to use. By default the
/// dart name is used. It is not valid to specify a custom [name] for class
@@ -23,10 +25,11 @@
const _Anonymous();
}
-/// A metadata annotation that indicates that a @JS annotated class is
-/// structural and does not have a known JavaScript prototype.
+/// An annotation that indicates a [JS] annotated class is structural and does
+/// not have a known JavaScript prototype.
///
-/// Factory constructors for anonymous JavaScript classes desugar to creating
-/// JavaScript object literals with name-value pairs corresponding to the
-/// parameter names and values.
+/// A class marked with [anonymous] must have an unnamed factory constructor
+/// with no positional arguments, only named arguments. Invoking the constructor
+/// desugars to creating a JavaScript object literal with name-value pairs
+/// corresponding to the parameter names and values.
const _Anonymous anonymous = const _Anonymous();
diff --git a/pkg/js/lib/js_util.dart b/pkg/js/lib/js_util.dart
index 1e47e5d..860f40f 100644
--- a/pkg/js/lib/js_util.dart
+++ b/pkg/js/lib/js_util.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.
-/// Allows interoperability with Javascript APIs.
+/// Utilities for interoperating with JavaScript.
library js_util;
export 'dart:js_util';
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index e6411b4..a7a4e0a 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,8 +1,8 @@
name: js
-version: 0.6.1+1
+version: 0.6.2
author: Dart Team <misc@dartlang.org>
description: Access JavaScript from Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
environment:
- sdk: '>=1.19.0-dev.0.0 <3.0.0'
+ sdk: '>=2.0.0 <3.0.0'
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 399ab56..400dc42 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -763,7 +763,10 @@
// Output 'a += 1' as '++a' and 'a -= 1' as '--a'.
_outputIncDec(op, assignment.leftHandSide);
return;
- } else if (leftHandSide is VariableUse && rightHandSide is Binary) {
+ }
+ if (!assignment.isCompound &&
+ leftHandSide is VariableUse &&
+ rightHandSide is Binary) {
Node rLeft = undefer(rightHandSide.left);
Node rRight = undefer(rightHandSide.right);
String op = rightHandSide.op;
diff --git a/pkg/js_ast/test/deferred_expression_test.dart b/pkg/js_ast/test/deferred_expression_test.dart
index 397aaaa..c91a151 100644
--- a/pkg/js_ast/test/deferred_expression_test.dart
+++ b/pkg/js_ast/test/deferred_expression_test.dart
@@ -29,6 +29,25 @@
test(map, '# = # - 1', [deferred, variableUseAlias], '--variable');
test(map, '# = # + 2', [variableUse, variableUseAlias], 'variable += 2');
test(map, '# = # + 2', [deferred, variableUseAlias], 'variable += 2');
+ test(map, '# = # * 2', [variableUse, variableUseAlias], 'variable *= 2');
+ test(map, '# = # * 2', [deferred, variableUseAlias], 'variable *= 2');
+
+ test(map, '# += # + 1', [variableUse, variableUseAlias],
+ 'variable += variable + 1');
+ test(map, '# += # + 1', [deferred, variableUseAlias],
+ 'variable += variable + 1');
+ test(map, '# += # - 1', [variableUse, variableUseAlias],
+ 'variable += variable - 1');
+ test(map, '# += # - 1', [deferred, variableUseAlias],
+ 'variable += variable - 1');
+ test(map, '# += # + 2', [variableUse, variableUseAlias],
+ 'variable += variable + 2');
+ test(map, '# += # + 2', [deferred, variableUseAlias],
+ 'variable += variable + 2');
+ test(map, '# += # * 2', [variableUse, variableUseAlias],
+ 'variable += variable * 2');
+ test(map, '# += # * 2', [deferred, variableUseAlias],
+ 'variable += variable * 2');
}
void test(Map<Expression, DeferredExpression> map, String template,
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0ff11cf..45fa1d8 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -4799,6 +4799,41 @@
// TYPES
// ------------------------------------------------------------------------
+/// Represents nullability of a type.
+enum Nullability {
+ /// Types in opt-out libraries are 'legacy' types.
+ ///
+ /// They are both subtypes and supertypes of the nullable and non-nullable
+ /// versions of the type.
+ legacy,
+
+ /// Nullable types are marked with the '?' modifier.
+ ///
+ /// Null, dynamic, and void are nullable by default.
+ nullable,
+
+ /// Non-nullable types are types that aren't marked with the '?' modifier.
+ ///
+ /// Note that Null, dynamic, and void that are nullable by default. Note also
+ /// that some types denoted by a type parameter without the '?' modifier can
+ /// be something else rather than non-nullable.
+ nonNullable,
+
+ /// Non-legacy types that are neither nullable, nor non-nullable.
+ ///
+ /// An example of such type is type T in the example below. Note that both
+ /// int and int? can be passed in for T, so an attempt to assign null to x is
+ /// a compile-time error as well as assigning x to y.
+ ///
+ /// class A<T extends Object?> {
+ /// foo(T x) {
+ /// x = null; // Compile-time error.
+ /// Object y = x; // Compile-time error.
+ /// }
+ /// }
+ neither
+}
+
/// A syntax-independent notion of a type.
///
/// [DartType]s are not AST nodes and may be shared between different parents.
@@ -4818,6 +4853,8 @@
bool operator ==(Object other);
+ Nullability get nullability;
+
/// If this is a typedef type, repeatedly unfolds its type definition until
/// the root term is not a typedef type, otherwise returns the type itself.
///
@@ -4843,6 +4880,8 @@
visitChildren(Visitor v) {}
bool operator ==(Object other) => other is InvalidType;
+
+ Nullability get nullability => throw "InvalidType doesn't have nullabiliity";
}
class DynamicType extends DartType {
@@ -4855,6 +4894,8 @@
visitChildren(Visitor v) {}
bool operator ==(Object other) => other is DynamicType;
+
+ Nullability get nullability => Nullability.nullable;
}
class VoidType extends DartType {
@@ -4867,6 +4908,8 @@
visitChildren(Visitor v) {}
bool operator ==(Object other) => other is VoidType;
+
+ Nullability get nullability => Nullability.nullable;
}
class BottomType extends DartType {
@@ -4879,21 +4922,29 @@
visitChildren(Visitor v) {}
bool operator ==(Object other) => other is BottomType;
+
+ Nullability get nullability => Nullability.nonNullable;
}
@coq
class InterfaceType extends DartType {
Reference className;
+
+ final Nullability nullability;
+
@nocoq
final List<DartType> typeArguments;
/// The [typeArguments] list must not be modified after this call. If the
/// list is omitted, 'dynamic' type arguments are filled in.
- InterfaceType(Class classNode, [List<DartType> typeArguments])
+ InterfaceType(Class classNode,
+ [List<DartType> typeArguments,
+ Nullability nullability = Nullability.legacy])
: this.byReference(getClassReference(classNode),
- typeArguments ?? _defaultTypeArguments(classNode));
+ typeArguments ?? _defaultTypeArguments(classNode), nullability);
- InterfaceType.byReference(this.className, this.typeArguments);
+ InterfaceType.byReference(this.className, this.typeArguments,
+ [this.nullability = Nullability.legacy]);
Class get classNode => className.asClass;
@@ -4946,6 +4997,7 @@
@coqsingle
final List<DartType> positionalParameters;
final List<NamedType> namedParameters; // Must be sorted.
+ final Nullability nullability;
/// The [Typedef] this function type is created for.
final TypedefType typedefType;
@@ -4956,6 +5008,7 @@
FunctionType(List<DartType> positionalParameters, this.returnType,
{this.namedParameters: const <NamedType>[],
this.typeParameters: const <TypeParameter>[],
+ this.nullability: Nullability.legacy,
int requiredParameterCount,
this.typedefType})
: this.positionalParameters = positionalParameters,
@@ -5073,14 +5126,18 @@
///
/// The underlying type can be extracted using [unalias].
class TypedefType extends DartType {
+ final Nullability nullability;
final Reference typedefReference;
final List<DartType> typeArguments;
- TypedefType(Typedef typedefNode, [List<DartType> typeArguments])
- : this.byReference(
- typedefNode.reference, typeArguments ?? const <DartType>[]);
+ TypedefType(Typedef typedefNode,
+ [List<DartType> typeArguments,
+ Nullability nullability = Nullability.legacy])
+ : this.byReference(typedefNode.reference,
+ typeArguments ?? const <DartType>[], nullability);
- TypedefType.byReference(this.typedefReference, this.typeArguments);
+ TypedefType.byReference(this.typedefReference, this.typeArguments,
+ [this.nullability = Nullability.legacy]);
Typedef get typedefNode => typedefReference.asTypedef;
@@ -5163,6 +5220,8 @@
/// is the same as the [TypeParameter]'s bound. This allows one to detect
/// whether the bound has been promoted.
class TypeParameterType extends DartType {
+ final Nullability nullability;
+
TypeParameter parameter;
/// An optional promoted bound on the type parameter.
@@ -5171,7 +5230,10 @@
/// is therefore the same as the bound of [parameter].
DartType promotedBound;
- TypeParameterType(this.parameter, [this.promotedBound]);
+ TypeParameterType(this.parameter,
+ [this.promotedBound, Nullability nullability])
+ : this.nullability =
+ getNullability(parameter, promotedBound, nullability);
accept(DartTypeVisitor v) => v.visitTypeParameterType(this);
accept1(DartTypeVisitor1 v, arg) => v.visitTypeParameterType(this, arg);
@@ -5186,6 +5248,115 @@
/// Returns the bound of the type parameter, accounting for promotions.
DartType get bound => promotedBound ?? parameter.bound;
+
+ /// Get nullability of [TypeParameterType] from arguments to its constructor.
+ ///
+ /// This method is supposed to be used only in the constructor of
+ /// [TypeParameterType] to compute the value of
+ /// [TypeParameterType.nullability] from the arguments passed to the constructor.
+ static Nullability getNullability(TypeParameter parameter,
+ DartType promotedBound, Nullability nullability) {
+ // If promotedBound is null, getNullability returns the nullability of
+ // either T or T? where T is parameter and the presence of '?' is determined
+ // by nullability.
+
+ // If promotedBound isn't null, getNullability returns the nullability of an
+ // instesection of the left-hand side (referred to as LHS below) and the
+ // right-hand side (referred to as RHS below). LHS is parameter followed by
+ // nullability, and RHS is promotedBound. That is, getNullability returns
+ // the nullability of either T & P or T? & P where T is parameter, P is
+ // promotedBound, and the presence of '?' is determined by nullability.
+ // Note that RHS is always a subtype of the bound of the type parameter.
+
+ Nullability lhsNullability;
+
+ // If the nullability is explicitly nullable, that is, if the type parameter
+ // type is followed by '?' in the code, the nullability of the type is
+ // 'nullable.'
+ if (nullability == Nullability.nullable) {
+ lhsNullability = Nullability.nullable;
+ } else {
+ // If the bound is nullable, both nullable and non-nullable types can be
+ // passed in for the type parameter, making the corresponding type
+ // parameter types 'neither.' Otherwise, the nullability matches that of
+ // the bound.
+ DartType bound = parameter.bound ?? const DynamicType();
+ Nullability boundNullability =
+ bound is InvalidType ? Nullability.neither : bound.nullability;
+ lhsNullability = boundNullability == Nullability.nullable
+ ? Nullability.neither
+ : boundNullability;
+ }
+ if (promotedBound == null) {
+ return lhsNullability;
+ }
+
+ // In practice a type parameter of legacy type can only be used in type
+ // annotations within the corresponding class declaration. If it's legacy,
+ // then the entire library containing the class is opt-out, and any RHS is
+ // deemed to be legacy too. So, it's necessary to only check LHS for being
+ // legacy.
+ if (lhsNullability == Nullability.legacy) {
+ return Nullability.legacy;
+ }
+
+ // Intersection is non-nullable if and only if RHS is non-nullable.
+ //
+ // The proof is as follows. Intersection is non-nullable if at least one of
+ // LHS or RHS is non-nullable. The case of non-nullable RHS is trivial. In
+ // the case of non-nullable LHS, its bound should be non-nullable. RHS is
+ // known to always be a subtype of the bound of LHS; therefore, RHS is
+ // non-nullable.
+ //
+ // Note that it also follows from the above that non-nullable RHS implies
+ // non-nullable LHS, so the check below covers the case lhsNullability ==
+ // Nullability.nonNullable.
+ if (promotedBound.nullability == Nullability.nonNullable) {
+ return Nullability.nonNullable;
+ }
+
+ // If the nullability of LHS is 'neither,' the nullability of the
+ // intersection is also 'neither' if RHS is 'neither' or nullable.
+ //
+ // Consider the following example:
+ //
+ // class A<X extends Object?, Y extends X> {
+ // foo(X x) {
+ // if (x is Y) {
+ // x = null; // Compile-time error. Consider X = Y = int.
+ // Object a = x; // Compile-time error. Consider X = Y = int?.
+ // }
+ // if (x is int?) {
+ // x = null; // Compile-time error. Consider X = int.
+ // Object b = x; // Compile-time error. Consider X = int?.
+ // }
+ // }
+ // }
+ //
+ // Note that RHS can't be 'legacy' or non-nullable at this point due to the
+ // checks above.
+ if (lhsNullability == Nullability.neither) {
+ return Nullability.neither;
+ }
+
+ // At this point the only possibility for LHS is to be nullable, and for RHS
+ // is to be either nullable or legacy. Both combinations for LHS and RHS
+ // should yield the nullability of RHS as the nullability for the
+ // intersection. Consider the following code for clarification:
+ //
+ // class A<X extends Object?, Y extends X> {
+ // foo(X? x) {
+ // if (x is Y) {
+ // x = null; // Compile-time error. Consider X = Y = int.
+ // Object a = x; // Compile-time error. Consider X = Y = int?.
+ // }
+ // if (x is int?) {
+ // x = null; // Ok. Both X? and int? are nullable.
+ // }
+ // }
+ // }
+ return promotedBound.nullability;
+ }
}
/// Declaration of a type variable.
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 474f907..ed156b1 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -247,14 +247,14 @@
/// Compares members by name, using the same sort order as
/// [getDeclaredMembers] and [getInterfaceMembers].
static int compareMembers(Member first, Member second) {
- return _compareNames(first.name, second.name);
+ return compareNames(first.name, second.name);
}
/// Compares names, using the same sort order as [getDeclaredMembers] and
/// [getInterfaceMembers].
///
/// This is an arbitrary as-fast-as-possible sorting criterion.
- static int _compareNames(Name firstName, Name secondName) {
+ static int compareNames(Name firstName, Name secondName) {
int firstHash = firstName.hashCode;
int secondHash = secondName.hashCode;
if (firstHash != secondHash) return firstHash - secondHash;
@@ -291,7 +291,7 @@
while (low <= high) {
int mid = low + ((high - low) >> 1);
Member pivot = members[mid];
- int comparison = _compareNames(name, pivot.name);
+ int comparison = compareNames(name, pivot.name);
if (comparison < 0) {
high = mid - 1;
} else if (comparison > 0) {
diff --git a/pkg/kernel/lib/external_name.dart b/pkg/kernel/lib/external_name.dart
index 2646fc4..6577041 100644
--- a/pkg/kernel/lib/external_name.dart
+++ b/pkg/kernel/lib/external_name.dart
@@ -20,16 +20,36 @@
return null;
}
for (final Expression annotation in procedure.annotations) {
- if (annotation is ConstructorInvocation) {
- if (_isExternalName(annotation.target.enclosingClass)) {
- return (annotation.arguments.positional.single as StringLiteral).value;
- }
- } else if (annotation is ConstantExpression) {
- final constant = annotation.constant;
- if (constant is InstanceConstant) {
- if (_isExternalName(constant.classNode)) {
- return (constant.fieldValues.values.single as StringConstant).value;
- }
+ final value = _getExternalNameValue(annotation);
+ if (value != null) {
+ return value;
+ }
+ }
+ return null;
+}
+
+/// Returns native extension URIs for given [library].
+List<String> getNativeExtensionUris(Library library) {
+ final uris = <String>[];
+ for (var annotation in library.annotations) {
+ final value = _getExternalNameValue(annotation);
+ if (value != null) {
+ uris.add(value);
+ }
+ }
+ return uris;
+}
+
+String _getExternalNameValue(Expression annotation) {
+ if (annotation is ConstructorInvocation) {
+ if (_isExternalName(annotation.target.enclosingClass)) {
+ return (annotation.arguments.positional.single as StringLiteral).value;
+ }
+ } else if (annotation is ConstantExpression) {
+ final constant = annotation.constant;
+ if (constant is InstanceConstant) {
+ if (_isExternalName(constant.classNode)) {
+ return (constant.fieldValues.values.single as StringConstant).value;
}
}
}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index b599cdf..8cb5c3f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -15,6 +15,7 @@
class ContinuationVariables {
static const awaitJumpVar = ':await_jump_var';
static const awaitContextVar = ':await_ctx_var';
+ static const asyncStackTraceVar = ':async_stack_trace';
static const exceptionParam = ':exception';
static const stackTraceParam = ':stack_trace';
@@ -270,7 +271,7 @@
final VariableDeclaration nestedClosureVariable =
new VariableDeclaration(":async_op");
final VariableDeclaration stackTraceVariable =
- new VariableDeclaration(":async_stack_trace");
+ new VariableDeclaration(ContinuationVariables.asyncStackTraceVar);
final VariableDeclaration thenContinuationVariable =
new VariableDeclaration(":async_op_then");
final VariableDeclaration catchErrorContinuationVariable =
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index eeb40cc..0365260 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.18
+version: 0.3.20
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/nnbd_migration/lib/src/decorated_class_hierarchy.dart b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
new file mode 100644
index 0000000..368bfbd
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
@@ -0,0 +1,85 @@
+// 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/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+
+/// Responsible for building and maintaining information about nullability
+/// decorations related to the class hierarchy.
+///
+/// For instance, if one class is a subclass of the other, we record the
+/// nullabilities of all the types involved in the subclass relationship.
+class DecoratedClassHierarchy {
+ final VariableRepository _variables;
+
+ final NullabilityGraph _graph;
+
+ /// Cache for speeding up the computation of
+ /// [_getGenericSupertypeDecorations].
+ final Map<ClassElement, Map<ClassElement, DecoratedType>>
+ _genericSupertypeDecorations = {};
+
+ DecoratedClassHierarchy(this._variables, this._graph);
+
+ /// Retrieves a [DecoratedType] describing how [class_] implements
+ /// [superclass].
+ ///
+ /// If [class_] does not implement [superclass], raises an exception.
+ ///
+ /// Note that the returned [DecoratedType] will have a node of `never`,
+ /// because the relationship between a class and its superclass is not
+ /// nullable.
+ DecoratedType getDecoratedSupertype(
+ ClassElement class_, ClassElement superclass) {
+ assert(class_ is! ClassElementHandle);
+ assert(superclass is! ClassElementHandle);
+ if (superclass.typeParameters.isEmpty) {
+ return DecoratedType(superclass.type, _graph.never);
+ }
+ return _getGenericSupertypeDecorations(class_)[superclass] ??
+ (throw StateError('Unrelated types'));
+ }
+
+ /// Computes a map whose keys are all the superclasses of [class_], and whose
+ /// values indicate how [class_] implements each superclass.
+ Map<ClassElement, DecoratedType> _getGenericSupertypeDecorations(
+ ClassElement class_) {
+ var decorations = _genericSupertypeDecorations[class_];
+ if (decorations == null) {
+ // Call ourselves recursively to compute how each of [class_]'s direct
+ // superclasses relates to all of its transitive superclasses.
+ decorations = _genericSupertypeDecorations[class_] = {};
+ var decoratedDirectSupertypes =
+ _variables.decoratedDirectSupertypes(class_);
+ for (var entry in decoratedDirectSupertypes.entries) {
+ var superclass = entry.key;
+ var decoratedSupertype = entry.value;
+ var supertype = decoratedSupertype.type as InterfaceType;
+ // Compute a type substitution to determine how [class_] relates to
+ // this specific [superclass].
+ Map<TypeParameterElement, DecoratedType> substitution = {};
+ for (int i = 0; i < supertype.typeArguments.length; i++) {
+ substitution[supertype.typeParameters[i]] =
+ decoratedSupertype.typeArguments[i];
+ }
+ // Apply that substitution to the relation between [superclass] and
+ // each of its transitive superclasses, to determine the relation
+ // between [class_] and the transitive superclass.
+ var recursiveSupertypeDecorations =
+ _getGenericSupertypeDecorations(superclass);
+ for (var entry in recursiveSupertypeDecorations.entries) {
+ decorations[entry.key] ??= entry.value.substitute(substitution);
+ }
+ // Also record the relation between [class_] and its direct
+ // superclass.
+ decorations[superclass] ??= decoratedSupertype;
+ }
+ }
+ return decorations;
+ }
+}
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 5205490..3387fbf 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -40,7 +40,47 @@
this.positionalParameters = const [],
this.namedParameters = const {},
this.typeArguments = const []}) {
- assert(node != null);
+ assert(() {
+ assert(node != null);
+ var type = this.type;
+ if (type is InterfaceType) {
+ assert(returnType == null);
+ assert(positionalParameters.isEmpty);
+ assert(namedParameters.isEmpty);
+ assert(typeArguments.length == type.typeArguments.length);
+ for (int i = 0; i < typeArguments.length; i++) {
+ assert(typeArguments[i].type == type.typeArguments[i]);
+ }
+ } else if (type is FunctionType) {
+ assert(returnType.type == type.returnType);
+ int positionalParameterCount = 0;
+ int namedParameterCount = 0;
+ for (var parameter in type.parameters) {
+ if (parameter.isNamed) {
+ assert(namedParameters[parameter.name].type == parameter.type);
+ namedParameterCount++;
+ } else {
+ assert(positionalParameters[positionalParameterCount].type ==
+ parameter.type);
+ positionalParameterCount++;
+ }
+ }
+ assert(positionalParameters.length == positionalParameterCount);
+ assert(namedParameters.length == namedParameterCount);
+ assert(typeArguments.isEmpty);
+ } else if (node is TypeParameterType) {
+ assert(returnType == null);
+ assert(positionalParameters.isEmpty);
+ assert(namedParameters.isEmpty);
+ assert(typeArguments.isEmpty);
+ } else {
+ assert(returnType == null);
+ assert(positionalParameters.isEmpty);
+ assert(namedParameters.isEmpty);
+ assert(typeArguments.isEmpty);
+ }
+ return true;
+ }());
}
/// Creates a [DecoratedType] corresponding to the given [element], which is
@@ -72,14 +112,32 @@
throw UnimplementedError('Decorating ${type.displayName}');
}
return DecoratedType(type, graph.never);
+ } else if (type is TypeParameterType) {
+ return DecoratedType(type, graph.never);
} else {
throw type.runtimeType; // TODO(paulberry)
}
}
+ // Sanity check:
+ // Ensure the element is not from a library that is being migrated.
+ // If this assertion fires, it probably means that the NodeBuilder failed to
+ // generate the appropriate decorated type for the element when it was
+ // visiting the source file.
+ if (graph.isBeingMigrated(element.source)) {
+ throw 'Internal Error: DecorateType.forElement should not be called'
+ ' for elements being migrated: ${element.runtimeType} :: $element';
+ }
+
DecoratedType decoratedType;
if (element is ExecutableElement) {
decoratedType = decorate(element.type);
+ } else if (element is TopLevelVariableElement) {
+ decoratedType = decorate(element.type);
+ } else if (element is TypeParameterElement) {
+ // By convention, type parameter elements are decorated with the type of
+ // their bounds.
+ decoratedType = decorate(element.bound ?? DynamicTypeImpl.instance);
} else {
// TODO(paulberry)
throw UnimplementedError('Decorating ${element.runtimeType}');
@@ -87,14 +145,117 @@
return decoratedType;
}
+ /// Creates a decorated type corresponding to [type], with fresh nullability
+ /// nodes everywhere that don't correspond to any source location. These
+ /// nodes can later be unioned with other nodes.
+ factory DecoratedType.forImplicitFunction(
+ FunctionType type, NullabilityNode node, NullabilityGraph graph,
+ {DecoratedType returnType}) {
+ if (type.typeFormals.isNotEmpty) {
+ throw new UnimplementedError('Decorating a generic function type');
+ }
+ var positionalParameters = <DecoratedType>[];
+ var namedParameters = <String, DecoratedType>{};
+ for (var parameter in type.parameters) {
+ if (parameter.isPositional) {
+ positionalParameters
+ .add(DecoratedType.forImplicitType(parameter.type, graph));
+ } else {
+ namedParameters[parameter.name] =
+ DecoratedType.forImplicitType(parameter.type, graph);
+ }
+ }
+ return DecoratedType(type, node,
+ returnType:
+ returnType ?? DecoratedType.forImplicitType(type.returnType, graph),
+ namedParameters: namedParameters,
+ positionalParameters: positionalParameters);
+ }
+
+ /// Creates a DecoratedType corresponding to [type], with fresh nullability
+ /// nodes everywhere that don't correspond to any source location. These
+ /// nodes can later be unioned with other nodes.
+ factory DecoratedType.forImplicitType(DartType type, NullabilityGraph graph) {
+ if (type.isDynamic || type.isVoid) {
+ return DecoratedType(type, graph.always);
+ } else if (type is InterfaceType) {
+ return DecoratedType(type, NullabilityNode.forInferredType(),
+ typeArguments: type.typeArguments
+ .map((t) => DecoratedType.forImplicitType(t, graph))
+ .toList());
+ } else if (type is FunctionType) {
+ return DecoratedType.forImplicitFunction(
+ type, NullabilityNode.forInferredType(), graph);
+ } else if (type is TypeParameterType) {
+ return DecoratedType(type, NullabilityNode.forInferredType());
+ }
+ // TODO(paulberry)
+ throw UnimplementedError(
+ 'DecoratedType.forImplicitType(${type.runtimeType})');
+ }
+
+ /// If `this` represents an interface type, returns the substitution necessary
+ /// to produce this type using the class's type as a starting point.
+ /// Otherwise throws an exception.
+ ///
+ /// For instance, if `this` represents `List<int?1>`, returns the substitution
+ /// `{T: int?1}`, where `T` is the [TypeParameterElement] for `List`'s type
+ /// parameter.
+ Map<TypeParameterElement, DecoratedType> get asSubstitution {
+ var type = this.type;
+ if (type is InterfaceType) {
+ return Map<TypeParameterElement, DecoratedType>.fromIterables(
+ type.element.typeParameters, typeArguments);
+ } else {
+ throw StateError(
+ 'Tried to convert a non-interface type to a substitution');
+ }
+ }
+
+ /// If this type is a function type, returns its generic formal parameters.
+ /// Otherwise returns `null`.
+ List<TypeParameterElement> get typeFormals {
+ var type = this.type;
+ if (type is FunctionType) {
+ return type.typeFormals;
+ } else {
+ return null;
+ }
+ }
+
+ /// Converts one function type into another by substituting the given
+ /// [argumentTypes] for the function's generic parameters.
+ DecoratedType instantiate(List<DecoratedType> argumentTypes) {
+ var type = this.type as FunctionType;
+ var typeFormals = type.typeFormals;
+ List<DartType> undecoratedArgumentTypes = [];
+ Map<TypeParameterElement, DecoratedType> substitution = {};
+ for (int i = 0; i < argumentTypes.length; i++) {
+ var argumentType = argumentTypes[i];
+ undecoratedArgumentTypes.add(argumentType.type);
+ substitution[typeFormals[i]] = argumentType;
+ }
+ return _substituteFunctionAfterFormals(
+ type.instantiate(undecoratedArgumentTypes), substitution);
+ }
+
/// Apply the given [substitution] to this type.
///
/// [undecoratedResult] is the result of the substitution, as determined by
- /// the normal type system.
+ /// the normal type system. If not supplied, it is inferred.
DecoratedType substitute(
Map<TypeParameterElement, DecoratedType> substitution,
- DartType undecoratedResult) {
+ [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);
+ }
return _substitute(substitution, undecoratedResult);
}
@@ -112,11 +273,31 @@
}
return '$name$args$trailing';
} else if (type is FunctionType) {
- assert(type.typeFormals.isEmpty); // TODO(paulberry)
- assert(type.namedParameterTypes.isEmpty &&
- namedParameters.isEmpty); // TODO(paulberry)
- var args = positionalParameters.map((p) => p.toString()).join(', ');
- return '$returnType Function($args)$trailing';
+ String formals = '';
+ if (type.typeFormals.isNotEmpty) {
+ formals = '<${type.typeFormals.join(', ')}>';
+ }
+ List<String> paramStrings = [];
+ for (int i = 0; i < positionalParameters.length; i++) {
+ var prefix = '';
+ if (i == type.normalParameterTypes.length) {
+ prefix = '[';
+ }
+ paramStrings.add('$prefix${positionalParameters[i]}');
+ }
+ if (type.normalParameterTypes.length < positionalParameters.length) {
+ paramStrings.last += ']';
+ }
+ if (namedParameters.isNotEmpty) {
+ var prefix = '{';
+ for (var entry in namedParameters.entries) {
+ paramStrings.add('$prefix${entry.key}: ${entry.value}');
+ prefix = '';
+ }
+ paramStrings.last += '}';
+ }
+ var args = paramStrings.join(', ');
+ return '$returnType Function$formals($args)$trailing';
} else if (type is DynamicTypeImpl) {
return 'dynamic';
} else {
@@ -138,30 +319,49 @@
var type = this.type;
if (type is FunctionType && undecoratedResult is FunctionType) {
assert(type.typeFormals.isEmpty); // TODO(paulberry)
- var newPositionalParameters = <DecoratedType>[];
- for (int i = 0; i < positionalParameters.length; i++) {
- var numRequiredParameters =
- undecoratedResult.normalParameterTypes.length;
- var undecoratedParameterType = i < numRequiredParameters
- ? undecoratedResult.normalParameterTypes[i]
- : undecoratedResult
- .optionalParameterTypes[i - numRequiredParameters];
- newPositionalParameters.add(positionalParameters[i]
- ._substitute(substitution, undecoratedParameterType));
+ return _substituteFunctionAfterFormals(undecoratedResult, substitution);
+ } else if (type is InterfaceType && undecoratedResult is InterfaceType) {
+ List<DecoratedType> newTypeArguments = [];
+ for (int i = 0; i < typeArguments.length; i++) {
+ newTypeArguments.add(typeArguments[i]
+ .substitute(substitution, undecoratedResult.typeArguments[i]));
}
return DecoratedType(undecoratedResult, node,
- returnType: returnType._substitute(
- substitution, undecoratedResult.returnType),
- positionalParameters: newPositionalParameters);
+ typeArguments: newTypeArguments);
} else if (type is TypeParameterType) {
var inner = substitution[type.element];
- return DecoratedType(undecoratedResult,
- NullabilityNode.forSubstitution(inner?.node, node));
+ if (inner == null) {
+ return this;
+ } else {
+ return inner
+ .withNode(NullabilityNode.forSubstitution(inner.node, node));
+ }
} else if (type is VoidType) {
return this;
}
throw '$type.substitute($substitution)'; // TODO(paulberry)
}
+
+ /// Performs the logic that is common to substitution and function type
+ /// instantiation. Namely, a decorated type is formed whose undecorated type
+ /// is [undecoratedResult], and whose return type, positional parameters, and
+ /// named parameters are formed by performing the given [substitution].
+ DecoratedType _substituteFunctionAfterFormals(FunctionType undecoratedResult,
+ Map<TypeParameterElement, DecoratedType> substitution) {
+ var newPositionalParameters = <DecoratedType>[];
+ for (int i = 0; i < positionalParameters.length; i++) {
+ var numRequiredParameters = undecoratedResult.normalParameterTypes.length;
+ var undecoratedParameterType = i < numRequiredParameters
+ ? undecoratedResult.normalParameterTypes[i]
+ : undecoratedResult.optionalParameterTypes[i - numRequiredParameters];
+ newPositionalParameters.add(positionalParameters[i]
+ ._substitute(substitution, undecoratedParameterType));
+ }
+ return DecoratedType(undecoratedResult, node,
+ returnType:
+ returnType._substitute(substitution, undecoratedResult.returnType),
+ positionalParameters: newPositionalParameters);
+ }
}
/// A [DecoratedType] based on a type annotation appearing explicitly in the
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
new file mode 100644
index 0000000..08c3f80
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -0,0 +1,1466 @@
+// 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/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.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';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_origin.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';
+
+/// Visitor that builds nullability graph edges by examining code to be
+/// migrated.
+///
+/// The return type of each `visit...` method is a [DecoratedType] indicating
+/// the static type of the visited expression, along with the constraint
+/// variables that will determine its nullability. For `visit...` methods that
+/// don't visit expressions, `null` will be returned.
+class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
+ final InheritanceManager2 _inheritanceManager;
+
+ /// The repository of constraint variables and decorated types (from a
+ /// previous pass over the source code).
+ final VariableRepository _variables;
+
+ final NullabilityMigrationListener /*?*/ listener;
+
+ final NullabilityGraph _graph;
+
+ /// The file being analyzed.
+ final Source _source;
+
+ final DecoratedClassHierarchy _decoratedClassHierarchy;
+
+ /// For convenience, a [DecoratedType] representing non-nullable `Object`.
+ final DecoratedType _notNullType;
+
+ /// For convenience, a [DecoratedType] representing non-nullable `bool`.
+ final DecoratedType _nonNullableBoolType;
+
+ /// For convenience, a [DecoratedType] representing non-nullable `Type`.
+ final DecoratedType _nonNullableTypeType;
+
+ /// For convenience, a [DecoratedType] representing `Null`.
+ final DecoratedType _nullType;
+
+ /// The [DecoratedType] of the innermost function or method being visited, or
+ /// `null` if the visitor is not inside any function or method.
+ ///
+ /// This is needed to construct the appropriate nullability constraints for
+ /// return statements.
+ DecoratedType _currentFunctionType;
+
+ /// Information about the most recently visited binary expression whose
+ /// boolean value could possibly affect nullability analysis.
+ _ConditionInfo _conditionInfo;
+
+ /// The set of nullability nodes that would have to be `nullable` for the code
+ /// currently being visited to be reachable.
+ ///
+ /// Guard variables are attached to the left hand side of any generated
+ /// constraints, so that constraints do not take effect if they come from
+ /// code that can be proven unreachable by the migration tool.
+ final _guards = <NullabilityNode>[];
+
+ /// Indicates whether the statement or expression being visited is within
+ /// conditional control flow. If `true`, this means that the enclosing
+ /// function might complete normally without executing the current statement
+ /// or expression.
+ bool _inConditionalControlFlow = false;
+
+ NullabilityNode _lastConditionalNode;
+
+ EdgeBuilder(TypeProvider typeProvider, TypeSystem typeSystem, this._variables,
+ this._graph, this._source, this.listener)
+ : _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph),
+ _inheritanceManager = InheritanceManager2(typeSystem),
+ _notNullType = DecoratedType(typeProvider.objectType, _graph.never),
+ _nonNullableBoolType =
+ DecoratedType(typeProvider.boolType, _graph.never),
+ _nonNullableTypeType =
+ DecoratedType(typeProvider.typeType, _graph.never),
+ _nullType = DecoratedType(typeProvider.nullType, _graph.always);
+
+ /// Gets the decorated type of [element] from [_variables], performing any
+ /// necessary substitutions.
+ DecoratedType getOrComputeElementType(Element element,
+ {DecoratedType targetType}) {
+ Map<TypeParameterElement, DecoratedType> substitution;
+ Element baseElement;
+ if (element is Member) {
+ assert(targetType != null);
+ baseElement = element.baseElement;
+ var targetTypeType = targetType.type;
+ if (targetTypeType is InterfaceType &&
+ baseElement is ClassMemberElement) {
+ var enclosingClass = baseElement.enclosingElement;
+ assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
+ substitution = <TypeParameterElement, DecoratedType>{};
+ assert(enclosingClass.typeParameters.length ==
+ targetTypeType.typeArguments.length); // TODO(paulberry)
+ for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
+ substitution[enclosingClass.typeParameters[i]] =
+ targetType.typeArguments[i];
+ }
+ }
+ } else {
+ baseElement = element;
+ }
+ DecoratedType decoratedBaseType;
+ if (baseElement is PropertyAccessorElement &&
+ baseElement.isSynthetic &&
+ !baseElement.variable.isSynthetic) {
+ var variable = baseElement.variable;
+ var decoratedElementType = _variables.decoratedElementType(variable);
+ if (baseElement.isGetter) {
+ decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
+ returnType: decoratedElementType);
+ } else {
+ assert(baseElement.isSetter);
+ decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
+ positionalParameters: [decoratedElementType],
+ returnType: DecoratedType(VoidTypeImpl.instance, _graph.always));
+ }
+ } else {
+ decoratedBaseType = _variables.decoratedElementType(baseElement);
+ }
+ if (substitution != null) {
+ DartType elementType;
+ if (element is MethodElement) {
+ elementType = element.type;
+ } else if (element is ConstructorElement) {
+ elementType = element.type;
+ } else {
+ throw element.runtimeType; // TODO(paulberry)
+ }
+ return decoratedBaseType.substitute(substitution, elementType);
+ } else {
+ return decoratedBaseType;
+ }
+ }
+
+ @override
+ DecoratedType visitAsExpression(AsExpression node) {
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'AsExpression');
+ }
+
+ @override
+ DecoratedType visitAssertStatement(AssertStatement node) {
+ _handleAssignment(node.condition, _notNullType);
+ if (identical(_conditionInfo?.condition, node.condition)) {
+ if (!_inConditionalControlFlow &&
+ _conditionInfo.trueDemonstratesNonNullIntent != null) {
+ _graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
+ _graph.never, NonNullAssertionOrigin(_source, node.offset),
+ hard: true);
+ }
+ }
+ node.message?.accept(this);
+ return null;
+ }
+
+ @override
+ DecoratedType visitAssignmentExpression(AssignmentExpression node) {
+ if (node.operator.type != TokenType.EQ) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Assignment with operator ${node.operator.lexeme}');
+ }
+ var leftType = node.leftHandSide.accept(this);
+ var conditionalNode = _lastConditionalNode;
+ _lastConditionalNode = null;
+ var expressionType = _handleAssignment(node.rightHandSide, leftType);
+ if (_isConditionalExpression(node.leftHandSide)) {
+ expressionType = expressionType.withNode(
+ NullabilityNode.forLUB(conditionalNode, expressionType.node));
+ _variables.recordDecoratedExpressionType(node, expressionType);
+ }
+ return expressionType;
+ }
+
+ @override
+ DecoratedType visitAwaitExpression(AwaitExpression node) {
+ var expressionType = node.expression.accept(this);
+ // TODO(paulberry) Handle subclasses of Future.
+ if (expressionType.type.isDartAsyncFuture ||
+ expressionType.type.isDartAsyncFutureOr) {
+ expressionType = expressionType.typeArguments[0];
+ }
+ return expressionType;
+ }
+
+ @override
+ DecoratedType visitBinaryExpression(BinaryExpression node) {
+ var operatorType = node.operator.type;
+ if (operatorType == TokenType.EQ_EQ || operatorType == TokenType.BANG_EQ) {
+ assert(node.leftOperand is! NullLiteral); // TODO(paulberry)
+ var leftType = node.leftOperand.accept(this);
+ node.rightOperand.accept(this);
+ if (node.rightOperand is NullLiteral) {
+ // TODO(paulberry): figure out what the rules for isPure should be.
+ // TODO(paulberry): only set falseChecksNonNull in unconditional
+ // control flow
+ bool isPure = node.leftOperand is SimpleIdentifier;
+ var conditionInfo = _ConditionInfo(node,
+ isPure: isPure,
+ trueGuard: leftType.node,
+ falseDemonstratesNonNullIntent: leftType.node);
+ _conditionInfo = operatorType == TokenType.EQ_EQ
+ ? conditionInfo
+ : conditionInfo.not(node);
+ }
+ return _nonNullableBoolType;
+ } else if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
+ operatorType == TokenType.BAR_BAR) {
+ _handleAssignment(node.leftOperand, _notNullType);
+ _handleAssignment(node.rightOperand, _notNullType);
+ return _nonNullableBoolType;
+ } else if (operatorType == TokenType.QUESTION_QUESTION) {
+ DecoratedType expressionType;
+ var leftType = node.leftOperand.accept(this);
+ try {
+ _guards.add(leftType.node);
+ var rightType = node.rightOperand.accept(this);
+ var ifNullNode = NullabilityNode.forIfNotNull();
+ expressionType = DecoratedType(node.staticType, ifNullNode);
+ _graph.connect(rightType.node, expressionType.node,
+ IfNullOrigin(_source, node.offset),
+ guards: _guards);
+ } finally {
+ _guards.removeLast();
+ }
+ _variables.recordDecoratedExpressionType(node, expressionType);
+ return expressionType;
+ } else if (operatorType.isUserDefinableOperator) {
+ _handleAssignment(node.leftOperand, _notNullType);
+ var callee = node.staticElement;
+ assert(!(callee is ClassMemberElement &&
+ callee
+ .enclosingElement.typeParameters.isNotEmpty)); // TODO(paulberry)
+ assert(callee != null); // TODO(paulberry)
+ var calleeType = getOrComputeElementType(callee);
+ // TODO(paulberry): substitute if necessary
+ assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
+ _handleAssignment(node.rightOperand, calleeType.positionalParameters[0]);
+ return calleeType.returnType;
+ } else {
+ // TODO(paulberry)
+ node.leftOperand.accept(this);
+ node.rightOperand.accept(this);
+ _unimplemented(
+ node, 'Binary expression with operator ${node.operator.lexeme}');
+ }
+ }
+
+ @override
+ DecoratedType visitBooleanLiteral(BooleanLiteral node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitCascadeExpression(CascadeExpression node) {
+ var type = node.target.accept(this);
+ node.cascadeSections.accept(this);
+ return type;
+ }
+
+ @override
+ DecoratedType visitClassDeclaration(ClassDeclaration node) {
+ node.members.accept(this);
+ return null;
+ }
+
+ @override
+ DecoratedType visitClassTypeAlias(ClassTypeAlias node) {
+ var classElement = node.declaredElement;
+ var supertype = classElement.supertype;
+ var superElement = supertype.element;
+ if (superElement is ClassElementHandle) {
+ superElement = (superElement as ClassElementHandle).actualElement;
+ }
+ for (var constructorElement in classElement.constructors) {
+ assert(constructorElement.isSynthetic);
+ var superConstructorElement =
+ superElement.getNamedConstructor(constructorElement.name);
+ var constructorDecoratedType = _variables
+ .decoratedElementType(constructorElement)
+ .substitute(_decoratedClassHierarchy
+ .getDecoratedSupertype(classElement, superElement)
+ .asSubstitution);
+ var superConstructorDecoratedType =
+ _variables.decoratedElementType(superConstructorElement);
+ var origin = ImplicitMixinSuperCallOrigin(_source, node.offset);
+ _unionDecoratedTypeParameters(
+ constructorDecoratedType, superConstructorDecoratedType, origin);
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitComment(Comment node) {
+ // Ignore comments.
+ return null;
+ }
+
+ @override
+ DecoratedType visitConditionalExpression(ConditionalExpression node) {
+ _handleAssignment(node.condition, _notNullType);
+ // TODO(paulberry): guard anything inside the true and false branches
+ var thenType = node.thenExpression.accept(this);
+ var elseType = node.elseExpression.accept(this);
+
+ var overallType = _decorateUpperOrLowerBound(
+ node, node.staticType, thenType, elseType, true);
+ _variables.recordDecoratedExpressionType(node, overallType);
+ return overallType;
+ }
+
+ @override
+ DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
+ _handleExecutableDeclaration(
+ node,
+ node.declaredElement,
+ node.metadata,
+ null,
+ node.parameters,
+ node.initializers,
+ node.body,
+ node.redirectedConstructor);
+ return null;
+ }
+
+ @override
+ DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
+ node.parameter.accept(this);
+ var defaultValue = node.defaultValue;
+ if (defaultValue == null) {
+ if (node.declaredElement.hasRequired) {
+ // Nothing to do; the implicit default value of `null` will never be
+ // reached.
+ } else {
+ _graph.connect(
+ _graph.always,
+ getOrComputeElementType(node.declaredElement).node,
+ OptionalFormalParameterOrigin(_source, node.offset),
+ guards: _guards);
+ }
+ } else {
+ _handleAssignment(
+ defaultValue, getOrComputeElementType(node.declaredElement),
+ canInsertChecks: false);
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitDoubleLiteral(DoubleLiteral node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ if (_currentFunctionType == null) {
+ _unimplemented(
+ node,
+ 'ExpressionFunctionBody with no current function '
+ '(parent is ${node.parent.runtimeType})');
+ }
+ _handleAssignment(node.expression, _currentFunctionType.returnType);
+ return null;
+ }
+
+ @override
+ DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
+ var parameterElement = node.declaredElement as FieldFormalParameterElement;
+ var parameterType = _variables.decoratedElementType(parameterElement);
+ var fieldType = _variables.decoratedElementType(parameterElement.field);
+ var origin = FieldFormalParameterOrigin(_source, node.offset);
+ if (node.type == null) {
+ _unionDecoratedTypes(parameterType, fieldType, origin);
+ } else {
+ _checkAssignment(origin,
+ source: parameterType, destination: fieldType, hard: true);
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
+ node.functionExpression.parameters?.accept(this);
+ assert(_currentFunctionType == null);
+ _currentFunctionType =
+ _variables.decoratedElementType(node.declaredElement);
+ _inConditionalControlFlow = false;
+ try {
+ node.functionExpression.body.accept(this);
+ } finally {
+ _currentFunctionType = null;
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitFunctionExpression(FunctionExpression node) {
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'FunctionExpression');
+ }
+
+ @override
+ DecoratedType visitFunctionExpressionInvocation(
+ FunctionExpressionInvocation node) {
+ DecoratedType calleeType = node.function.accept(this);
+ return _handleInvocationArguments(node, node.argumentList.arguments,
+ node.typeArguments, calleeType, null);
+ }
+
+ @override
+ DecoratedType visitIfStatement(IfStatement node) {
+ // TODO(paulberry): should the use of a boolean in an if-statement be
+ // treated like an implicit `assert(b != null)`? Probably.
+ _handleAssignment(node.condition, _notNullType);
+ _inConditionalControlFlow = true;
+ NullabilityNode trueGuard;
+ NullabilityNode falseGuard;
+ if (identical(_conditionInfo?.condition, node.condition)) {
+ trueGuard = _conditionInfo.trueGuard;
+ falseGuard = _conditionInfo.falseGuard;
+ _variables.recordConditionalDiscard(_source, node,
+ ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
+ }
+ if (trueGuard != null) {
+ _guards.add(trueGuard);
+ }
+ try {
+ node.thenStatement.accept(this);
+ } finally {
+ if (trueGuard != null) {
+ _guards.removeLast();
+ }
+ }
+ if (falseGuard != null) {
+ _guards.add(falseGuard);
+ }
+ try {
+ node.elseStatement?.accept(this);
+ } finally {
+ if (falseGuard != null) {
+ _guards.removeLast();
+ }
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitIndexExpression(IndexExpression node) {
+ DecoratedType targetType;
+ var target = node.realTarget;
+ if (target != null) {
+ targetType = _handleAssignment(target, _notNullType);
+ }
+ var callee = node.staticElement;
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Index expression with no static type');
+ }
+ var calleeType = getOrComputeElementType(callee, targetType: targetType);
+ // TODO(paulberry): substitute if necessary
+ _handleAssignment(node.index, calleeType.positionalParameters[0]);
+ if (node.inSetterContext()) {
+ return calleeType.positionalParameters[1];
+ } else {
+ return calleeType.returnType;
+ }
+ }
+
+ @override
+ DecoratedType visitInstanceCreationExpression(
+ InstanceCreationExpression node) {
+ var callee = node.staticElement;
+ var typeParameters = callee.enclosingElement.typeParameters;
+ List<DecoratedType> decoratedTypeArguments;
+ var typeArguments = node.constructorName.type.typeArguments;
+ if (typeArguments != null) {
+ decoratedTypeArguments = typeArguments.arguments
+ .map((t) => _variables.decoratedTypeAnnotation(_source, t))
+ .toList();
+ } else {
+ decoratedTypeArguments = const [];
+ }
+ var createdType = DecoratedType(node.staticType, _graph.never,
+ typeArguments: decoratedTypeArguments);
+ var calleeType = getOrComputeElementType(callee, targetType: createdType);
+ _handleInvocationArguments(node, node.argumentList.arguments, typeArguments,
+ calleeType, typeParameters);
+ return createdType;
+ }
+
+ @override
+ DecoratedType visitIntegerLiteral(IntegerLiteral node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @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');
+ } else if (type is GenericFunctionType) {
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'Is expression with GenericFunctionType');
+ }
+ node.visitChildren(this);
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitLibraryDirective(LibraryDirective node) {
+ // skip directives
+ return null;
+ }
+
+ @override
+ DecoratedType visitListLiteral(ListLiteral node) {
+ var listType = node.staticType as InterfaceType;
+ if (node.typeArguments == null) {
+ // TODO(brianwilkerson) We might want to create a fake node in the graph
+ // to represent the type argument so that we can still create edges from
+ // the elements to it.
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'List literal with no type arguments');
+ } else {
+ var typeArgumentType = _variables.decoratedTypeAnnotation(
+ _source, node.typeArguments.arguments[0]);
+ if (typeArgumentType == null) {
+ _unimplemented(node, 'Could not compute type argument type');
+ }
+ for (var element in node.elements) {
+ if (element is Expression) {
+ _handleAssignment(element, typeArgumentType);
+ } else {
+ // Handle spread and control flow elements.
+ element.accept(this);
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'Spread or control flow element');
+ }
+ }
+ return DecoratedType(listType, _graph.never,
+ typeArguments: [typeArgumentType]);
+ }
+ }
+
+ @override
+ DecoratedType visitMethodDeclaration(MethodDeclaration node) {
+ if (node.typeParameters != null) {
+ _unimplemented(node, 'Generic method');
+ }
+ _handleExecutableDeclaration(node, node.declaredElement, node.metadata,
+ node.returnType, node.parameters, null, node.body, null);
+ return null;
+ }
+
+ @override
+ DecoratedType visitMethodInvocation(MethodInvocation node) {
+ DecoratedType targetType;
+ var target = node.realTarget;
+ bool isConditional = _isConditionalExpression(node);
+ if (target != null) {
+ if (isConditional) {
+ targetType = target.accept(this);
+ } else {
+ _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
+ targetType = _handleAssignment(target, _notNullType);
+ }
+ }
+ var callee = node.methodName.staticElement;
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Unresolved method name');
+ }
+ var calleeType = getOrComputeElementType(callee, targetType: targetType);
+ if (callee is PropertyAccessorElement) {
+ calleeType = calleeType.returnType;
+ }
+ var expressionType = _handleInvocationArguments(node,
+ node.argumentList.arguments, node.typeArguments, calleeType, null);
+ if (isConditional) {
+ expressionType = expressionType.withNode(
+ NullabilityNode.forLUB(targetType.node, expressionType.node));
+ _variables.recordDecoratedExpressionType(node, expressionType);
+ }
+ return expressionType;
+ }
+
+ @override
+ DecoratedType visitNamespaceDirective(NamespaceDirective node) {
+ // skip directives
+ return null;
+ }
+
+ @override
+ DecoratedType visitNode(AstNode node) {
+ if (listener != null) {
+ try {
+ return super.visitNode(node);
+ } catch (exception, stackTrace) {
+ listener.addDetail('''
+$exception
+
+$stackTrace''');
+ return null;
+ }
+ } else {
+ return super.visitNode(node);
+ }
+ }
+
+ @override
+ DecoratedType visitNullLiteral(NullLiteral node) {
+ return _nullType;
+ }
+
+ @override
+ DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
+ return node.expression.accept(this);
+ }
+
+ @override
+ DecoratedType visitPostfixExpression(PostfixExpression node) {
+ var operatorType = node.operator.type;
+ if (operatorType == TokenType.PLUS_PLUS ||
+ operatorType == TokenType.MINUS_MINUS) {
+ _handleAssignment(node.operand, _notNullType);
+ var callee = node.staticElement;
+ if (callee is ClassMemberElement &&
+ callee.enclosingElement.typeParameters.isNotEmpty) {
+ // TODO(paulberry)
+ _unimplemented(node,
+ 'Operator ${operatorType.lexeme} defined on a class with type parameters');
+ }
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Unresolved operator ${operatorType.lexeme}');
+ }
+ var calleeType = getOrComputeElementType(callee);
+ // TODO(paulberry): substitute if necessary
+ return calleeType.returnType;
+ }
+ _unimplemented(
+ node, 'Postfix expression with operator ${node.operator.lexeme}');
+ }
+
+ @override
+ DecoratedType visitPrefixedIdentifier(PrefixedIdentifier node) {
+ if (node.prefix.staticElement is ImportElement) {
+ // TODO(paulberry)
+ _unimplemented(node, 'PrefixedIdentifier with a prefix');
+ } else {
+ return _handlePropertyAccess(node, node.prefix, node.identifier);
+ }
+ }
+
+ @override
+ DecoratedType visitPrefixExpression(PrefixExpression node) {
+ var targetType = _handleAssignment(node.operand, _notNullType);
+ var operatorType = node.operator.type;
+ if (operatorType == TokenType.BANG) {
+ return _nonNullableBoolType;
+ } else if (operatorType == TokenType.PLUS_PLUS ||
+ operatorType == TokenType.MINUS_MINUS) {
+ var callee = node.staticElement;
+ if (callee is ClassMemberElement &&
+ callee.enclosingElement.typeParameters.isNotEmpty) {
+ // TODO(paulberry)
+ _unimplemented(node,
+ 'Operator ${operatorType.lexeme} defined on a class with type parameters');
+ }
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Unresolved operator ${operatorType.lexeme}');
+ }
+ var calleeType = getOrComputeElementType(callee);
+ // TODO(paulberry): substitute if necessary
+ return calleeType.returnType;
+ } else {
+ var callee = node.staticElement;
+ var calleeType = getOrComputeElementType(callee, targetType: targetType);
+ return _handleInvocationArguments(node, [], null, calleeType, null);
+ }
+ }
+
+ @override
+ DecoratedType visitPropertyAccess(PropertyAccess node) {
+ return _handlePropertyAccess(node, node.realTarget, node.propertyName);
+ }
+
+ @override
+ DecoratedType visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ var callee = node.constructorName.staticElement;
+ var calleeType = _variables.decoratedElementType(callee);
+ _handleInvocationArguments(
+ node, node.argumentList.arguments, null, calleeType, null);
+ return null;
+ }
+
+ @override
+ DecoratedType visitReturnStatement(ReturnStatement node) {
+ DecoratedType returnType = _currentFunctionType.returnType;
+ Expression returnValue = node.expression;
+ // TODO(danrubel): This does not handle situations where the returnType
+ // or the returnValue's type extends or implements dart:async Future.
+ if ((returnType.type.isDartAsyncFuture ||
+ returnType.type.isDartAsyncFutureOr) &&
+ node.thisOrAncestorOfType<FunctionBody>().isAsynchronous &&
+ !returnValue.staticType.isDartAsyncFuture) {
+ returnType = returnType.typeArguments?.first;
+ if (returnType == null) {
+ return null;
+ }
+ }
+ if (returnValue == null) {
+ _checkAssignment(null,
+ source: _nullType, destination: returnType, hard: false);
+ } else {
+ _handleAssignment(returnValue, returnType);
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitSetOrMapLiteral(SetOrMapLiteral node) {
+ var listType = node.staticType as InterfaceType;
+ var typeArguments = node.typeArguments?.arguments;
+ if (typeArguments == null) {
+ // TODO(brianwilkerson) We might want to create fake nodes in the graph to
+ // represent the type arguments so that we can still create edges from
+ // the elements to them.
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'Set or map literal with no type arguments');
+ } else if (typeArguments.length == 1) {
+ var elementType =
+ _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
+ for (var element in node.elements) {
+ if (element is Expression) {
+ _handleAssignment(element, elementType);
+ } else {
+ // Handle spread and control flow elements.
+ element.accept(this);
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'Spread or control flow element');
+ }
+ }
+ return DecoratedType(listType, _graph.never,
+ typeArguments: [elementType]);
+ } else if (typeArguments.length == 2) {
+ var keyType =
+ _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
+ var valueType =
+ _variables.decoratedTypeAnnotation(_source, typeArguments[1]);
+ for (var element in node.elements) {
+ if (element is MapLiteralEntry) {
+ _handleAssignment(element.key, keyType);
+ _handleAssignment(element.value, valueType);
+ } else {
+ // Handle spread and control flow elements.
+ element.accept(this);
+ // TODO(brianwilkerson)
+ _unimplemented(node, 'Spread or control flow element');
+ }
+ }
+ return DecoratedType(listType, _graph.never,
+ typeArguments: [keyType, valueType]);
+ } else {
+ // TODO(brianwilkerson)
+ _unimplemented(
+ node, 'Set or map literal with more than two type arguments');
+ }
+ }
+
+ @override
+ DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
+ var staticElement = node.staticElement;
+ if (staticElement is ParameterElement ||
+ staticElement is LocalVariableElement ||
+ staticElement is FunctionElement ||
+ staticElement is MethodElement) {
+ return getOrComputeElementType(staticElement);
+ } else if (staticElement is PropertyAccessorElement) {
+ var elementType = getOrComputeElementType(staticElement);
+ return staticElement.isGetter
+ ? elementType.returnType
+ : elementType.positionalParameters[0];
+ } else if (staticElement is ClassElement) {
+ return _nonNullableTypeType;
+ } else {
+ // TODO(paulberry)
+ _unimplemented(node,
+ 'Simple identifier with a static element of type ${staticElement.runtimeType}');
+ }
+ }
+
+ @override
+ DecoratedType visitStringLiteral(StringLiteral node) {
+ node.visitChildren(this);
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitSuperExpression(SuperExpression node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitSymbolLiteral(SymbolLiteral node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitThisExpression(ThisExpression node) {
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitThrowExpression(ThrowExpression node) {
+ node.expression.accept(this);
+ // TODO(paulberry): do we need to check the expression type? I think not.
+ return DecoratedType(node.staticType, _graph.never);
+ }
+
+ @override
+ DecoratedType visitTypeName(TypeName typeName) {
+ var typeArguments = typeName.typeArguments?.arguments;
+ var element = typeName.name.staticElement;
+ if (element is TypeParameterizedElement) {
+ if (typeArguments == null) {
+ var instantiatedType =
+ _variables.decoratedTypeAnnotation(_source, typeName);
+ if (instantiatedType == null) {
+ throw new StateError('No type annotation for type name '
+ '${typeName.toSource()}, offset=${typeName.offset}');
+ }
+ var origin = InstantiateToBoundsOrigin(_source, typeName.offset);
+ for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
+ _unionDecoratedTypes(
+ instantiatedType.typeArguments[i],
+ _variables.decoratedElementType(element.typeParameters[i]),
+ origin);
+ }
+ } else {
+ for (int i = 0; i < typeArguments.length; i++) {
+ DecoratedType bound;
+ bound = _variables.decoratedElementType(element.typeParameters[i]);
+ var argumentType =
+ _variables.decoratedTypeAnnotation(_source, typeArguments[i]);
+ if (argumentType == null) {
+ _unimplemented(typeName,
+ 'No decorated type for type argument ${typeArguments[i]} ($i)');
+ }
+ _checkAssignment(null,
+ source: argumentType, destination: bound, hard: true);
+ }
+ }
+ }
+ return _nonNullableTypeType;
+ }
+
+ @override
+ DecoratedType visitVariableDeclarationList(VariableDeclarationList node) {
+ node.metadata.accept(this);
+ var typeAnnotation = node.type;
+ for (var variable in node.variables) {
+ variable.metadata.accept(this);
+ var initializer = variable.initializer;
+ if (initializer != null) {
+ var destinationType = getOrComputeElementType(variable.declaredElement);
+ if (typeAnnotation == null) {
+ var initializerType = initializer.accept(this);
+ if (initializerType == null) {
+ throw StateError('No type computed for ${initializer.runtimeType} '
+ '(${initializer.toSource()}) offset=${initializer.offset}');
+ }
+ _unionDecoratedTypes(initializerType, destinationType,
+ InitializerInferenceOrigin(_source, variable.name.offset));
+ } else {
+ _handleAssignment(initializer, destinationType);
+ }
+ }
+ }
+ return null;
+ }
+
+ /// Creates the necessary constraint(s) for an assignment from [source] to
+ /// [destination]. [origin] should be used as the origin for any edges
+ /// created. [hard] indicates whether a hard edge should be created.
+ void _checkAssignment(EdgeOrigin origin,
+ {@required DecoratedType source,
+ @required DecoratedType destination,
+ @required bool hard}) {
+ var edge = _graph.connect(source.node, destination.node, origin,
+ guards: _guards, hard: hard);
+ if (origin is ExpressionChecks) {
+ origin.edges.add(edge);
+ }
+ // TODO(paulberry): generalize this.
+ if ((_isSimple(source) || destination.type.isObject) &&
+ _isSimple(destination)) {
+ // Ok; nothing further to do.
+ } else if (source.type is InterfaceType &&
+ destination.type is InterfaceType &&
+ source.type.element == destination.type.element) {
+ assert(source.typeArguments.length == destination.typeArguments.length);
+ for (int i = 0; i < source.typeArguments.length; i++) {
+ _checkAssignment(origin,
+ source: source.typeArguments[i],
+ destination: destination.typeArguments[i],
+ hard: false);
+ }
+ } else if (source.type is FunctionType &&
+ destination.type is FunctionType) {
+ _checkAssignment(origin,
+ source: source.returnType,
+ destination: destination.returnType,
+ hard: hard);
+ if (source.typeArguments.isNotEmpty ||
+ destination.typeArguments.isNotEmpty) {
+ throw UnimplementedError('TODO(paulberry)');
+ }
+ for (int i = 0;
+ i < source.positionalParameters.length &&
+ i < destination.positionalParameters.length;
+ i++) {
+ // Note: source and destination are swapped due to contravariance.
+ _checkAssignment(origin,
+ source: destination.positionalParameters[i],
+ destination: source.positionalParameters[i],
+ hard: hard);
+ }
+ for (var entry in destination.namedParameters.entries) {
+ // Note: source and destination are swapped due to contravariance.
+ _checkAssignment(origin,
+ source: entry.value,
+ destination: source.namedParameters[entry.key],
+ hard: hard);
+ }
+ } else if (destination.type.isDynamic || source.type.isDynamic) {
+ // ok; nothing further to do.
+ } else {
+ throw '$destination <= $source'; // TODO(paulberry)
+ }
+ }
+
+ /// Double checks that [name] is not the name of a method or getter declared
+ /// on [Object].
+ ///
+ /// TODO(paulberry): get rid of this method and put the correct logic into the
+ /// call sites.
+ void _checkNonObjectMember(String name) {
+ assert(name != 'toString');
+ assert(name != 'hashCode');
+ assert(name != 'noSuchMethod');
+ assert(name != 'runtimeType');
+ }
+
+ DecoratedType _decorateUpperOrLowerBound(AstNode astNode, DartType type,
+ DecoratedType left, DecoratedType right, bool isLUB,
+ {NullabilityNode node}) {
+ if (type.isDynamic || type.isVoid) {
+ if (type.isDynamic) {
+ _unimplemented(astNode, 'LUB/GLB with dynamic');
+ }
+ return DecoratedType(type, _graph.always);
+ }
+ node ??= isLUB
+ ? NullabilityNode.forLUB(left.node, right.node)
+ : _nullabilityNodeForGLB(astNode, left.node, right.node);
+ if (type is InterfaceType) {
+ if (type.typeArguments.isEmpty) {
+ return DecoratedType(type, node);
+ } else {
+ var leftType = left.type;
+ var rightType = right.type;
+ if (leftType is InterfaceType && rightType is InterfaceType) {
+ if (leftType.element != type.element ||
+ rightType.element != type.element) {
+ _unimplemented(astNode, 'LUB/GLB with substitution');
+ }
+ List<DecoratedType> newTypeArguments = [];
+ for (int i = 0; i < type.typeArguments.length; i++) {
+ newTypeArguments.add(_decorateUpperOrLowerBound(
+ astNode,
+ type.typeArguments[i],
+ left.typeArguments[i],
+ right.typeArguments[i],
+ isLUB));
+ }
+ return DecoratedType(type, node, typeArguments: newTypeArguments);
+ } else {
+ _unimplemented(
+ astNode,
+ 'LUB/GLB with unexpected types: ${leftType.runtimeType}/'
+ '${rightType.runtimeType}');
+ }
+ }
+ } else if (type is FunctionType) {
+ var leftType = left.type;
+ var rightType = right.type;
+ if (leftType is FunctionType && rightType is FunctionType) {
+ var returnType = _decorateUpperOrLowerBound(
+ astNode, type.returnType, left.returnType, right.returnType, isLUB);
+ List<DecoratedType> positionalParameters = [];
+ Map<String, DecoratedType> namedParameters = {};
+ int positionalParameterCount = 0;
+ for (var parameter in type.parameters) {
+ DecoratedType leftParameterType;
+ DecoratedType rightParameterType;
+ if (parameter.isNamed) {
+ leftParameterType = left.namedParameters[parameter.name];
+ rightParameterType = right.namedParameters[parameter.name];
+ } else {
+ leftParameterType =
+ left.positionalParameters[positionalParameterCount];
+ rightParameterType =
+ right.positionalParameters[positionalParameterCount];
+ positionalParameterCount++;
+ }
+ var decoratedParameterType = _decorateUpperOrLowerBound(astNode,
+ parameter.type, leftParameterType, rightParameterType, !isLUB);
+ if (parameter.isNamed) {
+ namedParameters[parameter.name] = decoratedParameterType;
+ } else {
+ positionalParameters.add(decoratedParameterType);
+ }
+ }
+ return DecoratedType(type, node,
+ returnType: returnType,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters);
+ } else {
+ _unimplemented(
+ astNode,
+ 'LUB/GLB with unexpected types: ${leftType.runtimeType}/'
+ '${rightType.runtimeType}');
+ }
+ } else if (type is TypeParameterType) {
+ _unimplemented(astNode, 'LUB/GLB with type parameter types');
+ }
+ _unimplemented(astNode, '_decorateUpperOrLowerBound');
+ }
+
+ /// Creates the necessary constraint(s) for an assignment of the given
+ /// [expression] to a destination whose type is [destinationType].
+ DecoratedType _handleAssignment(
+ Expression expression, DecoratedType destinationType,
+ {bool canInsertChecks = true}) {
+ var sourceType = expression.accept(this);
+ if (sourceType == null) {
+ throw StateError('No type computed for ${expression.runtimeType} '
+ '(${expression.toSource()}) offset=${expression.offset}');
+ }
+ ExpressionChecks expressionChecks;
+ if (canInsertChecks) {
+ expressionChecks = ExpressionChecks(expression.end);
+ _variables.recordExpressionChecks(_source, expression, expressionChecks);
+ }
+ _checkAssignment(expressionChecks,
+ source: sourceType,
+ destination: destinationType,
+ hard: _isVariableOrParameterReference(expression) &&
+ !_inConditionalControlFlow);
+ return sourceType;
+ }
+
+ void _handleConstructorRedirection(
+ FormalParameterList parameters, ConstructorName redirectedConstructor) {
+ var callee = redirectedConstructor.staticElement;
+ if (callee is ConstructorMember) {
+ callee = (callee as ConstructorMember).baseElement;
+ }
+ var redirectedClass = callee.enclosingElement;
+ var calleeType = _variables.decoratedElementType(callee);
+ _handleInvocationArguments(
+ redirectedConstructor,
+ parameters.parameters,
+ redirectedConstructor.type.typeArguments,
+ calleeType,
+ redirectedClass.typeParameters);
+ }
+
+ void _handleExecutableDeclaration(
+ AstNode node,
+ ExecutableElement declaredElement,
+ NodeList<Annotation> metadata,
+ TypeAnnotation returnType,
+ FormalParameterList parameters,
+ NodeList<ConstructorInitializer> initializers,
+ FunctionBody body,
+ ConstructorName redirectedConstructor) {
+ assert(_currentFunctionType == null);
+ metadata.accept(this);
+ returnType?.accept(this);
+ parameters?.accept(this);
+ _currentFunctionType = _variables.decoratedElementType(declaredElement);
+ _inConditionalControlFlow = false;
+ try {
+ initializers?.accept(this);
+ body.accept(this);
+ if (redirectedConstructor != null) {
+ _handleConstructorRedirection(parameters, redirectedConstructor);
+ }
+ if (declaredElement is! ConstructorElement) {
+ var classElement = declaredElement.enclosingElement as ClassElement;
+ var origin = InheritanceOrigin(_source, node.offset);
+ for (var overridden in _inheritanceManager.getOverridden(
+ classElement.type,
+ Name(classElement.library.source.uri, declaredElement.name)) ??
+ const []) {
+ var overriddenElement = overridden.element as ExecutableElement;
+ assert(overriddenElement is! ExecutableMember);
+ var overriddenClass =
+ overriddenElement.enclosingElement as ClassElement;
+ var decoratedOverriddenFunctionType =
+ _variables.decoratedElementType(overriddenElement);
+ var decoratedSupertype = _decoratedClassHierarchy
+ .getDecoratedSupertype(classElement, overriddenClass);
+ var substitution = decoratedSupertype.asSubstitution;
+ var overriddenFunctionType =
+ decoratedOverriddenFunctionType.substitute(substitution);
+ if (returnType == null) {
+ _unionDecoratedTypes(_currentFunctionType.returnType,
+ overriddenFunctionType.returnType, origin);
+ } else {
+ _checkAssignment(origin,
+ source: _currentFunctionType.returnType,
+ destination: overriddenFunctionType.returnType,
+ hard: true);
+ }
+ if (parameters != null) {
+ int positionalParameterCount = 0;
+ for (var parameter in parameters.parameters) {
+ NormalFormalParameter normalParameter;
+ if (parameter is NormalFormalParameter) {
+ normalParameter = parameter;
+ } else {
+ normalParameter =
+ (parameter as DefaultFormalParameter).parameter;
+ }
+ DecoratedType currentParameterType;
+ DecoratedType overriddenParameterType;
+ if (parameter.isNamed) {
+ var name = normalParameter.identifier.name;
+ currentParameterType =
+ _currentFunctionType.namedParameters[name];
+ overriddenParameterType =
+ overriddenFunctionType.namedParameters[name];
+ } else {
+ if (positionalParameterCount <
+ _currentFunctionType.positionalParameters.length) {
+ currentParameterType = _currentFunctionType
+ .positionalParameters[positionalParameterCount];
+ }
+ if (positionalParameterCount <
+ overriddenFunctionType.positionalParameters.length) {
+ overriddenParameterType = overriddenFunctionType
+ .positionalParameters[positionalParameterCount];
+ }
+ positionalParameterCount++;
+ }
+ if (overriddenParameterType != null) {
+ if (_isUntypedParameter(normalParameter)) {
+ _unionDecoratedTypes(
+ overriddenParameterType, currentParameterType, origin);
+ } else {
+ _checkAssignment(origin,
+ source: overriddenParameterType,
+ destination: currentParameterType,
+ hard: true);
+ }
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ _currentFunctionType = null;
+ }
+ }
+
+ /// Creates the necessary constraint(s) for an [argumentList] when invoking an
+ /// executable element whose type is [calleeType].
+ ///
+ /// Returns the decorated return type of the invocation, after any necessary
+ /// substitutions.
+ DecoratedType _handleInvocationArguments(
+ AstNode node,
+ Iterable<AstNode> arguments,
+ TypeArgumentList typeArguments,
+ DecoratedType calleeType,
+ List<TypeParameterElement> constructorTypeParameters) {
+ var typeFormals = constructorTypeParameters ?? calleeType.typeFormals;
+ if (typeFormals.isNotEmpty) {
+ if (typeArguments != null) {
+ var argumentTypes = typeArguments.arguments
+ .map((t) => _variables.decoratedTypeAnnotation(_source, t))
+ .toList();
+ if (constructorTypeParameters != null) {
+ calleeType = calleeType.substitute(
+ Map<TypeParameterElement, DecoratedType>.fromIterables(
+ constructorTypeParameters, argumentTypes));
+ } else {
+ calleeType = calleeType.instantiate(argumentTypes);
+ }
+ } else {
+ _unimplemented(node, 'Inferred type parameters in invocation');
+ }
+ }
+ int i = 0;
+ var suppliedNamedParameters = Set<String>();
+ for (var argument in arguments) {
+ String name;
+ Expression expression;
+ if (argument is NamedExpression) {
+ name = argument.name.label.name;
+ expression = argument.expression;
+ } else if (argument is FormalParameter) {
+ if (argument.isNamed) {
+ name = argument.identifier.name;
+ }
+ expression = argument.identifier;
+ } else {
+ expression = argument;
+ }
+ DecoratedType parameterType;
+ if (name != null) {
+ parameterType = calleeType.namedParameters[name];
+ if (parameterType == null) {
+ // TODO(paulberry)
+ _unimplemented(expression, 'Missing type for named parameter');
+ }
+ suppliedNamedParameters.add(name);
+ } else {
+ if (calleeType.positionalParameters.length <= i) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Missing positional parameter at $i');
+ }
+ parameterType = calleeType.positionalParameters[i++];
+ }
+ _handleAssignment(expression, parameterType);
+ }
+ // 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));
+ }
+ return calleeType.returnType;
+ }
+
+ DecoratedType _handlePropertyAccess(
+ Expression node, Expression target, SimpleIdentifier propertyName) {
+ DecoratedType targetType;
+ bool isConditional = _isConditionalExpression(node);
+ if (isConditional) {
+ targetType = target.accept(this);
+ } else {
+ _checkNonObjectMember(propertyName.name); // TODO(paulberry)
+ targetType = _handleAssignment(target, _notNullType);
+ }
+ var callee = propertyName.staticElement;
+ if (callee == null) {
+ // TODO(paulberry)
+ _unimplemented(node, 'Unresolved property access');
+ }
+ var calleeType = getOrComputeElementType(callee, targetType: targetType);
+ // TODO(paulberry): substitute if necessary
+ if (propertyName.inSetterContext()) {
+ if (isConditional) {
+ _lastConditionalNode = targetType.node;
+ }
+ return calleeType.positionalParameters[0];
+ } else {
+ var expressionType = callee is PropertyAccessorElement
+ ? calleeType.returnType
+ : calleeType;
+ if (isConditional) {
+ expressionType = expressionType.withNode(
+ NullabilityNode.forLUB(targetType.node, expressionType.node));
+ _variables.recordDecoratedExpressionType(node, expressionType);
+ }
+ return expressionType;
+ }
+ }
+
+ bool _isConditionalExpression(Expression expression) {
+ Token token;
+ if (expression is MethodInvocation) {
+ token = expression.operator;
+ if (token == null) return false;
+ } else if (expression is PropertyAccess) {
+ token = expression.operator;
+ } else {
+ return false;
+ }
+ switch (token.type) {
+ case TokenType.PERIOD:
+ case TokenType.PERIOD_PERIOD:
+ return false;
+ case TokenType.QUESTION_PERIOD:
+ return true;
+ default:
+ // TODO(paulberry)
+ _unimplemented(
+ expression, 'Conditional expression with operator ${token.lexeme}');
+ }
+ }
+
+ /// Double checks that [type] is sufficiently simple for this naive prototype
+ /// implementation.
+ ///
+ /// TODO(paulberry): get rid of this method and put the correct logic into the
+ /// call sites.
+ bool _isSimple(DecoratedType type) {
+ if (type.type.isBottom) return true;
+ if (type.type.isVoid) return true;
+ if (type.type is TypeParameterType) return true;
+ if (type.type is! InterfaceType) return false;
+ if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
+ return true;
+ }
+
+ bool _isUntypedParameter(NormalFormalParameter parameter) {
+ if (parameter is SimpleFormalParameter) {
+ return parameter.type == null;
+ } else if (parameter is FieldFormalParameter) {
+ return parameter.type == null;
+ } else {
+ return false;
+ }
+ }
+
+ bool _isVariableOrParameterReference(Expression expression) {
+ expression = expression.unParenthesized;
+ if (expression is SimpleIdentifier) {
+ var element = expression.staticElement;
+ if (element is LocalVariableElement) return true;
+ if (element is ParameterElement) return true;
+ }
+ return false;
+ }
+
+ NullabilityNode _nullabilityNodeForGLB(
+ AstNode astNode, NullabilityNode leftNode, NullabilityNode rightNode) {
+ var node = NullabilityNode.forGLB();
+ var origin = GreatestLowerBoundOrigin(_source, astNode.offset);
+ _graph.connect(leftNode, node, origin, guards: [rightNode]);
+ _graph.connect(node, leftNode, origin);
+ _graph.connect(node, rightNode, origin);
+ return node;
+ }
+
+ @alwaysThrows
+ void _unimplemented(AstNode node, String message) {
+ CompilationUnit unit = node.root as CompilationUnit;
+ StringBuffer buffer = StringBuffer();
+ buffer.write(message);
+ buffer.write(' in "');
+ buffer.write(node.toSource());
+ buffer.write('" on line ');
+ buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
+ buffer.write(' of "');
+ buffer.write(unit.declaredElement.source.fullName);
+ buffer.write('"');
+ throw UnimplementedError(buffer.toString());
+ }
+
+ void _unionDecoratedTypeParameters(
+ DecoratedType x, DecoratedType y, EdgeOrigin origin) {
+ for (int i = 0;
+ i < x.positionalParameters.length && i < y.positionalParameters.length;
+ i++) {
+ _unionDecoratedTypes(
+ x.positionalParameters[i], y.positionalParameters[i], origin);
+ }
+ for (var entry in x.namedParameters.entries) {
+ var superParameterType = y.namedParameters[entry.key];
+ if (superParameterType != null) {
+ _unionDecoratedTypes(entry.value, y.namedParameters[entry.key], origin);
+ }
+ }
+ }
+
+ void _unionDecoratedTypes(
+ DecoratedType x, DecoratedType y, EdgeOrigin origin) {
+ _graph.union(x.node, y.node, origin);
+ _unionDecoratedTypeParameters(x, y, origin);
+ for (int i = 0;
+ i < x.typeArguments.length && i < y.typeArguments.length;
+ i++) {
+ _unionDecoratedTypes(x.typeArguments[i], y.typeArguments[i], origin);
+ }
+ if (x.returnType != null && y.returnType != null) {
+ _unionDecoratedTypes(x.returnType, y.returnType, origin);
+ }
+ }
+}
+
+/// Information about a binary expression whose boolean value could possibly
+/// affect nullability analysis.
+class _ConditionInfo {
+ /// The [expression] of interest.
+ final Expression condition;
+
+ /// Indicates whether [condition] is pure (free from side effects).
+ ///
+ /// For example, a condition like `x == null` is pure (assuming `x` is a local
+ /// variable or static variable), because evaluating it has no user-visible
+ /// effect other than returning a boolean value.
+ final bool isPure;
+
+ /// If not `null`, the [NullabilityNode] that would need to be nullable in
+ /// order for [condition] to evaluate to `true`.
+ final NullabilityNode trueGuard;
+
+ /// If not `null`, the [NullabilityNode] that would need to be nullable in
+ /// order for [condition] to evaluate to `false`.
+ final NullabilityNode falseGuard;
+
+ /// If not `null`, the [NullabilityNode] that should be asserted to have
+ // /// non-null intent if [condition] is asserted to be `true`.
+ final NullabilityNode trueDemonstratesNonNullIntent;
+
+ /// If not `null`, the [NullabilityNode] that should be asserted to have
+ /// non-null intent if [condition] is asserted to be `false`.
+ final NullabilityNode falseDemonstratesNonNullIntent;
+
+ _ConditionInfo(this.condition,
+ {@required this.isPure,
+ this.trueGuard,
+ this.falseGuard,
+ this.trueDemonstratesNonNullIntent,
+ this.falseDemonstratesNonNullIntent});
+
+ /// Returns a new [_ConditionInfo] describing the boolean "not" of `this`.
+ _ConditionInfo not(Expression condition) => _ConditionInfo(condition,
+ isPure: isPure,
+ trueGuard: falseGuard,
+ falseGuard: trueGuard,
+ trueDemonstratesNonNullIntent: falseDemonstratesNonNullIntent,
+ falseDemonstratesNonNullIntent: trueDemonstratesNonNullIntent);
+}
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 487edc1..db1c8c5 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -34,6 +34,58 @@
EdgeOriginWithLocation(this.source, this.offset);
}
+/// 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);
+}
+
+/// Edge origin resulting from the use of greatest lower bound.
+///
+/// For example, in the following code snippet:
+/// void Function(int) f(void Function(int) x, void Function(int) y)
+/// => x ?? y;
+///
+/// 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);
+}
+
+/// Edge origin resulting from the presence of a `??` operator.
+class IfNullOrigin extends EdgeOriginWithLocation {
+ IfNullOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from the implicit call from a mixin application
+/// constructor to the corresponding super constructor.
+///
+/// For example, in the following code snippet:
+/// class C {
+/// C(int i);
+/// }
+/// mixin M {}
+/// class D = C with M;
+///
+/// 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);
+}
+
+/// Edge origin resulting from an inheritance relationship between two methods.
+class InheritanceOrigin extends EdgeOriginWithLocation {
+ InheritanceOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from a type that is inferred from its initializer.
+class InitializerInferenceOrigin extends EdgeOriginWithLocation {
+ InitializerInferenceOrigin(Source source, int offset) : super(source, offset);
+}
+
/// Edge origin resulting from a class that is instantiated to bounds.
///
/// For example, in the following code snippet:
diff --git a/pkg/nnbd_migration/lib/src/graph_builder.dart b/pkg/nnbd_migration/lib/src/graph_builder.dart
deleted file mode 100644
index 6f99c8a..0000000
--- a/pkg/nnbd_migration/lib/src/graph_builder.dart
+++ /dev/null
@@ -1,980 +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/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:meta/meta.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:nnbd_migration/src/conditional_discard.dart';
-import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/edge_origin.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';
-
-/// Visitor that builds nullability graph edges by examining code to be
-/// migrated.
-///
-/// The return type of each `visit...` method is a [DecoratedType] indicating
-/// the static type of the visited expression, along with the constraint
-/// variables that will determine its nullability. For `visit...` methods that
-/// don't visit expressions, `null` will be returned.
-class GraphBuilder extends GeneralizingAstVisitor<DecoratedType> {
- /// The repository of constraint variables and decorated types (from a
- /// previous pass over the source code).
- final VariableRepository _variables;
-
- final NullabilityMigrationListener /*?*/ listener;
-
- final NullabilityGraph _graph;
-
- /// The file being analyzed.
- final Source _source;
-
- /// For convenience, a [DecoratedType] representing non-nullable `Object`.
- final DecoratedType _notNullType;
-
- /// For convenience, a [DecoratedType] representing non-nullable `bool`.
- final DecoratedType _nonNullableBoolType;
-
- /// For convenience, a [DecoratedType] representing non-nullable `Type`.
- final DecoratedType _nonNullableTypeType;
-
- /// For convenience, a [DecoratedType] representing `Null`.
- final DecoratedType _nullType;
-
- /// The [DecoratedType] of the innermost function or method being visited, or
- /// `null` if the visitor is not inside any function or method.
- ///
- /// This is needed to construct the appropriate nullability constraints for
- /// return statements.
- DecoratedType _currentFunctionType;
-
- /// Information about the most recently visited binary expression whose
- /// boolean value could possibly affect nullability analysis.
- _ConditionInfo _conditionInfo;
-
- /// The set of nullability nodes that would have to be `nullable` for the code
- /// currently being visited to be reachable.
- ///
- /// Guard variables are attached to the left hand side of any generated
- /// constraints, so that constraints do not take effect if they come from
- /// code that can be proven unreachable by the migration tool.
- final _guards = <NullabilityNode>[];
-
- /// Indicates whether the statement or expression being visited is within
- /// conditional control flow. If `true`, this means that the enclosing
- /// function might complete normally without executing the current statement
- /// or expression.
- bool _inConditionalControlFlow = false;
-
- NullabilityNode _lastConditionalNode;
-
- GraphBuilder(TypeProvider typeProvider, this._variables, this._graph,
- this._source, this.listener)
- : _notNullType = DecoratedType(typeProvider.objectType, _graph.never),
- _nonNullableBoolType =
- DecoratedType(typeProvider.boolType, _graph.never),
- _nonNullableTypeType =
- DecoratedType(typeProvider.typeType, _graph.never),
- _nullType = DecoratedType(typeProvider.nullType, _graph.always);
-
- /// Gets the decorated type of [element] from [_variables], performing any
- /// necessary substitutions.
- DecoratedType getOrComputeElementType(Element element,
- {DecoratedType targetType}) {
- Map<TypeParameterElement, DecoratedType> substitution;
- Element baseElement;
- if (element is Member) {
- assert(targetType != null);
- baseElement = element.baseElement;
- var targetTypeType = targetType.type;
- if (targetTypeType is InterfaceType &&
- baseElement is ClassMemberElement) {
- var enclosingClass = baseElement.enclosingElement;
- assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
- substitution = <TypeParameterElement, DecoratedType>{};
- assert(enclosingClass.typeParameters.length ==
- targetTypeType.typeArguments.length); // TODO(paulberry)
- for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
- substitution[enclosingClass.typeParameters[i]] =
- targetType.typeArguments[i];
- }
- }
- } else {
- baseElement = element;
- }
- DecoratedType decoratedBaseType;
- if (baseElement is PropertyAccessorElement &&
- baseElement.isSynthetic &&
- !baseElement.variable.isSynthetic) {
- var variable = baseElement.variable;
- var decoratedElementType =
- _variables.decoratedElementType(variable, create: true);
- if (baseElement.isGetter) {
- decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
- returnType: decoratedElementType);
- } else {
- assert(baseElement.isSetter);
- decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
- positionalParameters: [decoratedElementType]);
- }
- } else {
- decoratedBaseType =
- _variables.decoratedElementType(baseElement, create: true);
- }
- if (substitution != null) {
- DartType elementType;
- if (element is MethodElement) {
- elementType = element.type;
- } else {
- throw element.runtimeType; // TODO(paulberry)
- }
- return decoratedBaseType.substitute(substitution, elementType);
- } else {
- return decoratedBaseType;
- }
- }
-
- @override
- DecoratedType visitAsExpression(AsExpression node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'AsExpression');
- }
-
- @override
- DecoratedType visitAssertStatement(AssertStatement node) {
- _handleAssignment(_notNullType, node.condition);
- if (identical(_conditionInfo?.condition, node.condition)) {
- if (!_inConditionalControlFlow &&
- _conditionInfo.trueDemonstratesNonNullIntent != null) {
- _graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
- _graph.never, NonNullAssertionOrigin(_source, node.offset),
- hard: true);
- }
- }
- node.message?.accept(this);
- return null;
- }
-
- @override
- DecoratedType visitAssignmentExpression(AssignmentExpression node) {
- if (node.operator.type != TokenType.EQ) {
- // TODO(paulberry)
- _unimplemented(node, 'Assignment with operator ${node.operator.lexeme}');
- }
- var leftType = node.leftHandSide.accept(this);
- var conditionalNode = _lastConditionalNode;
- _lastConditionalNode = null;
- var expressionType = _handleAssignment(leftType, node.rightHandSide);
- if (_isConditionalExpression(node.leftHandSide)) {
- expressionType = expressionType.withNode(
- NullabilityNode.forLUB(conditionalNode, expressionType.node));
- _variables.recordDecoratedExpressionType(node, expressionType);
- }
- return expressionType;
- }
-
- @override
- DecoratedType visitAwaitExpression(AwaitExpression node) {
- var expressionType = node.expression.accept(this);
- // TODO(paulberry) Handle subclasses of Future.
- if (expressionType.type.isDartAsyncFuture ||
- expressionType.type.isDartAsyncFutureOr) {
- expressionType = expressionType.typeArguments[0];
- }
- return expressionType;
- }
-
- @override
- DecoratedType visitBinaryExpression(BinaryExpression node) {
- var operatorType = node.operator.type;
- if (operatorType == TokenType.EQ_EQ || operatorType == TokenType.BANG_EQ) {
- assert(node.leftOperand is! NullLiteral); // TODO(paulberry)
- var leftType = node.leftOperand.accept(this);
- node.rightOperand.accept(this);
- if (node.rightOperand is NullLiteral) {
- // TODO(paulberry): figure out what the rules for isPure should be.
- // TODO(paulberry): only set falseChecksNonNull in unconditional
- // control flow
- bool isPure = node.leftOperand is SimpleIdentifier;
- var conditionInfo = _ConditionInfo(node,
- isPure: isPure,
- trueGuard: leftType.node,
- falseDemonstratesNonNullIntent: leftType.node);
- _conditionInfo = operatorType == TokenType.EQ_EQ
- ? conditionInfo
- : conditionInfo.not(node);
- }
- return _nonNullableBoolType;
- } else if (operatorType.isUserDefinableOperator) {
- _handleAssignment(_notNullType, node.leftOperand);
- var callee = node.staticElement;
- assert(!(callee is ClassMemberElement &&
- callee
- .enclosingElement.typeParameters.isNotEmpty)); // TODO(paulberry)
- assert(callee != null); // TODO(paulberry)
- var calleeType = getOrComputeElementType(callee);
- // TODO(paulberry): substitute if necessary
- assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
- _handleAssignment(calleeType.positionalParameters[0], node.rightOperand);
- return calleeType.returnType;
- } else {
- // TODO(paulberry)
- _unimplemented(
- node, 'Binary expression with operator ${node.operator.lexeme}');
- }
- }
-
- @override
- DecoratedType visitBooleanLiteral(BooleanLiteral node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitCascadeExpression(CascadeExpression node) {
- var type = node.target.accept(this);
- node.cascadeSections.accept(this);
- return type;
- }
-
- @override
- DecoratedType visitClassDeclaration(ClassDeclaration node) {
- node.members.accept(this);
- return null;
- }
-
- @override
- DecoratedType visitConditionalExpression(ConditionalExpression node) {
- _handleAssignment(_notNullType, node.condition);
- // TODO(paulberry): guard anything inside the true and false branches
- var thenType = node.thenExpression.accept(this);
- assert(_isSimple(thenType)); // TODO(paulberry)
- var elseType = node.elseExpression.accept(this);
- assert(_isSimple(elseType)); // TODO(paulberry)
- var overallType = DecoratedType(
- node.staticType, NullabilityNode.forLUB(thenType.node, elseType.node));
- _variables.recordDecoratedExpressionType(node, overallType);
- return overallType;
- }
-
- @override
- DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
- var defaultValue = node.defaultValue;
- if (defaultValue == null) {
- if (node.declaredElement.hasRequired) {
- // Nothing to do; the implicit default value of `null` will never be
- // reached.
- } else {
- _graph.connect(
- _graph.always,
- getOrComputeElementType(node.declaredElement).node,
- OptionalFormalParameterOrigin(_source, node.offset),
- guards: _guards);
- }
- } else {
- _handleAssignment(
- getOrComputeElementType(node.declaredElement), defaultValue,
- canInsertChecks: false);
- }
- return null;
- }
-
- @override
- DecoratedType visitDoubleLiteral(DoubleLiteral node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitExpressionFunctionBody(ExpressionFunctionBody node) {
- _handleAssignment(_currentFunctionType.returnType, node.expression);
- return null;
- }
-
- @override
- DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
- node.functionExpression.parameters?.accept(this);
- assert(_currentFunctionType == null);
- _currentFunctionType =
- _variables.decoratedElementType(node.declaredElement);
- _inConditionalControlFlow = false;
- try {
- node.functionExpression.body.accept(this);
- } finally {
- _currentFunctionType = null;
- }
- return null;
- }
-
- @override
- DecoratedType visitFunctionExpression(FunctionExpression node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'FunctionExpression');
- }
-
- @override
- DecoratedType visitFunctionExpressionInvocation(
- FunctionExpressionInvocation node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'FunctionExpressionInvocation');
- }
-
- @override
- DecoratedType visitIfStatement(IfStatement node) {
- // TODO(paulberry): should the use of a boolean in an if-statement be
- // treated like an implicit `assert(b != null)`? Probably.
- _handleAssignment(_notNullType, node.condition);
- _inConditionalControlFlow = true;
- NullabilityNode trueGuard;
- NullabilityNode falseGuard;
- if (identical(_conditionInfo?.condition, node.condition)) {
- trueGuard = _conditionInfo.trueGuard;
- falseGuard = _conditionInfo.falseGuard;
- _variables.recordConditionalDiscard(_source, node,
- ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
- }
- if (trueGuard != null) {
- _guards.add(trueGuard);
- }
- try {
- node.thenStatement.accept(this);
- } finally {
- if (trueGuard != null) {
- _guards.removeLast();
- }
- }
- if (falseGuard != null) {
- _guards.add(falseGuard);
- }
- try {
- node.elseStatement?.accept(this);
- } finally {
- if (falseGuard != null) {
- _guards.removeLast();
- }
- }
- return null;
- }
-
- @override
- DecoratedType visitIndexExpression(IndexExpression node) {
- DecoratedType targetType;
- var target = node.realTarget;
- if (target != null) {
- targetType = _handleAssignment(_notNullType, target);
- }
- var callee = node.staticElement;
- if (callee == null) {
- // TODO(paulberry)
- _unimplemented(node, 'Index expression with no static type');
- }
- var calleeType = getOrComputeElementType(callee, targetType: targetType);
- // TODO(paulberry): substitute if necessary
- _handleAssignment(calleeType.positionalParameters[0], node.index);
- if (node.inSetterContext()) {
- return calleeType.positionalParameters[1];
- } else {
- return calleeType.returnType;
- }
- }
-
- @override
- DecoratedType visitInstanceCreationExpression(
- InstanceCreationExpression node) {
- var callee = node.staticElement;
- var calleeType = getOrComputeElementType(callee);
- if (callee.enclosingElement.typeParameters.isNotEmpty) {
- // If the class has type parameters then we might need to substitute the
- // appropriate type arguments.
- // TODO(brianwilkerson)
- _unimplemented(node, 'Instance creation expression with type arguments');
- }
- _handleInvocationArguments(node.argumentList, calleeType);
- return calleeType.returnType;
- }
-
- @override
- DecoratedType visitIntegerLiteral(IntegerLiteral node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @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');
- } else if (type is GenericFunctionType) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'Is expression with GenericFunctionType');
- }
- node.visitChildren(this);
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitListLiteral(ListLiteral node) {
- var listType = node.staticType as InterfaceType;
- if (node.typeArguments == null) {
- // TODO(brianwilkerson) We might want to create a fake node in the graph
- // to represent the type argument so that we can still create edges from
- // the elements to it.
- // TODO(brianwilkerson)
- _unimplemented(node, 'List literal with no type arguments');
- } else {
- var typeArgumentType = _variables.decoratedTypeAnnotation(
- _source, node.typeArguments.arguments[0]);
- for (var element in node.elements) {
- if (element is Expression) {
- _handleAssignment(typeArgumentType, element);
- } else {
- // Handle spread and control flow elements.
- element.accept(this);
- // TODO(brianwilkerson)
- _unimplemented(node, 'Spread or control flow element');
- }
- }
- return DecoratedType(listType, _graph.never,
- typeArguments: [typeArgumentType]);
- }
- }
-
- @override
- DecoratedType visitMethodDeclaration(MethodDeclaration node) {
- node.parameters?.accept(this);
- assert(_currentFunctionType == null);
- _currentFunctionType =
- _variables.decoratedElementType(node.declaredElement);
- _inConditionalControlFlow = false;
- try {
- node.body.accept(this);
- } finally {
- _currentFunctionType = null;
- }
- return null;
- }
-
- @override
- DecoratedType visitMethodInvocation(MethodInvocation node) {
- DecoratedType targetType;
- var target = node.realTarget;
- bool isConditional = _isConditionalExpression(node);
- if (target != null) {
- if (isConditional) {
- targetType = target.accept(this);
- } else {
- _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
- targetType = _handleAssignment(_notNullType, target);
- }
- }
- var callee = node.methodName.staticElement;
- if (callee == null) {
- // TODO(paulberry)
- _unimplemented(node, 'Unresolved method name');
- }
- var calleeType = getOrComputeElementType(callee, targetType: targetType);
- // TODO(paulberry): substitute if necessary
- _handleInvocationArguments(node.argumentList, calleeType);
- var expressionType = calleeType.returnType;
- if (isConditional) {
- expressionType = expressionType.withNode(
- NullabilityNode.forLUB(targetType.node, expressionType.node));
- _variables.recordDecoratedExpressionType(node, expressionType);
- }
- return expressionType;
- }
-
- @override
- DecoratedType visitNamespaceDirective(NamespaceDirective node) {
- // skip directives
- return null;
- }
-
- @override
- DecoratedType visitNode(AstNode node) {
- if (listener != null) {
- try {
- return super.visitNode(node);
- } catch (exception, stackTrace) {
- listener.addDetail('''
-$exception
-
-$stackTrace''');
- return null;
- }
- } else {
- return super.visitNode(node);
- }
- }
-
- @override
- DecoratedType visitNullLiteral(NullLiteral node) {
- return _nullType;
- }
-
- @override
- DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
- return node.expression.accept(this);
- }
-
- @override
- DecoratedType visitPostfixExpression(PostfixExpression node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'PostfixExpression');
- }
-
- @override
- DecoratedType visitPrefixedIdentifier(PrefixedIdentifier node) {
- if (node.prefix.staticElement is ImportElement) {
- // TODO(paulberry)
- _unimplemented(node, 'PrefixedIdentifier with a prefix');
- } else {
- return _handlePropertyAccess(node, node.prefix, node.identifier);
- }
- }
-
- @override
- DecoratedType visitPrefixExpression(PrefixExpression node) {
- /* DecoratedType operandType = */
- _handleAssignment(_notNullType, node.operand);
- if (node.operator.type == TokenType.BANG) {
- return _nonNullableBoolType;
- }
- // TODO(brianwilkerson) The remaining cases are invocations.
- _unimplemented(
- node, 'Prefix expression with operator ${node.operator.lexeme}');
- }
-
- @override
- DecoratedType visitPropertyAccess(PropertyAccess node) {
- return _handlePropertyAccess(node, node.realTarget, node.propertyName);
- }
-
- @override
- DecoratedType visitReturnStatement(ReturnStatement node) {
- if (node.expression == null) {
- _checkAssignment(_currentFunctionType.returnType, _nullType, null,
- hard: false);
- } else {
- _handleAssignment(_currentFunctionType.returnType, node.expression);
- }
- return null;
- }
-
- @override
- DecoratedType visitSetOrMapLiteral(SetOrMapLiteral node) {
- var listType = node.staticType as InterfaceType;
- var typeArguments = node.typeArguments?.arguments;
- if (typeArguments == null) {
- // TODO(brianwilkerson) We might want to create fake nodes in the graph to
- // represent the type arguments so that we can still create edges from
- // the elements to them.
- // TODO(brianwilkerson)
- _unimplemented(node, 'Set or map literal with no type arguments');
- } else if (typeArguments.length == 1) {
- var elementType =
- _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
- for (var element in node.elements) {
- if (element is Expression) {
- _handleAssignment(elementType, element);
- } else {
- // Handle spread and control flow elements.
- element.accept(this);
- // TODO(brianwilkerson)
- _unimplemented(node, 'Spread or control flow element');
- }
- }
- return DecoratedType(listType, _graph.never,
- typeArguments: [elementType]);
- } else if (typeArguments.length == 2) {
- var keyType =
- _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
- var valueType =
- _variables.decoratedTypeAnnotation(_source, typeArguments[1]);
- for (var element in node.elements) {
- if (element is MapLiteralEntry) {
- _handleAssignment(keyType, element.key);
- _handleAssignment(valueType, element.value);
- } else {
- // Handle spread and control flow elements.
- element.accept(this);
- // TODO(brianwilkerson)
- _unimplemented(node, 'Spread or control flow element');
- }
- }
- return DecoratedType(listType, _graph.never,
- typeArguments: [keyType, valueType]);
- } else {
- // TODO(brianwilkerson)
- _unimplemented(
- node, 'Set or map literal with more than two type arguments');
- }
- }
-
- @override
- DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
- var staticElement = node.staticElement;
- if (staticElement is ParameterElement ||
- staticElement is LocalVariableElement) {
- return getOrComputeElementType(staticElement);
- } else if (staticElement is PropertyAccessorElement) {
- // TODO(danrubel): assuming getter context... need to handle setter
- return getOrComputeElementType(staticElement).returnType;
- } else if (staticElement is ClassElement) {
- return _nonNullableTypeType;
- } else {
- // TODO(paulberry)
- _unimplemented(node,
- 'Simple identifier with a static element of type ${staticElement.runtimeType}');
- }
- }
-
- @override
- DecoratedType visitStringLiteral(StringLiteral node) {
- node.visitChildren(this);
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitSuperExpression(SuperExpression node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitSymbolLiteral(SymbolLiteral node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitThisExpression(ThisExpression node) {
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitThrowExpression(ThrowExpression node) {
- node.expression.accept(this);
- // TODO(paulberry): do we need to check the expression type? I think not.
- return DecoratedType(node.staticType, _graph.never);
- }
-
- @override
- DecoratedType visitTypeName(TypeName typeName) {
- var typeArguments = typeName.typeArguments?.arguments;
- var element = typeName.name.staticElement;
- if (element is TypeParameterizedElement) {
- if (typeArguments == null) {
- var instantiatedType =
- _variables.decoratedTypeAnnotation(_source, typeName);
- if (instantiatedType == null) {
- throw new StateError('No type annotation for type name '
- '${typeName.toSource()}, offset=${typeName.offset}');
- }
- var origin = InstantiateToBoundsOrigin(_source, typeName.offset);
- for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
- _unionDecoratedTypes(
- instantiatedType.typeArguments[i],
- _variables.decoratedElementType(element.typeParameters[i],
- create: true),
- origin);
- }
- } else {
- for (int i = 0; i < typeArguments.length; i++) {
- DecoratedType bound;
- bound = _variables.decoratedElementType(element.typeParameters[i],
- create: true);
- _checkAssignment(
- bound,
- _variables.decoratedTypeAnnotation(_source, typeArguments[i]),
- null,
- hard: true);
- }
- }
- }
- return _nonNullableTypeType;
- }
-
- @override
- DecoratedType visitVariableDeclaration(VariableDeclaration node) {
- var destinationType = getOrComputeElementType(node.declaredElement);
- var initializer = node.initializer;
- if (initializer == null) {
- // TODO(paulberry)
- _unimplemented(node, 'Variable declaration with no initializer');
- } else {
- _handleAssignment(destinationType, initializer);
- }
- return null;
- }
-
- /// Creates the necessary constraint(s) for an assignment from [sourceType] to
- /// [destinationType]. [expressionChecks] tracks checks that might have to be
- /// done on the type of an expression. [hard] indicates whether a hard edge
- /// should be created.
- void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
- ExpressionChecks expressionChecks,
- {@required bool hard}) {
- var edge = _graph.connect(
- sourceType.node, destinationType.node, expressionChecks,
- guards: _guards, hard: hard);
- expressionChecks?.edges?.add(edge);
- // TODO(paulberry): generalize this.
-
- if ((_isSimple(sourceType) || destinationType.type.isObject) &&
- _isSimple(destinationType)) {
- // Ok; nothing further to do.
- return;
- }
-
- if (sourceType.type is InterfaceType &&
- destinationType.type is InterfaceType &&
- sourceType.type.element == destinationType.type.element) {
- assert(sourceType.typeArguments.length ==
- destinationType.typeArguments.length);
- for (int i = 0; i < sourceType.typeArguments.length; i++) {
- _checkAssignment(destinationType.typeArguments[i],
- sourceType.typeArguments[i], expressionChecks,
- hard: false);
- }
- return;
- }
-
- if (destinationType.type.isDynamic || sourceType.type.isDynamic) {
- // ok; nothing further to do.
- return;
- }
-
- // TODO(paulberry)
- throw '$destinationType <= $sourceType';
- }
-
- /// Double checks that [name] is not the name of a method or getter declared
- /// on [Object].
- ///
- /// TODO(paulberry): get rid of this method and put the correct logic into the
- /// call sites.
- void _checkNonObjectMember(String name) {
- assert(name != 'toString');
- assert(name != 'hashCode');
- assert(name != 'noSuchMethod');
- assert(name != 'runtimeType');
- }
-
- /// Creates the necessary constraint(s) for an assignment of the given
- /// [expression] to a destination whose type is [destinationType].
- DecoratedType _handleAssignment(
- DecoratedType destinationType, Expression expression,
- {bool canInsertChecks = true}) {
- var sourceType = expression.accept(this);
- if (sourceType == null) {
- throw StateError('No type computed for ${expression.runtimeType} '
- '(${expression.toSource()}) offset=${expression.offset}');
- }
- ExpressionChecks expressionChecks;
- if (canInsertChecks) {
- expressionChecks = ExpressionChecks(expression.end);
- _variables.recordExpressionChecks(_source, expression, expressionChecks);
- }
- _checkAssignment(destinationType, sourceType, expressionChecks,
- hard: _isVariableOrParameterReference(expression) &&
- !_inConditionalControlFlow);
- return sourceType;
- }
-
- /// Creates the necessary constraint(s) for an [argumentList] when invoking an
- /// executable element whose type is [calleeType].
- void _handleInvocationArguments(
- ArgumentList argumentList, DecoratedType calleeType) {
- var arguments = argumentList.arguments;
- int i = 0;
- var suppliedNamedParameters = Set<String>();
- for (var expression in arguments) {
- if (expression is NamedExpression) {
- var name = expression.name.label.name;
- var parameterType = calleeType.namedParameters[name];
- if (parameterType == null) {
- // TODO(paulberry)
- _unimplemented(expression, 'Missing type for named parameter');
- }
- _handleAssignment(parameterType, expression.expression);
- suppliedNamedParameters.add(name);
- } else {
- if (calleeType.positionalParameters.length <= i) {
- // TODO(paulberry)
- _unimplemented(argumentList, 'Missing positional parameter at $i');
- }
- _handleAssignment(calleeType.positionalParameters[i++], expression);
- }
- }
- // 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, argumentList.offset));
- }
- }
-
- DecoratedType _handlePropertyAccess(
- Expression node, Expression target, SimpleIdentifier propertyName) {
- DecoratedType targetType;
- bool isConditional = _isConditionalExpression(node);
- if (isConditional) {
- targetType = target.accept(this);
- } else {
- _checkNonObjectMember(propertyName.name); // TODO(paulberry)
- targetType = _handleAssignment(_notNullType, target);
- }
- var callee = propertyName.staticElement;
- if (callee == null) {
- // TODO(paulberry)
- _unimplemented(node, 'Unresolved property access');
- }
- var calleeType = getOrComputeElementType(callee, targetType: targetType);
- // TODO(paulberry): substitute if necessary
- if (propertyName.inSetterContext()) {
- if (isConditional) {
- _lastConditionalNode = targetType.node;
- }
- return calleeType.positionalParameters[0];
- } else {
- var expressionType = calleeType.returnType;
- if (isConditional) {
- expressionType = expressionType.withNode(
- NullabilityNode.forLUB(targetType.node, expressionType.node));
- _variables.recordDecoratedExpressionType(node, expressionType);
- }
- return expressionType;
- }
- }
-
- bool _isConditionalExpression(Expression expression) {
- Token token;
- if (expression is MethodInvocation) {
- token = expression.operator;
- if (token == null) return false;
- } else if (expression is PropertyAccess) {
- token = expression.operator;
- } else {
- return false;
- }
- switch (token.type) {
- case TokenType.PERIOD:
- case TokenType.PERIOD_PERIOD:
- return false;
- case TokenType.QUESTION_PERIOD:
- return true;
- default:
- // TODO(paulberry)
- _unimplemented(
- expression, 'Conditional expression with operator ${token.lexeme}');
- }
- }
-
- /// Double checks that [type] is sufficiently simple for this naive prototype
- /// implementation.
- ///
- /// TODO(paulberry): get rid of this method and put the correct logic into the
- /// call sites.
- bool _isSimple(DecoratedType type) {
- if (type.type.isBottom) return true;
- if (type.type.isVoid) return true;
- if (type.type is TypeParameterType) return true;
- if (type.type is! InterfaceType) return false;
- if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
- return true;
- }
-
- bool _isVariableOrParameterReference(Expression expression) {
- expression = expression.unParenthesized;
- if (expression is SimpleIdentifier) {
- var element = expression.staticElement;
- if (element is LocalVariableElement) return true;
- if (element is ParameterElement) return true;
- }
- return false;
- }
-
- @alwaysThrows
- void _unimplemented(AstNode node, String message) {
- CompilationUnit unit = node.root as CompilationUnit;
- StringBuffer buffer = StringBuffer();
- buffer.write(message);
- buffer.write(' in "');
- buffer.write(node.toSource());
- buffer.write('" on line ');
- buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
- buffer.write(' of "');
- buffer.write(unit.declaredElement.source.fullName);
- buffer.write('"');
- throw UnimplementedError(buffer.toString());
- }
-
- void _unionDecoratedTypes(
- DecoratedType x, DecoratedType y, EdgeOrigin origin) {
- _graph.union(x.node, y.node, origin);
- if (x.typeArguments.isNotEmpty ||
- y.typeArguments.isNotEmpty ||
- x.returnType != null ||
- y.returnType != null ||
- x.positionalParameters.isNotEmpty ||
- y.positionalParameters.isNotEmpty ||
- x.namedParameters.isNotEmpty ||
- y.namedParameters.isNotEmpty) {
- // TODO(paulberry)
- throw UnimplementedError('_unionDecoratedTypes($x, $y, $origin)');
- }
- }
-}
-
-/// Information about a binary expression whose boolean value could possibly
-/// affect nullability analysis.
-class _ConditionInfo {
- /// The [expression] of interest.
- final Expression condition;
-
- /// Indicates whether [condition] is pure (free from side effects).
- ///
- /// For example, a condition like `x == null` is pure (assuming `x` is a local
- /// variable or static variable), because evaluating it has no user-visible
- /// effect other than returning a boolean value.
- final bool isPure;
-
- /// If not `null`, the [NullabilityNode] that would need to be nullable in
- /// order for [condition] to evaluate to `true`.
- final NullabilityNode trueGuard;
-
- /// If not `null`, the [NullabilityNode] that would need to be nullable in
- /// order for [condition] to evaluate to `false`.
- final NullabilityNode falseGuard;
-
- /// If not `null`, the [NullabilityNode] that should be asserted to have
- // /// non-null intent if [condition] is asserted to be `true`.
- final NullabilityNode trueDemonstratesNonNullIntent;
-
- /// If not `null`, the [NullabilityNode] that should be asserted to have
- /// non-null intent if [condition] is asserted to be `false`.
- final NullabilityNode falseDemonstratesNonNullIntent;
-
- _ConditionInfo(this.condition,
- {@required this.isPure,
- this.trueGuard,
- this.falseGuard,
- this.trueDemonstratesNonNullIntent,
- this.falseDemonstratesNonNullIntent});
-
- /// Returns a new [_ConditionInfo] describing the boolean "not" of `this`.
- _ConditionInfo not(Expression condition) => _ConditionInfo(condition,
- isPure: isPure,
- trueGuard: falseGuard,
- falseGuard: trueGuard,
- trueDemonstratesNonNullIntent: falseDemonstratesNonNullIntent,
- falseDemonstratesNonNullIntent: trueDemonstratesNonNullIntent);
-}
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 202fe0a..43c9143 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -48,40 +49,107 @@
final TypeProvider _typeProvider;
- NodeBuilder(this._variables, this._source, this.listener, this._graph,
- this._typeProvider);
+ /// For convenience, a [DecoratedType] representing non-nullable `Object`.
+ final DecoratedType _nonNullableObjectType;
- /// Creates and stores a [DecoratedType] object corresponding to the given
- /// [type] AST, and returns it.
- DecoratedType decorateType(TypeAnnotation type, AstNode enclosingNode) {
- return type == null
- // TODO(danrubel): Return something other than this
- // to indicate that we should insert a type for the declaration
- // that is missing a type reference.
- ? new DecoratedType(
- DynamicTypeImpl.instance,
- NullabilityNode.forInferredDynamicType(
- _graph, _source, enclosingNode.offset))
- : type.accept(this);
+ NodeBuilder(this._variables, this._source, this.listener, this._graph,
+ this._typeProvider)
+ : _nonNullableObjectType =
+ DecoratedType(_typeProvider.objectType, _graph.never);
+
+ @override
+ DecoratedType visitCatchClause(CatchClause node) {
+ DecoratedType exceptionType = node.exceptionType?.accept(this);
+ if (node.exceptionParameter != null) {
+ exceptionType ??= DecoratedType(_typeProvider.objectType, _graph.never);
+ _variables.recordDecoratedElementType(
+ node.exceptionParameter.staticElement, exceptionType);
+ }
+ node.stackTraceParameter?.accept(this);
+ node.body?.accept(this);
+ return null;
+ }
+
+ @override
+ DecoratedType visitClassDeclaration(ClassDeclaration node) {
+ node.metadata.accept(this);
+ node.name.accept(this);
+ node.typeParameters?.accept(this);
+ node.nativeClause?.accept(this);
+ node.members.accept(this);
+ var classElement = node.declaredElement;
+ _handleSupertypeClauses(classElement, node.extendsClause?.superclass,
+ node.withClause, node.implementsClause, null);
+ var constructors = classElement.constructors;
+ if (constructors.length == 1) {
+ var constructorElement = constructors[0];
+ if (constructorElement.isSynthetic) {
+ // Need to create a decorated type for the default constructor.
+ var decoratedReturnType =
+ _createDecoratedTypeForClass(classElement, node);
+ var functionType = DecoratedType(constructorElement.type, _graph.never,
+ returnType: decoratedReturnType,
+ positionalParameters: [],
+ namedParameters: {});
+ _variables.recordDecoratedElementType(constructorElement, functionType);
+ }
+ }
+ return null;
+ }
+
+ @override
+ visitClassTypeAlias(ClassTypeAlias node) {
+ node.metadata.accept(this);
+ node.name.accept(this);
+ node.typeParameters?.accept(this);
+ var classElement = node.declaredElement;
+ _handleSupertypeClauses(classElement, node.superclass, node.withClause,
+ node.implementsClause, null);
+ for (var constructorElement in classElement.constructors) {
+ assert(constructorElement.isSynthetic);
+ var decoratedReturnType =
+ _createDecoratedTypeForClass(classElement, node);
+ var functionType = DecoratedType.forImplicitFunction(
+ constructorElement.type, _graph.never, _graph,
+ returnType: decoratedReturnType);
+ _variables.recordDecoratedElementType(constructorElement, functionType);
+ }
+ return null;
+ }
+
+ @override
+ DecoratedType visitCompilationUnit(CompilationUnit node) {
+ _graph.migrating(_source);
+ return super.visitCompilationUnit(node);
}
@override
DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
- if (node.factoryKeyword != null) {
- // Factory constructors can return null, but we don't want to propagate a
- // null type if we can prove that null is never returned.
- // TODO(brianwilkerson)
- _unimplemented(node, 'Declaration of a factory constructor');
- }
- _handleExecutableDeclaration(
- node.declaredElement, null, node.parameters, node.body, node);
+ _handleExecutableDeclaration(node.declaredElement, null, node.parameters,
+ node.body, node.redirectedConstructor, node);
return null;
}
@override
+ DecoratedType visitDeclaredIdentifier(DeclaredIdentifier node) {
+ node.metadata.accept(this);
+ DecoratedType type = node.type?.accept(this);
+ if (node.identifier != null) {
+ _variables.recordDecoratedElementType(
+ node.identifier.staticElement,
+ type ??
+ DecoratedType.forImplicitType(node.declaredElement.type, _graph));
+ }
+ return type;
+ }
+
+ @override
DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
var decoratedType = node.parameter.accept(this);
- if (node.declaredElement.hasRequired || node.defaultValue != null) {
+ if (node.defaultValue != null) {
+ node.defaultValue.accept(this);
+ return null;
+ } else if (node.declaredElement.hasRequired) {
return null;
}
if (decoratedType == null) {
@@ -95,26 +163,19 @@
@override
DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'FieldFormalParameter');
- }
-
- @override
- DecoratedType visitFormalParameter(FormalParameter node) {
- // Do not visit children
- // TODO(paulberry): handle all types of formal parameters
- // - NormalFormalParameter
- // - SimpleFormalParameter
- // - FieldFormalParameter
- // - FunctionTypedFormalParameter
- // - DefaultFormalParameter
- return null;
+ return _handleFormalParameter(
+ node, node.type, node.typeParameters, node.parameters);
}
@override
DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
- _handleExecutableDeclaration(node.declaredElement, node.returnType,
- node.functionExpression.parameters, node.functionExpression.body, node);
+ _handleExecutableDeclaration(
+ node.declaredElement,
+ node.returnType,
+ node.functionExpression.parameters,
+ node.functionExpression.body,
+ null,
+ node);
return null;
}
@@ -127,14 +188,25 @@
@override
DecoratedType visitFunctionTypedFormalParameter(
FunctionTypedFormalParameter node) {
- // TODO(brianwilkerson)
- _unimplemented(node, 'FunctionTypedFormalParameter');
+ return _handleFormalParameter(
+ node, node.returnType, node.typeParameters, node.parameters);
}
@override
DecoratedType visitMethodDeclaration(MethodDeclaration node) {
_handleExecutableDeclaration(node.declaredElement, node.returnType,
- node.parameters, node.body, node);
+ node.parameters, node.body, null, node);
+ return null;
+ }
+
+ @override
+ visitMixinDeclaration(MixinDeclaration node) {
+ node.metadata.accept(this);
+ node.name?.accept(this);
+ node.typeParameters?.accept(this);
+ node.members.accept(this);
+ _handleSupertypeClauses(
+ node.declaredElement, null, null, node.implementsClause, node.onClause);
return null;
}
@@ -157,15 +229,7 @@
@override
DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
- var type = decorateType(node.type, node);
- var declaredElement = node.declaredElement;
- _variables.recordDecoratedElementType(declaredElement, type);
- if (declaredElement.isNamed) {
- _namedParameters[declaredElement.name] = type;
- } else {
- _positionalParameters.add(type);
- }
- return type;
+ return _handleFormalParameter(node, node.type, null, null);
}
@override
@@ -183,14 +247,15 @@
return decoratedType;
}
var typeArguments = const <DecoratedType>[];
- DecoratedType returnType;
+ DecoratedType decoratedReturnType;
var positionalParameters = const <DecoratedType>[];
var namedParameters = const <String, DecoratedType>{};
if (type is InterfaceType && type.typeParameters.isNotEmpty) {
if (node is TypeName) {
if (node.typeArguments == null) {
- typeArguments =
- type.typeArguments.map(_decorateImplicitTypeArgument).toList();
+ typeArguments = type.typeArguments
+ .map((t) => DecoratedType.forImplicitType(t, _graph))
+ .toList();
} else {
typeArguments =
node.typeArguments.arguments.map((t) => t.accept(this)).toList();
@@ -200,15 +265,16 @@
}
}
if (node is GenericFunctionType) {
- returnType = decorateType(node.returnType, node);
+ var returnType = node.returnType;
+ decoratedReturnType = returnType == null
+ ? DecoratedType.forImplicitType(DynamicTypeImpl.instance, _graph)
+ : returnType.accept(this);
if (node.typeParameters != null) {
// TODO(paulberry)
_unimplemented(node, 'Generic function type with type parameters');
}
positionalParameters = <DecoratedType>[];
namedParameters = <String, DecoratedType>{};
- }
- if (node is GenericFunctionType) {
var previousPositionalParameters = _positionalParameters;
var previousNamedParameters = _namedParameters;
try {
@@ -220,10 +286,21 @@
_namedParameters = previousNamedParameters;
}
}
- var decoratedType = DecoratedTypeAnnotation(
- type, NullabilityNode.forTypeAnnotation(node.end), node.end,
+ NullabilityNode nullabilityNode;
+ var parent = node.parent;
+ if (parent is ExtendsClause ||
+ parent is ImplementsClause ||
+ parent is WithClause ||
+ parent is OnClause ||
+ parent is ClassTypeAlias ||
+ parent is CatchClause) {
+ nullabilityNode = _graph.never;
+ } else {
+ nullabilityNode = NullabilityNode.forTypeAnnotation(node.end);
+ }
+ var decoratedType = DecoratedTypeAnnotation(type, nullabilityNode, node.end,
typeArguments: typeArguments,
- returnType: returnType,
+ returnType: decoratedReturnType,
positionalParameters: positionalParameters,
namedParameters: namedParameters);
_variables.recordDecoratedTypeAnnotation(_source, node, decoratedType);
@@ -250,20 +327,31 @@
@override
DecoratedType visitTypeParameter(TypeParameter node) {
var element = node.declaredElement;
- var decoratedBound = node.bound?.accept(this) ??
- DecoratedType(
- element.bound ?? _typeProvider.objectType,
- NullabilityNode.forInferredDynamicType(
- _graph, _source, node.offset));
+ var bound = node.bound;
+ DecoratedType decoratedBound;
+ if (bound != null) {
+ decoratedBound = bound.accept(this);
+ } else {
+ var nullabilityNode = NullabilityNode.forInferredType();
+ _graph.union(_graph.always, nullabilityNode,
+ AlwaysNullableTypeOrigin(_source, node.offset));
+ decoratedBound = DecoratedType(_typeProvider.objectType, nullabilityNode);
+ }
_variables.recordDecoratedElementType(element, decoratedBound);
return null;
}
@override
DecoratedType visitVariableDeclarationList(VariableDeclarationList node) {
- var type = decorateType(node.type, node);
+ node.metadata.accept(this);
+ var typeAnnotation = node.type;
+ var type = typeAnnotation?.accept(this);
for (var variable in node.variables) {
- _variables.recordDecoratedElementType(variable.declaredElement, type);
+ variable.metadata.accept(this);
+ var declaredElement = variable.declaredElement;
+ _variables.recordDecoratedElementType(declaredElement,
+ type ?? DecoratedType.forImplicitType(declaredElement.type, _graph));
+ variable.initializer?.accept(this);
}
return null;
}
@@ -276,20 +364,13 @@
return _NullabilityComment.none;
}
- /// Creates a DecoratedType corresponding to [type], with fresh nullability
- /// nodes everywhere that don't correspond to any source location. These
- /// nodes can later be unioned with other nodes.
- DecoratedType _decorateImplicitTypeArgument(DartType type) {
- if (type.isDynamic) {
- return DecoratedType(type, _graph.always);
- } else if (type is InterfaceType) {
- return DecoratedType(type, NullabilityNode.forInferredType(),
- typeArguments:
- type.typeArguments.map(_decorateImplicitTypeArgument).toList());
- }
- // TODO(paulberry)
- throw UnimplementedError(
- '_decorateImplicitTypeArgument(${type.runtimeType})');
+ DecoratedType _createDecoratedTypeForClass(
+ ClassElement classElement, AstNode node) {
+ var typeArguments = classElement.typeParameters
+ .map((t) => DecoratedType(t.type, _graph.never))
+ .toList();
+ return DecoratedType(classElement.type, _graph.never,
+ typeArguments: typeArguments);
}
/// Common handling of function and method declarations.
@@ -298,46 +379,124 @@
TypeAnnotation returnType,
FormalParameterList parameters,
FunctionBody body,
+ ConstructorName redirectedConstructor,
AstNode enclosingNode) {
+ var functionType = declaredElement.type;
DecoratedType decoratedReturnType;
- if (returnType == null && declaredElement is ConstructorElement) {
+ if (returnType != null) {
+ decoratedReturnType = returnType.accept(this);
+ } else if (declaredElement is ConstructorElement) {
// Constructors have no explicit return type annotation, so use the
// implicit return type.
- if (declaredElement.isFactory) {
- // Factory constructors can return null, but we don't want to propagate
- // a null type if we can prove that null is never returned.
- // TODO(brianwilkerson)
- _unimplemented(
- parameters.parent, 'Declaration of a factory constructor');
- }
- if (declaredElement.enclosingElement.typeParameters.isNotEmpty) {
- // Need to decorate the type parameters appropriately.
- // TODO(paulberry,brianwilkerson)
- _unimplemented(parameters.parent,
- 'Declaration of a constructor with type parameters');
- }
- decoratedReturnType = new DecoratedType(
- declaredElement.enclosingElement.type, _graph.never);
+ decoratedReturnType = _createDecoratedTypeForClass(
+ declaredElement.enclosingElement, parameters.parent);
} else {
- decoratedReturnType = decorateType(returnType, enclosingNode);
+ // Inferred return type.
+ decoratedReturnType =
+ DecoratedType.forImplicitType(functionType.returnType, _graph);
}
var previousPositionalParameters = _positionalParameters;
var previousNamedParameters = _namedParameters;
_positionalParameters = [];
_namedParameters = {};
- DecoratedType functionType;
+ DecoratedType decoratedFunctionType;
try {
parameters?.accept(this);
- body?.accept(this);
- functionType = DecoratedType(declaredElement.type, _graph.never,
+ redirectedConstructor?.accept(this);
+ decoratedFunctionType = DecoratedType(functionType, _graph.never,
returnType: decoratedReturnType,
positionalParameters: _positionalParameters,
namedParameters: _namedParameters);
+ body?.accept(this);
} finally {
_positionalParameters = previousPositionalParameters;
_namedParameters = previousNamedParameters;
}
- _variables.recordDecoratedElementType(declaredElement, functionType);
+ _variables.recordDecoratedElementType(
+ declaredElement, decoratedFunctionType);
+ }
+
+ DecoratedType _handleFormalParameter(
+ FormalParameter node,
+ TypeAnnotation type,
+ TypeParameterList typeParameters,
+ FormalParameterList parameters) {
+ var declaredElement = node.declaredElement;
+ node.metadata?.accept(this);
+ DecoratedType decoratedType;
+ if (parameters == null) {
+ decoratedType = type != null
+ ? type.accept(this)
+ : DecoratedType.forImplicitType(declaredElement.type, _graph);
+ } else {
+ var decoratedReturnType = type == null
+ ? DecoratedType.forImplicitType(DynamicTypeImpl.instance, _graph)
+ : type.accept(this);
+ if (typeParameters != null) {
+ // TODO(paulberry)
+ _unimplemented(
+ typeParameters, 'Function-typed parameter with type parameters');
+ }
+ var positionalParameters = <DecoratedType>[];
+ var namedParameters = <String, DecoratedType>{};
+ var previousPositionalParameters = _positionalParameters;
+ var previousNamedParameters = _namedParameters;
+ try {
+ _positionalParameters = positionalParameters;
+ _namedParameters = namedParameters;
+ parameters.accept(this);
+ } finally {
+ _positionalParameters = previousPositionalParameters;
+ _namedParameters = previousNamedParameters;
+ }
+ decoratedType = DecoratedTypeAnnotation(declaredElement.type,
+ NullabilityNode.forTypeAnnotation(node.end), node.end,
+ returnType: decoratedReturnType,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters);
+ }
+ _variables.recordDecoratedElementType(declaredElement, decoratedType);
+ if (declaredElement.isNamed) {
+ _namedParameters[declaredElement.name] = decoratedType;
+ } else {
+ _positionalParameters.add(decoratedType);
+ }
+ return decoratedType;
+ }
+
+ void _handleSupertypeClauses(
+ ClassElement declaredElement,
+ TypeName superclass,
+ WithClause withClause,
+ ImplementsClause implementsClause,
+ OnClause onClause) {
+ var supertypes = <TypeName>[];
+ supertypes.add(superclass);
+ if (withClause != null) {
+ supertypes.addAll(withClause.mixinTypes);
+ }
+ if (implementsClause != null) {
+ supertypes.addAll(implementsClause.interfaces);
+ }
+ if (onClause != null) {
+ supertypes.addAll(onClause.superclassConstraints);
+ }
+ var decoratedSupertypes = <ClassElement, DecoratedType>{};
+ for (var supertype in supertypes) {
+ DecoratedType decoratedSupertype;
+ if (supertype == null) {
+ decoratedSupertype = _nonNullableObjectType;
+ } else {
+ decoratedSupertype = supertype.accept(this);
+ }
+ var class_ = (decoratedSupertype.type as InterfaceType).element;
+ if (class_ is ClassElementHandle) {
+ class_ = (class_ as ClassElementHandle).actualElement;
+ }
+ decoratedSupertypes[class_] = decoratedSupertype;
+ }
+ _variables.recordDecoratedDirectSupertypes(
+ declaredElement, decoratedSupertypes);
}
@alwaysThrows
@@ -363,6 +522,11 @@
/// ([NodeBuilder], which finds all the variables that need to be
/// constrained).
abstract class VariableRecorder {
+ /// Associates a [class_] with decorated type information for the superclasses
+ /// it directly implements/extends/etc.
+ void recordDecoratedDirectSupertypes(ClassElement class_,
+ Map<ClassElement, DecoratedType> decoratedDirectSupertypes);
+
/// Associates decorated type information with the given [element].
void recordDecoratedElementType(Element element, DecoratedType type);
@@ -386,12 +550,18 @@
/// results of the first ([NodeBuilder], which finds all the
/// variables that need to be constrained).
abstract class VariableRepository {
+ /// Given a [class_], gets the decorated type information for the superclasses
+ /// it directly implements/extends/etc.
+ Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
+ ClassElement class_);
+
/// Retrieves the [DecoratedType] associated with the static type of the given
/// [element].
///
- /// If [create] is `true`, and no decorated type is found for the given
- /// element, one is synthesized using [DecoratedType.forElement].
- DecoratedType decoratedElementType(Element element, {bool create: false});
+ /// If no decorated type is found for the given element, and the element is in
+ /// a library that's not being migrated, a decorated type is synthesized using
+ /// [DecoratedType.forElement].
+ DecoratedType decoratedElementType(Element element);
/// Gets the [DecoratedType] associated with the given [typeAnnotation].
DecoratedType decoratedTypeAnnotation(
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 3d405a3..6fede39 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -7,8 +7,8 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_builder.dart';
import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/graph_builder.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';
@@ -59,8 +59,8 @@
void processInput(ResolvedUnitResult result) {
var unit = result.unit;
- unit.accept(GraphBuilder(result.typeProvider, _variables, _graph,
- unit.declaredElement.source, _permissive ? listener : null));
+ unit.accept(EdgeBuilder(result.typeProvider, result.typeSystem, _variables,
+ _graph, unit.declaredElement.source, _permissive ? listener : null));
}
}
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index d71920e..6e345f4 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -97,6 +97,9 @@
/// node.
final NullabilityNode never = _NullabilityNodeImmutable('never', false);
+ /// Set containing all sources being migrated.
+ final _sourcesBeingMigrated = <Source>{};
+
/// Records that [sourceNode] is immediately upstream from [destinationNode].
///
/// Returns the edge created by the connection.
@@ -108,6 +111,16 @@
return _connect(sources, destinationNode, kind, origin);
}
+ /// Determine if [source] is in the code being migrated.
+ bool isBeingMigrated(Source source) {
+ return _sourcesBeingMigrated.contains(source);
+ }
+
+ /// Record source as code that is being migrated.
+ void migrating(Source source) {
+ _sourcesBeingMigrated.add(source);
+ }
+
/// Determines the nullability of each node in the graph by propagating
/// nullability information from one node to another.
///
@@ -154,7 +167,9 @@
var destinations =
edges.where((edge) => edge.primarySource == source).map((edge) {
var suffixes = <Object>[];
- if (edge.hard) {
+ if (edge.isUnion) {
+ suffixes.add('union');
+ } else if (edge.hard) {
suffixes.add('hard');
}
suffixes.addAll(edge.guards);
@@ -257,6 +272,14 @@
/// testing.
@visibleForTesting
class NullabilityGraphForTesting extends NullabilityGraph {
+ /// Iterates through all edges that have this node as one of their sources.
+ ///
+ /// There is no guarantee of uniqueness of the iterated edges.
+ @visibleForTesting
+ Iterable<NullabilityEdge> getDownstreamEdges(NullabilityNode node) {
+ return node._downstreamEdges;
+ }
+
/// Iterates through all edges that have this node as their destination.
///
/// There is no guarantee of uniqueness of the iterated nodes.
@@ -288,17 +311,17 @@
/// List of edges that have this node as their destination.
final _upstreamEdges = <NullabilityEdge>[];
- /// Creates a [NullabilityNode] representing the nullability of a variable
- /// whose type is `dynamic` due to type inference.
+ /// Creates a [NullabilityNode] representing the nullability of an expression
+ /// which is nullable iff two other nullability nodes are both nullable.
///
- /// TODO(paulberry): this should go away; we should decorate the actual
- /// inferred type rather than assuming `dynamic`.
- factory NullabilityNode.forInferredDynamicType(
- NullabilityGraph graph, Source source, int offset) {
- var node = _NullabilityNodeSimple('inferredDynamic($offset)');
- graph.union(node, graph.always, AlwaysNullableTypeOrigin(source, offset));
- return node;
- }
+ /// The caller is required to create the appropriate graph edges to ensure
+ /// that the appropriate relationship between the nodes' nullabilities holds.
+ factory NullabilityNode.forGLB() => _NullabilityNodeSimple('GLB');
+
+ /// Creates a [NullabilityNode] representing the nullability of a variable
+ /// whose type is determined by the `??` operator.
+ factory NullabilityNode.forIfNotNull() =>
+ _NullabilityNodeSimple('?? operator');
/// Creates a [NullabilityNode] representing the nullability of a variable
/// whose type is determined by type inference.
@@ -306,12 +329,7 @@
_NullabilityNodeSimple('inferred');
/// Creates a [NullabilityNode] representing the nullability of an
- /// expression which is nullable iff both [a] and [b] are nullable.
- ///
- /// The constraint variable contained in the new node is created using the
- /// [joinNullabilities] callback. TODO(paulberry): this should become
- /// unnecessary once constraint solving is performed directly using
- /// [NullabilityNode] objects.
+ /// expression which is nullable iff either [a] or [b] is nullable.
factory NullabilityNode.forLUB(NullabilityNode left, NullabilityNode right) =
NullabilityNodeForLUB._;
@@ -387,6 +405,11 @@
void trackPossiblyOptional() {
_isPossiblyOptional = true;
}
+
+ @visibleForTesting
+ static void clearDebugNames() {
+ _debugNamesInUse.clear();
+ }
}
/// Derived class for nullability nodes that arise from the least-upper-bound
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 9a8e653..ccb4aec 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
@@ -17,6 +18,9 @@
final _decoratedElementTypes = <Element, DecoratedType>{};
+ final _decoratedDirectSupertypes =
+ <ClassElement, Map<ClassElement, DecoratedType>>{};
+
final _decoratedTypeAnnotations =
<Source, Map<int, DecoratedTypeAnnotation>>{};
@@ -25,16 +29,32 @@
Variables(this._graph);
@override
- DecoratedType decoratedElementType(Element element, {bool create: false}) =>
- _decoratedElementTypes[element] ??= create
- ? DecoratedType.forElement(element, _graph)
- : throw StateError('No element found');
+ Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
+ ClassElement class_) {
+ assert(class_ is! ClassElementHandle);
+ return _decoratedDirectSupertypes[class_] ??
+ _decorateDirectSupertypes(class_);
+ }
+
+ @override
+ DecoratedType decoratedElementType(Element element) =>
+ _decoratedElementTypes[element] ??= _createDecoratedElementType(element);
@override
DecoratedType decoratedTypeAnnotation(
Source source, TypeAnnotation typeAnnotation) {
- return _decoratedTypeAnnotations[source]
- [_uniqueOffsetForTypeAnnotation(typeAnnotation)];
+ var annotationsInSource = _decoratedTypeAnnotations[source];
+ if (annotationsInSource == null) {
+ throw StateError('No declarated type annotations in ${source.fullName}; '
+ 'expected one for ${typeAnnotation.toSource()}');
+ }
+ DecoratedTypeAnnotation decoratedTypeAnnotation =
+ annotationsInSource[_uniqueOffsetForTypeAnnotation(typeAnnotation)];
+ if (decoratedTypeAnnotation == null) {
+ throw StateError('Missing declarated type annotation'
+ ' in ${source.fullName}; for ${typeAnnotation.toSource()}');
+ }
+ return decoratedTypeAnnotation;
}
Map<Source, List<PotentialModification>> getPotentialModifications() =>
@@ -47,7 +67,30 @@
source, ConditionalModification(node, conditionalDiscard));
}
+ @override
+ void recordDecoratedDirectSupertypes(ClassElement class_,
+ Map<ClassElement, DecoratedType> decoratedDirectSupertypes) {
+ assert(() {
+ assert(class_ is! ClassElementHandle);
+ for (var key in decoratedDirectSupertypes.keys) {
+ assert(key is! ClassElementHandle);
+ }
+ return true;
+ }());
+ _decoratedDirectSupertypes[class_] = decoratedDirectSupertypes;
+ }
+
void recordDecoratedElementType(Element element, DecoratedType type) {
+ assert(() {
+ var library = element.library;
+ if (library == null) {
+ // No problem; the element is probably a parameter of a function type
+ // expressed using new-style Function syntax.
+ } else {
+ assert(_graph.isBeingMigrated(library.source));
+ }
+ return true;
+ }());
_decoratedElementTypes[element] = type;
}
@@ -126,6 +169,28 @@
(_potentialModifications[source] ??= []).add(potentialModification);
}
+ DecoratedType _createDecoratedElementType(Element element) {
+ if (_graph.isBeingMigrated(element.library.source)) {
+ throw StateError('A decorated type for $element should have been stored '
+ 'by the NodeBuilder via recordDecoratedElementType');
+ }
+ return DecoratedType.forElement(element, _graph);
+ }
+
+ /// Creates an entry [_decoratedDirectSupertypes] for an already-migrated
+ /// class.
+ Map<ClassElement, DecoratedType> _decorateDirectSupertypes(
+ ClassElement class_) {
+ if (class_.type.isObject) {
+ // TODO(paulberry): this special case is just to get the basic
+ // infrastructure working (necessary since all classes derive from
+ // Object). Once we have the full implementation this case shouldn't be
+ // needed.
+ return const {};
+ }
+ throw UnimplementedError('TODO(paulberry)');
+ }
+
int _uniqueOffsetForTypeAnnotation(TypeAnnotation typeAnnotation) =>
typeAnnotation is GenericFunctionType
? typeAnnotation.functionKeyword.offset
diff --git a/pkg/nnbd_migration/test/abstract_single_unit.dart b/pkg/nnbd_migration/test/abstract_single_unit.dart
index 25c5f87..9ccb588 100644
--- a/pkg/nnbd_migration/test/abstract_single_unit.dart
+++ b/pkg/nnbd_migration/test/abstract_single_unit.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
@@ -20,12 +21,14 @@
String testCode;
String testFile;
+ Uri testUri;
Source testSource;
ResolvedUnitResult testAnalysisResult;
CompilationUnit testUnit;
CompilationUnitElement testUnitElement;
LibraryElement testLibraryElement;
FindNode findNode;
+ FindElement findElement;
void addTestSource(String code, [Uri uri]) {
testCode = code;
@@ -33,7 +36,7 @@
}
Future<void> resolveTestUnit(String code) async {
- addTestSource(code);
+ addTestSource(code, testUri);
testAnalysisResult = await session.getResolvedUnit(testFile);
testUnit = testAnalysisResult.unit;
if (verifyNoTestUnitErrors) {
@@ -50,11 +53,13 @@
testUnitElement = testUnit.declaredElement;
testLibraryElement = testUnitElement.library;
findNode = FindNode(code, testUnit);
+ findElement = FindElement(testUnit);
}
@override
void setUp() {
super.setUp();
testFile = convertPath('/home/test/lib/test.dart');
+ testUri = Uri.parse('package:test/test.dart');
}
}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index c378285..e53b981 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -76,6 +76,44 @@
/// Mixin containing test cases for the provisional API.
mixin _ProvisionalApiTestCases on _ProvisionalApiTestBase {
+ test_class_alias_synthetic_constructor_with_parameters() async {
+ var content = '''
+void main() {
+ D d = D(null);
+}
+class C {
+ C(int i);
+}
+mixin M {}
+class D = C with M;
+''';
+ var expected = '''
+void main() {
+ D d = D(null);
+}
+class C {
+ C(int? i);
+}
+mixin M {}
+class D = C with M;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_class_with_default_constructor() async {
+ var content = '''
+void main() => f(Foo());
+f(Foo f) {}
+class Foo {}
+''';
+ var expected = '''
+void main() => f(Foo());
+f(Foo f) {}
+class Foo {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_comment_bang_implies_non_null_intent() async {
var content = '''
void f(int/*!*/ i) {}
@@ -224,6 +262,72 @@
await _checkSingleFileChanges(content, expected);
}
+ test_constructorDeclaration_factory_non_null_return() async {
+ var content = '''
+class C {
+ C._();
+ factory C() {
+ C c = f();
+ return c;
+ }
+}
+C f() => null;
+''';
+ var expected = '''
+class C {
+ C._();
+ factory C() {
+ C c = f()!;
+ return c;
+ }
+}
+C? f() => null;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_constructorDeclaration_factory_simple() async {
+ var content = '''
+class C {
+ C._();
+ factory C(int i) => C._();
+}
+main() {
+ C(null);
+}
+''';
+ var expected = '''
+class C {
+ C._();
+ factory C(int? i) => C._();
+}
+main() {
+ C(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_constructorDeclaration_named() async {
+ var content = '''
+class C {
+ C.named(int i);
+}
+main() {
+ C.named(null);
+}
+''';
+ var expected = '''
+class C {
+ C.named(int? i);
+}
+main() {
+ C.named(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_constructorDeclaration_namedParameter() async {
var content = '''
class C {
@@ -332,6 +436,24 @@
await _checkSingleFileChanges(content, expected);
}
+ test_data_flow_function_return_type() async {
+ var content = '''
+int Function() f(int Function() x) => x;
+int g() => null;
+main() {
+ f(g);
+}
+''';
+ var expected = '''
+int? Function() f(int? Function() x) => x;
+int? g() => null;
+main() {
+ f(g);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_data_flow_generic_contravariant_inward() async {
var content = '''
class C<T> {
@@ -370,6 +492,52 @@
await _checkSingleFileChanges(content, expected);
}
+ test_data_flow_generic_contravariant_inward_function() async {
+ var content = '''
+T f<T>(T t) => t;
+int g(int x) => f<int>(x);
+void h() {
+ g(null);
+}
+''';
+
+ // As with the generic class case (see
+ // [test_data_flow_generic_contravariant_inward_function]), we favor adding
+ // nullability at the call site, so that other uses of `f` don't necessarily
+ // see a nullable return value.
+ var expected = '''
+T f<T>(T t) => t;
+int? g(int? x) => f<int?>(x);
+void h() {
+ g(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_data_flow_generic_contravariant_inward_using_core_class() async {
+ var content = '''
+void f(List<int> x, int i) {
+ x.add(i);
+}
+void test(List<int> x) {
+ f(x, null);
+}
+''';
+ // TODO(paulberry): possible improvement: detect that since add uses T in
+ // a contravariant way, and deduce that test should change to
+ // `void test(List<int?> x)`
+ var expected = '''
+void f(List<int?> x, int? i) {
+ x.add(i);
+}
+void test(List<int> x) {
+ f(x, null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_data_flow_generic_covariant_outward() async {
var content = '''
class C<T> {
@@ -645,6 +813,217 @@
await _checkSingleFileChanges(content, expected);
}
+ test_field_formal_param_typed() async {
+ var content = '''
+class C {
+ int i;
+ C(int this.i);
+}
+main() {
+ C(null);
+}
+''';
+ var expected = '''
+class C {
+ int? i;
+ C(int? this.i);
+}
+main() {
+ C(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_field_formal_param_typed_non_nullable() async {
+ var content = '''
+class C {
+ int/*!*/ i;
+ C(int this.i);
+}
+void f(int i, bool b) {
+ if (b) {
+ C(i);
+ }
+}
+main() {
+ f(null, false);
+}
+''';
+ var expected = '''
+class C {
+ int/*!*/ i;
+ C(int this.i);
+}
+void f(int? i, bool b) {
+ if (b) {
+ C(i!);
+ }
+}
+main() {
+ f(null, false);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_field_formal_param_untyped() async {
+ var content = '''
+class C {
+ int i;
+ C(this.i);
+}
+main() {
+ C(null);
+}
+''';
+ var expected = '''
+class C {
+ int? i;
+ C(this.i);
+}
+main() {
+ C(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_field_type_inferred() async {
+ var content = '''
+int f() => null;
+class C {
+ var x = 1;
+ void g() {
+ x = f();
+ }
+}
+''';
+ // The type of x is inferred from its initializer, so it is non-nullable,
+ // even though we try to assign a nullable value to it. So a null check
+ // must be added.
+ var expected = '''
+int? f() => null;
+class C {
+ var x = 1;
+ void g() {
+ x = f()!;
+ }
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_function_expression_invocation() async {
+ var content = '''
+abstract class C {
+ void Function(int) f();
+ int/*?*/ Function() g();
+}
+int test(C c) {
+ c.f()(null);
+ return c.g()();
+}
+''';
+ var expected = '''
+abstract class C {
+ void Function(int?) f();
+ int?/*?*/ Function() g();
+}
+int? test(C c) {
+ c.f()(null);
+ return c.g()();
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_function_expression_invocation_via_getter() async {
+ var content = '''
+abstract class C {
+ void Function(int) get f;
+ int/*?*/ Function() get g;
+}
+int test(C c) {
+ c.f(null);
+ return c.g();
+}
+''';
+ var expected = '''
+abstract class C {
+ void Function(int?) get f;
+ int?/*?*/ Function() get g;
+}
+int? test(C c) {
+ c.f(null);
+ return c.g();
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_function_typed_field_formal_param() async {
+ var content = '''
+class C {
+ int Function(int) f;
+ C(int this.f(int i));
+}
+int g(int i) => i;
+int test(int i) => C(g).f(i);
+main() {
+ test(null);
+}
+''';
+ var expected = '''
+class C {
+ int? Function(int?) f;
+ C(int? this.f(int? i));
+}
+int? g(int? i) => i;
+int? test(int? i) => C(g).f(i);
+main() {
+ test(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_function_typed_formal_param() async {
+ var content = '''
+int f(int callback(int i), int j) => callback(j);
+int g(int i) => i;
+int test(int i) => f(g, i);
+main() {
+ test(null);
+}
+''';
+ var expected = '''
+int? f(int? callback(int? i), int? j) => callback(j);
+int? g(int? i) => i;
+int? test(int? i) => f(g, i);
+main() {
+ test(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_generic_function_type_syntax_inferred_dynamic_return() async {
+ var content = '''
+abstract class C {
+ Function() f();
+}
+Object g(C c) => c.f()();
+''';
+ var expected = '''
+abstract class C {
+ Function() f();
+}
+Object? g(C c) => c.f()();
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_genericType_noTypeArguments() async {
var content = '''
void f(C c) {}
@@ -710,6 +1089,148 @@
await _checkSingleFileChanges(content, expected);
}
+ test_inferred_method_parameter_type_non_nullable() async {
+ var content = '''
+class B {
+ void f(int i) {
+ assert(i != null);
+ }
+}
+class C extends B {
+ void f(i) {}
+}
+void g(C c, int i, bool b) {
+ if (b) {
+ c.f(i);
+ }
+}
+void h(C c) {
+ g(c, null, false);
+}
+''';
+ // B.f's parameter type is `int`. Since C.f's parameter type is inferred
+ // from B.f's, it has a parameter type of `int` too. Therefore there must
+ // be a null check in g().
+ var expected = '''
+class B {
+ void f(int i) {
+ assert(i != null);
+ }
+}
+class C extends B {
+ void f(i) {}
+}
+void g(C c, int? i, bool b) {
+ if (b) {
+ c.f(i!);
+ }
+}
+void h(C c) {
+ g(c, null, false);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_inferred_method_parameter_type_nullable() async {
+ var content = '''
+class B {
+ void f(int i) {}
+}
+class C extends B {
+ void f(i) {}
+}
+void g(C c) {
+ c.f(null);
+}
+''';
+ // The call to C.f from g forces C.f's parameter to be nullable. Since
+ // C.f's parameter type is inferred from B.f's parameter type, B.f's
+ // parameter must be nullable too.
+ var expected = '''
+class B {
+ void f(int? i) {}
+}
+class C extends B {
+ void f(i) {}
+}
+void g(C c) {
+ c.f(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_inferred_method_return_type_non_nullable() async {
+ var content = '''
+class B {
+ int f() => 1;
+}
+class C extends B {
+ f() => 1;
+}
+int g(C c) => c.f();
+''';
+ // B.f's return type is `int`. Since C.f's return type is inferred from
+ // B.f's, it has a return type of `int` too. Therefore g's return type
+ // must be `int`.
+ var expected = '''
+class B {
+ int f() => 1;
+}
+class C extends B {
+ f() => 1;
+}
+int g(C c) => c.f();
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_inferred_method_return_type_nullable() async {
+ var content = '''
+class B {
+ int f() => null;
+}
+class C extends B {
+ f() => 1;
+}
+int g(C c) => c.f();
+''';
+ // B.f's return type is `int?`. Since C.f's return type is inferred from
+ // B.f's, it has a return type of `int?` too. Therefore g's return type
+ // must be `int?`.
+ var expected = '''
+class B {
+ int? f() => null;
+}
+class C extends B {
+ f() => 1;
+}
+int? g(C c) => c.f();
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_instance_creation_generic() async {
+ var content = '''
+class C<T> {
+ C(T t);
+}
+main() {
+ C<int> c = C<int>(null);
+}
+''';
+ var expected = '''
+class C<T> {
+ C(T t);
+}
+main() {
+ C<int?> c = C<int?>(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_instanceCreation_noTypeArguments_noParameters() async {
var content = '''
void main() {
@@ -732,6 +1253,27 @@
await _checkSingleFileChanges(content, expected);
}
+ test_localVariable_type_inferred() async {
+ var content = '''
+int f() => null;
+void main() {
+ var x = 1;
+ x = f();
+}
+''';
+ // The type of x is inferred from its initializer, so it is non-nullable,
+ // even though we try to assign a nullable value to it. So a null check
+ // must be added.
+ var expected = '''
+int? f() => null;
+void main() {
+ var x = 1;
+ x = f()!;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_named_parameter_no_default_unused() async {
var content = '''
void f({String s}) {}
@@ -1023,6 +1565,154 @@
await _checkSingleFileChanges(content, expected);
}
+ test_override_parameter_type_non_nullable() async {
+ var content = '''
+abstract class Base {
+ void f(int i);
+}
+class Derived extends Base {
+ void f(int i) {
+ assert(i != null);
+ }
+}
+void g(int i, bool b, Base base) {
+ if (b) {
+ base.f(i);
+ }
+}
+void h(Base base) {
+ g(null, false, base);
+}
+''';
+ var expected = '''
+abstract class Base {
+ void f(int i);
+}
+class Derived extends Base {
+ void f(int i) {
+ assert(i != null);
+ }
+}
+void g(int? i, bool b, Base base) {
+ if (b) {
+ base.f(i!);
+ }
+}
+void h(Base base) {
+ g(null, false, base);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_override_parameter_type_nullable() async {
+ var content = '''
+abstract class Base {
+ void f(int i);
+}
+class Derived extends Base {
+ void f(int i) {}
+}
+void g(int i, Base base) {
+ base.f(null);
+}
+''';
+ var expected = '''
+abstract class Base {
+ void f(int? i);
+}
+class Derived extends Base {
+ void f(int? i) {}
+}
+void g(int i, Base base) {
+ base.f(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_override_return_type_non_nullable() async {
+ var content = '''
+abstract class Base {
+ int/*!*/ f();
+}
+class Derived extends Base {
+ int f() => g();
+}
+int g() => null;
+''';
+ var expected = '''
+abstract class Base {
+ int/*!*/ f();
+}
+class Derived extends Base {
+ int f() => g()!;
+}
+int? g() => null;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_override_return_type_nullable() async {
+ var content = '''
+abstract class Base {
+ int f();
+}
+class Derived extends Base {
+ int f() => null;
+}
+''';
+ var expected = '''
+abstract class Base {
+ int? f();
+}
+class Derived extends Base {
+ int? f() => null;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_override_return_type_nullable_substitution_complex() async {
+ var content = '''
+abstract class Base<T> {
+ T f();
+}
+class Derived extends Base<List<int>> {
+ List<int> f() => <int>[null];
+}
+''';
+ var expected = '''
+abstract class Base<T> {
+ T f();
+}
+class Derived extends Base<List<int?>> {
+ List<int?> f() => <int?>[null];
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_override_return_type_nullable_substitution_simple() async {
+ var content = '''
+abstract class Base<T> {
+ T f();
+}
+class Derived extends Base<int> {
+ int f() => null;
+}
+''';
+ var expected = '''
+abstract class Base<T> {
+ T f();
+}
+class Derived extends Base<int?> {
+ int? f() => null;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_parameter_genericFunctionType() async {
var content = '''
int f(int x, int Function(int i) g) {
@@ -1037,6 +1727,42 @@
await _checkSingleFileChanges(content, expected);
}
+ test_prefix_minus() async {
+ var content = '''
+class C {
+ D operator-() => null;
+}
+class D {}
+D test(C c) => -c;
+''';
+ var expected = '''
+class C {
+ D? operator-() => null;
+}
+class D {}
+D? test(C c) => -c;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_prefix_minus_substitute() async {
+ var content = '''
+abstract class C<T> {
+ D<T> operator-();
+}
+class D<U> {}
+D<int> test(C<int/*?*/> c) => -c;
+''';
+ var expected = '''
+abstract class C<T> {
+ D<T> operator-();
+}
+class D<U> {}
+D<int?> test(C<int?/*?*/> c) => -c;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_prefixExpression_bang() async {
var content = '''
bool f(bool b) => !b;
@@ -1063,6 +1789,54 @@
await _checkSingleFileChanges(content, expected);
}
+ test_redirecting_constructor_factory() async {
+ var content = '''
+class C {
+ factory C(int i, int j) = D;
+}
+class D implements C {
+ D(int i, int j);
+}
+main() {
+ C(null, 1);
+}
+''';
+ var expected = '''
+class C {
+ factory C(int? i, int j) = D;
+}
+class D implements C {
+ D(int? i, int j);
+}
+main() {
+ C(null, 1);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_redirecting_constructor_ordinary() async {
+ var content = '''
+class C {
+ C(int i, int j) : this.named(j, i);
+ C.named(int j, int i);
+}
+main() {
+ C(null, 1);
+}
+''';
+ var expected = '''
+class C {
+ C(int? i, int j) : this.named(j, i);
+ C.named(int j, int? i);
+}
+main() {
+ C(null, 1);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_single_file_multiple_changes() async {
var content = '''
int f() => null;
@@ -1085,6 +1859,49 @@
await _checkSingleFileChanges(content, expected);
}
+ test_topLevelFunction_parameterType_implicit_dynamic() async {
+ var content = '''
+Object f(x) => x;
+''';
+ var expected = '''
+Object? f(x) => x;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_topLevelFunction_returnType_implicit_dynamic() async {
+ var content = '''
+f() {}
+Object g() => f();
+''';
+ var expected = '''
+f() {}
+Object? g() => f();
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_topLevelVariable_type_inferred() async {
+ var content = '''
+int f() => null;
+var x = 1;
+void main() {
+ x = f();
+}
+''';
+ // The type of x is inferred from its initializer, so it is non-nullable,
+ // even though we try to assign a nullable value to it. So a null check
+ // must be added.
+ var expected = '''
+int? f() => null;
+var x = 1;
+void main() {
+ x = f()!;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_two_files() async {
var root = '/home/test/lib';
var path1 = convertPath('$root/file1.dart');
@@ -1397,6 +2214,12 @@
with _ProvisionalApiTestCases {
@override
bool get _usePermissiveMode => true;
+
+ // TODO(danrubel): Remove this once the superclass test has been fixed.
+ // This runs in permissive mode but not when permissive mode is disabled.
+ test_instanceCreation_noTypeArguments_noParameters() async {
+ super.test_instanceCreation_noTypeArguments_noParameters();
+ }
}
/// Tests of the provisional API, where the driver is reset between calls to
diff --git a/pkg/nnbd_migration/test/decorated_class_hierarchy_test.dart b/pkg/nnbd_migration/test/decorated_class_hierarchy_test.dart
new file mode 100644
index 0000000..9e09dca
--- /dev/null
+++ b/pkg/nnbd_migration/test/decorated_class_hierarchy_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:analyzer/dart/ast/ast.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DecoratedClassHierarchyTest);
+ });
+}
+
+@reflectiveTest
+class DecoratedClassHierarchyTest extends MigrationVisitorTestBase {
+ DecoratedClassHierarchy _hierarchy;
+
+ @override
+ Future<CompilationUnit> analyze(String code) async {
+ var unit = await super.analyze(code);
+ _hierarchy = DecoratedClassHierarchy(variables, graph);
+ return unit;
+ }
+
+ test_getDecoratedSupertype_complex() async {
+ await analyze('''
+class Base<T> {}
+class Intermediate<U> extends Base<List<U>> {}
+class Derived<V> extends Intermediate<Map<int, V>> {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.class_('Derived'), findElement.class_('Base'));
+ var listRef = decoratedTypeAnnotation('List');
+ var uRef = decoratedTypeAnnotation('U>>');
+ var mapRef = decoratedTypeAnnotation('Map');
+ var intRef = decoratedTypeAnnotation('int');
+ var vRef = decoratedTypeAnnotation('V>>');
+ expect(decoratedSupertype.type.toString(), 'Base<List<Map<int, V>>>');
+ expect(decoratedSupertype.node, same(never));
+ var baseArgs = decoratedSupertype.typeArguments;
+ expect(baseArgs, hasLength(1));
+ expect(baseArgs[0].type.toString(), 'List<Map<int, V>>');
+ expect(baseArgs[0].node, same(listRef.node));
+ var listArgs = baseArgs[0].typeArguments;
+ expect(listArgs, hasLength(1));
+ expect(listArgs[0].type.toString(), 'Map<int, V>');
+ var mapNode = listArgs[0].node as NullabilityNodeForSubstitution;
+ expect(mapNode.innerNode, same(mapRef.node));
+ expect(mapNode.outerNode, same(uRef.node));
+ var mapArgs = listArgs[0].typeArguments;
+ expect(mapArgs, hasLength(2));
+ expect(mapArgs[0].type.toString(), 'int');
+ expect(mapArgs[0].node, same(intRef.node));
+ expect(mapArgs[1].type.toString(), 'V');
+ expect(mapArgs[1].node, same(vRef.node));
+ }
+
+ test_getDecoratedSupertype_extends_simple() async {
+ await analyze('''
+class Base<T, U> {}
+class Derived<V, W> extends Base<V, W> {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.class_('Derived'), findElement.class_('Base'));
+ var vRef = decoratedTypeAnnotation('V, W> {');
+ var wRef = decoratedTypeAnnotation('W> {');
+ expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+ expect(decoratedSupertype.node, same(never));
+ expect(decoratedSupertype.typeArguments, hasLength(2));
+ expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+ expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+ expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+ expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+ }
+
+ test_getDecoratedSupertype_implements_simple() async {
+ await analyze('''
+class Base<T, U> {}
+class Derived<V, W> implements Base<V, W> {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.class_('Derived'), findElement.class_('Base'));
+ var vRef = decoratedTypeAnnotation('V, W> {');
+ var wRef = decoratedTypeAnnotation('W> {');
+ expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+ expect(decoratedSupertype.node, same(never));
+ expect(decoratedSupertype.typeArguments, hasLength(2));
+ expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+ expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+ expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+ expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+ }
+
+ test_getDecoratedSupertype_not_generic() async {
+ await analyze('''
+class Base {}
+class Derived<T> extends Base {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.class_('Derived'), findElement.class_('Base'));
+ expect(decoratedSupertype.type.toString(), 'Base');
+ expect(decoratedSupertype.node, same(never));
+ expect(decoratedSupertype.typeArguments, isEmpty);
+ }
+
+ test_getDecoratedSupertype_on_simple() async {
+ await analyze('''
+class Base<T, U> {}
+mixin Derived<V, W> on Base<V, W> {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.mixin('Derived'), findElement.class_('Base'));
+ var vRef = decoratedTypeAnnotation('V, W> {');
+ var wRef = decoratedTypeAnnotation('W> {');
+ expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+ expect(decoratedSupertype.node, same(never));
+ expect(decoratedSupertype.typeArguments, hasLength(2));
+ expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+ expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+ expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+ expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+ }
+
+ test_getDecoratedSupertype_unrelated_type() async {
+ await analyze('''
+class A<T> {}
+class B<T> {}
+''');
+ expect(
+ () => _hierarchy.getDecoratedSupertype(
+ findElement.class_('A'), findElement.class_('B')),
+ throwsA(TypeMatcher<StateError>()));
+ }
+
+ test_getDecoratedSupertype_with_simple() async {
+ await analyze('''
+class Base<T, U> {}
+class Derived<V, W> extends Object with Base<V, W> {}
+''');
+ var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+ findElement.class_('Derived'), findElement.class_('Base'));
+ var vRef = decoratedTypeAnnotation('V, W> {');
+ var wRef = decoratedTypeAnnotation('W> {');
+ expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+ expect(decoratedSupertype.node, same(never));
+ expect(decoratedSupertype.typeArguments, hasLength(2));
+ expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+ expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+ expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+ expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+ }
+}
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
new file mode 100644
index 0000000..bd63ab4
--- /dev/null
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -0,0 +1,93 @@
+// 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:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'abstract_single_unit.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DecoratedTypeTest);
+ });
+}
+
+@reflectiveTest
+class DecoratedTypeTest extends AbstractSingleUnitTest {
+ final _graph = NullabilityGraph();
+
+ NullabilityNode get always => _graph.always;
+
+ @override
+ void setUp() {
+ NullabilityNode.clearDebugNames();
+ super.setUp();
+ }
+
+ test_toString_named_parameter() async {
+ await resolveTestUnit('''dynamic f({int x}) {}''');
+ var type = findElement.function('f').type;
+ var decoratedType = DecoratedType(type, always,
+ namedParameters: {
+ 'x': DecoratedType(type.namedParameterTypes['x'], _node(1))
+ },
+ returnType: DecoratedType(type.returnType, always));
+ expect(decoratedType.toString(), 'dynamic Function({x: int?(type(1))})?');
+ }
+
+ test_toString_normal_and_named_parameter() async {
+ await resolveTestUnit('''dynamic f(int x, {int y}) {}''');
+ var type = findElement.function('f').type;
+ var decoratedType = DecoratedType(type, always,
+ positionalParameters: [
+ DecoratedType(type.normalParameterTypes[0], _node(1))
+ ],
+ namedParameters: {
+ 'y': DecoratedType(type.namedParameterTypes['y'], _node(2))
+ },
+ returnType: DecoratedType(type.returnType, always));
+ expect(decoratedType.toString(),
+ 'dynamic Function(int?(type(1)), {y: int?(type(2))})?');
+ }
+
+ test_toString_normal_and_optional_parameter() async {
+ await resolveTestUnit('''dynamic f(int x, [int y]) {}''');
+ var type = findElement.function('f').type;
+ var decoratedType = DecoratedType(type, always,
+ positionalParameters: [
+ DecoratedType(type.normalParameterTypes[0], _node(1)),
+ DecoratedType(type.optionalParameterTypes[0], _node(2))
+ ],
+ returnType: DecoratedType(type.returnType, always));
+ expect(decoratedType.toString(),
+ 'dynamic Function(int?(type(1)), [int?(type(2))])?');
+ }
+
+ test_toString_normal_parameter() async {
+ await resolveTestUnit('''dynamic f(int x) {}''');
+ var type = findElement.function('f').type;
+ var decoratedType = DecoratedType(type, always,
+ positionalParameters: [
+ DecoratedType(type.normalParameterTypes[0], _node(1))
+ ],
+ returnType: DecoratedType(type.returnType, always));
+ expect(decoratedType.toString(), 'dynamic Function(int?(type(1)))?');
+ }
+
+ test_toString_optional_parameter() async {
+ await resolveTestUnit('''dynamic f([int x]) {}''');
+ var type = findElement.function('f').type;
+ var decoratedType = DecoratedType(type, always,
+ positionalParameters: [
+ DecoratedType(type.optionalParameterTypes[0], _node(1))
+ ],
+ returnType: DecoratedType(type.returnType, always));
+ expect(decoratedType.toString(), 'dynamic Function([int?(type(1))])?');
+ }
+
+ NullabilityNode _node(int offset) =>
+ NullabilityNode.forTypeAnnotation(offset);
+}
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
new file mode 100644
index 0000000..0996ae3
--- /dev/null
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -0,0 +1,2805 @@
+// 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/dart/element/member.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_builder.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EdgeBuilderTest);
+ });
+}
+
+@reflectiveTest
+class EdgeBuilderTest extends MigrationVisitorTestBase {
+ /// Analyzes the given source code, producing constraint variables and
+ /// constraints for it.
+ @override
+ Future<CompilationUnit> analyze(String code) async {
+ var unit = await super.analyze(code);
+ unit.accept(EdgeBuilder(
+ typeProvider, typeSystem, variables, graph, testSource, null));
+ return unit;
+ }
+
+ void assertGLB(
+ NullabilityNode node, NullabilityNode left, NullabilityNode right) {
+ expect(node, isNot(TypeMatcher<NullabilityNodeForLUB>()));
+ assertEdge(left, node, hard: false, guards: [right]);
+ assertEdge(node, left, hard: false);
+ assertEdge(node, right, hard: false);
+ }
+
+ void assertLUB(
+ NullabilityNode node, NullabilityNode left, NullabilityNode right) {
+ var conditionalNode = node as NullabilityNodeForLUB;
+ expect(conditionalNode.left, same(left));
+ expect(conditionalNode.right, same(right));
+ }
+
+ /// Checks that there are no nullability nodes upstream from [node] that could
+ /// cause it to become nullable.
+ void assertNoUpstreamNullability(NullabilityNode node) {
+ // never can never become nullable, even if it has nodes
+ // upstream from it.
+ if (node == never) return;
+
+ for (var edge in graph.getUpstreamEdges(node)) {
+ expect(edge.primarySource, never);
+ }
+ }
+
+ /// Verifies that a null check will occur when the given edge is unsatisfied.
+ ///
+ /// [expressionChecks] is the object tracking whether or not a null check is
+ /// needed.
+ void assertNullCheck(
+ ExpressionChecks expressionChecks, NullabilityEdge expectedEdge) {
+ expect(expressionChecks.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) {
+ return variables.checkExpression(findNode.expression(text));
+ }
+
+ /// Gets the [DecoratedType] associated with the expression whose text
+ /// representation is [text], or `null` if the expression has no
+ /// [DecoratedType] associated with it.
+ DecoratedType decoratedExpressionType(String text) {
+ return variables.decoratedExpressionType(findNode.expression(text));
+ }
+
+ test_assert_demonstrates_non_null_intent() async {
+ await analyze('''
+void f(int i) {
+ assert(i != null);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
+ test_assignmentExpression_field() async {
+ await analyze('''
+class C {
+ int x = 0;
+}
+void f(C c, int i) {
+ c.x = i;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_field_cascaded() async {
+ await analyze('''
+class C {
+ int x = 0;
+}
+void f(C c, int i) {
+ c..x = i;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_field_target_check() async {
+ await analyze('''
+class C {
+ int x = 0;
+}
+void f(C c, int i) {
+ c.x = i;
+}
+''');
+ assertNullCheck(checkExpression('c.x'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_assignmentExpression_field_target_check_cascaded() async {
+ await analyze('''
+class C {
+ int x = 0;
+}
+void f(C c, int i) {
+ c..x = i;
+}
+''');
+ assertNullCheck(checkExpression('c..x'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_assignmentExpression_indexExpression_index() async {
+ await analyze('''
+class C {
+ void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+ c[i] = j;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int a').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_indexExpression_return_value() async {
+ await analyze('''
+class C {
+ void operator[]=(int a, int b) {}
+}
+int f(C c, int i, int j) => c[i] = j;
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int f').node,
+ hard: false);
+ }
+
+ test_assignmentExpression_indexExpression_target_check() async {
+ await analyze('''
+class C {
+ void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+ c[i] = j;
+}
+''');
+ assertNullCheck(checkExpression('c['),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_assignmentExpression_indexExpression_value() async {
+ await analyze('''
+class C {
+ void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+ c[i] = j;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int b').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_operands() async {
+ await analyze('''
+void f(int i, int j) {
+ i = j;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_return_value() async {
+ await analyze('''
+void f(int i, int j) {
+ g(i = j);
+}
+void g(int k) {}
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int k').node,
+ hard: false);
+ }
+
+ test_assignmentExpression_setter() async {
+ await analyze('''
+class C {
+ void set s(int value) {}
+}
+void f(C c, int i) {
+ c.s = i;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int value').node,
+ hard: true);
+ }
+
+ test_assignmentExpression_setter_null_aware() async {
+ await analyze('''
+class C {
+ void set s(int value) {}
+}
+int f(C c, int i) => (c?.s = i);
+''');
+ var lubNode =
+ decoratedExpressionType('(c?.s = i)').node as NullabilityNodeForLUB;
+ expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+ expect(lubNode.right, same(decoratedTypeAnnotation('int i').node));
+ assertEdge(lubNode, decoratedTypeAnnotation('int f').node, hard: false);
+ }
+
+ test_assignmentExpression_setter_target_check() async {
+ await analyze('''
+class C {
+ void set s(int value) {}
+}
+void f(C c, int i) {
+ c.s = i;
+}
+''');
+ assertNullCheck(checkExpression('c.s'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ @failingTest
+ test_awaitExpression_future_nonNullable() async {
+ await analyze('''
+Future<void> f() async {
+ int x = await g();
+}
+Future<int> g() async => 3;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ @failingTest
+ test_awaitExpression_future_nullable() async {
+ await analyze('''
+Future<void> f() async {
+ int x = await g();
+}
+Future<int> g() async => null;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_awaitExpression_nonFuture() async {
+ await analyze('''
+Future<void> f() async {
+ int x = await 3;
+}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_binaryExpression_ampersand_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i & j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_ampersandAmpersand() async {
+ await analyze('''
+bool f(bool i, bool j) => i && j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool i').node);
+ }
+
+ test_binaryExpression_bar_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i | j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_barBar() async {
+ await analyze('''
+bool f(bool i, bool j) => i || j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool i').node);
+ }
+
+ test_binaryExpression_caret_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i ^ j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_equal() async {
+ await analyze('''
+bool f(int i, int j) => i == j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_gt_result_not_null() async {
+ await analyze('''
+bool f(int i, int j) => i > j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_gtEq_result_not_null() async {
+ await analyze('''
+bool f(int i, int j) => i >= j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_gtGt_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i >> j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_lt_result_not_null() async {
+ await analyze('''
+bool f(int i, int j) => i < j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_ltEq_result_not_null() async {
+ await analyze('''
+bool f(int i, int j) => i <= j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_ltLt_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i << j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_minus_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i - j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_notEqual() async {
+ await analyze('''
+bool f(int i, int j) => i != j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+ }
+
+ test_binaryExpression_percent_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i % j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_plus_left_check() async {
+ await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+ assertNullCheck(checkExpression('i +'),
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true));
+ }
+
+ test_binaryExpression_plus_left_check_custom() async {
+ await analyze('''
+class Int {
+ Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j;
+''');
+
+ assertNullCheck(checkExpression('i +'),
+ assertEdge(decoratedTypeAnnotation('Int i').node, never, hard: true));
+ }
+
+ test_binaryExpression_plus_result_custom() async {
+ await analyze('''
+class Int {
+ Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => (i + j);
+''');
+
+ assertNullCheck(
+ checkExpression('(i + j)'),
+ assertEdge(decoratedTypeAnnotation('Int operator+').node,
+ decoratedTypeAnnotation('Int f').node,
+ hard: false));
+ }
+
+ test_binaryExpression_plus_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_plus_right_check() async {
+ await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+ assertNullCheck(checkExpression('j;'),
+ assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true));
+ }
+
+ test_binaryExpression_plus_right_check_custom() async {
+ await analyze('''
+class Int {
+ Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j/*check*/;
+''');
+
+ assertNullCheck(
+ checkExpression('j/*check*/'),
+ assertEdge(decoratedTypeAnnotation('Int j').node,
+ decoratedTypeAnnotation('Int other').node,
+ hard: true));
+ }
+
+ test_binaryExpression_questionQuestion() async {
+ await analyze('''
+int f(int i, int j) => i ?? j;
+''');
+
+ var left = decoratedTypeAnnotation('int i').node;
+ var right = decoratedTypeAnnotation('int j').node;
+ var expression = decoratedExpressionType('??').node;
+ assertEdge(right, expression, guards: [left], hard: false);
+ }
+
+ test_binaryExpression_slash_result_not_null() async {
+ await analyze('''
+double f(int i, int j) => i / j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('double f').node);
+ }
+
+ test_binaryExpression_star_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i * j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_binaryExpression_tildeSlash_result_not_null() async {
+ await analyze('''
+int f(int i, int j) => i ~/ j;
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+ }
+
+ test_boolLiteral() async {
+ await analyze('''
+bool f() {
+ return true;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ }
+
+ test_cascadeExpression() async {
+ await analyze('''
+class C {
+ int x = 0;
+}
+C f(C c, int i) => c..x = i;
+''');
+ assertEdge(decoratedTypeAnnotation('C c').node,
+ decoratedTypeAnnotation('C f').node,
+ hard: false);
+ }
+
+ test_catch_clause() async {
+ await analyze('''
+foo() => 1;
+main() {
+ try { foo(); } on Exception catch (e) { print(e); }
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_catch_clause_no_type() async {
+ await analyze('''
+foo() => 1;
+main() {
+ try { foo(); } catch (e) { print(e); }
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_class_alias_synthetic_constructor_with_parameters_complex() async {
+ await analyze('''
+class MyList<T> {}
+class C {
+ C(MyList<int>/*1*/ x);
+}
+mixin M {}
+class D = C with M;
+D f(MyList<int>/*2*/ x) => D(x);
+''');
+ var syntheticConstructor = findElement.unnamedConstructor('D');
+ var constructorType = variables.decoratedElementType(syntheticConstructor);
+ var constructorParameterType = constructorType.positionalParameters[0];
+ assertEdge(decoratedTypeAnnotation('MyList<int>/*2*/').node,
+ constructorParameterType.node,
+ hard: true);
+ assertEdge(decoratedTypeAnnotation('int>/*2*/').node,
+ constructorParameterType.typeArguments[0].node,
+ hard: false);
+ assertUnion(constructorParameterType.node,
+ decoratedTypeAnnotation('MyList<int>/*1*/').node);
+ assertUnion(constructorParameterType.typeArguments[0].node,
+ decoratedTypeAnnotation('int>/*1*/').node);
+ }
+
+ test_class_alias_synthetic_constructor_with_parameters_generic() async {
+ await analyze('''
+class C<T> {
+ C(T t);
+}
+mixin M {}
+class D<U> = C<U> with M;
+''');
+ var syntheticConstructor = findElement.unnamedConstructor('D');
+ var constructorType = variables.decoratedElementType(syntheticConstructor);
+ var constructorParameterType = constructorType.positionalParameters[0];
+ assertUnion(
+ constructorParameterType.node, decoratedTypeAnnotation('T t').node);
+ }
+
+ test_class_alias_synthetic_constructor_with_parameters_named() async {
+ await analyze('''
+class C {
+ C({int/*1*/ i});
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i: i);
+''');
+ var syntheticConstructor = findElement.unnamedConstructor('D');
+ var constructorType = variables.decoratedElementType(syntheticConstructor);
+ var constructorParameterType = constructorType.namedParameters['i'];
+ assertEdge(
+ decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+ hard: true);
+ assertUnion(constructorParameterType.node,
+ decoratedTypeAnnotation('int/*1*/').node);
+ }
+
+ test_class_alias_synthetic_constructor_with_parameters_optional() async {
+ await analyze('''
+class C {
+ C([int/*1*/ i]);
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i);
+''');
+ var syntheticConstructor = findElement.unnamedConstructor('D');
+ var constructorType = variables.decoratedElementType(syntheticConstructor);
+ var constructorParameterType = constructorType.positionalParameters[0];
+ assertEdge(
+ decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+ hard: true);
+ assertUnion(constructorParameterType.node,
+ decoratedTypeAnnotation('int/*1*/').node);
+ }
+
+ test_class_alias_synthetic_constructor_with_parameters_required() async {
+ await analyze('''
+class C {
+ C(int/*1*/ i);
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i);
+''');
+ var syntheticConstructor = findElement.unnamedConstructor('D');
+ var constructorType = variables.decoratedElementType(syntheticConstructor);
+ var constructorParameterType = constructorType.positionalParameters[0];
+ assertEdge(
+ decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+ hard: true);
+ assertUnion(constructorParameterType.node,
+ decoratedTypeAnnotation('int/*1*/').node);
+ }
+
+ test_conditionalExpression_condition_check() async {
+ await analyze('''
+int f(bool b, int i, int j) {
+ return (b ? i : j);
+}
+''');
+
+ var nullable_b = decoratedTypeAnnotation('bool b').node;
+ var check_b = checkExpression('b ?');
+ assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
+ }
+
+ test_conditionalExpression_functionTyped_namedParameter() async {
+ await analyze('''
+void f(bool b, void Function({int p}) x, void Function({int p}) y) {
+ (b ? x : y);
+}
+''');
+ var xType =
+ decoratedGenericFunctionTypeAnnotation('void Function({int p}) x');
+ var yType =
+ decoratedGenericFunctionTypeAnnotation('void Function({int p}) y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertGLB(resultType.namedParameters['p'].node,
+ xType.namedParameters['p'].node, yType.namedParameters['p'].node);
+ }
+
+ test_conditionalExpression_functionTyped_normalParameter() async {
+ await analyze('''
+void f(bool b, void Function(int) x, void Function(int) y) {
+ (b ? x : y);
+}
+''');
+ var xType = decoratedGenericFunctionTypeAnnotation('void Function(int) x');
+ var yType = decoratedGenericFunctionTypeAnnotation('void Function(int) y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertGLB(resultType.positionalParameters[0].node,
+ xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+ }
+
+ test_conditionalExpression_functionTyped_normalParameters() async {
+ await analyze('''
+void f(bool b, void Function(int, int) x, void Function(int, int) y) {
+ (b ? x : y);
+}
+''');
+ var xType =
+ decoratedGenericFunctionTypeAnnotation('void Function(int, int) x');
+ var yType =
+ decoratedGenericFunctionTypeAnnotation('void Function(int, int) y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertGLB(resultType.positionalParameters[0].node,
+ xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+ assertGLB(resultType.positionalParameters[1].node,
+ xType.positionalParameters[1].node, yType.positionalParameters[1].node);
+ }
+
+ test_conditionalExpression_functionTyped_optionalParameter() async {
+ await analyze('''
+void f(bool b, void Function([int]) x, void Function([int]) y) {
+ (b ? x : y);
+}
+''');
+ var xType =
+ decoratedGenericFunctionTypeAnnotation('void Function([int]) x');
+ var yType =
+ decoratedGenericFunctionTypeAnnotation('void Function([int]) y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertGLB(resultType.positionalParameters[0].node,
+ xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+ }
+
+ test_conditionalExpression_functionTyped_returnType() async {
+ await analyze('''
+void f(bool b, int Function() x, int Function() y) {
+ (b ? x : y);
+}
+''');
+ var xType = decoratedGenericFunctionTypeAnnotation('int Function() x');
+ var yType = decoratedGenericFunctionTypeAnnotation('int Function() y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertLUB(resultType.returnType.node, xType.returnType.node,
+ yType.returnType.node);
+ }
+
+ test_conditionalExpression_functionTyped_returnType_void() async {
+ await analyze('''
+void f(bool b, void Function() x, void Function() y) {
+ (b ? x : y);
+}
+''');
+ var xType = decoratedGenericFunctionTypeAnnotation('void Function() x');
+ var yType = decoratedGenericFunctionTypeAnnotation('void Function() y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ expect(resultType.returnType.node, same(always));
+ }
+
+ test_conditionalExpression_general() async {
+ await analyze('''
+int f(bool b, int i, int j) {
+ return (b ? i : j);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_j = decoratedTypeAnnotation('int j').node;
+ var nullable_conditional = decoratedExpressionType('(b ?').node;
+ assertLUB(nullable_conditional, nullable_i, nullable_j);
+ var nullable_return = decoratedTypeAnnotation('int f').node;
+ assertNullCheck(checkExpression('(b ? i : j)'),
+ assertEdge(nullable_conditional, nullable_return, hard: false));
+ }
+
+ test_conditionalExpression_generic() async {
+ await analyze('''
+void f(bool b, Map<int, String> x, Map<int, String> y) {
+ (b ? x : y);
+}
+''');
+ var xType = decoratedTypeAnnotation('Map<int, String> x');
+ var yType = decoratedTypeAnnotation('Map<int, String> y');
+ var resultType = decoratedExpressionType('(b ?');
+ assertLUB(resultType.node, xType.node, yType.node);
+ assertLUB(resultType.typeArguments[0].node, xType.typeArguments[0].node,
+ yType.typeArguments[0].node);
+ assertLUB(resultType.typeArguments[1].node, xType.typeArguments[1].node,
+ yType.typeArguments[1].node);
+ }
+
+ test_conditionalExpression_left_non_null() async {
+ await analyze('''
+int f(bool b, int i) {
+ return (b ? (throw i) : i);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_conditional =
+ decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
+ var nullable_throw = nullable_conditional.left;
+ assertNoUpstreamNullability(nullable_throw);
+ assertLUB(nullable_conditional, nullable_throw, nullable_i);
+ }
+
+ test_conditionalExpression_left_null() async {
+ await analyze('''
+int f(bool b, int i) {
+ return (b ? null : i);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_conditional = decoratedExpressionType('(b ?').node;
+ assertLUB(nullable_conditional, always, nullable_i);
+ }
+
+ test_conditionalExpression_right_non_null() async {
+ await analyze('''
+int f(bool b, int i) {
+ return (b ? i : (throw i));
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_conditional =
+ decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
+ var nullable_throw = nullable_conditional.right;
+ assertNoUpstreamNullability(nullable_throw);
+ assertLUB(nullable_conditional, nullable_i, nullable_throw);
+ }
+
+ test_conditionalExpression_right_null() async {
+ await analyze('''
+int f(bool b, int i) {
+ return (b ? i : null);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_conditional = decoratedExpressionType('(b ?').node;
+ assertLUB(nullable_conditional, nullable_i, always);
+ }
+
+ test_constructor_named() async {
+ await analyze('''
+class C {
+ C.named();
+}
+''');
+ // No assertions; just need to make sure that the test doesn't cause an
+ // exception to be thrown.
+ }
+
+ test_constructorDeclaration_returnType_generic() async {
+ await analyze('''
+class C<T, U> {
+ C();
+}
+''');
+ var constructor = findElement.unnamedConstructor('C');
+ var constructorDecoratedType = variables.decoratedElementType(constructor);
+ expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
+ expect(constructorDecoratedType.node, same(never));
+ expect(constructorDecoratedType.typeFormals, isEmpty);
+ expect(constructorDecoratedType.returnType.node, same(never));
+ expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
+ var typeArguments = constructorDecoratedType.returnType.typeArguments;
+ expect(typeArguments, hasLength(2));
+ expect(typeArguments[0].type.toString(), 'T');
+ expect(typeArguments[0].node, same(never));
+ expect(typeArguments[1].type.toString(), 'U');
+ expect(typeArguments[1].node, same(never));
+ }
+
+ test_constructorDeclaration_returnType_generic_implicit() async {
+ await analyze('''
+class C<T, U> {}
+''');
+ var constructor = findElement.unnamedConstructor('C');
+ var constructorDecoratedType = variables.decoratedElementType(constructor);
+ expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
+ expect(constructorDecoratedType.node, same(never));
+ expect(constructorDecoratedType.typeFormals, isEmpty);
+ expect(constructorDecoratedType.returnType.node, same(never));
+ expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
+ var typeArguments = constructorDecoratedType.returnType.typeArguments;
+ expect(typeArguments, hasLength(2));
+ expect(typeArguments[0].type.toString(), 'T');
+ expect(typeArguments[0].node, same(never));
+ expect(typeArguments[1].type.toString(), 'U');
+ expect(typeArguments[1].node, same(never));
+ }
+
+ test_constructorDeclaration_returnType_simple() async {
+ await analyze('''
+class C {
+ C();
+}
+''');
+ var constructorDecoratedType =
+ variables.decoratedElementType(findElement.unnamedConstructor('C'));
+ expect(constructorDecoratedType.type.toString(), 'C Function()');
+ expect(constructorDecoratedType.node, same(never));
+ expect(constructorDecoratedType.typeFormals, isEmpty);
+ expect(constructorDecoratedType.returnType.node, same(never));
+ expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
+ }
+
+ test_constructorDeclaration_returnType_simple_implicit() async {
+ await analyze('''
+class C {}
+''');
+ var constructorDecoratedType =
+ variables.decoratedElementType(findElement.unnamedConstructor('C'));
+ expect(constructorDecoratedType.type.toString(), 'C Function()');
+ expect(constructorDecoratedType.node, same(never));
+ expect(constructorDecoratedType.typeFormals, isEmpty);
+ expect(constructorDecoratedType.returnType.node, same(never));
+ expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
+ }
+
+ test_doubleLiteral() async {
+ await analyze('''
+double f() {
+ return 1.0;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
+ }
+
+ test_field_type_inferred() async {
+ await analyze('''
+int f() => 1;
+class C {
+ var x = f();
+}
+''');
+ var xType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+ }
+
+ test_fieldFormalParameter_function_typed() async {
+ await analyze('''
+class C {
+ int Function(int, {int j}) f;
+ C(int this.f(int i, {int j}));
+}
+''');
+ var ctorParamType = variables
+ .decoratedElementType(findElement.unnamedConstructor('C'))
+ .positionalParameters[0];
+ var fieldType = variables.decoratedElementType(findElement.field('f'));
+ assertEdge(ctorParamType.node, fieldType.node, hard: true);
+ assertEdge(ctorParamType.returnType.node, fieldType.returnType.node,
+ hard: true);
+ assertEdge(fieldType.positionalParameters[0].node,
+ ctorParamType.positionalParameters[0].node,
+ hard: true);
+ assertEdge(fieldType.namedParameters['j'].node,
+ ctorParamType.namedParameters['j'].node,
+ hard: true);
+ }
+
+ test_fieldFormalParameter_typed() async {
+ await analyze('''
+class C {
+ int i;
+ C(int this.i);
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int this').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true);
+ }
+
+ test_fieldFormalParameter_untyped() async {
+ await analyze('''
+class C {
+ int i;
+ C.named(this.i);
+}
+''');
+ var decoratedConstructorParamType =
+ decoratedConstructorDeclaration('named').positionalParameters[0];
+ assertUnion(decoratedConstructorParamType.node,
+ decoratedTypeAnnotation('int i').node);
+ }
+
+ test_for_with_declaration() async {
+ await analyze('''
+main() {
+ for (int i in <int>[1, 2, 3]) { print(i); }
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_for_with_var() async {
+ await analyze('''
+main() {
+ for (var i in <int>[1, 2, 3]) { print(i); }
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_function_assignment() async {
+ await analyze('''
+class C {
+ void f1(String message) {}
+ void f2(String message) {}
+}
+foo(C c, bool flag) {
+ Function(String message) out = flag ? c.f1 : c.f2;
+ out('hello');
+}
+bar() {
+ foo(C(), true);
+ foo(C(), false);
+}
+''');
+ var type = decoratedTypeAnnotation('Function(String message)');
+ expect(type.returnType, isNotNull);
+ }
+
+ test_functionDeclaration_expression_body() async {
+ await analyze('''
+int/*1*/ f(int/*2*/ i) => i/*3*/;
+''');
+
+ assertNullCheck(
+ checkExpression('i/*3*/'),
+ assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+ decoratedTypeAnnotation('int/*1*/').node,
+ hard: true));
+ }
+
+ test_functionDeclaration_parameter_named_default_listConst() async {
+ await analyze('''
+void f({List<int/*1*/> i = const <int/*2*/>[]}) {}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('List<int/*1*/>').node);
+ assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+ decoratedTypeAnnotation('int/*1*/').node,
+ hard: false);
+ }
+
+ test_functionDeclaration_parameter_named_default_notNull() async {
+ await analyze('''
+void f({int i = 1}) {}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_functionDeclaration_parameter_named_default_null() async {
+ await analyze('''
+void f({int i = null}) {}
+''');
+
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_functionDeclaration_parameter_named_no_default() async {
+ await analyze('''
+void f({int i}) {}
+''');
+
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_functionDeclaration_parameter_named_no_default_required() async {
+ addMetaPackage();
+ await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
+ await analyze('''
+void f([int i = 1]) {}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_functionDeclaration_parameter_positionalOptional_default_null() async {
+ await analyze('''
+void f([int i = null]) {}
+''');
+
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_functionDeclaration_parameter_positionalOptional_no_default() async {
+ await analyze('''
+void f([int i]) {}
+''');
+
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_functionDeclaration_resets_unconditional_control_flow() async {
+ await analyze('''
+void f(bool b, int i, int j) {
+ assert(i != null);
+ if (b) return;
+ assert(j != null);
+}
+void g(int k) {
+ assert(k != null);
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ assertNoEdge(always, decoratedTypeAnnotation('int j').node);
+ assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
+ }
+
+ test_functionExpressionInvocation_parameterType() async {
+ await analyze('''
+abstract class C {
+ void Function(int) f();
+}
+void g(C c, int i) {
+ c.f()(i);
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int)').node,
+ hard: true);
+ }
+
+ test_functionExpressionInvocation_returnType() async {
+ await analyze('''
+abstract class C {
+ int Function() f();
+}
+int g(C c) => c.f()();
+''');
+ assertEdge(decoratedTypeAnnotation('int Function').node,
+ decoratedTypeAnnotation('int g').node,
+ hard: false);
+ }
+
+ test_functionInvocation_parameter_fromLocalParameter() async {
+ await analyze('''
+void f(int/*1*/ i) {}
+void test(int/*2*/ i) {
+ f(i/*3*/);
+}
+''');
+
+ var int_1 = decoratedTypeAnnotation('int/*1*/');
+ var int_2 = decoratedTypeAnnotation('int/*2*/');
+ var i_3 = checkExpression('i/*3*/');
+ assertNullCheck(i_3, assertEdge(int_2.node, int_1.node, hard: true));
+ assertEdge(int_2.node, int_1.node, hard: true);
+ }
+
+ test_functionInvocation_parameter_named() async {
+ await analyze('''
+void f({int i: 0}) {}
+void g(int j) {
+ f(i: j/*check*/);
+}
+''');
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_j = decoratedTypeAnnotation('int j').node;
+ assertNullCheck(checkExpression('j/*check*/'),
+ assertEdge(nullable_j, nullable_i, hard: true));
+ }
+
+ test_functionInvocation_parameter_named_missing() async {
+ await analyze('''
+void f({int i}) {}
+void g() {
+ f();
+}
+''');
+ var optional_i = possiblyOptionalParameter('int i');
+ expect(getEdges(always, optional_i), isNotEmpty);
+ }
+
+ test_functionInvocation_parameter_named_missing_required() async {
+ addMetaPackage();
+ verifyNoTestUnitErrors = false;
+ await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+void g() {
+ f();
+}
+''');
+ // The call at `f()` is presumed to be in error; no constraint is recorded.
+ var optional_i = possiblyOptionalParameter('int i');
+ expect(optional_i, isNull);
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ assertNoUpstreamNullability(nullable_i);
+ }
+
+ test_functionInvocation_parameter_null() async {
+ await analyze('''
+void f(int i) {}
+void test() {
+ f(null);
+}
+''');
+
+ assertNullCheck(checkExpression('null'),
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+ }
+
+ test_functionInvocation_return() async {
+ await analyze('''
+int/*1*/ f() => 0;
+int/*2*/ g() {
+ return (f());
+}
+''');
+
+ assertNullCheck(
+ checkExpression('(f())'),
+ assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+ decoratedTypeAnnotation('int/*2*/').node,
+ hard: false));
+ }
+
+ test_if_condition() async {
+ await analyze('''
+void f(bool b) {
+ if (b) {}
+}
+''');
+
+ assertNullCheck(checkExpression('b) {}'),
+ assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+ }
+
+ test_if_conditional_control_flow_after() async {
+ // Asserts after ifs don't demonstrate non-null intent.
+ // TODO(paulberry): if both branches complete normally, they should.
+ await analyze('''
+void f(bool b, int i) {
+ if (b) return;
+ assert(i != null);
+}
+''');
+
+ assertNoEdge(always, decoratedTypeAnnotation('int i').node);
+ }
+
+ test_if_conditional_control_flow_within() async {
+ // Asserts inside ifs don't demonstrate non-null intent.
+ await analyze('''
+void f(bool b, int i) {
+ if (b) {
+ assert(i != null);
+ } else {
+ assert(i != null);
+ }
+}
+''');
+
+ assertNoEdge(always, decoratedTypeAnnotation('int i').node);
+ }
+
+ test_if_guard_equals_null() async {
+ await analyze('''
+int f(int i, int j, int k) {
+ if (i == null) {
+ return j/*check*/;
+ } else {
+ return k/*check*/;
+ }
+}
+''');
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_j = decoratedTypeAnnotation('int j').node;
+ var nullable_k = decoratedTypeAnnotation('int k').node;
+ var nullable_return = decoratedTypeAnnotation('int f').node;
+ assertNullCheck(
+ checkExpression('j/*check*/'),
+ assertEdge(nullable_j, nullable_return,
+ guards: [nullable_i], hard: false));
+ assertNullCheck(checkExpression('k/*check*/'),
+ assertEdge(nullable_k, nullable_return, hard: false));
+ var discard = statementDiscard('if (i == null)');
+ expect(discard.trueGuard, same(nullable_i));
+ expect(discard.falseGuard, null);
+ expect(discard.pureCondition, true);
+ }
+
+ test_if_simple() async {
+ await analyze('''
+int f(bool b, int i, int j) {
+ if (b) {
+ return i/*check*/;
+ } else {
+ return j/*check*/;
+ }
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_j = decoratedTypeAnnotation('int j').node;
+ var nullable_return = decoratedTypeAnnotation('int f').node;
+ assertNullCheck(checkExpression('i/*check*/'),
+ assertEdge(nullable_i, nullable_return, hard: false));
+ assertNullCheck(checkExpression('j/*check*/'),
+ assertEdge(nullable_j, nullable_return, hard: false));
+ }
+
+ test_if_without_else() async {
+ await analyze('''
+int f(bool b, int i) {
+ if (b) {
+ return i/*check*/;
+ }
+ return 0;
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_return = decoratedTypeAnnotation('int f').node;
+ assertNullCheck(checkExpression('i/*check*/'),
+ assertEdge(nullable_i, nullable_return, hard: false));
+ }
+
+ test_indexExpression_index() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c, int j) => c[j];
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true);
+ }
+
+ test_indexExpression_index_cascaded() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+C f(C c, int j) => c..[j];
+''');
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: true);
+ }
+
+ test_indexExpression_return_type() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+ assertEdge(decoratedTypeAnnotation('int operator').node,
+ decoratedTypeAnnotation('int f').node,
+ hard: false);
+ }
+
+ test_indexExpression_target_check() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+ assertNullCheck(checkExpression('c['),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_indexExpression_target_check_cascaded() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+C f(C c) => c..[0];
+''');
+ assertNullCheck(checkExpression('c..['),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_indexExpression_target_demonstrates_non_null_intent() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+ }
+
+ test_indexExpression_target_demonstrates_non_null_intent_cascaded() async {
+ await analyze('''
+class C {
+ int operator[](int i) => 1;
+}
+C f(C c) => c..[0];
+''');
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+ }
+
+ test_instanceCreation_generic() async {
+ await analyze('''
+class C<T> {}
+C<int> f() => C<int>();
+''');
+ assertEdge(decoratedTypeAnnotation('int>(').node,
+ decoratedTypeAnnotation('int> f').node,
+ hard: false);
+ }
+
+ test_instanceCreation_generic_parameter() async {
+ await analyze('''
+class C<T> {
+ C(T t);
+}
+f(int i) => C<int>(i/*check*/);
+''');
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ 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;
+ 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,
+ assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
+ }
+
+ test_instanceCreation_parameter_named_optional() async {
+ await analyze('''
+class C {
+ C({int x = 0});
+}
+void f(int y) {
+ C(x: y);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int y').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
+ test_instanceCreation_parameter_positional_optional() async {
+ await analyze('''
+class C {
+ C([int x]);
+}
+void f(int y) {
+ C(y);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int y').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
+ test_instanceCreation_parameter_positional_required() async {
+ await analyze('''
+class C {
+ C(int x);
+}
+void f(int y) {
+ C(y);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int y').node,
+ decoratedTypeAnnotation('int x').node,
+ hard: true);
+ }
+
+ test_integerLiteral() async {
+ await analyze('''
+int f() {
+ return 0;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ @failingTest
+ test_isExpression_genericFunctionType() async {
+ await analyze('''
+bool f(a) => a is int Function(String);
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ }
+
+ test_isExpression_typeName_noTypeArguments() async {
+ await analyze('''
+bool f(a) => a is String;
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ }
+
+ @failingTest
+ test_isExpression_typeName_typeArguments() async {
+ await analyze('''
+bool f(a) => a is List<int>;
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ }
+
+ test_libraryDirective() async {
+ await analyze('''
+library foo;
+''');
+ // Passes if no exceptions are thrown.
+ }
+
+ @failingTest
+ test_listLiteral_noTypeArgument_noNullableElements() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+List<String> f() {
+ return ['a', 'b'];
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+ // TODO(brianwilkerson) Add an assertion that there is an edge from the list
+ // literal's fake type argument to the return type's type argument.
+ }
+
+ @failingTest
+ test_listLiteral_noTypeArgument_nullableElement() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+List<String> f() {
+ return ['a', null, 'c'];
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+ assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+ }
+
+ test_listLiteral_typeArgument_noNullableElements() async {
+ await analyze('''
+List<String> f() {
+ return <String>['a', 'b'];
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+ var typeArgForLiteral = decoratedTypeAnnotation('String>[').node;
+ var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
+ assertNoUpstreamNullability(typeArgForLiteral);
+ assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
+ }
+
+ test_listLiteral_typeArgument_nullableElement() async {
+ await analyze('''
+List<String> f() {
+ return <String>['a', null, 'c'];
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+ assertEdge(always, decoratedTypeAnnotation('String>[').node, hard: false);
+ }
+
+ test_localVariable_type_inferred() async {
+ await analyze('''
+int f() => 1;
+main() {
+ var x = f();
+}
+''');
+ var xType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+ }
+
+ test_method_parameterType_inferred() async {
+ await analyze('''
+class B {
+ void f/*B*/(int x) {}
+}
+class C extends B {
+ void f/*C*/(x) {}
+}
+''');
+ var bReturnType = decoratedMethodType('f/*B*/').positionalParameters[0];
+ var cReturnType = decoratedMethodType('f/*C*/').positionalParameters[0];
+ assertUnion(bReturnType.node, cReturnType.node);
+ }
+
+ test_method_parameterType_inferred_named() async {
+ await analyze('''
+class B {
+ void f/*B*/({int x = 0}) {}
+}
+class C extends B {
+ void f/*C*/({x = 0}) {}
+}
+''');
+ var bReturnType = decoratedMethodType('f/*B*/').namedParameters['x'];
+ var cReturnType = decoratedMethodType('f/*C*/').namedParameters['x'];
+ assertUnion(bReturnType.node, cReturnType.node);
+ }
+
+ test_method_returnType_inferred() async {
+ await analyze('''
+class B {
+ int f/*B*/() => 1;
+}
+class C extends B {
+ f/*C*/() => 1;
+}
+''');
+ var bReturnType = decoratedMethodType('f/*B*/').returnType;
+ var cReturnType = decoratedMethodType('f/*C*/').returnType;
+ assertUnion(bReturnType.node, cReturnType.node);
+ }
+
+ test_methodDeclaration_resets_unconditional_control_flow() async {
+ await analyze('''
+class C {
+ void f(bool b, int i, int j) {
+ assert(i != null);
+ if (b) return;
+ assert(j != null);
+ }
+ void g(int k) {
+ assert(k != null);
+ }
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ assertNoEdge(always, decoratedTypeAnnotation('int j').node);
+ assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
+ }
+
+ test_methodInvocation_parameter_contravariant() async {
+ await analyze('''
+class C<T> {
+ void f(T t) {}
+}
+void g(C<int> c, int i) {
+ c.f(i/*check*/);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ 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;
+ 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,
+ assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
+ }
+
+ test_methodInvocation_parameter_contravariant_from_migrated_class() async {
+ await analyze('''
+void f(List<int> x, int i) {
+ x.add(i/*check*/);
+}
+''');
+
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_list_t =
+ decoratedTypeAnnotation('List<int>').typeArguments[0].node;
+ var addMethod = findNode.methodInvocation('x.add').methodName.staticElement
+ as MethodMember;
+ var nullable_t = variables
+ .decoratedElementType(addMethod.baseElement)
+ .positionalParameters[0]
+ .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;
+ 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,
+ assertEdge(nullable_i, nullable_list_t_or_nullable_t, hard: true));
+ }
+
+ test_methodInvocation_parameter_contravariant_function() async {
+ await analyze('''
+void f<T>(T t) {}
+void g(int i) {
+ f<int>(i/*check*/);
+}
+''');
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ 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;
+ 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,
+ assertEdge(nullable_i, nullable_f_t_or_nullable_t, hard: true));
+ }
+
+ test_methodInvocation_parameter_generic() async {
+ await analyze('''
+class C<T> {}
+void f(C<int/*1*/>/*2*/ c) {}
+void g(C<int/*3*/>/*4*/ c) {
+ f(c/*check*/);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int/*3*/').node,
+ decoratedTypeAnnotation('int/*1*/').node,
+ hard: false);
+ assertNullCheck(
+ checkExpression('c/*check*/'),
+ assertEdge(decoratedTypeAnnotation('C<int/*3*/>/*4*/').node,
+ decoratedTypeAnnotation('C<int/*1*/>/*2*/').node,
+ hard: true));
+ }
+
+ test_methodInvocation_parameter_named() async {
+ await analyze('''
+class C {
+ void f({int i: 0}) {}
+}
+void g(C c, int j) {
+ c.f(i: j/*check*/);
+}
+''');
+ var nullable_i = decoratedTypeAnnotation('int i').node;
+ var nullable_j = decoratedTypeAnnotation('int j').node;
+ assertNullCheck(checkExpression('j/*check*/'),
+ assertEdge(nullable_j, nullable_i, hard: true));
+ }
+
+ test_methodInvocation_parameter_named_differentPackage() async {
+ addPackageFile('pkgC', 'c.dart', '''
+class C {
+ void f({int i}) {}
+}
+''');
+ await analyze('''
+import "package:pkgC/c.dart";
+void g(C c, int j) {
+ c.f(i: j/*check*/);
+}
+''');
+ var nullable_j = decoratedTypeAnnotation('int j');
+ assertNullCheck(checkExpression('j/*check*/'),
+ assertEdge(nullable_j.node, never, hard: true));
+ }
+
+ test_methodInvocation_resolves_to_getter() async {
+ await analyze('''
+abstract class C {
+ int/*1*/ Function(int/*2*/ i) get f;
+}
+int/*3*/ g(C c, int/*4*/ i) => c.f(i);
+''');
+ assertEdge(decoratedTypeAnnotation('int/*4*/').node,
+ decoratedTypeAnnotation('int/*2*/').node,
+ hard: true);
+ assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+ decoratedTypeAnnotation('int/*3*/').node,
+ hard: false);
+ }
+
+ test_methodInvocation_return_type() async {
+ await analyze('''
+class C {
+ bool m() => true;
+}
+bool f(C c) => c.m();
+''');
+ assertEdge(decoratedTypeAnnotation('bool m').node,
+ decoratedTypeAnnotation('bool f').node,
+ hard: false);
+ }
+
+ test_methodInvocation_return_type_generic_function() async {
+ await analyze('''
+T f<T>(T t) => t;
+int g() => (f<int>(1));
+''');
+ 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_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));
+ var nullable_return = decoratedTypeAnnotation('int g').node;
+ assertNullCheck(check_i,
+ assertEdge(nullable_f_t_or_nullable_t, nullable_return, hard: false));
+ }
+
+ test_methodInvocation_return_type_null_aware() async {
+ await analyze('''
+class C {
+ bool m() => true;
+}
+bool f(C c) => (c?.m());
+''');
+ var lubNode =
+ decoratedExpressionType('(c?.m())').node as NullabilityNodeForLUB;
+ expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+ expect(lubNode.right, same(decoratedTypeAnnotation('bool m').node));
+ assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
+ }
+
+ test_methodInvocation_target_check() async {
+ await analyze('''
+class C {
+ void m() {}
+}
+void test(C c) {
+ c.m();
+}
+''');
+
+ assertNullCheck(checkExpression('c.m'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_methodInvocation_target_check_cascaded() async {
+ await analyze('''
+class C {
+ void m() {}
+}
+void test(C c) {
+ c..m();
+}
+''');
+
+ assertNullCheck(checkExpression('c..m'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_methodInvocation_target_demonstrates_non_null_intent() async {
+ await analyze('''
+class C {
+ void m() {}
+}
+void test(C c) {
+ c.m();
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+ }
+
+ test_methodInvocation_target_demonstrates_non_null_intent_cascaded() async {
+ await analyze('''
+class C {
+ void m() {}
+}
+void test(C c) {
+ c..m();
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+ }
+
+ test_never() async {
+ await analyze('');
+
+ expect(never.isNullable, isFalse);
+ }
+
+ test_override_parameter_type_named() async {
+ await analyze('''
+abstract class Base {
+ void f({int/*1*/ i});
+}
+class Derived extends Base {
+ void f({int/*2*/ i}) {}
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int1.node, int2.node, hard: true);
+ }
+
+ test_override_parameter_type_named_over_none() async {
+ await analyze('''
+abstract class Base {
+ void f();
+}
+class Derived extends Base {
+ void f({int i}) {}
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_override_parameter_type_operator() async {
+ await analyze('''
+abstract class Base {
+ Base operator+(Base/*1*/ b);
+}
+class Derived extends Base {
+ Base operator+(Base/*2*/ b) => this;
+}
+''');
+ var base1 = decoratedTypeAnnotation('Base/*1*/');
+ var base2 = decoratedTypeAnnotation('Base/*2*/');
+ assertEdge(base1.node, base2.node, hard: true);
+ }
+
+ test_override_parameter_type_optional() async {
+ await analyze('''
+abstract class Base {
+ void f([int/*1*/ i]);
+}
+class Derived extends Base {
+ void f([int/*2*/ i]) {}
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int1.node, int2.node, hard: true);
+ }
+
+ test_override_parameter_type_optional_over_none() async {
+ await analyze('''
+abstract class Base {
+ void f();
+}
+class Derived extends Base {
+ void f([int i]) {}
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_override_parameter_type_optional_over_required() async {
+ await analyze('''
+abstract class Base {
+ void f(int/*1*/ i);
+}
+class Derived extends Base {
+ void f([int/*2*/ i]) {}
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int1.node, int2.node, hard: true);
+ }
+
+ test_override_parameter_type_required() async {
+ await analyze('''
+abstract class Base {
+ void f(int/*1*/ i);
+}
+class Derived extends Base {
+ void f(int/*2*/ i) {}
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int1.node, int2.node, hard: true);
+ }
+
+ test_override_parameter_type_setter() async {
+ await analyze('''
+abstract class Base {
+ void set x(int/*1*/ value);
+}
+class Derived extends Base {
+ void set x(int/*2*/ value) {}
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int1.node, int2.node, hard: true);
+ }
+
+ test_override_return_type_getter() async {
+ await analyze('''
+abstract class Base {
+ int/*1*/ get x;
+}
+class Derived extends Base {
+ int/*2*/ get x => null;
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int2.node, int1.node, hard: true);
+ }
+
+ test_override_return_type_method() async {
+ await analyze('''
+abstract class Base {
+ int/*1*/ f();
+}
+class Derived extends Base {
+ int/*2*/ f() => null;
+}
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int2.node, int1.node, hard: true);
+ }
+
+ test_override_return_type_operator() async {
+ await analyze('''
+abstract class Base {
+ Base/*1*/ operator-();
+}
+class Derived extends Base {
+ Derived/*2*/ operator-() => null;
+}
+''');
+ var base1 = decoratedTypeAnnotation('Base/*1*/');
+ var derived2 = decoratedTypeAnnotation('Derived/*2*/');
+ assertEdge(derived2.node, base1.node, hard: true);
+ }
+
+ test_parenthesizedExpression() async {
+ await analyze('''
+int f() {
+ return (null);
+}
+''');
+
+ assertNullCheck(checkExpression('(null)'),
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+ }
+
+ test_postfixExpression_minusMinus() async {
+ await analyze('''
+int f(int i) {
+ return i--;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i--');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
+ test_postfixExpression_plusPlus() async {
+ await analyze('''
+int f(int i) {
+ return i++;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i++');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
+ test_prefixedIdentifier_field_type() async {
+ await analyze('''
+class C {
+ bool b = true;
+}
+bool f(C c) => c.b;
+''');
+ assertEdge(decoratedTypeAnnotation('bool b').node,
+ decoratedTypeAnnotation('bool f').node,
+ hard: false);
+ }
+
+ test_prefixedIdentifier_getter_type() async {
+ await analyze('''
+class C {
+ bool get b => true;
+}
+bool f(C c) => c.b;
+''');
+ assertEdge(decoratedTypeAnnotation('bool get').node,
+ decoratedTypeAnnotation('bool f').node,
+ hard: false);
+ }
+
+ test_prefixedIdentifier_target_check() async {
+ await analyze('''
+class C {
+ int get x => 1;
+}
+void test(C c) {
+ c.x;
+}
+''');
+
+ assertNullCheck(checkExpression('c.x'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_prefixedIdentifier_target_demonstrates_non_null_intent() async {
+ await analyze('''
+class C {
+ int get x => 1;
+}
+void test(C c) {
+ c.x;
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+ }
+
+ test_prefixedIdentifier_tearoff() async {
+ await analyze('''
+abstract class C {
+ int f(int i);
+}
+int Function(int) g(C c) => c.f;
+''');
+ var fType = variables.decoratedElementType(findElement.method('f'));
+ var gReturnType =
+ variables.decoratedElementType(findElement.function('g')).returnType;
+ assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+ assertEdge(gReturnType.positionalParameters[0].node,
+ fType.positionalParameters[0].node,
+ hard: false);
+ }
+
+ test_prefixExpression_bang() async {
+ await analyze('''
+bool f(bool b) {
+ return !b;
+}
+''');
+
+ var nullable_b = decoratedTypeAnnotation('bool b').node;
+ var check_b = checkExpression('b;');
+ assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
+
+ var return_f = decoratedTypeAnnotation('bool f').node;
+ assertEdge(never, return_f, hard: false);
+ }
+
+ test_prefixExpression_minus() async {
+ await analyze('''
+abstract class C {
+ C operator-();
+}
+C test(C c) => -c/*check*/;
+''');
+ assertEdge(decoratedTypeAnnotation('C operator').node,
+ decoratedTypeAnnotation('C test').node,
+ hard: false);
+ assertNullCheck(checkExpression('c/*check*/'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_prefixExpression_minusMinus() async {
+ await analyze('''
+int f(int i) {
+ return --i;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i;');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
+ test_prefixExpression_plusPlus() async {
+ await analyze('''
+int f(int i) {
+ return ++i;
+}
+''');
+
+ var declaration = decoratedTypeAnnotation('int i').node;
+ var use = checkExpression('i;');
+ assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+ var returnType = decoratedTypeAnnotation('int f').node;
+ assertEdge(never, returnType, hard: false);
+ }
+
+ test_propertyAccess_return_type() async {
+ await analyze('''
+class C {
+ bool get b => true;
+}
+bool f(C c) => (c).b;
+''');
+ assertEdge(decoratedTypeAnnotation('bool get').node,
+ decoratedTypeAnnotation('bool f').node,
+ hard: false);
+ }
+
+ test_propertyAccess_return_type_null_aware() async {
+ await analyze('''
+class C {
+ bool get b => true;
+}
+bool f(C c) => (c?.b);
+''');
+ var lubNode =
+ decoratedExpressionType('(c?.b)').node as NullabilityNodeForLUB;
+ expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+ expect(lubNode.right, same(decoratedTypeAnnotation('bool get b').node));
+ assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
+ }
+
+ test_propertyAccess_target_check() async {
+ await analyze('''
+class C {
+ int get x => 1;
+}
+void test(C c) {
+ (c).x;
+}
+''');
+
+ assertNullCheck(checkExpression('c).x'),
+ assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+ }
+
+ test_redirecting_constructor_factory() async {
+ await analyze('''
+class C {
+ factory C(int/*1*/ i, {int/*2*/ j}) = D;
+}
+class D implements C {
+ D(int/*3*/ i, {int/*4*/ j});
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+ decoratedTypeAnnotation('int/*3*/').node,
+ hard: true);
+ assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+ decoratedTypeAnnotation('int/*4*/').node,
+ hard: true);
+ }
+
+ test_redirecting_constructor_factory_from_generic_to_generic() async {
+ await analyze('''
+class C<T> {
+ factory C(T/*1*/ t) = D<T/*2*/>;
+}
+class D<U> implements C<U> {
+ D(U/*3*/ u);
+}
+''');
+ var nullable_t1 = decoratedTypeAnnotation('T/*1*/').node;
+ var nullable_t2 = decoratedTypeAnnotation('T/*2*/').node;
+ var nullable_u3 = decoratedTypeAnnotation('U/*3*/').node;
+ var nullable_t2_or_nullable_u3 = graph
+ .getDownstreamEdges(nullable_t1)
+ .single
+ .destinationNode as NullabilityNodeForSubstitution;
+ expect(nullable_t2_or_nullable_u3.innerNode, same(nullable_t2));
+ expect(nullable_t2_or_nullable_u3.outerNode, same(nullable_u3));
+ assertEdge(nullable_t1, nullable_t2_or_nullable_u3, hard: true);
+ }
+
+ test_redirecting_constructor_factory_to_generic() async {
+ await analyze('''
+class C {
+ factory C(int/*1*/ i) = D<int/*2*/>;
+}
+class D<T> implements C {
+ D(T/*3*/ i);
+}
+''');
+ var nullable_i1 = decoratedTypeAnnotation('int/*1*/').node;
+ var nullable_i2 = decoratedTypeAnnotation('int/*2*/').node;
+ var nullable_t3 = decoratedTypeAnnotation('T/*3*/').node;
+ var nullable_i2_or_nullable_t3 = graph
+ .getDownstreamEdges(nullable_i1)
+ .single
+ .destinationNode as NullabilityNodeForSubstitution;
+ expect(nullable_i2_or_nullable_t3.innerNode, same(nullable_i2));
+ expect(nullable_i2_or_nullable_t3.outerNode, same(nullable_t3));
+ assertEdge(nullable_i1, nullable_i2_or_nullable_t3, hard: true);
+ }
+
+ test_redirecting_constructor_ordinary() async {
+ await analyze('''
+class C {
+ C(int/*1*/ i, int/*2*/ j) : this.named(j, i);
+ C.named(int/*3*/ j, int/*4*/ i);
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+ decoratedTypeAnnotation('int/*4*/').node,
+ hard: true);
+ assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+ decoratedTypeAnnotation('int/*3*/').node,
+ hard: true);
+ }
+
+ test_return_from_async_future() async {
+ await analyze('''
+Future<int> f() async {
+ return g();
+}
+int g() => 1;
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_return_from_async_futureOr() async {
+ await analyze('''
+import 'dart:async';
+FutureOr<int> f() async {
+ return g();
+}
+int g() => 1;
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
+ test_return_function_type_simple() async {
+ await analyze('''
+int/*1*/ Function() f(int/*2*/ Function() x) => x;
+''');
+ var int1 = decoratedTypeAnnotation('int/*1*/');
+ var int2 = decoratedTypeAnnotation('int/*2*/');
+ assertEdge(int2.node, int1.node, hard: true);
+ }
+
+ test_return_implicit_null() async {
+ verifyNoTestUnitErrors = false;
+ await analyze('''
+int f() {
+ return;
+}
+''');
+
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_return_null() async {
+ await analyze('''
+int f() {
+ return null;
+}
+''');
+
+ assertNullCheck(checkExpression('null'),
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+ }
+
+ test_return_null_generic() async {
+ await analyze('''
+class C<T> {
+ T f() {
+ return null;
+ }
+}
+''');
+ var tNode = decoratedTypeAnnotation('T f').node;
+ assertEdge(always, tNode, hard: false);
+ assertNullCheck(
+ checkExpression('null'), assertEdge(always, tNode, hard: false));
+ }
+
+ @failingTest
+ test_setOrMapLiteral_map_noTypeArgument_noNullableKeysAndValues() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Map<String, int> f() {
+ return {'a' : 1, 'b' : 2};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ // TODO(brianwilkerson) Add an assertion that there is an edge from the set
+ // literal's fake type argument to the return type's type argument.
+ }
+
+ @failingTest
+ test_setOrMapLiteral_map_noTypeArgument_nullableKey() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Map<String, int> f() {
+ return {'a' : 1, null : 2, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ @failingTest
+ test_setOrMapLiteral_map_noTypeArgument_nullableKeyAndValue() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Map<String, int> f() {
+ return {'a' : 1, null : null, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ @failingTest
+ test_setOrMapLiteral_map_noTypeArgument_nullableValue() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Map<String, int> f() {
+ return {'a' : 1, 'b' : null, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_setOrMapLiteral_map_typeArguments_noNullableKeysAndValues() async {
+ await analyze('''
+Map<String, int> f() {
+ return <String, int>{'a' : 1, 'b' : 2};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+
+ var keyForLiteral = decoratedTypeAnnotation('String, int>{').node;
+ var keyForReturnType = decoratedTypeAnnotation('String, int> ').node;
+ assertNoUpstreamNullability(keyForLiteral);
+ assertEdge(keyForLiteral, keyForReturnType, hard: false);
+
+ var valueForLiteral = decoratedTypeAnnotation('int>{').node;
+ var valueForReturnType = decoratedTypeAnnotation('int> ').node;
+ assertNoUpstreamNullability(valueForLiteral);
+ assertEdge(valueForLiteral, valueForReturnType, hard: false);
+ }
+
+ test_setOrMapLiteral_map_typeArguments_nullableKey() async {
+ await analyze('''
+Map<String, int> f() {
+ return <String, int>{'a' : 1, null : 2, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
+ hard: false);
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int>{').node);
+ }
+
+ test_setOrMapLiteral_map_typeArguments_nullableKeyAndValue() async {
+ await analyze('''
+Map<String, int> f() {
+ return <String, int>{'a' : 1, null : null, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
+ hard: false);
+ assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
+ }
+
+ test_setOrMapLiteral_map_typeArguments_nullableValue() async {
+ await analyze('''
+Map<String, int> f() {
+ return <String, int>{'a' : 1, 'b' : null, 'c' : 3};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+ assertNoUpstreamNullability(decoratedTypeAnnotation('String, int>{').node);
+ assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
+ }
+
+ @failingTest
+ test_setOrMapLiteral_set_noTypeArgument_noNullableElements() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Set<String> f() {
+ return {'a', 'b'};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+ // TODO(brianwilkerson) Add an assertion that there is an edge from the set
+ // literal's fake type argument to the return type's type argument.
+ }
+
+ @failingTest
+ test_setOrMapLiteral_set_noTypeArgument_nullableElement() async {
+ // Failing because we're not yet handling collection literals without a
+ // type argument.
+ await analyze('''
+Set<String> f() {
+ return {'a', null, 'c'};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+ assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+ }
+
+ test_setOrMapLiteral_set_typeArgument_noNullableElements() async {
+ await analyze('''
+Set<String> f() {
+ return <String>{'a', 'b'};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+ var typeArgForLiteral = decoratedTypeAnnotation('String>{').node;
+ var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
+ assertNoUpstreamNullability(typeArgForLiteral);
+ assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
+ }
+
+ test_setOrMapLiteral_set_typeArgument_nullableElement() async {
+ await analyze('''
+Set<String> f() {
+ return <String>{'a', null, 'c'};
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+ assertEdge(always, decoratedTypeAnnotation('String>{').node, hard: false);
+ }
+
+ test_simpleIdentifier_function() async {
+ await analyze('''
+int f() => null;
+main() {
+ int Function() g = f;
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int f').node,
+ decoratedTypeAnnotation('int Function').node,
+ hard: false);
+ }
+
+ test_simpleIdentifier_local() async {
+ await analyze('''
+main() {
+ int i = 0;
+ int j = i;
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int j').node,
+ hard: true);
+ }
+
+ test_simpleIdentifier_tearoff_function() async {
+ await analyze('''
+int f(int i) => 0;
+int Function(int) g() => f;
+''');
+ var fType = variables.decoratedElementType(findElement.function('f'));
+ var gReturnType =
+ variables.decoratedElementType(findElement.function('g')).returnType;
+ assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+ assertEdge(gReturnType.positionalParameters[0].node,
+ fType.positionalParameters[0].node,
+ hard: false);
+ }
+
+ test_simpleIdentifier_tearoff_method() async {
+ await analyze('''
+abstract class C {
+ int f(int i);
+ int Function(int) g() => f;
+}
+''');
+ var fType = variables.decoratedElementType(findElement.method('f'));
+ var gReturnType =
+ variables.decoratedElementType(findElement.method('g')).returnType;
+ assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+ assertEdge(gReturnType.positionalParameters[0].node,
+ fType.positionalParameters[0].node,
+ hard: false);
+ }
+
+ test_skipDirectives() async {
+ await analyze('''
+import "dart:core" as one;
+main() {}
+''');
+ // No test expectations.
+ // Just verifying that the test passes
+ }
+
+ test_soft_edge_for_non_variable_reference() async {
+ // Edges originating in things other than variable references should be
+ // soft.
+ await analyze('''
+int f() => null;
+''');
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+ }
+
+ test_stringLiteral() async {
+ // TODO(paulberry): also test string interpolations
+ await analyze('''
+String f() {
+ return 'x';
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
+ }
+
+ test_superExpression() async {
+ await analyze('''
+class C {
+ C f() => super;
+}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
+ }
+
+ test_symbolLiteral() async {
+ await analyze('''
+Symbol f() {
+ return #symbol;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Symbol').node);
+ }
+
+ test_thisExpression() async {
+ await analyze('''
+class C {
+ C f() => this;
+}
+''');
+
+ assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
+ }
+
+ test_throwExpression() async {
+ await analyze('''
+int f() {
+ return throw null;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+ }
+
+ test_topLevelSetter() async {
+ await analyze('''
+void set x(int value) {}
+main() { x = 1; }
+''');
+ var setXType = decoratedTypeAnnotation('int value');
+ assertEdge(never, setXType.node, hard: false);
+ }
+
+ test_topLevelSetter_nullable() async {
+ await analyze('''
+void set x(int value) {}
+main() { x = null; }
+''');
+ var setXType = decoratedTypeAnnotation('int value');
+ assertEdge(always, setXType.node, hard: false);
+ }
+
+ test_topLevelVar_reference() async {
+ await analyze('''
+double pi = 3.1415;
+double get myPi => pi;
+''');
+ var piType = decoratedTypeAnnotation('double pi');
+ var myPiType = decoratedTypeAnnotation('double get');
+ assertEdge(piType.node, myPiType.node, hard: false);
+ }
+
+ test_topLevelVar_reference_differentPackage() async {
+ addPackageFile('pkgPi', 'piConst.dart', '''
+double pi = 3.1415;
+''');
+ await analyze('''
+import "package:pkgPi/piConst.dart";
+double get myPi => pi;
+''');
+ var myPiType = decoratedTypeAnnotation('double get');
+ assertEdge(never, myPiType.node, hard: false);
+ }
+
+ test_topLevelVariable_type_inferred() async {
+ await analyze('''
+int f() => 1;
+var x = f();
+''');
+ var xType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+ }
+
+ test_type_argument_explicit_bound() async {
+ await analyze('''
+class C<T extends Object> {}
+void f(C<int> c) {}
+''');
+ assertEdge(decoratedTypeAnnotation('int>').node,
+ decoratedTypeAnnotation('Object>').node,
+ hard: true);
+ }
+
+ test_type_parameterized_migrated_bound_class() async {
+ await analyze('''
+import 'dart:math';
+void f(Point<int> x) {}
+''');
+ var pointClass =
+ findNode.typeName('Point').name.staticElement as ClassElement;
+ var pointBound =
+ variables.decoratedElementType(pointClass.typeParameters[0]);
+ expect(pointBound.type.toString(), 'num');
+ assertEdge(decoratedTypeAnnotation('int>').node, pointBound.node,
+ hard: true);
+ }
+
+ test_type_parameterized_migrated_bound_dynamic() async {
+ await analyze('''
+void f(List<int> x) {}
+''');
+ var listClass = typeProvider.listType.element;
+ var listBound = variables.decoratedElementType(listClass.typeParameters[0]);
+ expect(listBound.type.toString(), 'dynamic');
+ assertEdge(decoratedTypeAnnotation('int>').node, listBound.node,
+ hard: true);
+ }
+
+ test_typeName() async {
+ await analyze('''
+Type f() {
+ return int;
+}
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
+ }
+
+ test_typeName_union_with_bound() async {
+ await analyze('''
+class C<T extends Object> {}
+void f(C c) {}
+''');
+ var cType = decoratedTypeAnnotation('C c');
+ var cBound = decoratedTypeAnnotation('Object');
+ assertUnion(cType.typeArguments[0].node, cBound.node);
+ }
+
+ test_typeName_union_with_bound_function_type() async {
+ await analyze('''
+class C<T extends int Function()> {}
+void f(C c) {}
+''');
+ var cType = decoratedTypeAnnotation('C c');
+ var cBound = decoratedGenericFunctionTypeAnnotation('int Function()');
+ assertUnion(cType.typeArguments[0].node, cBound.node);
+ assertUnion(cType.typeArguments[0].returnType.node, cBound.returnType.node);
+ }
+
+ test_typeName_union_with_bounds() async {
+ await analyze('''
+class C<T extends Object, U extends Object> {}
+void f(C c) {}
+''');
+ var cType = decoratedTypeAnnotation('C c');
+ var tBound = decoratedTypeAnnotation('Object,');
+ var uBound = decoratedTypeAnnotation('Object>');
+ assertUnion(cType.typeArguments[0].node, tBound.node);
+ assertUnion(cType.typeArguments[1].node, uBound.node);
+ }
+
+ test_variableDeclaration() async {
+ await analyze('''
+void f(int i) {
+ int j = i;
+}
+''');
+ assertEdge(decoratedTypeAnnotation('int i').node,
+ decoratedTypeAnnotation('int j').node,
+ hard: true);
+ }
+}
diff --git a/pkg/nnbd_migration/test/graph_builder_test.dart b/pkg/nnbd_migration/test/graph_builder_test.dart
deleted file mode 100644
index f3a938e..0000000
--- a/pkg/nnbd_migration/test/graph_builder_test.dart
+++ /dev/null
@@ -1,1706 +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:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/graph_builder.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'migration_visitor_test_base.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(GraphBuilderTest);
- });
-}
-
-@reflectiveTest
-class GraphBuilderTest extends MigrationVisitorTestBase {
- /// Analyzes the given source code, producing constraint variables and
- /// constraints for it.
- @override
- Future<CompilationUnit> analyze(String code) async {
- var unit = await super.analyze(code);
- unit.accept(GraphBuilder(typeProvider, variables, graph, testSource, null));
- return unit;
- }
-
- void assertConditional(
- NullabilityNode node, NullabilityNode left, NullabilityNode right) {
- var conditionalNode = node as NullabilityNodeForLUB;
- expect(conditionalNode.left, same(left));
- expect(conditionalNode.right, same(right));
- }
-
- /// Checks that there are no nullability nodes upstream from [node] that could
- /// cause it to become nullable.
- void assertNoUpstreamNullability(NullabilityNode node) {
- // never can never become nullable, even if it has nodes
- // upstream from it.
- if (node == never) return;
-
- for (var edge in graph.getUpstreamEdges(node)) {
- expect(edge.primarySource, never);
- }
- }
-
- /// Verifies that a null check will occur when the given edge is unsatisfied.
- ///
- /// [expressionChecks] is the object tracking whether or not a null check is
- /// needed.
- void assertNullCheck(
- ExpressionChecks expressionChecks, NullabilityEdge expectedEdge) {
- expect(expressionChecks.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) {
- return variables.checkExpression(findNode.expression(text));
- }
-
- /// Gets the [DecoratedType] associated with the expression whose text
- /// representation is [text], or `null` if the expression has no
- /// [DecoratedType] associated with it.
- DecoratedType decoratedExpressionType(String text) {
- return variables.decoratedExpressionType(findNode.expression(text));
- }
-
- test_assert_demonstrates_non_null_intent() async {
- await analyze('''
-void f(int i) {
- assert(i != null);
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
- }
-
- test_assignmentExpression_field() async {
- await analyze('''
-class C {
- int x = 0;
-}
-void f(C c, int i) {
- c.x = i;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int x').node,
- hard: true);
- }
-
- test_assignmentExpression_field_cascaded() async {
- await analyze('''
-class C {
- int x = 0;
-}
-void f(C c, int i) {
- c..x = i;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int x').node,
- hard: true);
- }
-
- test_assignmentExpression_field_target_check() async {
- await analyze('''
-class C {
- int x = 0;
-}
-void f(C c, int i) {
- c.x = i;
-}
-''');
- assertNullCheck(checkExpression('c.x'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_assignmentExpression_field_target_check_cascaded() async {
- await analyze('''
-class C {
- int x = 0;
-}
-void f(C c, int i) {
- c..x = i;
-}
-''');
- assertNullCheck(checkExpression('c..x'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_assignmentExpression_indexExpression_index() async {
- await analyze('''
-class C {
- void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
- c[i] = j;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int a').node,
- hard: true);
- }
-
- test_assignmentExpression_indexExpression_return_value() async {
- await analyze('''
-class C {
- void operator[]=(int a, int b) {}
-}
-int f(C c, int i, int j) => c[i] = j;
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int f').node,
- hard: false);
- }
-
- test_assignmentExpression_indexExpression_target_check() async {
- await analyze('''
-class C {
- void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
- c[i] = j;
-}
-''');
- assertNullCheck(checkExpression('c['),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_assignmentExpression_indexExpression_value() async {
- await analyze('''
-class C {
- void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
- c[i] = j;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int b').node,
- hard: true);
- }
-
- test_assignmentExpression_operands() async {
- await analyze('''
-void f(int i, int j) {
- i = j;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int i').node,
- hard: true);
- }
-
- test_assignmentExpression_return_value() async {
- await analyze('''
-void f(int i, int j) {
- g(i = j);
-}
-void g(int k) {}
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int k').node,
- hard: false);
- }
-
- test_assignmentExpression_setter() async {
- await analyze('''
-class C {
- void set s(int value) {}
-}
-void f(C c, int i) {
- c.s = i;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int value').node,
- hard: true);
- }
-
- test_assignmentExpression_setter_null_aware() async {
- await analyze('''
-class C {
- void set s(int value) {}
-}
-int f(C c, int i) => (c?.s = i);
-''');
- var lubNode =
- decoratedExpressionType('(c?.s = i)').node as NullabilityNodeForLUB;
- expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
- expect(lubNode.right, same(decoratedTypeAnnotation('int i').node));
- assertEdge(lubNode, decoratedTypeAnnotation('int f').node, hard: false);
- }
-
- test_assignmentExpression_setter_target_check() async {
- await analyze('''
-class C {
- void set s(int value) {}
-}
-void f(C c, int i) {
- c.s = i;
-}
-''');
- assertNullCheck(checkExpression('c.s'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- @failingTest
- test_awaitExpression_future_nonNullable() async {
- await analyze('''
-Future<void> f() async {
- int x = await g();
-}
-Future<int> g() async => 3;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- @failingTest
- test_awaitExpression_future_nullable() async {
- await analyze('''
-Future<void> f() async {
- int x = await g();
-}
-Future<int> g() async => null;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_awaitExpression_nonFuture() async {
- await analyze('''
-Future<void> f() async {
- int x = await 3;
-}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_binaryExpression_ampersand_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i & j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_bar_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i | j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_caret_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i ^ j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_equal() async {
- await analyze('''
-bool f(int i, int j) => i == j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_gt_result_not_null() async {
- await analyze('''
-bool f(int i, int j) => i > j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_gtEq_result_not_null() async {
- await analyze('''
-bool f(int i, int j) => i >= j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_gtGt_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i >> j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_lt_result_not_null() async {
- await analyze('''
-bool f(int i, int j) => i < j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_ltEq_result_not_null() async {
- await analyze('''
-bool f(int i, int j) => i <= j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_ltLt_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i << j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_minus_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i - j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_notEqual() async {
- await analyze('''
-bool f(int i, int j) => i != j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
- }
-
- test_binaryExpression_percent_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i % j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_plus_left_check() async {
- await analyze('''
-int f(int i, int j) => i + j;
-''');
-
- assertNullCheck(checkExpression('i +'),
- assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true));
- }
-
- test_binaryExpression_plus_left_check_custom() async {
- await analyze('''
-class Int {
- Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => i + j;
-''');
-
- assertNullCheck(checkExpression('i +'),
- assertEdge(decoratedTypeAnnotation('Int i').node, never, hard: true));
- }
-
- test_binaryExpression_plus_result_custom() async {
- await analyze('''
-class Int {
- Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => (i + j);
-''');
-
- assertNullCheck(
- checkExpression('(i + j)'),
- assertEdge(decoratedTypeAnnotation('Int operator+').node,
- decoratedTypeAnnotation('Int f').node,
- hard: false));
- }
-
- test_binaryExpression_plus_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i + j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_plus_right_check() async {
- await analyze('''
-int f(int i, int j) => i + j;
-''');
-
- assertNullCheck(checkExpression('j;'),
- assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true));
- }
-
- test_binaryExpression_plus_right_check_custom() async {
- await analyze('''
-class Int {
- Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => i + j/*check*/;
-''');
-
- assertNullCheck(
- checkExpression('j/*check*/'),
- assertEdge(decoratedTypeAnnotation('Int j').node,
- decoratedTypeAnnotation('Int other').node,
- hard: true));
- }
-
- test_binaryExpression_slash_result_not_null() async {
- await analyze('''
-double f(int i, int j) => i / j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('double f').node);
- }
-
- test_binaryExpression_star_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i * j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_binaryExpression_tildeSlash_result_not_null() async {
- await analyze('''
-int f(int i, int j) => i ~/ j;
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
- }
-
- test_boolLiteral() async {
- await analyze('''
-bool f() {
- return true;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
- }
-
- test_cascadeExpression() async {
- await analyze('''
-class C {
- int x = 0;
-}
-C f(C c, int i) => c..x = i;
-''');
- assertEdge(decoratedTypeAnnotation('C c').node,
- decoratedTypeAnnotation('C f').node,
- hard: false);
- }
-
- test_conditionalExpression_condition_check() async {
- await analyze('''
-int f(bool b, int i, int j) {
- return (b ? i : j);
-}
-''');
-
- var nullable_b = decoratedTypeAnnotation('bool b').node;
- var check_b = checkExpression('b ?');
- assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
- }
-
- test_conditionalExpression_general() async {
- await analyze('''
-int f(bool b, int i, int j) {
- return (b ? i : j);
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_j = decoratedTypeAnnotation('int j').node;
- var nullable_conditional = decoratedExpressionType('(b ?').node;
- assertConditional(nullable_conditional, nullable_i, nullable_j);
- var nullable_return = decoratedTypeAnnotation('int f').node;
- assertNullCheck(checkExpression('(b ? i : j)'),
- assertEdge(nullable_conditional, nullable_return, hard: false));
- }
-
- test_conditionalExpression_left_non_null() async {
- await analyze('''
-int f(bool b, int i) {
- return (b ? (throw i) : i);
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_conditional =
- decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
- var nullable_throw = nullable_conditional.left;
- assertNoUpstreamNullability(nullable_throw);
- assertConditional(nullable_conditional, nullable_throw, nullable_i);
- }
-
- test_conditionalExpression_left_null() async {
- await analyze('''
-int f(bool b, int i) {
- return (b ? null : i);
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_conditional = decoratedExpressionType('(b ?').node;
- assertConditional(nullable_conditional, always, nullable_i);
- }
-
- test_conditionalExpression_right_non_null() async {
- await analyze('''
-int f(bool b, int i) {
- return (b ? i : (throw i));
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_conditional =
- decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
- var nullable_throw = nullable_conditional.right;
- assertNoUpstreamNullability(nullable_throw);
- assertConditional(nullable_conditional, nullable_i, nullable_throw);
- }
-
- test_conditionalExpression_right_null() async {
- await analyze('''
-int f(bool b, int i) {
- return (b ? i : null);
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_conditional = decoratedExpressionType('(b ?').node;
- assertConditional(nullable_conditional, nullable_i, always);
- }
-
- test_doubleLiteral() async {
- await analyze('''
-double f() {
- return 1.0;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
- }
-
- test_functionDeclaration_expression_body() async {
- await analyze('''
-int/*1*/ f(int/*2*/ i) => i/*3*/;
-''');
-
- assertNullCheck(
- checkExpression('i/*3*/'),
- assertEdge(decoratedTypeAnnotation('int/*2*/').node,
- decoratedTypeAnnotation('int/*1*/').node,
- hard: true));
- }
-
- test_functionDeclaration_parameter_named_default_notNull() async {
- await analyze('''
-void f({int i = 1}) {}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_functionDeclaration_parameter_named_default_null() async {
- await analyze('''
-void f({int i = null}) {}
-''');
-
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_functionDeclaration_parameter_named_no_default() async {
- await analyze('''
-void f({int i}) {}
-''');
-
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_functionDeclaration_parameter_named_no_default_required() async {
- addMetaPackage();
- await analyze('''
-import 'package:meta/meta.dart';
-void f({@required int i}) {}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
- await analyze('''
-void f([int i = 1]) {}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_functionDeclaration_parameter_positionalOptional_default_null() async {
- await analyze('''
-void f([int i = null]) {}
-''');
-
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_functionDeclaration_parameter_positionalOptional_no_default() async {
- await analyze('''
-void f([int i]) {}
-''');
-
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_functionDeclaration_resets_unconditional_control_flow() async {
- await analyze('''
-void f(bool b, int i, int j) {
- assert(i != null);
- if (b) return;
- assert(j != null);
-}
-void g(int k) {
- assert(k != null);
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
- assertNoEdge(always, decoratedTypeAnnotation('int j').node);
- assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
- }
-
- test_functionInvocation_parameter_fromLocalParameter() async {
- await analyze('''
-void f(int/*1*/ i) {}
-void test(int/*2*/ i) {
- f(i/*3*/);
-}
-''');
-
- var int_1 = decoratedTypeAnnotation('int/*1*/');
- var int_2 = decoratedTypeAnnotation('int/*2*/');
- var i_3 = checkExpression('i/*3*/');
- assertNullCheck(i_3, assertEdge(int_2.node, int_1.node, hard: true));
- assertEdge(int_2.node, int_1.node, hard: true);
- }
-
- test_functionInvocation_parameter_named() async {
- await analyze('''
-void f({int i: 0}) {}
-void g(int j) {
- f(i: j/*check*/);
-}
-''');
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_j = decoratedTypeAnnotation('int j').node;
- assertNullCheck(checkExpression('j/*check*/'),
- assertEdge(nullable_j, nullable_i, hard: true));
- }
-
- test_functionInvocation_parameter_named_missing() async {
- await analyze('''
-void f({int i}) {}
-void g() {
- f();
-}
-''');
- var optional_i = possiblyOptionalParameter('int i');
- expect(getEdges(always, optional_i), isNotEmpty);
- }
-
- test_functionInvocation_parameter_named_missing_required() async {
- addMetaPackage();
- verifyNoTestUnitErrors = false;
- await analyze('''
-import 'package:meta/meta.dart';
-void f({@required int i}) {}
-void g() {
- f();
-}
-''');
- // The call at `f()` is presumed to be in error; no constraint is recorded.
- var optional_i = possiblyOptionalParameter('int i');
- expect(optional_i, isNull);
- var nullable_i = decoratedTypeAnnotation('int i').node;
- assertNoUpstreamNullability(nullable_i);
- }
-
- test_functionInvocation_parameter_null() async {
- await analyze('''
-void f(int i) {}
-void test() {
- f(null);
-}
-''');
-
- assertNullCheck(checkExpression('null'),
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
- }
-
- test_functionInvocation_return() async {
- await analyze('''
-int/*1*/ f() => 0;
-int/*2*/ g() {
- return (f());
-}
-''');
-
- assertNullCheck(
- checkExpression('(f())'),
- assertEdge(decoratedTypeAnnotation('int/*1*/').node,
- decoratedTypeAnnotation('int/*2*/').node,
- hard: false));
- }
-
- test_if_condition() async {
- await analyze('''
-void f(bool b) {
- if (b) {}
-}
-''');
-
- assertNullCheck(checkExpression('b) {}'),
- assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
- }
-
- test_if_conditional_control_flow_after() async {
- // Asserts after ifs don't demonstrate non-null intent.
- // TODO(paulberry): if both branches complete normally, they should.
- await analyze('''
-void f(bool b, int i) {
- if (b) return;
- assert(i != null);
-}
-''');
-
- assertNoEdge(always, decoratedTypeAnnotation('int i').node);
- }
-
- test_if_conditional_control_flow_within() async {
- // Asserts inside ifs don't demonstrate non-null intent.
- await analyze('''
-void f(bool b, int i) {
- if (b) {
- assert(i != null);
- } else {
- assert(i != null);
- }
-}
-''');
-
- assertNoEdge(always, decoratedTypeAnnotation('int i').node);
- }
-
- test_if_guard_equals_null() async {
- await analyze('''
-int f(int i, int j, int k) {
- if (i == null) {
- return j/*check*/;
- } else {
- return k/*check*/;
- }
-}
-''');
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_j = decoratedTypeAnnotation('int j').node;
- var nullable_k = decoratedTypeAnnotation('int k').node;
- var nullable_return = decoratedTypeAnnotation('int f').node;
- assertNullCheck(
- checkExpression('j/*check*/'),
- assertEdge(nullable_j, nullable_return,
- guards: [nullable_i], hard: false));
- assertNullCheck(checkExpression('k/*check*/'),
- assertEdge(nullable_k, nullable_return, hard: false));
- var discard = statementDiscard('if (i == null)');
- expect(discard.trueGuard, same(nullable_i));
- expect(discard.falseGuard, null);
- expect(discard.pureCondition, true);
- }
-
- test_if_simple() async {
- await analyze('''
-int f(bool b, int i, int j) {
- if (b) {
- return i/*check*/;
- } else {
- return j/*check*/;
- }
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_j = decoratedTypeAnnotation('int j').node;
- var nullable_return = decoratedTypeAnnotation('int f').node;
- assertNullCheck(checkExpression('i/*check*/'),
- assertEdge(nullable_i, nullable_return, hard: false));
- assertNullCheck(checkExpression('j/*check*/'),
- assertEdge(nullable_j, nullable_return, hard: false));
- }
-
- test_if_without_else() async {
- await analyze('''
-int f(bool b, int i) {
- if (b) {
- return i/*check*/;
- }
- return 0;
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_return = decoratedTypeAnnotation('int f').node;
- assertNullCheck(checkExpression('i/*check*/'),
- assertEdge(nullable_i, nullable_return, hard: false));
- }
-
- test_indexExpression_index() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-int f(C c, int j) => c[j];
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int i').node,
- hard: true);
- }
-
- test_indexExpression_index_cascaded() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-C f(C c, int j) => c..[j];
-''');
- assertEdge(decoratedTypeAnnotation('int j').node,
- decoratedTypeAnnotation('int i').node,
- hard: true);
- }
-
- test_indexExpression_return_type() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
- assertEdge(decoratedTypeAnnotation('int operator').node,
- decoratedTypeAnnotation('int f').node,
- hard: false);
- }
-
- test_indexExpression_target_check() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
- assertNullCheck(checkExpression('c['),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_indexExpression_target_check_cascaded() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-C f(C c) => c..[0];
-''');
- assertNullCheck(checkExpression('c..['),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_indexExpression_target_demonstrates_non_null_intent() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
- }
-
- test_indexExpression_target_demonstrates_non_null_intent_cascaded() async {
- await analyze('''
-class C {
- int operator[](int i) => 1;
-}
-C f(C c) => c..[0];
-''');
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
- }
-
- test_instanceCreation_parameter_named_optional() async {
- await analyze('''
-class C {
- C({int x = 0});
-}
-void f(int y) {
- C(x: y);
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int y').node,
- decoratedTypeAnnotation('int x').node,
- hard: true);
- }
-
- test_instanceCreation_parameter_positional_optional() async {
- await analyze('''
-class C {
- C([int x]);
-}
-void f(int y) {
- C(y);
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int y').node,
- decoratedTypeAnnotation('int x').node,
- hard: true);
- }
-
- test_instanceCreation_parameter_positional_required() async {
- await analyze('''
-class C {
- C(int x);
-}
-void f(int y) {
- C(y);
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int y').node,
- decoratedTypeAnnotation('int x').node,
- hard: true);
- }
-
- test_integerLiteral() async {
- await analyze('''
-int f() {
- return 0;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- @failingTest
- test_isExpression_genericFunctionType() async {
- await analyze('''
-bool f(a) => a is int Function(String);
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
- }
-
- test_isExpression_typeName_noTypeArguments() async {
- await analyze('''
-bool f(a) => a is String;
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
- }
-
- @failingTest
- test_isExpression_typeName_typeArguments() async {
- await analyze('''
-bool f(a) => a is List<int>;
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
- }
-
- @failingTest
- test_listLiteral_noTypeArgument_noNullableElements() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-List<String> f() {
- return ['a', 'b'];
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
- // TODO(brianwilkerson) Add an assertion that there is an edge from the list
- // literal's fake type argument to the return type's type argument.
- }
-
- @failingTest
- test_listLiteral_noTypeArgument_nullableElement() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-List<String> f() {
- return ['a', null, 'c'];
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
- assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
- }
-
- test_listLiteral_typeArgument_noNullableElements() async {
- await analyze('''
-List<String> f() {
- return <String>['a', 'b'];
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
- var typeArgForLiteral = decoratedTypeAnnotation('String>[').node;
- var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
- assertNoUpstreamNullability(typeArgForLiteral);
- assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
- }
-
- test_listLiteral_typeArgument_nullableElement() async {
- await analyze('''
-List<String> f() {
- return <String>['a', null, 'c'];
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
- assertEdge(always, decoratedTypeAnnotation('String>[').node, hard: false);
- }
-
- test_methodDeclaration_resets_unconditional_control_flow() async {
- await analyze('''
-class C {
- void f(bool b, int i, int j) {
- assert(i != null);
- if (b) return;
- assert(j != null);
- }
- void g(int k) {
- assert(k != null);
- }
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
- assertNoEdge(always, decoratedTypeAnnotation('int j').node);
- assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
- }
-
- test_methodInvocation_parameter_contravariant() async {
- await analyze('''
-class C<T> {
- void f(T t) {}
-}
-void g(C<int> c, int i) {
- c.f(i/*check*/);
-}
-''');
-
- var nullable_i = decoratedTypeAnnotation('int i').node;
- 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;
- 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,
- assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
- }
-
- test_methodInvocation_parameter_generic() async {
- await analyze('''
-class C<T> {}
-void f(C<int/*1*/>/*2*/ c) {}
-void g(C<int/*3*/>/*4*/ c) {
- f(c/*check*/);
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int/*3*/').node,
- decoratedTypeAnnotation('int/*1*/').node,
- hard: false);
- assertNullCheck(
- checkExpression('c/*check*/'),
- assertEdge(decoratedTypeAnnotation('C<int/*3*/>/*4*/').node,
- decoratedTypeAnnotation('C<int/*1*/>/*2*/').node,
- hard: true));
- }
-
- test_methodInvocation_parameter_named() async {
- await analyze('''
-class C {
- void f({int i: 0}) {}
-}
-void g(C c, int j) {
- c.f(i: j/*check*/);
-}
-''');
- var nullable_i = decoratedTypeAnnotation('int i').node;
- var nullable_j = decoratedTypeAnnotation('int j').node;
- assertNullCheck(checkExpression('j/*check*/'),
- assertEdge(nullable_j, nullable_i, hard: true));
- }
-
- test_methodInvocation_parameter_named_differentPackage() async {
- addPackageFile('pkgC', 'c.dart', '''
-class C {
- void f({int i}) {}
-}
-''');
- await analyze('''
-import "package:pkgC/c.dart";
-void g(C c, int j) {
- c.f(i: j/*check*/);
-}
-''');
- var nullable_j = decoratedTypeAnnotation('int j');
- assertNullCheck(checkExpression('j/*check*/'),
- assertEdge(nullable_j.node, never, hard: true));
- }
-
- test_methodInvocation_return_type() async {
- await analyze('''
-class C {
- bool m() => true;
-}
-bool f(C c) => c.m();
-''');
- assertEdge(decoratedTypeAnnotation('bool m').node,
- decoratedTypeAnnotation('bool f').node,
- hard: false);
- }
-
- test_methodInvocation_return_type_null_aware() async {
- await analyze('''
-class C {
- bool m() => true;
-}
-bool f(C c) => (c?.m());
-''');
- var lubNode =
- decoratedExpressionType('(c?.m())').node as NullabilityNodeForLUB;
- expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
- expect(lubNode.right, same(decoratedTypeAnnotation('bool m').node));
- assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
- }
-
- test_methodInvocation_target_check() async {
- await analyze('''
-class C {
- void m() {}
-}
-void test(C c) {
- c.m();
-}
-''');
-
- assertNullCheck(checkExpression('c.m'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_methodInvocation_target_check_cascaded() async {
- await analyze('''
-class C {
- void m() {}
-}
-void test(C c) {
- c..m();
-}
-''');
-
- assertNullCheck(checkExpression('c..m'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_methodInvocation_target_demonstrates_non_null_intent() async {
- await analyze('''
-class C {
- void m() {}
-}
-void test(C c) {
- c.m();
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
- }
-
- test_methodInvocation_target_demonstrates_non_null_intent_cascaded() async {
- await analyze('''
-class C {
- void m() {}
-}
-void test(C c) {
- c..m();
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
- }
-
- test_never() async {
- await analyze('');
-
- expect(never.isNullable, isFalse);
- }
-
- test_parenthesizedExpression() async {
- await analyze('''
-int f() {
- return (null);
-}
-''');
-
- assertNullCheck(checkExpression('(null)'),
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
- }
-
- test_prefixedIdentifier_field_type() async {
- await analyze('''
-class C {
- bool b = true;
-}
-bool f(C c) => c.b;
-''');
- assertEdge(decoratedTypeAnnotation('bool b').node,
- decoratedTypeAnnotation('bool f').node,
- hard: false);
- }
-
- test_prefixedIdentifier_getter_type() async {
- await analyze('''
-class C {
- bool get b => true;
-}
-bool f(C c) => c.b;
-''');
- assertEdge(decoratedTypeAnnotation('bool get').node,
- decoratedTypeAnnotation('bool f').node,
- hard: false);
- }
-
- test_prefixedIdentifier_target_check() async {
- await analyze('''
-class C {
- int get x => 1;
-}
-void test(C c) {
- c.x;
-}
-''');
-
- assertNullCheck(checkExpression('c.x'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_prefixedIdentifier_target_demonstrates_non_null_intent() async {
- await analyze('''
-class C {
- int get x => 1;
-}
-void test(C c) {
- c.x;
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
- }
-
- test_prefixExpression_bang2() async {
- await analyze('''
-bool f(bool b) {
- return !b;
-}
-''');
-
- var nullable_b = decoratedTypeAnnotation('bool b').node;
- var check_b = checkExpression('b;');
- assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
-
- var return_f = decoratedTypeAnnotation('bool f').node;
- assertEdge(never, return_f, hard: false);
- }
-
- test_propertyAccess_return_type() async {
- await analyze('''
-class C {
- bool get b => true;
-}
-bool f(C c) => (c).b;
-''');
- assertEdge(decoratedTypeAnnotation('bool get').node,
- decoratedTypeAnnotation('bool f').node,
- hard: false);
- }
-
- test_propertyAccess_return_type_null_aware() async {
- await analyze('''
-class C {
- bool get b => true;
-}
-bool f(C c) => (c?.b);
-''');
- var lubNode =
- decoratedExpressionType('(c?.b)').node as NullabilityNodeForLUB;
- expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
- expect(lubNode.right, same(decoratedTypeAnnotation('bool get b').node));
- assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
- }
-
- test_propertyAccess_target_check() async {
- await analyze('''
-class C {
- int get x => 1;
-}
-void test(C c) {
- (c).x;
-}
-''');
-
- assertNullCheck(checkExpression('c).x'),
- assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
- }
-
- test_return_implicit_null() async {
- verifyNoTestUnitErrors = false;
- await analyze('''
-int f() {
- return;
-}
-''');
-
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_return_null() async {
- await analyze('''
-int f() {
- return null;
-}
-''');
-
- assertNullCheck(checkExpression('null'),
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
- }
-
- test_return_null_generic() async {
- await analyze('''
-class C<T> {
- T f() {
- return null;
- }
-}
-''');
- var tNode = decoratedTypeAnnotation('T f').node;
- assertEdge(always, tNode, hard: false);
- assertNullCheck(
- checkExpression('null'), assertEdge(always, tNode, hard: false));
- }
-
- @failingTest
- test_setOrMapLiteral_map_noTypeArgument_noNullableKeysAndValues() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Map<String, int> f() {
- return {'a' : 1, 'b' : 2};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- // TODO(brianwilkerson) Add an assertion that there is an edge from the set
- // literal's fake type argument to the return type's type argument.
- }
-
- @failingTest
- test_setOrMapLiteral_map_noTypeArgument_nullableKey() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Map<String, int> f() {
- return {'a' : 1, null : 2, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- @failingTest
- test_setOrMapLiteral_map_noTypeArgument_nullableKeyAndValue() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Map<String, int> f() {
- return {'a' : 1, null : null, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- @failingTest
- test_setOrMapLiteral_map_noTypeArgument_nullableValue() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Map<String, int> f() {
- return {'a' : 1, 'b' : null, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_setOrMapLiteral_map_typeArguments_noNullableKeysAndValues() async {
- await analyze('''
-Map<String, int> f() {
- return <String, int>{'a' : 1, 'b' : 2};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-
- var keyForLiteral = decoratedTypeAnnotation('String, int>{').node;
- var keyForReturnType = decoratedTypeAnnotation('String, int> ').node;
- assertNoUpstreamNullability(keyForLiteral);
- assertEdge(keyForLiteral, keyForReturnType, hard: false);
-
- var valueForLiteral = decoratedTypeAnnotation('int>{').node;
- var valueForReturnType = decoratedTypeAnnotation('int> ').node;
- assertNoUpstreamNullability(valueForLiteral);
- assertEdge(valueForLiteral, valueForReturnType, hard: false);
- }
-
- test_setOrMapLiteral_map_typeArguments_nullableKey() async {
- await analyze('''
-Map<String, int> f() {
- return <String, int>{'a' : 1, null : 2, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
- hard: false);
- assertNoUpstreamNullability(decoratedTypeAnnotation('int>{').node);
- }
-
- test_setOrMapLiteral_map_typeArguments_nullableKeyAndValue() async {
- await analyze('''
-Map<String, int> f() {
- return <String, int>{'a' : 1, null : null, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
- hard: false);
- assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
- }
-
- test_setOrMapLiteral_map_typeArguments_nullableValue() async {
- await analyze('''
-Map<String, int> f() {
- return <String, int>{'a' : 1, 'b' : null, 'c' : 3};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
- assertNoUpstreamNullability(decoratedTypeAnnotation('String, int>{').node);
- assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
- }
-
- @failingTest
- test_setOrMapLiteral_set_noTypeArgument_noNullableElements() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Set<String> f() {
- return {'a', 'b'};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
- // TODO(brianwilkerson) Add an assertion that there is an edge from the set
- // literal's fake type argument to the return type's type argument.
- }
-
- @failingTest
- test_setOrMapLiteral_set_noTypeArgument_nullableElement() async {
- // Failing because we're not yet handling collection literals without a
- // type argument.
- await analyze('''
-Set<String> f() {
- return {'a', null, 'c'};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
- assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
- }
-
- test_setOrMapLiteral_set_typeArgument_noNullableElements() async {
- await analyze('''
-Set<String> f() {
- return <String>{'a', 'b'};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
- var typeArgForLiteral = decoratedTypeAnnotation('String>{').node;
- var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
- assertNoUpstreamNullability(typeArgForLiteral);
- assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
- }
-
- test_setOrMapLiteral_set_typeArgument_nullableElement() async {
- await analyze('''
-Set<String> f() {
- return <String>{'a', null, 'c'};
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
- assertEdge(always, decoratedTypeAnnotation('String>{').node, hard: false);
- }
-
- test_simpleIdentifier_local() async {
- await analyze('''
-main() {
- int i = 0;
- int j = i;
-}
-''');
-
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int j').node,
- hard: true);
- }
-
- test_skipDirectives() async {
- await analyze('''
-import "dart:core" as one;
-main() {}
-''');
- // No test expectations.
- // Just verifying that the test passes
- }
-
- test_soft_edge_for_non_variable_reference() async {
- // Edges originating in things other than variable references should be
- // soft.
- await analyze('''
-int f() => null;
-''');
- assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
- }
-
- test_stringLiteral() async {
- // TODO(paulberry): also test string interpolations
- await analyze('''
-String f() {
- return 'x';
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
- }
-
- test_superExpression() async {
- await analyze('''
-class C {
- C f() => super;
-}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
- }
-
- test_symbolLiteral() async {
- await analyze('''
-Symbol f() {
- return #symbol;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Symbol').node);
- }
-
- test_thisExpression() async {
- await analyze('''
-class C {
- C f() => this;
-}
-''');
-
- assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
- }
-
- test_throwExpression() async {
- await analyze('''
-int f() {
- return throw null;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
- }
-
- test_topLevelVar_reference() async {
- await analyze('''
-double pi = 3.1415;
-double get myPi => pi;
-''');
- var pi = findNode.topLevelVariableDeclaration('double pi');
- var piType =
- variables.decoratedTypeAnnotation(testSource, pi.variables.type);
- var myPi = findNode.any('myPi').parent as FunctionDeclaration;
- var myPiType =
- variables.decoratedTypeAnnotation(testSource, myPi.returnType);
- assertEdge(piType.node, myPiType.node, hard: false);
- }
-
- test_type_argument_explicit_bound() async {
- await analyze('''
-class C<T extends Object> {}
-void f(C<int> c) {}
-''');
- assertEdge(decoratedTypeAnnotation('int>').node,
- decoratedTypeAnnotation('Object>').node,
- hard: true);
- }
-
- test_typeName() async {
- await analyze('''
-Type f() {
- return int;
-}
-''');
- assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
- }
-
- test_typeName_union_with_bound() async {
- await analyze('''
-class C<T extends Object> {}
-void f(C c) {}
-''');
- var cType = decoratedTypeAnnotation('C c');
- var cBound = decoratedTypeAnnotation('Object');
- assertUnion(cType.typeArguments[0].node, cBound.node);
- }
-
- test_typeName_union_with_bounds() async {
- await analyze('''
-class C<T extends Object, U extends Object> {}
-void f(C c) {}
-''');
- var cType = decoratedTypeAnnotation('C c');
- var tBound = decoratedTypeAnnotation('Object,');
- var uBound = decoratedTypeAnnotation('Object>');
- assertUnion(cType.typeArguments[0].node, tBound.node);
- assertUnion(cType.typeArguments[1].node, uBound.node);
- }
-
- test_variableDeclaration() async {
- await analyze('''
-void f(int i) {
- int j = i;
-}
-''');
- assertEdge(decoratedTypeAnnotation('int i').node,
- decoratedTypeAnnotation('int j').node,
- hard: true);
- }
-}
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 2e2e9d1..f1c70ba 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -3,6 +3,7 @@
// 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/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:meta/meta.dart';
@@ -96,6 +97,8 @@
TypeProvider get typeProvider => testAnalysisResult.typeProvider;
+ TypeSystem get typeSystem => testAnalysisResult.typeSystem;
+
Future<CompilationUnit> analyze(String code) async {
await resolveTestUnit(code);
testUnit
@@ -137,6 +140,15 @@
fail('Expected union between $x and $y, not found');
}
+ /// Gets the [DecoratedType] associated with the constructor declaration whose
+ /// name matches [search].
+ DecoratedType decoratedConstructorDeclaration(String search) => variables
+ .decoratedElementType(findNode.constructor(search).declaredElement);
+
+ Map<ClassElement, DecoratedType> decoratedDirectSupertypes(String name) {
+ return variables.decoratedDirectSupertypes(findElement.classOrMixin(name));
+ }
+
/// Gets the [DecoratedType] associated with the generic function type
/// annotation whose text is [text].
DecoratedType decoratedGenericFunctionTypeAnnotation(String text) {
@@ -144,6 +156,11 @@
testSource, findNode.genericFunctionType(text));
}
+ /// Gets the [DecoratedType] associated with the method declaration whose
+ /// name matches [search].
+ DecoratedType decoratedMethodType(String search) => variables
+ .decoratedElementType(findNode.methodDeclaration(search).declaredElement);
+
/// Gets the [DecoratedType] associated with the type annotation whose text
/// is [text].
DecoratedType decoratedTypeAnnotation(String text) {
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index ef4476f..fbfab3b 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -17,11 +17,6 @@
@reflectiveTest
class NodeBuilderTest extends MigrationVisitorTestBase {
- /// Gets the [DecoratedType] associated with the constructor declaration whose
- /// name matches [search].
- DecoratedType decoratedConstructorDeclaration(String search) => variables
- .decoratedElementType(findNode.constructor(search).declaredElement);
-
/// Gets the [DecoratedType] associated with the function declaration whose
/// name matches [search].
DecoratedType decoratedFunctionType(String search) =>
@@ -31,6 +26,171 @@
DecoratedType decoratedTypeParameterBound(String search) => variables
.decoratedElementType(findNode.typeParameter(search).declaredElement);
+ test_class_alias_synthetic_constructors_no_parameters() async {
+ await analyze('''
+class C {
+ C.a();
+ C.b();
+}
+mixin M {}
+class D = C with M;
+''');
+ var constructors = findElement.class_('D').constructors;
+ expect(constructors, hasLength(2));
+ var a = findElement.constructor('a', of: 'D');
+ var aType = variables.decoratedElementType(a);
+ expect(aType.type.toString(), 'D Function()');
+ expect(aType.node, same(never));
+ expect(aType.typeArguments, isEmpty);
+ expect(aType.returnType.type.toString(), 'D');
+ expect(aType.returnType.node, same(never));
+ var b = findElement.constructor('b', of: 'D');
+ var bType = variables.decoratedElementType(b);
+ expect(bType.type.toString(), 'D Function()');
+ expect(bType.node, same(never));
+ expect(bType.typeArguments, isEmpty);
+ expect(bType.returnType.type.toString(), 'D');
+ expect(bType.returnType.node, same(never));
+ }
+
+ test_class_alias_synthetic_constructors_with_parameters() async {
+ await analyze('''
+class C {
+ C.a(int i);
+ C.b([int i]);
+ C.c({int i});
+ C.d(List<int> x);
+}
+mixin M {}
+class D = C with M;
+''');
+ var constructors = findElement.class_('D').constructors;
+ expect(constructors, hasLength(4));
+ var a = findElement.constructor('a', of: 'D');
+ var aType = variables.decoratedElementType(a);
+ expect(aType.type.toString(), 'D Function(int)');
+ expect(aType.node, same(never));
+ expect(aType.typeArguments, isEmpty);
+ expect(aType.returnType.type.toString(), 'D');
+ expect(aType.returnType.node, same(never));
+ expect(aType.positionalParameters, hasLength(1));
+ expect(aType.positionalParameters[0].type.toString(), 'int');
+ expect(aType.positionalParameters[0].node,
+ TypeMatcher<NullabilityNodeMutable>());
+ expect(aType.namedParameters, isEmpty);
+ var b = findElement.constructor('b', of: 'D');
+ var bType = variables.decoratedElementType(b);
+ expect(bType.type.toString(), 'D Function([int])');
+ expect(bType.node, same(never));
+ expect(bType.typeArguments, isEmpty);
+ expect(bType.returnType.type.toString(), 'D');
+ expect(bType.returnType.node, same(never));
+ expect(bType.positionalParameters, hasLength(1));
+ expect(bType.positionalParameters[0].type.toString(), 'int');
+ expect(bType.positionalParameters[0].node,
+ TypeMatcher<NullabilityNodeMutable>());
+ expect(bType.namedParameters, isEmpty);
+ var c = findElement.constructor('c', of: 'D');
+ var cType = variables.decoratedElementType(c);
+ expect(cType.type.toString(), 'D Function({i: int})');
+ expect(cType.node, same(never));
+ expect(cType.typeArguments, isEmpty);
+ expect(cType.returnType.type.toString(), 'D');
+ expect(cType.returnType.node, same(never));
+ expect(cType.positionalParameters, isEmpty);
+ expect(cType.namedParameters, hasLength(1));
+ expect(cType.namedParameters, contains('i'));
+ expect(cType.namedParameters['i'].type.toString(), 'int');
+ expect(
+ cType.namedParameters['i'].node, TypeMatcher<NullabilityNodeMutable>());
+ var d = findElement.constructor('d', of: 'D');
+ var dType = variables.decoratedElementType(d);
+ expect(dType.type.toString(), 'D Function(List<int>)');
+ expect(dType.node, same(never));
+ expect(dType.typeArguments, isEmpty);
+ expect(dType.returnType.type.toString(), 'D');
+ expect(dType.returnType.node, same(never));
+ expect(dType.positionalParameters, hasLength(1));
+ expect(dType.positionalParameters[0].type.toString(), 'List<int>');
+ expect(dType.positionalParameters[0].node,
+ TypeMatcher<NullabilityNodeMutable>());
+ expect(dType.positionalParameters[0].typeArguments, hasLength(1));
+ expect(
+ dType.positionalParameters[0].typeArguments[0].type.toString(), 'int');
+ expect(dType.positionalParameters[0].typeArguments[0].node,
+ TypeMatcher<NullabilityNodeMutable>());
+ expect(dType.namedParameters, isEmpty);
+ }
+
+ test_class_alias_synthetic_constructors_with_parameters_generic() async {
+ await analyze('''
+class C<T> {
+ C(T t);
+}
+mixin M {}
+class D<U> = C<U> with M;
+''');
+ var dConstructor = findElement.unnamedConstructor('D');
+ var dConstructorType = variables.decoratedElementType(dConstructor);
+ expect(dConstructorType.type.toString(), 'D<U> Function(U)');
+ expect(dConstructorType.node, same(never));
+ expect(dConstructorType.typeFormals, isEmpty);
+ expect(dConstructorType.returnType.type.toString(), 'D<U>');
+ expect(dConstructorType.returnType.node, same(never));
+ var typeArguments = dConstructorType.returnType.typeArguments;
+ expect(typeArguments, hasLength(1));
+ expect(typeArguments[0].type.toString(), 'U');
+ expect(typeArguments[0].node, same(never));
+ var dParams = dConstructorType.positionalParameters;
+ expect(dParams, hasLength(1));
+ expect(dParams[0].type.toString(), 'U');
+ expect(dParams[0].node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_class_with_default_constructor() async {
+ await analyze('''
+class C {}
+''');
+ var defaultConstructor = findElement.class_('C').constructors.single;
+ var decoratedConstructorType =
+ variables.decoratedElementType(defaultConstructor);
+ expect(decoratedConstructorType.type.toString(), 'C Function()');
+ expect(decoratedConstructorType.node, same(never));
+ expect(decoratedConstructorType.returnType.type.toString(), 'C');
+ expect(decoratedConstructorType.returnType.node, same(never));
+ }
+
+ test_class_with_default_constructor_generic() async {
+ await analyze('''
+class C<T, U> {}
+''');
+ var defaultConstructor = findElement.class_('C').constructors.single;
+ var decoratedConstructorType =
+ variables.decoratedElementType(defaultConstructor);
+ expect(decoratedConstructorType.type.toString(), 'C<T, U> Function()');
+ expect(decoratedConstructorType.node, same(never));
+ expect(decoratedConstructorType.typeArguments, isEmpty);
+ var returnType = decoratedConstructorType.returnType;
+ expect(returnType.type.toString(), 'C<T, U>');
+ expect(returnType.node, same(never));
+ expect(returnType.typeArguments, hasLength(2));
+ expect(returnType.typeArguments[0].type.toString(), 'T');
+ expect(returnType.typeArguments[0].node, same(never));
+ expect(returnType.typeArguments[1].type.toString(), 'U');
+ expect(returnType.typeArguments[1].node, same(never));
+ }
+
+ test_constructor_factory() async {
+ await analyze('''
+class C {
+ C._();
+ factory C() => C._();
+}
+''');
+ var decoratedType = decoratedConstructorDeclaration('C(').returnType;
+ expect(decoratedType.node, same(never));
+ }
+
test_constructor_returnType_implicit_dynamic() async {
await analyze('''
class C {
@@ -41,6 +201,158 @@
expect(decoratedType.node, same(never));
}
+ test_directSupertypes_class_extends() async {
+ await analyze('''
+class C<T, U> {}
+class D<V> extends C<int, V> {}
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> {').node));
+ }
+
+ test_directSupertypes_class_extends_default() async {
+ await analyze('''
+class C<T, U> {}
+''');
+ var types = decoratedDirectSupertypes('C');
+ var decorated = types[typeProvider.objectType.element];
+ expect(decorated.type.toString(), 'Object');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, isEmpty);
+ }
+
+ test_directSupertypes_class_implements() async {
+ await analyze('''
+class C<T, U> {}
+class D<V> implements C<int, V> {}
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> {').node));
+ }
+
+ test_directSupertypes_class_with() async {
+ await analyze('''
+class C<T, U> {}
+class D<V> extends Object with C<int, V> {}
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> {').node));
+ }
+
+ test_directSupertypes_classAlias_extends() async {
+ await analyze('''
+class M {}
+class C<T, U> {}
+class D<V> = C<int, V> with M;
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> w').node));
+ }
+
+ test_directSupertypes_classAlias_implements() async {
+ await analyze('''
+class M {}
+class C<T, U> {}
+class D<V> = Object with M implements C<int, V>;
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V>;').node));
+ }
+
+ test_directSupertypes_classAlias_with() async {
+ await analyze('''
+class C<T, U> {}
+class D<V> = Object with C<int, V>;
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V>;').node));
+ }
+
+ test_directSupertypes_mixin_extends_default() async {
+ await analyze('''
+mixin C<T, U> {}
+''');
+ var types = decoratedDirectSupertypes('C');
+ var decorated = types[typeProvider.objectType.element];
+ expect(decorated.type.toString(), 'Object');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, isEmpty);
+ }
+
+ test_directSupertypes_mixin_implements() async {
+ await analyze('''
+class C<T, U> {}
+mixin D<V> implements C<int, V> {}
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> {').node));
+ }
+
+ test_directSupertypes_mixin_on() async {
+ await analyze('''
+class C<T, U> {}
+mixin D<V> on C<int, V> {}
+''');
+ var types = decoratedDirectSupertypes('D');
+ var decorated = types[findElement.class_('C')];
+ expect(decorated.type.toString(), 'C<int, V>');
+ expect(decorated.node, same(never));
+ expect(decorated.typeArguments, hasLength(2));
+ expect(decorated.typeArguments[0].node,
+ same(decoratedTypeAnnotation('int').node));
+ expect(decorated.typeArguments[1].node,
+ same(decoratedTypeAnnotation('V> {').node));
+ }
+
test_dynamic_type() async {
await analyze('''
dynamic f() {}
@@ -50,6 +362,40 @@
assertEdge(always, decoratedType.node, hard: false);
}
+ test_field_type_implicit_dynamic() async {
+ await analyze('''
+class C {
+ var x;
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
+ test_field_type_inferred() async {
+ await analyze('''
+class C {
+ var x = 1;
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_field_type_inferred_dynamic() async {
+ await analyze('''
+dynamic f() {}
+class C {
+ var x = f();
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
test_field_type_simple() async {
await analyze('''
class C {
@@ -64,6 +410,235 @@
same(decoratedType));
}
+ test_fieldFormalParameter_function_namedParameter_typed() async {
+ await analyze('''
+class C {
+ Object f;
+ C(void this.f({int i}));
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.namedParameters['i'],
+ same(decoratedTypeAnnotation('int')));
+ }
+
+ test_fieldFormalParameter_function_namedParameter_untyped() async {
+ await analyze('''
+class C {
+ Object f;
+ C(void this.f({i}));
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.namedParameters['i'].type.toString(), 'dynamic');
+ expect(ctorParamType.namedParameters['i'].node, same(always));
+ }
+
+ test_fieldFormalParameter_function_positionalParameter_typed() async {
+ await analyze('''
+class C {
+ Object f;
+ C(void this.f(int i));
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.positionalParameters[0],
+ same(decoratedTypeAnnotation('int')));
+ }
+
+ test_fieldFormalParameter_function_positionalParameter_untyped() async {
+ await analyze('''
+class C {
+ Object f;
+ C(void this.f(i));
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.positionalParameters[0].type.toString(), 'dynamic');
+ expect(ctorParamType.positionalParameters[0].node, same(always));
+ }
+
+ test_fieldFormalParameter_function_return_typed() async {
+ await analyze('''
+class C {
+ Object f;
+ C(int this.f());
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.returnType, same(decoratedTypeAnnotation('int')));
+ }
+
+ test_fieldFormalParameter_function_return_untyped() async {
+ await analyze('''
+class C {
+ Object f;
+ C(this.f()) {}
+}
+''');
+ var ctor = findElement.unnamedConstructor('C');
+ var ctorParam = ctor.parameters[0];
+ var ctorType = variables.decoratedElementType(ctor);
+ var ctorParamType = variables.decoratedElementType(ctorParam);
+ expect(ctorType.positionalParameters[0], same(ctorParamType));
+ expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(ctorParamType.returnType.type.toString(), 'dynamic');
+ expect(ctorParamType.returnType.node, same(always));
+ }
+
+ test_fieldFormalParameter_typed() async {
+ await analyze('''
+class C {
+ int i;
+ C.named(int this.i);
+}
+''');
+ var decoratedConstructorParamType =
+ decoratedConstructorDeclaration('named').positionalParameters[0];
+ expect(decoratedTypeAnnotation('int this'),
+ same(decoratedConstructorParamType));
+ expect(decoratedConstructorParamType.type.toString(), 'int');
+ expect(decoratedConstructorParamType.node,
+ TypeMatcher<NullabilityNodeMutable>());
+ // Note: the edge builder will connect this node to the node for the type of
+ // the field.
+ }
+
+ test_fieldFormalParameter_untyped() async {
+ await analyze('''
+class C {
+ int i;
+ C.named(this.i);
+}
+''');
+ var decoratedConstructorParamType =
+ decoratedConstructorDeclaration('named').positionalParameters[0];
+ expect(decoratedConstructorParamType.type.toString(), 'int');
+ expect(decoratedConstructorParamType.node,
+ TypeMatcher<NullabilityNodeMutable>());
+ // Note: the edge builder will unify this implicit type with the type of the
+ // field.
+ }
+
+ test_functionTypedFormalParameter_namedParameter_typed() async {
+ await analyze('''
+void f(void g({int i})) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.namedParameters['i'], same(decoratedTypeAnnotation('int')));
+ }
+
+ test_functionTypedFormalParameter_namedParameter_untyped() async {
+ await analyze('''
+void f(void g({i})) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.namedParameters['i'].type.toString(), 'dynamic');
+ expect(gType.namedParameters['i'].node, same(always));
+ }
+
+ test_functionTypedFormalParameter_positionalParameter_typed() async {
+ await analyze('''
+void f(void g(int i)) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.positionalParameters[0], same(decoratedTypeAnnotation('int')));
+ }
+
+ test_functionTypedFormalParameter_positionalParameter_untyped() async {
+ await analyze('''
+void f(void g(i)) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.positionalParameters[0].type.toString(), 'dynamic');
+ expect(gType.positionalParameters[0].node, same(always));
+ }
+
+ test_functionTypedFormalParameter_return_typed() async {
+ await analyze('''
+void f(int g()) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.returnType, same(decoratedTypeAnnotation('int')));
+ }
+
+ test_functionTypedFormalParameter_return_untyped() async {
+ await analyze('''
+void f(g()) {}
+''');
+ var f = findElement.function('f');
+ var g = f.parameters[0];
+ var fType = variables.decoratedElementType(f);
+ var gType = variables.decoratedElementType(g);
+ expect(fType.positionalParameters[0], same(gType));
+ expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(gType.returnType.type.toString(), 'dynamic');
+ expect(gType.returnType.node, same(always));
+ }
+
+ test_generic_function_type_syntax_inferred_dynamic_return() async {
+ await analyze('''
+abstract class C {
+ Function() f();
+}
+''');
+ var decoratedFType = decoratedMethodType('f');
+ var decoratedFReturnType = decoratedFType.returnType;
+ var decoratedFReturnReturnType = decoratedFReturnType.returnType;
+ expect(decoratedFReturnReturnType.type.toString(), 'dynamic');
+ expect(decoratedFReturnReturnType.node, same(always));
+ }
+
test_genericFunctionType_namedParameterType() async {
await analyze('''
void f(void Function({int y}) x) {}
@@ -122,18 +697,54 @@
expect(decoratedArgType.node, same(always));
}
+ test_interfaceType_generic_instantiate_to_function_type() async {
+ await analyze('''
+class C<T extends int Function()> {}
+void f(C x) {}
+''');
+ var decoratedCType = decoratedTypeAnnotation('C x');
+ expect(decoratedFunctionType('f').positionalParameters[0],
+ same(decoratedCType));
+ expect(decoratedCType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedCType.typeArguments, hasLength(1));
+ var decoratedArgType = decoratedCType.typeArguments[0];
+ expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedArgType.typeArguments, isEmpty);
+ var decoratedArgReturnType = decoratedArgType.returnType;
+ expect(decoratedArgReturnType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedArgReturnType.typeArguments, isEmpty);
+ }
+
+ test_interfaceType_generic_instantiate_to_function_type_void() async {
+ await analyze('''
+class C<T extends void Function()> {}
+void f(C x) {}
+''');
+ var decoratedCType = decoratedTypeAnnotation('C x');
+ expect(decoratedFunctionType('f').positionalParameters[0],
+ same(decoratedCType));
+ expect(decoratedCType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedCType.typeArguments, hasLength(1));
+ var decoratedArgType = decoratedCType.typeArguments[0];
+ expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedArgType.typeArguments, isEmpty);
+ var decoratedArgReturnType = decoratedArgType.returnType;
+ expect(decoratedArgReturnType.node, same(always));
+ expect(decoratedArgReturnType.typeArguments, isEmpty);
+ }
+
test_interfaceType_generic_instantiate_to_generic_type() async {
await analyze('''
class C<T> {}
class D<T extends C<int>> {}
void f(D x) {}
''');
- var decoratedListType = decoratedTypeAnnotation('D x');
+ var decoratedDType = decoratedTypeAnnotation('D x');
expect(decoratedFunctionType('f').positionalParameters[0],
- same(decoratedListType));
- expect(decoratedListType.node, TypeMatcher<NullabilityNodeMutable>());
- expect(decoratedListType.typeArguments, hasLength(1));
- var decoratedArgType = decoratedListType.typeArguments[0];
+ same(decoratedDType));
+ expect(decoratedDType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedDType.typeArguments, hasLength(1));
+ var decoratedArgType = decoratedDType.typeArguments[0];
expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
expect(decoratedArgType.typeArguments, hasLength(1));
var decoratedArgArgType = decoratedArgType.typeArguments[0];
@@ -202,6 +813,157 @@
expect(decoratedIntType.node, isNot(never));
}
+ test_localVariable_type_implicit_dynamic() async {
+ await analyze('''
+main() {
+ var x;
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
+ test_localVariable_type_inferred() async {
+ await analyze('''
+main() {
+ var x = 1;
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_localVariable_type_inferred_dynamic() async {
+ await analyze('''
+dynamic f() {}
+main() {
+ var x = f();
+}
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_parameterType_implicit_dynamic() async {
+ await analyze('''
+class C {
+ void f(x) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f').positionalParameters[0];
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_parameterType_implicit_dynamic_named() async {
+ await analyze('''
+class C {
+ void f({x}) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f').namedParameters['x'];
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_parameterType_inferred() async {
+ await analyze('''
+class B {
+ void f(int x) {}
+}
+class C extends B {
+ void f/*C*/(x) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').positionalParameters[0];
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_method_parameterType_inferred_dynamic() async {
+ await analyze('''
+class B {
+ void f(dynamic x) {}
+}
+class C extends B {
+ void f/*C*/(x) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').positionalParameters[0];
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_parameterType_inferred_dynamic_named() async {
+ await analyze('''
+class B {
+ void f({dynamic x = 0}) {}
+}
+class C extends B {
+ void f/*C*/({x = 0}) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').namedParameters['x'];
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_parameterType_inferred_named() async {
+ await analyze('''
+class B {
+ void f({int x = 0}) {}
+}
+class C extends B {
+ void f/*C*/({x = 0}) {}
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').namedParameters['x'];
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_method_returnType_implicit_dynamic() async {
+ await analyze('''
+class C {
+ f() => 1;
+}
+''');
+ var decoratedType = decoratedMethodType('f').returnType;
+ expect(decoratedType.node, same(always));
+ }
+
+ test_method_returnType_inferred() async {
+ await analyze('''
+class B {
+ int f() => 1;
+}
+class C extends B {
+ f/*C*/() => 1;
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').returnType;
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_method_returnType_inferred_dynamic() async {
+ await analyze('''
+class B {
+ dynamic f() => 1;
+}
+class C extends B {
+ f/*C*/() => 1;
+}
+''');
+ var decoratedType = decoratedMethodType('f/*C*/').returnType;
+ expect(decoratedType.node, same(always));
+ }
+
+ test_parameters() async {
+ await analyze('''
+void foo({List<int> values}) {
+ values.where((i) => true);
+}
+''');
+ // No assertions; just checking that it doesn't crash.
+ }
+
test_topLevelFunction_parameterType_implicit_dynamic() async {
await analyze('''
void f(x) {}
@@ -211,7 +973,6 @@
expect(decoratedFunctionType('f').positionalParameters[0],
same(decoratedType));
expect(decoratedType.type.isDynamic, isTrue);
- assertUnion(always, decoratedType.node);
}
test_topLevelFunction_parameterType_named_no_default() async {
@@ -282,7 +1043,6 @@
''');
var decoratedType = decoratedFunctionType('f').returnType;
expect(decoratedType.type.isDynamic, isTrue);
- assertUnion(always, decoratedType.node);
}
test_topLevelFunction_returnType_simple() async {
@@ -295,6 +1055,34 @@
expect(decoratedType.node, isNot(never));
}
+ test_topLevelVariable_type_implicit_dynamic() async {
+ await analyze('''
+var x;
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
+ test_topLevelVariable_type_inferred() async {
+ await analyze('''
+var x = 1;
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
+ test_topLevelVariable_type_inferred_dynamic() async {
+ await analyze('''
+dynamic f() {}
+var x = f();
+''');
+ var decoratedType =
+ variables.decoratedElementType(findNode.simple('x').staticElement);
+ expect(decoratedType.node, same(always));
+ }
+
test_type_comment_bang() async {
await analyze('''
void f(int/*!*/ i) {}
@@ -341,6 +1129,17 @@
expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
}
+ test_variableDeclaration_visit_initializer() async {
+ await analyze('''
+class C<T> {}
+void f(C<dynamic> c) {
+ var x = c as C<int>;
+}
+''');
+ var decoratedType = decoratedTypeAnnotation('int');
+ expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+ }
+
test_void_type() async {
await analyze('''
void f() {}
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 4241cf2..e8b5c72 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -5,14 +5,18 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'api_test.dart' as api_test;
-import 'graph_builder_test.dart' as graph_builder_test;
+import 'decorated_class_hierarchy_test.dart' as decorated_class_hierarchy_test;
+import 'decorated_type_test.dart' as decorated_type_test;
+import 'edge_builder_test.dart' as edge_builder_test;
import 'node_builder_test.dart' as node_builder_test;
import 'nullability_node_test.dart' as nullability_node_test;
main() {
defineReflectiveSuite(() {
api_test.main();
- graph_builder_test.main();
+ decorated_class_hierarchy_test.main();
+ decorated_type_test.main();
+ edge_builder_test.main();
node_builder_test.main();
nullability_node_test.main();
});
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index 9fc946a..eb79e61 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -303,7 +303,7 @@
final bool isCsp;
- // TODO(rnystrom): Remove this when Dart 1.0 is no longer supported.
+ /// Enables asserts in the dart2js compiler.
final bool isHostChecked;
final bool isMinified;
@@ -585,13 +585,11 @@
class Compiler extends NamedEnum {
static const none = const Compiler._('none');
- static const precompiler = const Compiler._('precompiler');
static const dart2js = const Compiler._('dart2js');
static const dart2analyzer = const Compiler._('dart2analyzer');
static const compareAnalyzerCfe = const Compiler._('compare_analyzer_cfe');
static const dartdevc = const Compiler._('dartdevc');
static const dartdevk = const Compiler._('dartdevk');
- static const appJit = const Compiler._('app_jit');
static const appJitk = const Compiler._('app_jitk');
static const dartk = const Compiler._('dartk');
static const dartkp = const Compiler._('dartkp');
@@ -603,13 +601,11 @@
static final _all = new Map<String, Compiler>.fromIterable([
none,
- precompiler,
dart2js,
dart2analyzer,
compareAnalyzerCfe,
dartdevc,
dartdevk,
- appJit,
appJitk,
dartk,
dartkp,
@@ -664,12 +660,10 @@
case Compiler.dart2analyzer:
case Compiler.compareAnalyzerCfe:
return const [Runtime.none];
- case Compiler.appJit:
case Compiler.appJitk:
case Compiler.dartk:
case Compiler.dartkb:
return const [Runtime.vm, Runtime.selfCheck];
- case Compiler.precompiler:
case Compiler.dartkp:
return const [Runtime.dartPrecompiled];
case Compiler.specParser:
@@ -695,12 +689,10 @@
case Compiler.dart2analyzer:
case Compiler.compareAnalyzerCfe:
return Runtime.none;
- case Compiler.appJit:
case Compiler.appJitk:
case Compiler.dartk:
case Compiler.dartkb:
return Runtime.vm;
- case Compiler.precompiler:
case Compiler.dartkp:
return Runtime.dartPrecompiled;
case Compiler.specParser:
@@ -828,7 +820,7 @@
return Compiler.none;
case dartPrecompiled:
- return Compiler.precompiler;
+ return Compiler.dartkp;
case d8:
case jsshell:
diff --git a/pkg/sourcemap_testing/README.md b/pkg/sourcemap_testing/README.md
index fa8ea7a..11167b4 100644
--- a/pkg/sourcemap_testing/README.md
+++ b/pkg/sourcemap_testing/README.md
@@ -112,8 +112,7 @@
### Technical details
Some of the logic comes from https://github.com/ChromeDevTools/devtools-frontend/, for instance see
-https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/
-front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
+https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
for how a line breakpoint is resolved:
Basically the line asked to break on in user code (e.g. in dart code) is asked for first and last
javascript positions; these are then used to get possible breakpoints in that part. If there are
diff --git a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
index 2e2f18b..505b951 100644
--- a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
@@ -7,13 +7,12 @@
import 'dart:convert' show jsonDecode;
import 'package:expect/expect.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import 'package:source_maps/source_maps.dart';
import 'package:source_maps/src/utils.dart';
import 'package:source_span/source_span.dart';
import 'package:dart2js_tools/src/dart2js_mapping.dart';
-import 'annotated_code_helper.dart';
-
const String INPUT_FILE_NAME = 'input.dart';
class Test {
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index 7cd8a6b..d001fd6 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -1,11 +1,10 @@
import 'dart:io';
import 'package:expect/minitest.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import 'package:path/path.dart' as path;
import 'package:source_maps/source_maps.dart';
-import 'annotated_code_helper.dart';
-
/**
* Runs D8 and steps as the AnnotatedCode dictates.
*
diff --git a/pkg/sourcemap_testing/pubspec.yaml b/pkg/sourcemap_testing/pubspec.yaml
index a7ee40e..070ea67 100644
--- a/pkg/sourcemap_testing/pubspec.yaml
+++ b/pkg/sourcemap_testing/pubspec.yaml
@@ -8,3 +8,4 @@
dependencies:
package_config: '>=0.1.1 <2.0.0'
pub_semver: ^1.2.1
+ front_end: ^0.1.20
diff --git a/pkg/status_file/test/data/lib_2_app_jit.status b/pkg/status_file/test/data/lib_2_app_jit.status
deleted file mode 100644
index a2a86f3..0000000
--- a/pkg/status_file/test/data/lib_2_app_jit.status
+++ /dev/null
@@ -1,6 +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.
-
-[ $compiler == app_jit ]
-mirrors/*: Skip # Issue 27929: Triage
diff --git a/pkg/status_file/test/data/standalone_2_vm.status b/pkg/status_file/test/data/standalone_2_vm.status
index 8c521ab..2b85902 100644
--- a/pkg/status_file/test/data/standalone_2_vm.status
+++ b/pkg/status_file/test/data/standalone_2_vm.status
@@ -43,13 +43,6 @@
[ $system == windows && $compiler != dart2analyzer ]
io/platform_resolved_executable_test/06: RuntimeError # Issue 23641
-[ $compiler == app_jit ]
-io/test_extension_test: Skip # Platform.executable
-io/test_extension_fail_test: Skip # Platform.executable
-io/platform_test: Skip # Platform.executable
-full_coverage_test: Skip # Platform.executable
-regress_26031_test: Skip # Platform.resolvedExecutable
-
[ $system == android ]
io/process_exit_test: Skip # Issue 29578
io/process_path_test: Skip # Issue 26376
diff --git a/pkg/status_file/test/data/vm.status b/pkg/status_file/test/data/vm.status
index bf2543f..5cb581d 100644
--- a/pkg/status_file/test/data/vm.status
+++ b/pkg/status_file/test/data/vm.status
@@ -126,9 +126,6 @@
[ $compiler == dart2analyzer && $strong ]
*: Skip # Issue 28649
-[ $compiler == app_jit ]
-dart/snapshot_version_test: Fail,OK # Expects to find script snapshot relative to Dart source.
-
[ $runtime != vm ]
dart/snapshot_version_test: SkipByDesign # Spawns processes
dart/spawn_infinite_loop_test: Skip # VM shutdown test
@@ -156,18 +153,12 @@
cc/IsolateReload_TypeIdentityGeneric: Fail # Issue 28349
cc/IsolateReload_TypeIdentityParameter: Fail # Issue 28349
-[ $compiler == precompiler ]
-dart/byte_array_test: Skip # Incompatible flag --disable_alloc_stubs_after_gc
-
-[ $compiler == precompiler || $mode == product ]
+[ $mode == product ]
dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
-[ $compiler == app_jit ]
-dart/optimized_stacktrace_line_and_column_test: RuntimeError,OK # app-jit lacks column information
-
[ $runtime == dart_precompiled ]
dart/optimized_stacktrace_line_and_column_test: RuntimeError,OK # AOT lacks column information
dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
diff --git a/pkg/telemetry/lib/telemetry.dart b/pkg/telemetry/lib/telemetry.dart
index 6340cd2..ef3491f 100644
--- a/pkg/telemetry/lib/telemetry.dart
+++ b/pkg/telemetry/lib/telemetry.dart
@@ -4,6 +4,7 @@
import 'dart:io';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:usage/src/usage_impl.dart';
import 'package:usage/src/usage_impl_io.dart';
@@ -52,14 +53,26 @@
///
/// This analytics instance will share a common enablement state with the rest
/// of the Dart SDK tools.
-_TelemetryAnalytics createAnalyticsInstance(
+Analytics createAnalyticsInstance(
String trackingId,
String applicationName, {
bool disableForSession: false,
}) {
Directory dir = getDartStorageDirectory();
+ if (dir == null) {
+ // Some systems don't support user home directories; for those, fail
+ // gracefully by returning a disabled analytics object.
+ return new _DisabledAnalytics(trackingId, applicationName);
+ }
+
if (!dir.existsSync()) {
- dir.createSync();
+ try {
+ dir.createSync();
+ } catch (e) {
+ // If we can't create the directory for the analytics settings, fail
+ // gracefully by returning a disabled analytics object.
+ return new _DisabledAnalytics(trackingId, applicationName);
+ }
}
File file = new File(path.join(dir.path, _settingsFileName));
@@ -71,8 +84,15 @@
///
/// Typically, the directory is `~/.dart/` (and the settings file is
/// `analytics.json`).
+///
+/// This can return null under some conditions, including when the user's home
+/// directory does not exist.
+@visibleForTesting
Directory getDartStorageDirectory() {
- return new Directory(path.join(userHomeDir(), _dartDirectoryName));
+ Directory homeDirectory = new Directory(userHomeDir());
+ if (!homeDirectory.existsSync()) return null;
+
+ return new Directory(path.join(homeDirectory.path, _dartDirectoryName));
}
/// Return the version of the Dart SDK.
@@ -111,6 +131,23 @@
}
}
+class _DisabledAnalytics extends AnalyticsMock {
+ @override
+ final String trackingId;
+ @override
+ final String applicationName;
+
+ _DisabledAnalytics(this.trackingId, this.applicationName);
+
+ @override
+ bool get enabled => false;
+}
+
+/// Detect whether we're running on a bot or in a continuous testing
+/// environment.
+///
+/// We should periodically keep this code up to date with
+/// https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/base/utils.dart#L20.
bool isRunningOnBot() {
final Map<String, String> env = Platform.environment;
diff --git a/pkg/telemetry/pubspec.yaml b/pkg/telemetry/pubspec.yaml
index 15dc588..8084a84 100644
--- a/pkg/telemetry/pubspec.yaml
+++ b/pkg/telemetry/pubspec.yaml
@@ -8,6 +8,7 @@
dependencies:
http: ^0.12.0
+ meta: ^1.0.2
path: ^1.4.0
stack_trace: ^1.7.0
usage: ^3.2.0+1
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index dd67eef..afd23cb 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -1194,7 +1194,7 @@
errorReportingServer = server;
void errorReportingHandler(HttpRequest request) {
var buffer = StringBuffer();
- request.transform(utf8.decoder).listen((data) {
+ request.cast<List<int>>().transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
var back = buffer.toString();
@@ -1285,7 +1285,7 @@
void handleReport(HttpRequest request, String browserId, int testId,
{bool isStatusUpdate}) {
var buffer = StringBuffer();
- request.transform(utf8.decoder).listen((data) {
+ request.cast<List<int>>().transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
var back = buffer.toString();
@@ -1306,7 +1306,7 @@
// If an error occurs while receiving the data from the request stream,
// we don't handle it specially. We can safely ignore it, since the started
// events are not crucial.
- request.transform(utf8.decoder).listen((data) {
+ request.cast<List<int>>().transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
var back = buffer.toString();
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index e6ea871..d8707ab 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -76,20 +76,21 @@
}
static Command adbPrecompiled(
- String precompiledRunner,
+ String buildPath,
String processTest,
String testDirectory,
List<String> arguments,
bool useBlobs,
- bool useElf) {
- return AdbPrecompilationCommand._(precompiledRunner, processTest,
- testDirectory, arguments, useBlobs, useElf);
+ bool useElf,
+ List<String> extraLibs) {
+ return AdbPrecompilationCommand._(buildPath, processTest, testDirectory,
+ arguments, useBlobs, useElf, extraLibs);
}
- static Command adbDartk(String precompiledRunner, String processTest,
- String script, List<String> arguments, List<String> extraLibraries) {
+ static Command adbDartk(String buildPath, String processTest, String script,
+ List<String> arguments, List<String> extraLibraries) {
return AdbDartkCommand._(
- precompiledRunner, processTest, script, arguments, extraLibraries);
+ buildPath, processTest, script, arguments, extraLibraries);
}
static Command jsCommandLine(
@@ -587,54 +588,72 @@
}
}
-class AdbPrecompilationCommand extends Command {
- final String precompiledRunnerFilename;
+abstract class AdbCommand {
+ String get buildPath;
+ List<String> get extraLibraries;
+}
+
+class AdbPrecompilationCommand extends Command implements AdbCommand {
+ final String buildPath; // Path to the output directory of the build.
final String processTestFilename;
final String precompiledTestDirectory;
final List<String> arguments;
final bool useBlobs;
final bool useElf;
+ final List<String> extraLibraries;
AdbPrecompilationCommand._(
- this.precompiledRunnerFilename,
+ this.buildPath,
this.processTestFilename,
this.precompiledTestDirectory,
this.arguments,
this.useBlobs,
this.useElf,
+ this.extraLibraries,
{int index = 0})
: super._("adb_precompilation", index: index);
AdbPrecompilationCommand indexedCopy(int index) => AdbPrecompilationCommand._(
- precompiledRunnerFilename,
+ buildPath,
processTestFilename,
precompiledTestDirectory,
arguments,
useBlobs,
useElf,
+ extraLibraries,
index: index);
_buildHashCode(HashCodeBuilder builder) {
super._buildHashCode(builder);
- builder.add(precompiledRunnerFilename);
+ builder.add(buildPath);
builder.add(precompiledTestDirectory);
builder.add(arguments);
builder.add(useBlobs);
builder.add(useElf);
+ extraLibraries.forEach(builder.add);
+ }
+
+ static bool _listEquals(List<String> x, List<String> y) {
+ if (x.length != y.length) return false;
+ for (int i = 0; i < x.length; ++i) {
+ if (x[i] != y[i]) return false;
+ }
+ return true;
}
bool _equal(AdbPrecompilationCommand other) =>
super._equal(other) &&
- precompiledRunnerFilename == other.precompiledRunnerFilename &&
+ buildPath == other.buildPath &&
useBlobs == other.useBlobs &&
useElf == other.useElf &&
arguments == other.arguments &&
- precompiledTestDirectory == other.precompiledTestDirectory;
+ precompiledTestDirectory == other.precompiledTestDirectory &&
+ _listEquals(extraLibraries, other.extraLibraries);
String toString() => 'Steps to push precompiled runner and precompiled code '
'to an attached device. Uses (and requires) adb.';
}
-class AdbDartkCommand extends Command {
+class AdbDartkCommand extends Command implements AdbCommand {
final String buildPath;
final String processTestFilename;
final String kernelFile;
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 8a5ee37..3758033 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -9,7 +9,7 @@
import 'path.dart';
import 'repository.dart';
import 'runtime_configuration.dart';
-import 'test_suite.dart';
+import 'test_file.dart';
import 'utils.dart';
List<String> _replaceDartFiles(List<String> list, String replacement) {
@@ -67,16 +67,9 @@
case Compiler.dartdevk:
return DevCompilerConfiguration(configuration);
- case Compiler.appJit:
- return AppJitCompilerConfiguration(configuration, previewDart2: false);
-
case Compiler.appJitk:
return AppJitCompilerConfiguration(configuration);
- case Compiler.precompiler:
- return PrecompilerCompilerConfiguration(configuration,
- previewDart2: false);
-
case Compiler.dartk:
case Compiler.dartkb:
if (configuration.architecture == Architecture.simdbc64 ||
@@ -141,17 +134,13 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
- return sharedOptions.toList()
- ..addAll(_configuration.sharedOptions)
- ..addAll(args);
+ return [...sharedOptions, ..._configuration.sharedOptions, ...args];
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
return [artifact.filename];
@@ -167,32 +156,26 @@
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- var args = <String>[];
- if (_isDebug) {
- // Temporarily disable background compilation to avoid flaky crashes
- // (see http://dartbug.com/30016 for details).
- args.add('--no-background-compilation');
- }
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
- if (_configuration.hotReload) {
- args.add('--hot-reload-test-mode');
- } else if (_configuration.hotReloadRollback) {
- args.add('--hot-reload-rollback-test-mode');
- }
- return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(originalArguments)
- ..addAll(dartOptions);
+ return [
+ if (_isDebug)
+ // Temporarily disable background compilation to avoid flaky crashes
+ // (see http://dartbug.com/30016 for details).
+ '--no-background-compilation',
+ if (_useEnableAsserts) '--enable_asserts',
+ if (_configuration.hotReload)
+ '--hot-reload-test-mode'
+ else if (_configuration.hotReloadRollback)
+ '--hot-reload-rollback-test-mode',
+ ...vmOptions,
+ ...testFile.sharedOptions,
+ ..._configuration.sharedOptions,
+ ...originalArguments,
+ ...testFile.dartOptions
+ ];
}
}
@@ -233,41 +216,39 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
- return sharedOptions.toList()
- ..addAll(_configuration.sharedOptions)
- ..addAll(vmOptions)
- ..addAll(args);
+ return [
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...vmOptions,
+ ...args
+ ];
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- var args = <String>[];
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
- if (_configuration.hotReload) {
- args.add('--hot-reload-test-mode');
- } else if (_configuration.hotReloadRollback) {
- args.add('--hot-reload-rollback-test-mode');
- }
var filename = artifact.filename;
if (runtimeConfiguration is DartkAdbRuntimeConfiguration) {
// On Android the Dill file will be pushed to a different directory on the
// device. Use that one instead.
filename = "${DartkAdbRuntimeConfiguration.DeviceTestDir}/out.dill";
}
- return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(_replaceDartFiles(originalArguments, filename))
- ..addAll(dartOptions);
+
+ return [
+ if (_useEnableAsserts) '--enable_asserts',
+ if (_configuration.hotReload)
+ '--hot-reload-test-mode'
+ else if (_configuration.hotReloadRollback)
+ '--hot-reload-rollback-test-mode',
+ ...vmOptions,
+ ...testFile.sharedOptions,
+ ..._configuration.sharedOptions,
+ ..._replaceDartFiles(originalArguments, filename),
+ ...testFile.dartOptions
+ ];
}
}
@@ -358,31 +339,24 @@
List<String> args) {
// The result will be passed as an input to [extractArguments]
// (i.e. the arguments to the [PipelineCommand]).
- return <String>[]
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(args);
+ return [
+ ...vmOptions,
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...args
+ ];
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
CompilerConfiguration lastCompilerConfiguration =
pipelineCommands.last.compilerConfiguration;
return lastCompilerConfiguration.computeRuntimeArguments(
- runtimeConfiguration,
- info,
- vmOptions,
- sharedOptions,
- dartOptions,
- originalArguments,
- artifact);
+ runtimeConfiguration, testFile, vmOptions, originalArguments, artifact);
}
}
@@ -445,14 +419,6 @@
Dart2jsCompilerConfiguration(TestConfiguration configuration)
: super('dart2js', configuration);
- int get timeoutMultiplier {
- var multiplier = 1;
- if (_isDebug) multiplier *= 4;
- if (_isChecked) multiplier *= 2;
- if (_isHostChecked) multiplier *= 16;
- return multiplier;
- }
-
List<String> computeCompilerArguments(
List<String> vmOptions,
List<String> sharedOptions,
@@ -460,19 +426,18 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
- return <String>[]
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(dart2jsOptions)
- ..addAll(args);
+ return [
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...dart2jsOptions,
+ ...args
+ ];
}
CommandArtifact computeCompilationArtifact(String tempDir,
List<String> arguments, Map<String, String> environmentOverrides) {
- var compilerArguments = arguments.toList()
- ..addAll(_configuration.dart2jsOptions);
+ var compilerArguments = [...arguments, ..._configuration.dart2jsOptions];
- var commands = <Command>[];
// TODO(athom): input filename extraction is copied from DDC. Maybe this
// should be passed to computeCompilationArtifact, instead?
var inputFile = arguments.last;
@@ -483,22 +448,19 @@
if (babel != null && babel.isNotEmpty) {
out = out.replaceAll('.js', '.raw.js');
}
- commands.add(computeCompilationCommand(
- out, compilerArguments, environmentOverrides));
-
- if (babel != null && babel.isNotEmpty) {
- commands.add(computeBabelCommand(out, babelOut, babel));
- }
+ var commands = [
+ computeCompilationCommand(out, compilerArguments, environmentOverrides),
+ if (babel != null && babel.isNotEmpty)
+ computeBabelCommand(out, babelOut, babel)
+ ];
return CommandArtifact(commands, babelOut, 'application/javascript');
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
Uri sdk = _useSdk
@@ -545,13 +507,13 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
- var result = sharedOptions.toList()
- ..addAll(_configuration.sharedOptions)
- ..addAll(ddcOptions);
- // The file being compiled is the last argument.
- result.add(args.last);
-
- return result;
+ return [
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...ddcOptions,
+ // The file being compiled is the last argument.
+ args.last
+ ];
}
Command _createCommand(String inputFile, String outputFile,
@@ -653,8 +615,6 @@
class PrecompilerCompilerConfiguration extends CompilerConfiguration
with VMKernelCompilerMixin {
- final bool previewDart2;
-
bool get _isAndroid => _configuration.system == System.android;
bool get _isArm => _configuration.architecture == Architecture.arm;
@@ -663,8 +623,7 @@
bool get _isAot => true;
- PrecompilerCompilerConfiguration(TestConfiguration configuration,
- {this.previewDart2 = true})
+ PrecompilerCompilerConfiguration(TestConfiguration configuration)
: super._subclass(configuration);
int get timeoutMultiplier {
@@ -714,10 +673,10 @@
if (Platform.isWindows) {
exec = 'cmd.exe';
- args = <String>['/c', 'del', tempKernelFile(tempDir)];
+ args = ['/c', 'del', tempKernelFile(tempDir)];
} else {
exec = 'rm';
- args = <String>[tempKernelFile(tempDir)];
+ args = [tempKernelFile(tempDir)];
}
return Command.compilation('remove_kernel_file', tempDir,
@@ -728,7 +687,7 @@
Command computeDartBootstrapCommand(String tempDir, List<String> arguments,
Map<String, String> environmentOverrides) {
var buildDir = _configuration.buildDirectory;
- String exec = _configuration.genSnapshotPath;
+ var exec = _configuration.genSnapshotPath;
if (exec == null) {
if (_isAndroid) {
if (_isArm) {
@@ -741,27 +700,21 @@
}
}
- final args = <String>[];
- if (_configuration.useBlobs) {
- args.add("--snapshot-kind=app-aot-blobs");
- args.add("--blobs_container_filename=$tempDir/out.aotsnapshot");
- } else if (_configuration.useElf) {
- args.add("--snapshot-kind=app-aot-elf");
- args.add("--elf=$tempDir/out.aotsnapshot");
- } else {
- args.add("--snapshot-kind=app-aot-assembly");
- args.add("--assembly=$tempDir/out.S");
- }
-
- if (_isAndroid && _isArm) {
- args.add('--no-sim-use-hardfp');
- }
-
- if (_configuration.isMinified) {
- args.add('--obfuscate');
- }
-
- args.addAll(_replaceDartFiles(arguments, tempKernelFile(tempDir)));
+ var args = [
+ if (_configuration.useBlobs) ...[
+ "--snapshot-kind=app-aot-blobs",
+ "--blobs_container_filename=$tempDir/out.aotsnapshot"
+ ] else if (_configuration.useElf) ...[
+ "--snapshot-kind=app-aot-elf",
+ "--elf=$tempDir/out.aotsnapshot"
+ ] else ...[
+ "--snapshot-kind=app-aot-assembly",
+ "--assembly=$tempDir/out.S"
+ ],
+ if (_isAndroid && _isArm) '--no-sim-use-hardfp',
+ if (_configuration.isMinified) '--obfuscate',
+ ..._replaceDartFiles(arguments, tempKernelFile(tempDir))
+ ];
return Command.compilation('precompiler', tempDir, bootstrapDependencies(),
exec, args, environmentOverrides,
@@ -815,18 +768,18 @@
throw "Architecture not supported: ${_configuration.architecture.name}";
}
- var exec = cc;
- var args = <String>[];
- if (ccFlags != null) args.add(ccFlags);
- if (ldFlags != null) args.add(ldFlags);
- args.add(shared);
- args.add('-nostdlib');
- args.add('-o');
- args.add('$tempDir/out.aotsnapshot');
- args.add('$tempDir/out.S');
+ var args = [
+ if (ccFlags != null) ccFlags,
+ if (ldFlags != null) ldFlags,
+ shared,
+ '-nostdlib',
+ '-o',
+ '$tempDir/out.aotsnapshot',
+ '$tempDir/out.S'
+ ];
- return Command.compilation('assemble', tempDir, bootstrapDependencies(),
- exec, args, environmentOverrides,
+ return Command.compilation('assemble', tempDir, bootstrapDependencies(), cc,
+ args, environmentOverrides,
alwaysCompile: !_useSdk);
}
@@ -839,11 +792,8 @@
/// almost identical configurations are tested simultaneously.
Command computeRemoveAssemblyCommand(String tempDir, List arguments,
Map<String, String> environmentOverrides) {
- var exec = 'rm';
- var args = ['$tempDir/out.S'];
-
return Command.compilation('remove_assembly', tempDir,
- bootstrapDependencies(), exec, args, environmentOverrides,
+ bootstrapDependencies(), 'rm', ['$tempDir/out.S'], environmentOverrides,
alwaysCompile: !_useSdk);
}
@@ -863,29 +813,21 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> originalArguments) {
- List<String> args = [];
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
- return args
- ..addAll(filterVmOptions(vmOptions))
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(originalArguments);
+ return [
+ if (_useEnableAsserts) '--enable_asserts',
+ ...filterVmOptions(vmOptions),
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...originalArguments
+ ];
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- var args = <String>[];
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
var dir = artifact.filename;
if (runtimeConfiguration is DartPrecompiledAdbRuntimeConfiguration) {
// On android the precompiled snapshot will be pushed to a different
@@ -895,20 +837,19 @@
originalArguments =
_replaceDartFiles(originalArguments, "$dir/out.aotsnapshot");
- return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(originalArguments)
- ..addAll(dartOptions);
+ return [
+ if (_useEnableAsserts) '--enable_asserts',
+ ...vmOptions,
+ ...testFile.sharedOptions,
+ ..._configuration.sharedOptions,
+ ...originalArguments,
+ ...testFile.dartOptions
+ ];
}
}
class AppJitCompilerConfiguration extends CompilerConfiguration {
- final bool previewDart2;
-
- AppJitCompilerConfiguration(TestConfiguration configuration,
- {this.previewDart2 = true})
+ AppJitCompilerConfiguration(TestConfiguration configuration)
: super._subclass(configuration);
int get timeoutMultiplier {
@@ -929,13 +870,14 @@
Command computeCompilationCommand(String tempDir, List<String> arguments,
Map<String, String> environmentOverrides) {
- var exec = "${_configuration.buildDirectory}/dart";
var snapshot = "$tempDir/out.jitsnapshot";
- var args = ["--snapshot=$snapshot", "--snapshot-kind=app-jit"];
- args.addAll(arguments);
-
- return Command.compilation('app_jit', tempDir, bootstrapDependencies(),
- exec, args, environmentOverrides,
+ return Command.compilation(
+ 'app_jit',
+ tempDir,
+ bootstrapDependencies(),
+ "${_configuration.buildDirectory}/dart",
+ ["--snapshot=$snapshot", "--snapshot-kind=app-jit", ...arguments],
+ environmentOverrides,
alwaysCompile: !_useSdk);
}
@@ -946,36 +888,30 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> originalArguments) {
- var args = <String>[];
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
- return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(originalArguments)
- ..addAll(dartOptions);
+ return [
+ if (_useEnableAsserts) '--enable_asserts',
+ ...vmOptions,
+ ...sharedOptions,
+ ..._configuration.sharedOptions,
+ ...originalArguments,
+ ...dartOptions
+ ];
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- var args = <String>[];
- if (_useEnableAsserts) {
- args.add('--enable_asserts');
- }
- return args
- ..addAll(vmOptions)
- ..addAll(sharedOptions)
- ..addAll(_configuration.sharedOptions)
- ..addAll(_replaceDartFiles(originalArguments, artifact.filename))
- ..addAll(dartOptions);
+ return [
+ if (_useEnableAsserts) '--enable_asserts',
+ ...vmOptions,
+ ...testFile.sharedOptions,
+ ..._configuration.sharedOptions,
+ ..._replaceDartFiles(originalArguments, artifact.filename),
+ ...testFile.dartOptions
+ ];
}
}
@@ -988,7 +924,7 @@
String computeCompilerPath() {
var prefix = 'sdk/bin';
- String suffix = executableScriptSuffix;
+ var suffix = executableScriptSuffix;
if (_isHostChecked) {
if (_useSdk) {
throw "--host-checked and --use-sdk cannot be used together";
@@ -1006,32 +942,30 @@
CommandArtifact computeCompilationArtifact(String tempDir,
List<String> arguments, Map<String, String> environmentOverrides) {
- arguments = arguments.toList();
if (!previewDart2) {
throw ArgumentError('--no-preview-dart-2 not supported');
}
- if (_configuration.useAnalyzerCfe) {
- arguments.add('--use-cfe');
- }
- if (_configuration.useAnalyzerFastaParser) {
- arguments.add('--use-fasta-parser');
- }
+
+ var args = [
+ ...arguments,
+ if (_configuration.useAnalyzerCfe) '--use-cfe',
+ if (_configuration.useAnalyzerFastaParser) '--use-fasta-parser',
+ ];
// Since this is not a real compilation, no artifacts are produced.
- return CommandArtifact([
- Command.analysis(computeCompilerPath(), arguments, environmentOverrides)
- ], null, null);
+ return CommandArtifact(
+ [Command.analysis(computeCompilerPath(), args, environmentOverrides)],
+ null,
+ null);
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- return <String>[];
+ return [];
}
}
@@ -1052,7 +986,6 @@
CommandArtifact computeCompilationArtifact(String tempDir,
List<String> arguments, Map<String, String> environmentOverrides) {
- arguments = arguments.toList();
if (!previewDart2) {
throw ArgumentError('--no-preview-dart-2 not supported');
}
@@ -1060,19 +993,17 @@
// Since this is not a real compilation, no artifacts are produced.
return CommandArtifact([
Command.compareAnalyzerCfe(
- computeCompilerPath(), arguments, environmentOverrides)
+ computeCompilerPath(), arguments.toList(), environmentOverrides)
], null, null);
}
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- return <String>[];
+ return [];
}
}
@@ -1095,13 +1026,11 @@
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
- return <String>[];
+ return [];
}
}
@@ -1141,44 +1070,35 @@
kernelBinariesFolder += '/dart-sdk/lib/_internal';
}
- final vmPlatform = '$kernelBinariesFolder/vm_platform_strong.dill';
+ var vmPlatform = '$kernelBinariesFolder/vm_platform_strong.dill';
- final dillFile = tempKernelFile(tempDir);
+ var dillFile = tempKernelFile(tempDir);
- final args = [
+ var causalAsyncStacks = !arguments.any(noCausalAsyncStacksRegExp.hasMatch);
+
+ var args = [
_isAot ? '--aot' : '--no-aot',
'--platform=$vmPlatform',
'-o',
dillFile,
+ arguments.where((name) => name.endsWith('.dart')).single,
+ ...arguments.where((name) =>
+ name.startsWith('-D') ||
+ name.startsWith('--packages=') ||
+ name.startsWith('--enable-experiment=')),
+ '-Ddart.developer.causal_async_stacks=$causalAsyncStacks',
+ if (_useEnableAsserts ||
+ arguments.contains('--enable-asserts') ||
+ arguments.contains('--enable_asserts'))
+ '--enable-asserts',
+ if (_configuration.useKernelBytecode) ...[
+ '--gen-bytecode',
+ '--drop-ast',
+ '--bytecode-options=source-positions,local-var-info'
+ ]
];
- final batchArgs = <String>[];
- if (useAbiVersion != null) {
- batchArgs.add(useAbiVersion);
- }
-
- args.add(arguments.where((name) => name.endsWith('.dart')).single);
- args.addAll(arguments.where((name) =>
- name.startsWith('-D') ||
- name.startsWith('--packages=') ||
- name.startsWith('--enable-experiment=')));
-
- final bool causalAsyncStacks =
- !arguments.any((String arg) => noCausalAsyncStacksRegExp.hasMatch(arg));
- args.add('-Ddart.developer.causal_async_stacks=$causalAsyncStacks');
-
- if (_useEnableAsserts ||
- arguments.contains('--enable-asserts') ||
- arguments.contains('--enable_asserts')) {
- args.add('--enable-asserts');
- }
-
- if (_configuration.useKernelBytecode) {
- args.add('--gen-bytecode');
- args.add('--drop-ast');
- args.add('--emit-bytecode-source-positions');
- args.add('--emit-bytecode-local-var-info');
- }
+ var batchArgs = [if (useAbiVersion != null) useAbiVersion];
return Command.vmKernelCompilation(dillFile, true, bootstrapDependencies(),
genKernel, args, environmentOverrides, batchArgs);
@@ -1230,14 +1150,15 @@
Uri.base.resolveUri(Uri.directory(tempDir)).resolve("out.dill");
var outputFileName = output.toFilePath();
- var compilerArguments = <String>['--verify'];
- if (_isLegacy) {
- compilerArguments.add("--legacy-mode");
- }
-
- compilerArguments.addAll(
- ["-o", outputFileName, "--platform", _platformDill.toFilePath()]);
- compilerArguments.addAll(arguments);
+ var compilerArguments = [
+ '--verify',
+ if (_isLegacy) "--legacy-mode",
+ "-o",
+ outputFileName,
+ "--platform",
+ _platformDill.toFilePath(),
+ ...arguments
+ ];
return CommandArtifact([
Command.fasta(
@@ -1259,9 +1180,8 @@
List<String> dart2jsOptions,
List<String> ddcOptions,
List<String> args) {
- List<String> arguments = List<String>.from(sharedOptions);
- arguments.addAll(_configuration.sharedOptions);
- for (String argument in args) {
+ var arguments = [...sharedOptions, ..._configuration.sharedOptions];
+ for (var argument in args) {
if (argument == "--ignore-unrecognized-flags") continue;
arguments.add(argument);
if (!argument.startsWith("-")) {
@@ -1277,16 +1197,14 @@
@override
List<String> computeRuntimeArguments(
RuntimeConfiguration runtimeConfiguration,
- TestInformation info,
+ TestFile testFile,
List<String> vmOptions,
- List<String> sharedOptions,
- List<String> dartOptions,
List<String> originalArguments,
CommandArtifact artifact) {
if (runtimeConfiguration is! NoneRuntimeConfiguration) {
throw "--compiler=fasta only supports --runtime=none";
}
- return <String>[];
+ return [];
}
}
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index 987af25..ec1a0cf 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -73,7 +73,7 @@
import "dart:io";
import "path.dart";
-import "test_suite.dart";
+import "test_file.dart";
import "utils.dart";
/// Until legacy multitests are ported we need to support both /// and //#
@@ -90,7 +90,7 @@
'checked mode compile-time error' // This is now a no-op
].toSet();
-void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
+void _generateTestsFromMultitest(Path filePath, Map<String, String> tests,
Map<String, Set<String>> outcomes) {
var contents = File(filePath.toNativePath()).readAsStringSync();
@@ -162,31 +162,26 @@
}
}
-Future doMultitest(Path filePath, String outputDir, Path suiteDir,
- CreateTest doTest, bool hotReload) {
- void writeFile(String filepath, String content) {
- var file = File(filepath);
- if (file.existsSync()) {
- var oldContent = file.readAsStringSync();
- if (oldContent == content) {
- // Don't write to the file if the content is the same
- return;
- }
- }
- file.writeAsStringSync(content);
- }
-
- // Each new test is a single String value in the Map tests.
+/// Split the given [multitest] into a series of separate tests for each
+/// section.
+///
+/// Writes the resulting tests to [outputDir] and returns a list of [TestFile]s
+/// for each of those generated tests.
+Future<List<TestFile>> splitMultitest(
+ TestFile multitest, String outputDir, Path suiteDir,
+ {bool hotReload}) async {
+ // 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>{};
var outcomes = <String, Set<String>>{};
- extractTestsFromMultitest(filePath, tests, outcomes);
+ _generateTestsFromMultitest(multitest.path, tests, outcomes);
- var sourceDir = filePath.directoryPath;
+ var sourceDir = multitest.path.directoryPath;
var targetDir = _createMultitestDirectory(outputDir, suiteDir, sourceDir);
assert(targetDir != null);
// Copy all the relative imports of the multitest.
- var importsToCopy = _findAllRelativeImports(filePath);
+ var importsToCopy = _findAllRelativeImports(multitest.path);
var futureCopies = <Future>[];
for (var relativeImport in importsToCopy) {
var importPath = Path(relativeImport);
@@ -200,39 +195,56 @@
// 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.pipe(target));
+ futureCopies.add(source.cast<List<int>>().pipe(target));
}
// Wait until all imports are copied before scheduling test cases.
- return Future.wait(futureCopies).then((_) {
- var baseFilename = filePath.filenameWithoutExtension;
- for (var key in tests.keys) {
- var multitestFilename = targetDir.append('${baseFilename}_$key.dart');
- writeFile(multitestFilename.toNativePath(), tests[key]);
+ await Future.wait(futureCopies);
- var outcome = outcomes[key];
- var hasStaticWarning = outcome.contains('static type warning');
- var hasRuntimeError = outcome.contains('runtime error');
- var hasSyntaxError = outcome.contains('syntax error');
- var hasCompileError =
- hasSyntaxError || outcome.contains('compile-time error');
+ var baseFilename = multitest.path.filenameWithoutExtension;
- if (hotReload && hasCompileError) {
- // Running a test that expects a compilation error with hot reloading
- // is redundant with a regular run of the test.
- continue;
- }
+ var testFiles = <TestFile>[];
+ for (var test in tests.keys) {
+ var sectionFilePath = targetDir.append('${baseFilename}_$test.dart');
+ _writeFile(sectionFilePath.toNativePath(), tests[test]);
- doTest(multitestFilename, filePath,
- hasSyntaxError: hasSyntaxError,
- hasCompileError: hasCompileError,
- hasRuntimeError: hasRuntimeError,
- hasStaticWarning: hasStaticWarning,
- multitestKey: key);
+ var outcome = outcomes[test];
+ var hasStaticWarning = outcome.contains('static type warning');
+ var hasRuntimeError = outcome.contains('runtime error');
+ var hasSyntaxError = outcome.contains('syntax error');
+ var hasCompileError =
+ hasSyntaxError || outcome.contains('compile-time error');
+
+ if (hotReload && hasCompileError) {
+ // Running a test that expects a compilation error with hot reloading
+ // is redundant with a regular run of the test.
+ continue;
}
- return null;
- });
+ // Create a [TestFile] for each split out section test.
+ testFiles.add(multitest.split(sectionFilePath, test, tests[test],
+ hasSyntaxError: hasSyntaxError,
+ hasCompileError: hasCompileError,
+ hasRuntimeError: hasRuntimeError,
+ hasStaticWarning: hasStaticWarning));
+ }
+
+ return testFiles;
+}
+
+/// Writes [content] to [filePath] unless there is already a file at that path
+/// with the same content.
+void _writeFile(String filePath, String content) {
+ var file = File(filePath);
+
+ // Don't overwrite the file if the contents are the same. This way build
+ // systems don't think it has been modified.
+ if (file.existsSync()) {
+ var oldContent = file.readAsStringSync();
+ if (oldContent == content) return;
+ }
+
+ file.writeAsStringSync(content);
}
/// A multitest annotation in the special `//#` comment.
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 0d5c77c..9df9cb5 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -19,6 +19,7 @@
import 'output_log.dart';
import 'runtime_configuration.dart';
import 'test_case.dart';
+import 'test_file.dart';
import 'test_progress.dart';
import 'test_suite.dart';
import 'utils.dart';
@@ -236,7 +237,7 @@
// Cache information about test cases per test suite. For multiple
// configurations there is no need to repeatedly search the file
// system, generate tests, and search test files for options.
- var testCache = <String, List<TestInformation>>{};
+ var testCache = <String, List<TestFile>>{};
var iterator = testSuites.iterator;
void enqueueNextSuite() {
@@ -628,9 +629,23 @@
}
}
+ List<_StepFunction> _pushLibraries(AdbCommand command, AdbDevice device,
+ String deviceDir, String deviceTestDir) {
+ final List<_StepFunction> steps = [];
+ for (var lib in command.extraLibraries) {
+ var libName = "lib${lib}.so";
+ steps.add(() => device.runAdbCommand([
+ 'push',
+ '${command.buildPath}/$libName',
+ '$deviceTestDir/$libName'
+ ]));
+ }
+ return steps;
+ }
+
Future<CommandOutput> _runAdbPrecompilationCommand(
AdbDevice device, AdbPrecompilationCommand command, int timeout) async {
- var runner = command.precompiledRunnerFilename;
+ final String buildPath = command.buildPath;
var processTest = command.processTestFilename;
var testdir = command.precompiledTestDirectory;
var arguments = command.arguments;
@@ -651,8 +666,8 @@
steps.add(() => device.runAdbShellCommand(['rm', '-Rf', deviceTestDir]));
steps.add(() => device.runAdbShellCommand(['mkdir', '-p', deviceTestDir]));
- steps.add(() =>
- device.pushCachedData(runner, '$devicedir/dart_precompiled_runtime'));
+ steps.add(() => device.pushCachedData('$buildPath/dart_precompiled_runtime',
+ '$devicedir/dart_precompiled_runtime'));
steps.add(
() => device.pushCachedData(processTest, '$devicedir/process_test'));
steps.add(() => device.runAdbShellCommand([
@@ -661,6 +676,8 @@
'$devicedir/dart_precompiled_runtime $devicedir/process_test'
]));
+ steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
+
for (var file in files) {
steps.add(() => device
.runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file']));
@@ -668,7 +685,8 @@
steps.add(() => device.runAdbShellCommand(
[
- '$devicedir/dart_precompiled_runtime',
+ 'export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$deviceTestDir;'
+ '$devicedir/dart_precompiled_runtime',
]..addAll(arguments),
timeout: timeoutDuration));
@@ -722,11 +740,7 @@
steps.add(() => device
.runAdbCommand(['push', hostKernelFile, '$deviceTestDir/out.dill']));
- for (var lib in command.extraLibraries) {
- var libName = "lib${lib}.so";
- steps.add(() => device.runAdbCommand(
- ['push', '${buildPath}/$libName', '$deviceTestDir/$libName']));
- }
+ steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
steps.add(() => device.runAdbShellCommand(
[
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 16690f8..fa26f2d 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -369,11 +369,10 @@
throw "dart_precompiled cannot run files of type '$type'.";
}
- String precompiledRunner = dartPrecompiledBinaryFileName;
String processTest = processTestBinaryFileName;
return [
Command.adbPrecompiled(
- precompiledRunner, processTest, script, arguments, useBlobs, useElf)
+ buildDir, processTest, script, arguments, useBlobs, useElf, extraLibs)
];
}
}
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 6d1aa4e..af02960 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -15,7 +15,7 @@
import 'output_log.dart';
import 'process_queue.dart';
import 'repository.dart';
-import 'test_suite.dart';
+import 'test_file.dart';
import 'utils.dart';
const _slowTimeoutMultiplier = 4;
@@ -71,27 +71,27 @@
TestCase(this.displayName, this.commands, this.configuration,
this.expectedOutcomes,
- {TestInformation info}) {
+ {TestFile testFile}) {
// A test case should do something.
assert(commands.isNotEmpty);
- if (info != null) {
- _setExpectations(info);
- hash = (info?.originTestPath?.relativeTo(Repository.dir)?.toString())
+ if (testFile != null) {
+ _setExpectations(testFile);
+ hash = (testFile.originPath?.relativeTo(Repository.dir)?.toString())
.hashCode;
}
}
- void _setExpectations(TestInformation info) {
+ void _setExpectations(TestFile testFile) {
// We don't want to keep the entire (large) TestInformation structure,
// so we copy the needed bools into flags set in a single integer.
- if (info.hasRuntimeError) _expectations |= _hasRuntimeError;
- if (info.hasSyntaxError) _expectations |= _hasSyntaxError;
- if (info.hasCrash) _expectations |= _hasCrash;
- if (info.hasCompileError || info.hasSyntaxError) {
+ if (testFile.hasRuntimeError) _expectations |= _hasRuntimeError;
+ if (testFile.hasSyntaxError) _expectations |= _hasSyntaxError;
+ if (testFile.hasCrash) _expectations |= _hasCrash;
+ if (testFile.hasCompileError || testFile.hasSyntaxError) {
_expectations |= _hasCompileError;
}
- if (info.hasStaticWarning) _expectations |= _hasStaticWarning;
+ if (testFile.hasStaticWarning) _expectations |= _hasStaticWarning;
}
TestCase indexedCopy(int index) {
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
new file mode 100644
index 0000000..4279b8e
--- /dev/null
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -0,0 +1,675 @@
+// 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';
+
+import 'path.dart';
+
+final _multiHtmlTestGroupRegExp = RegExp(r"\s*[^/]\s*group\('[^,']*");
+final _multiHtmlTestRegExp = RegExp(r"useHtmlIndividualConfiguration\(\)");
+
+// TODO(rnystrom): Remove support for "///" once tests have been migrated.
+// https://dart-review.googlesource.com/c/sdk/+/106201
+// https://github.com/dart-lang/co19/issues/391
+/// Require at least one non-space character before '//[/#]'.
+final _multitestRegExp = RegExp(r"\S *//[#/] \w+:(.*)");
+
+final _vmOptionsRegExp = RegExp(r"// VMOptions=(.*)");
+final _environmentRegExp = RegExp(r"// Environment=(.*)");
+final _packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
+final _packagesRegExp = RegExp(r"// Packages=(.*)");
+
+List<String> _splitWords(String s) =>
+ s.split(' ').where((e) => e != '').toList();
+
+List<String> _parseOption(String filePath, String contents, String name,
+ {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>[];
+ for (var match in matches) {
+ options.addAll(_splitWords(match[1]));
+ }
+
+ return options;
+}
+
+/// A single error expectation comment from a [TestFile].
+///
+/// If a test contains any of these, then it is a "static error test" and
+/// exists to validate that a conforming front end produces the expected
+/// compile-time errors.
+///
+/// In order to make it easier to incrementally add error tests before a
+/// feature is fully implemented or specified, an error expectation can be in
+/// an "unspecified" state. That means all that's known is the line number. All
+/// other fields will be `null`. In that state, a front end is expected to
+/// report *some* error on that line, but it can be any location, error code, or
+/// message.
+///
+/// Aside from location, there are two interesting attributes of an error that
+/// a test can verify: its error code and the error message. Currently, for
+/// analyzer we only care about the error code. The CFE does not report an
+/// error code and only reports a message. So this class takes advantage of
+/// that by allowing you to set expectations for analyzer and CFE independently
+/// by assuming the [code] field is only used for the former and the [message]
+/// for the latter.
+class ErrorExpectation {
+ /// The one-based line number of the beginning of the error's location.
+ final int line;
+
+ /// The one-based column number of the beginning of the error's location.
+ final int column;
+
+ /// The number of characters in the error location.
+ final int length;
+
+ /// The expected analyzer error code for the error or `null` if this error
+ /// isn't expected to be reported by analyzer.
+ final String code;
+
+ /// The expected CFE error message or `null` if this error isn't expected to
+ /// be reported by the CFE.
+ final String message;
+
+ ErrorExpectation(
+ {this.line, this.column, this.length, this.code, this.message});
+
+ String toString() {
+ var result = "Error at line $line, column $column, length $length";
+ if (code != null) result += "\n$code";
+ if (message != null) result += "\n$message";
+ return result;
+ }
+}
+
+abstract class _TestFileBase {
+ /// The test suite directory containing this test.
+ final Path _suiteDirectory;
+
+ /// The full path to the test file.
+ final Path path;
+
+ /// The path to the original multitest file this test was generated from.
+ ///
+ /// If this test was not generated from a multitest, just returns [path].
+ Path get originPath;
+
+ /// The parsed error expectation markers in this test, if it is a static
+ /// error test.
+ final List<ErrorExpectation> expectedErrors;
+
+ /// The name of the multitest section this file corresponds to if it was
+ /// generated from a multitest. Otherwise, returns an empty string.
+ String get multitestKey;
+
+ _TestFileBase(this._suiteDirectory, this.path, this.expectedErrors) {
+ assert(path.isAbsolute);
+ }
+
+ /// The logical name of the test.
+ ///
+ /// This is its path relative to the test suite directory containing it,
+ /// minus any file extension. If this test was split from a multitest,
+ /// it contains the multitest key.
+ String get name {
+ var testNamePath = originPath.relativeTo(_suiteDirectory);
+ var directory = testNamePath.directoryPath;
+ var filenameWithoutExt = testNamePath.filenameWithoutExtension;
+
+ String concat(String base, String part) {
+ if (base == "") return part;
+ if (part == "") return base;
+ return "$base/$part";
+ }
+
+ var result = "$directory";
+ result = concat(result, "$filenameWithoutExt");
+ result = concat(result, multitestKey);
+ return result;
+ }
+}
+
+/// Represents a single ".dart" file used as a test and the parsed metadata it
+/// contains.
+///
+/// Special options for individual tests are currently specified in various
+/// ways: with comments directly in test files, by using certain imports, or
+/// by creating additional files in the test directories.
+///
+/// Here is a list of options that are used by 'test.dart' today:
+///
+/// * Flags can be passed to the VM process that runs the test by adding a
+/// comment to the test file:
+///
+/// // VMOptions=--flag1 --flag2
+///
+/// * Flags can be passed to dart2js, vm or dartdevc by adding a comment to
+/// the test file:
+///
+/// // SharedOptions=--flag1 --flag2
+///
+/// * Flags can be passed to dart2js by adding a comment to the test file:
+///
+/// // dart2jsOptions=--flag1 --flag2
+///
+/// * Flags can be passed to the dart script that contains the test also
+/// using comments, as follows:
+///
+/// // DartOptions=--flag1 --flag2
+///
+/// * Extra environment variables can be passed to the process that runs
+/// the test by adding comment(s) to the test file:
+///
+/// // Environment=ENV_VAR1=foo bar
+/// // Environment=ENV_VAR2=bazz
+///
+/// * Most tests are not web tests, but can (and will be) wrapped within an
+/// HTML file and another script file to test them also on browser
+/// environments (e.g. language and corelib tests are run this way). We
+/// deduce that if a file with the same name as the test, but ending in
+/// ".html" instead of ".dart" exists, the test was intended to be a web
+/// test and no wrapping is necessary.
+///
+/// * This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be in
+/// the system linker path of the VM.
+///
+/// // SharedObjects=foobar
+///
+/// * 'test.dart' assumes tests fail if the process returns a non-zero exit
+/// code (in the case of web tests, we check for PASS/FAIL indications in
+/// the test output).
+class TestFile extends _TestFileBase {
+ /// Read the test file from the given [filePath].
+ factory TestFile.read(Path suiteDirectory, String filePath) => TestFile.parse(
+ suiteDirectory, filePath, File(filePath).readAsStringSync());
+
+ /// Parse a test file with [contents].
+ factory TestFile.parse(
+ Path suiteDirectory, String filePath, String contents) {
+ if (filePath.endsWith('.dill')) {
+ return TestFile._(suiteDirectory, Path(filePath), [],
+ vmOptions: [[]],
+ sharedOptions: [],
+ dart2jsOptions: [],
+ ddcOptions: [],
+ dartOptions: [],
+ packageRoot: null,
+ packages: null,
+ hasSyntaxError: false,
+ hasCompileError: false,
+ hasRuntimeError: false,
+ hasStaticWarning: false,
+ hasCrash: false,
+ isMultitest: false,
+ isMultiHtmlTest: false,
+ subtestNames: [],
+ sharedObjects: [],
+ otherResources: []);
+ }
+
+ // VM options.
+ var vmOptions = <List<String>>[];
+ var matches = _vmOptionsRegExp.allMatches(contents);
+ for (var match in matches) {
+ vmOptions.add(_splitWords(match[1]));
+ }
+ 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);
+
+ // Environment.
+ Map<String, String> environment;
+ matches = _environmentRegExp.allMatches(contents);
+ for (var match in matches) {
+ var envDef = match[1];
+ var pos = envDef.indexOf('=');
+ var name = (pos < 0) ? envDef : envDef.substring(0, pos);
+ var value = (pos < 0) ? '' : envDef.substring(pos + 1);
+ environment ??= {};
+ environment[name] = value;
+ }
+
+ // Packages.
+ String packageRoot;
+ String packages;
+ matches = _packageRootRegExp.allMatches(contents);
+ for (var match in matches) {
+ if (packageRoot != null || packages != null) {
+ throw Exception('More than one "// Package... line in test $filePath');
+ }
+ packageRoot = match[1];
+ if (packageRoot != 'none') {
+ // PackageRoot=none means that no packages or package-root option
+ // should be given. Any other value overrides package-root and
+ // removes any packages option. Don't use with // Packages=.
+ packageRoot = Uri.file(filePath)
+ .resolveUri(Uri.directory(packageRoot))
+ .toFilePath();
+ }
+ }
+
+ matches = _packagesRegExp.allMatches(contents);
+ for (var match in matches) {
+ if (packages != null || packageRoot != null) {
+ throw Exception('More than one "// Package..." line in test $filePath');
+ }
+ packages = match[1];
+ if (packages != 'none') {
+ // Packages=none means that no packages or package-root option
+ // should be given. Any other value overrides packages and removes
+ // any package-root option. Don't use with // PackageRoot=.
+ packages =
+ Uri.file(filePath).resolveUri(Uri.file(packages)).toFilePath();
+ }
+ }
+
+ var isMultitest = _multitestRegExp.hasMatch(contents);
+ var isMultiHtmlTest = _multiHtmlTestRegExp.hasMatch(contents);
+
+ var subtestNames = <String>[];
+ if (isMultiHtmlTest) {
+ for (var match in _multiHtmlTestGroupRegExp.allMatches(contents)) {
+ var fullMatch = match.group(0);
+ subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
+ }
+ }
+
+ // TODO(rnystrom): During the migration of the existing tests to Dart 2.0,
+ // we have a number of tests that used to both generate static type warnings
+ // and also validate some runtime behavior in an implementation that
+ // ignores those warnings. Those warnings are now errors. The test code
+ // validates the runtime behavior can and should be removed, but the code
+ // that causes the static warning should still be preserved since that is
+ // part of our coverage of the static type system.
+ //
+ // The test needs to indicate that it should have a static error. We could
+ // put that in the status file, but that makes it confusing because it
+ // would look like implementations that *don't* report the error are more
+ // correct. Eventually, we want to have a notation similar to what front_end
+ // is using for the inference tests where we can put a comment inside the
+ // test that says "This specific static error should be reported right by
+ // this token."
+ //
+ // That system isn't in place yet, so we do a crude approximation here in
+ // test.dart. If a test contains `/*@compile-error=`, which matches the
+ // beginning of the tag syntax that front_end uses, then we assume that
+ // this test must have a static error somewhere in it.
+ //
+ // Redo this code once we have a more precise test framework for detecting
+ // and locating these errors.
+ var hasSyntaxError = contents.contains("@syntax-error");
+ var hasCompileError = hasSyntaxError || contents.contains("@compile-error");
+
+ List<ErrorExpectation> errorExpectations;
+ try {
+ errorExpectations = _ErrorExpectationParser(contents).parse();
+ } on FormatException catch (error) {
+ throw FormatException(
+ "Invalid error expectation syntax in $filePath:\n$error");
+ }
+
+ return TestFile._(suiteDirectory, Path(filePath), errorExpectations,
+ packageRoot: packageRoot,
+ packages: packages,
+ environment: environment,
+ isMultitest: isMultitest,
+ isMultiHtmlTest: isMultiHtmlTest,
+ hasSyntaxError: hasSyntaxError,
+ hasCompileError: hasCompileError,
+ hasRuntimeError: contents.contains("@runtime-error"),
+ hasStaticWarning: contents.contains("@static-warning"),
+ hasCrash: false,
+ subtestNames: subtestNames,
+ sharedOptions: sharedOptions,
+ dartOptions: dartOptions,
+ dart2jsOptions: dart2jsOptions,
+ ddcOptions: ddcOptions,
+ vmOptions: vmOptions,
+ sharedObjects: sharedObjects,
+ otherResources: otherResources);
+ }
+
+ /// A special fake test file for representing a VM unit test written in C++.
+ TestFile.vmUnitTest(
+ {this.hasSyntaxError,
+ this.hasCompileError,
+ this.hasRuntimeError,
+ this.hasStaticWarning,
+ this.hasCrash})
+ : packageRoot = null,
+ packages = null,
+ environment = null,
+ isMultitest = false,
+ isMultiHtmlTest = false,
+ subtestNames = [],
+ sharedOptions = [],
+ dartOptions = [],
+ dart2jsOptions = [],
+ ddcOptions = [],
+ vmOptions = [],
+ sharedObjects = [],
+ otherResources = [],
+ super(null, null, []);
+
+ TestFile._(
+ Path suiteDirectory, Path path, List<ErrorExpectation> expectedErrors,
+ {this.packageRoot,
+ this.packages,
+ this.environment,
+ this.isMultitest,
+ this.isMultiHtmlTest,
+ this.hasSyntaxError,
+ this.hasCompileError,
+ this.hasRuntimeError,
+ this.hasStaticWarning,
+ this.hasCrash,
+ this.subtestNames,
+ this.sharedOptions,
+ this.dartOptions,
+ this.dart2jsOptions,
+ this.ddcOptions,
+ this.vmOptions,
+ this.sharedObjects,
+ this.otherResources})
+ : super(suiteDirectory, path, expectedErrors) {
+ assert(!isMultitest || dartOptions.isEmpty);
+ }
+
+ Path get originPath => path;
+
+ String get multitestKey => "";
+
+ final String packageRoot;
+ final String packages;
+
+ final Map<String, String> environment;
+
+ final bool isMultitest;
+ final bool isMultiHtmlTest;
+ final bool hasSyntaxError;
+ final bool hasCompileError;
+ final bool hasRuntimeError;
+ final bool hasStaticWarning;
+ final bool hasCrash;
+
+ final List<String> subtestNames;
+ final List<String> sharedOptions;
+ final List<String> dartOptions;
+ final List<String> dart2jsOptions;
+ final List<String> ddcOptions;
+ final List<List<String>> vmOptions;
+ final List<String> sharedObjects;
+ final List<String> otherResources;
+
+ /// Derive a multitest test section file from this multitest file with the
+ /// given [multitestKey] and expectations.
+ TestFile split(Path path, String multitestKey, String contents,
+ {bool hasCompileError,
+ bool hasRuntimeError,
+ bool hasStaticWarning,
+ bool hasSyntaxError}) =>
+ _MultitestFile(
+ this, path, multitestKey, _ErrorExpectationParser(contents).parse(),
+ hasCompileError: hasCompileError ?? false,
+ hasRuntimeError: hasRuntimeError ?? false,
+ hasStaticWarning: hasStaticWarning ?? false,
+ hasSyntaxError: hasSyntaxError ?? false);
+
+ String toString() => """TestFile(
+ packageRoot: $packageRoot
+ packages: $packages
+ environment: $environment
+ isMultitest: $isMultitest
+ isMultiHtmlTest: $isMultiHtmlTest
+ hasSyntaxError: $hasSyntaxError
+ hasCompileError: $hasCompileError
+ hasRuntimeError: $hasRuntimeError
+ hasStaticWarning: $hasStaticWarning
+ hasCrash: $hasCrash
+ subtestNames: $subtestNames
+ sharedOptions: $sharedOptions
+ dartOptions: $dartOptions
+ dart2jsOptions: $dart2jsOptions
+ ddcOptions: $ddcOptions
+ vmOptions: $vmOptions
+ sharedObjects: $sharedObjects
+ otherResources: $otherResources
+)""";
+}
+
+/// A [TestFile] for a single section file derived from a multitest.
+///
+/// This inherits most properties from the original test file, but overrides
+/// the error flags based on the multitest section's expectation.
+class _MultitestFile extends _TestFileBase implements TestFile {
+ /// The authored test file that was split to generate this multitest.
+ final TestFile _origin;
+
+ final String multitestKey;
+
+ final bool hasCompileError;
+ final bool hasRuntimeError;
+ final bool hasStaticWarning;
+ final bool hasSyntaxError;
+ bool get hasCrash => _origin.hasCrash;
+
+ _MultitestFile(this._origin, Path path, this.multitestKey,
+ List<ErrorExpectation> expectedErrors,
+ {this.hasCompileError,
+ this.hasRuntimeError,
+ this.hasStaticWarning,
+ this.hasSyntaxError})
+ : super(_origin._suiteDirectory, path, expectedErrors);
+
+ Path get originPath => _origin.path;
+
+ String get packageRoot => _origin.packageRoot;
+ String get packages => _origin.packages;
+
+ List<String> get dart2jsOptions => _origin.dart2jsOptions;
+ List<String> get dartOptions => _origin.dartOptions;
+ List<String> get ddcOptions => _origin.ddcOptions;
+ Map<String, String> get environment => _origin.environment;
+
+ bool get isMultiHtmlTest => _origin.isMultiHtmlTest;
+ bool get isMultitest => _origin.isMultitest;
+
+ List<String> get otherResources => _origin.otherResources;
+ List<String> get sharedObjects => _origin.sharedObjects;
+ List<String> get sharedOptions => _origin.sharedOptions;
+ List<String> get subtestNames => _origin.subtestNames;
+ List<List<String>> get vmOptions => _origin.vmOptions;
+
+ TestFile split(Path path, String multitestKey, String contents,
+ {bool hasCompileError,
+ bool hasRuntimeError,
+ bool hasStaticWarning,
+ bool hasSyntaxError}) =>
+ throw UnsupportedError(
+ "Can't derive a test from one already derived from a multitest.");
+}
+
+class _ErrorExpectationParser {
+ /// Marks the location of an expected error, like so:
+ ///
+ /// int i = "s";
+ /// // ^^^
+ ///
+ /// We look for a line that starts with a line comment followed by spaces and
+ /// carets.
+ static final _caretLocationRegExp = RegExp(r"^\s*//\s*(\^+)\s*$");
+
+ /// Matches an explicit error location, like:
+ ///
+ /// // [error line 1, column 17, length 3]
+ static final _explicitLocationRegExp =
+ RegExp(r"^\s*//\s*\[\s*error line\s+(\d+)\s*,\s*column\s+(\d+)\s*,\s*"
+ r"length\s+(\d+)\s*\]\s*$");
+
+ /// An analyzer error code is a dotted identifier.
+ static final _unspecifiedErrorRegExp =
+ RegExp(r"^\s*// \[unspecified error\]");
+
+ /// An analyzer error expectation starts with "// [analyzer]".
+ static final _analyzerErrorRegExp = RegExp(r"^\s*// \[analyzer\]\s*(.*)");
+
+ /// An analyzer error code is a dotted identifier.
+ static final _errorCodeRegExp = RegExp(r"^\w+\.\w+$");
+
+ /// The first line of a CFE error expectation starts with "// [cfe]".
+ static final _cfeErrorRegExp = RegExp(r"^\s*// \[cfe\]\s*(.*)");
+
+ /// Any line-comment-only lines after the first line of a CFE error message are
+ /// part of it.
+ static final _errorMessageRestRegExp = RegExp(r"^\s*//\s*(.*)");
+
+ /// Matches the multitest marker and yields the preceding content.
+ final _stripMultitestRegExp = RegExp(r"(.*)//#");
+
+ final List<String> _lines;
+ final List<ErrorExpectation> _errors = [];
+ int _currentLine = 0;
+
+ /// One-based index of the last line that wasn't part of an error expectation.
+ int _lastRealLine = -1;
+
+ _ErrorExpectationParser(String source) : _lines = source.split("\n");
+
+ List<ErrorExpectation> parse() {
+ while (!_isAtEnd) {
+ var sourceLine = _peek(0);
+
+ var match = _caretLocationRegExp.firstMatch(sourceLine);
+ if (match != null) {
+ if (_lastRealLine == -1) {
+ _fail("An error expectation must follow some code.");
+ }
+
+ _parseErrorDetails(
+ line: _lastRealLine,
+ column: sourceLine.indexOf("^") + 1,
+ length: match.group(1).length);
+ _advance();
+ continue;
+ }
+
+ match = _explicitLocationRegExp.firstMatch(sourceLine);
+ if (match != null) {
+ _parseErrorDetails(
+ line: int.parse(match.group(1)),
+ column: int.parse(match.group(2)),
+ length: int.parse(match.group(3)));
+ _advance();
+ continue;
+ }
+
+ match = _unspecifiedErrorRegExp.firstMatch(sourceLine);
+ if (match != null) {
+ _errors.add(ErrorExpectation(line: _lastRealLine));
+ _advance();
+ continue;
+ }
+
+ _lastRealLine = _currentLine + 1;
+ _advance();
+ }
+
+ return _errors;
+ }
+
+ /// Finishes parsing an error expectation after parsing the location.
+ void _parseErrorDetails({int line, int column, int length}) {
+ String code;
+ String message;
+
+ // Look for an error code line.
+ if (!_isAtEnd) {
+ var match = _analyzerErrorRegExp.firstMatch(_peek(1));
+ if (match != null) {
+ code = match.group(1);
+
+ if (!_errorCodeRegExp.hasMatch(code)) {
+ _fail("An analyzer error expectation should be a dotted identifier.");
+ }
+
+ _advance();
+ }
+ }
+
+ // Look for an error message.
+ if (!_isAtEnd) {
+ var match = _cfeErrorRegExp.firstMatch(_peek(1));
+ if (match != null) {
+ message = match.group(1);
+ _advance();
+
+ // Consume as many additional error message lines as we find.
+ while (!_isAtEnd) {
+ var nextLine = _peek(1);
+
+ // A location line shouldn't be treated as a message.
+ if (_caretLocationRegExp.hasMatch(nextLine)) break;
+ if (_explicitLocationRegExp.hasMatch(nextLine)) break;
+
+ // Don't let users arbitrarily order the error code and message.
+ if (_analyzerErrorRegExp.hasMatch(nextLine)) {
+ _fail("An analyzer expectation must come before a CFE "
+ "expectation.");
+ }
+
+ var messageMatch = _errorMessageRestRegExp.firstMatch(nextLine);
+ if (messageMatch == null) break;
+
+ message += "\n" + messageMatch.group(1);
+ _advance();
+ }
+ }
+ }
+
+ if (code == null && message == null) {
+ _fail("An error expectation must specify at least an analyzer or CFE "
+ "error.");
+ }
+
+ _errors.add(ErrorExpectation(
+ line: line,
+ column: column,
+ length: length,
+ code: code,
+ message: message));
+ }
+
+ bool get _isAtEnd => _currentLine >= _lines.length;
+
+ void _advance() {
+ _currentLine++;
+ }
+
+ String _peek(int offset) {
+ var line = _lines[_currentLine + offset];
+
+ // Strip off any multitest marker.
+ var multitestMatch = _stripMultitestRegExp.firstMatch(line);
+ if (multitestMatch != null) {
+ line = multitestMatch.group(1).trimRight();
+ }
+
+ return line;
+ }
+
+ void _fail(String message) {
+ throw FormatException("Test error on line ${_currentLine + 1}: $message");
+ }
+}
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 1204a81..618a023 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -26,15 +26,10 @@
import 'summary_report.dart';
import 'test_case.dart';
import 'test_configurations.dart';
+import 'test_file.dart';
import 'testing_servers.dart';
import 'utils.dart';
-RegExp _multiHtmlTestGroupRegExp = RegExp(r"\s*[^/]\s*group\('[^,']*");
-RegExp _multiHtmlTestRegExp = RegExp(r"useHtmlIndividualConfiguration\(\)");
-
-/// Require at least one non-space character before '//[/#]'.
-RegExp _multiTestRegExp = RegExp(r"\S *//[#/] \w+:(.*)");
-
typedef TestCaseEvent = void Function(TestCase testCase);
/// A simple function that tests [arg] and returns `true` or `false`.
@@ -151,20 +146,20 @@
/// cache information about the test suite, so that directories do not need
/// to be listed each time.
Future forEachTest(
- TestCaseEvent onTest, Map<String, List<TestInformation>> testCache,
+ TestCaseEvent onTest, Map<String, List<TestFile>> testCache,
[VoidFunction onDone]);
- /// This function will be called for every TestCase of this test suite.
- /// It will:
- /// - handle sharding
- /// - update SummaryReport
- /// - handle SKIP/SKIP_BY_DESIGN markers
- /// - test if the selector matches
- /// and will enqueue the test (if necessary).
- void enqueueNewTestCase(
- String testName, List<Command> commands, Set<Expectation> expectations,
- [TestInformation info]) {
- var displayName = '$suiteName/$testName';
+ /// This function is called for every TestCase of this test suite. It:
+ ///
+ /// - 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) {
+ var displayName = '$suiteName/$fullName';
// If the test is not going to be run at all, then a RuntimeError,
// MissingRuntimeError or Timeout will never occur.
@@ -178,9 +173,9 @@
if (expectations.isEmpty) expectations.add(Expectation.pass);
}
- var negative = info != null ? isNegative(info) : false;
+ var negative = testFile != null ? isNegative(testFile) : false;
var testCase = TestCase(displayName, commands, configuration, expectations,
- info: info);
+ testFile: testFile);
if (negative &&
configuration.runtimeConfiguration.shouldSkipNegativeTests) {
return;
@@ -213,12 +208,12 @@
}
}
- // Update Summary report
+ // Update Summary report.
if (configuration.printReport) {
summaryReport.add(testCase);
}
- // Handle skipped tests
+ // Handle skipped tests.
if (expectations.contains(Expectation.skip) ||
expectations.contains(Expectation.skipByDesign) ||
expectations.contains(Expectation.skipSlow)) {
@@ -236,9 +231,9 @@
doTest(testCase);
}
- bool isNegative(TestInformation info) =>
- info.hasCompileError ||
- info.hasRuntimeError && configuration.runtime != Runtime.none;
+ bool isNegative(TestFile testFile) =>
+ testFile.hasCompileError ||
+ testFile.hasRuntimeError && configuration.runtime != Runtime.none;
String createGeneratedTestDirectoryHelper(
String name, String dirname, Path testPath) {
@@ -258,24 +253,6 @@
.replaceAll('\\', '/');
}
- String buildTestCaseDisplayName(Path suiteDir, Path originTestPath,
- {String multitestName = ""}) {
- Path testNamePath = originTestPath.relativeTo(suiteDir);
- var directory = testNamePath.directoryPath;
- var filenameWithoutExt = testNamePath.filenameWithoutExtension;
-
- String concat(String base, String part) {
- if (base == "") return part;
- if (part == "") return base;
- return "$base/$part";
- }
-
- var testName = "$directory";
- testName = concat(testName, "$filenameWithoutExt");
- testName = concat(testName, multitestName);
- return testName;
- }
-
/// Create a directories for generated assets (tests, html files,
/// pubspec checkouts ...).
String createOutputDirectory(Path testPath) {
@@ -364,11 +341,11 @@
}
void _addTest(ExpectationSet testExpectations, VMUnitTest test) {
- final fullName = 'cc/${test.name}';
+ var fullName = 'cc/${test.name}';
var expectations = testExpectations.expectations(fullName);
// Get the expectation from the cc/ test itself.
- final Expectation testExpectation = Expectation.find(test.expectation);
+ var testExpectation = Expectation.find(test.expectation);
// Update the legacy status-file based expectations to include
// [testExpectation].
@@ -378,26 +355,22 @@
}
// Update the new workflow based expectations to include [testExpectation].
- final Path filePath = null;
- final Path originTestPath = null;
- final hasSyntaxError = false;
- final hasStaticWarning = false;
- final hasCompileTimeError = testExpectation == Expectation.compileTimeError;
- final hasRuntimeError = testExpectation == Expectation.runtimeError;
- final hasCrash = testExpectation == Expectation.crash;
- final optionsFromFile = const <String, dynamic>{};
- final testInfo = TestInformation(filePath, originTestPath, optionsFromFile,
- hasSyntaxError, hasCompileTimeError, hasRuntimeError, hasStaticWarning,
- hasCrash: hasCrash);
+ var testFile = TestFile.vmUnitTest(
+ hasSyntaxError: false,
+ hasCompileError: testExpectation == Expectation.compileTimeError,
+ hasRuntimeError: testExpectation == Expectation.runtimeError,
+ hasStaticWarning: false,
+ hasCrash: testExpectation == Expectation.crash);
var args = configuration.standardOptions.toList();
if (configuration.compilerConfiguration.previewDart2) {
- final filename = configuration.architecture == Architecture.x64
+ var filename = configuration.architecture == Architecture.x64
? '$buildDir/gen/kernel-service.dart.snapshot'
: '$buildDir/gen/kernel_service.dill';
- final dfePath = Path(filename).absolute.toNativePath();
+ var dfePath = Path(filename).absolute.toNativePath();
// '--dfe' has to be the first argument for run_vm_test to pick it up.
args.insert(0, '--dfe=$dfePath');
+ args.addAll(configuration.vmOptions);
}
if (expectations.contains(Expectation.crash)) {
args.insert(0, '--suppress-core-dump');
@@ -405,9 +378,9 @@
args.add(test.name);
- final command = Command.process(
+ var command = Command.process(
'run_vm_unittest', targetRunnerPath, args, environmentOverrides);
- enqueueNewTestCase(fullName, [command], expectations, testInfo);
+ enqueueNewTestCase(testFile, fullName, [command], expectations);
}
Future<Iterable<VMUnitTest>> _listTests(String runnerPath) async {
@@ -435,37 +408,12 @@
VMUnitTest(this.name, this.expectation);
}
-class TestInformation {
- Path filePath;
- Path originTestPath;
- Map<String, dynamic> optionsFromFile;
- bool hasSyntaxError;
- bool hasCompileError;
- bool hasRuntimeError;
- bool hasStaticWarning;
- bool hasCrash;
- String multitestKey;
-
- TestInformation(
- this.filePath,
- this.originTestPath,
- this.optionsFromFile,
- this.hasSyntaxError,
- this.hasCompileError,
- this.hasRuntimeError,
- this.hasStaticWarning,
- {this.multitestKey = '',
- this.hasCrash = false}) {
- assert(filePath.isAbsolute);
- }
-}
-
/// A standard [TestSuite] implementation that searches for tests in a
/// directory, and creates [TestCase]s that compile and/or run them.
class StandardTestSuite extends TestSuite {
final Path suiteDir;
ExpectationSet testExpectations;
- List<TestInformation> cachedTests;
+ List<TestFile> cachedTests;
final Path dartDir;
final bool listRecursively;
final List<String> extraVmOptions;
@@ -581,19 +529,18 @@
List<String> additionalOptions(Path filePath) => [];
- Future forEachTest(
- Function onTest, Map<String, List<TestInformation>> testCache,
+ Future forEachTest(Function onTest, Map<String, List<TestFile>> testCache,
[VoidFunction onDone]) async {
doTest = onTest;
testExpectations = readExpectations();
// Check if we have already found and generated the tests for this suite.
if (!testCache.containsKey(suiteName)) {
- cachedTests = testCache[suiteName] = <TestInformation>[];
+ cachedTests = testCache[suiteName] = <TestFile>[];
await enqueueTests();
} else {
- for (var info in testCache[suiteName]) {
- enqueueTestCaseFromTestInformation(info);
+ for (var testFile in testCache[suiteName]) {
+ enqueueTestCaseFromTestFile(testFile);
}
}
testExpectations = null;
@@ -638,93 +585,73 @@
group.add(lister);
}
- void enqueueFile(String filename, FutureGroup group) {
+ void enqueueFile(String filePath, FutureGroup group) {
// This is an optimization to avoid scanning and generating extra tests.
// The definitive check against configuration.testList is performed in
// TestSuite.enqueueNewTestCase().
- if (_testListPossibleFilenames?.contains(filename) == false) return;
+ if (_testListPossibleFilenames?.contains(filePath) == false) return;
+
// Note: have to use Path instead of a filename for matching because
// on Windows we need to convert backward slashes to forward slashes.
// Our display test names (and filters) are given using forward slashes
// while filenames on Windows use backwards slashes.
- final Path filePath = Path(filename);
- if (!_selectorFilenameRegExp.hasMatch(filePath.toString())) return;
+ if (!_selectorFilenameRegExp.hasMatch(Path(filePath).toString())) return;
- if (!isTestFile(filename)) return;
+ if (!isTestFile(filePath)) return;
- var optionsFromFile = readOptionsFromFile(Uri.file(filename));
- CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
+ var testFile = TestFile.read(suiteDir, filePath);
- if (optionsFromFile['isMultitest'] as bool) {
- group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase,
- configuration.hotReload || configuration.hotReloadRollback));
+ 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);
+ }
+ }));
} else {
- createTestCase(filePath, filePath,
- hasSyntaxError: optionsFromFile['hasSyntaxError'] as bool,
- hasCompileError: optionsFromFile['hasCompileError'] as bool,
- hasRuntimeError: optionsFromFile['hasRuntimeError'] as bool,
- hasStaticWarning: optionsFromFile['hasStaticWarning'] as bool);
+ cachedTests.add(testFile);
+ enqueueTestCaseFromTestFile(testFile);
}
}
- void enqueueTestCaseFromTestInformation(TestInformation info) {
- String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
- multitestName: info.optionsFromFile['isMultitest'] as bool
- ? info.multitestKey
- : "");
- var optionsFromFile = info.optionsFromFile;
-
- // If this test is inside a package, we will check if there is a
- // pubspec.yaml file and if so, create a custom package root for it.
- Path packageRoot;
- Path packages;
-
- if (optionsFromFile['packageRoot'] == null &&
- optionsFromFile['packages'] == null) {
- if (configuration.packageRoot != null) {
- packageRoot = Path(configuration.packageRoot);
- optionsFromFile['packageRoot'] = packageRoot.toNativePath();
- }
- if (configuration.packages != null) {
- Path packages = Path(configuration.packages);
- optionsFromFile['packages'] = packages.toNativePath();
- }
- }
+ void enqueueTestCaseFromTestFile(TestFile testFile) {
if (configuration.compilerConfiguration.hasCompiler &&
- info.hasCompileError) {
+ testFile.hasCompileError) {
// 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(info, testName);
+ enqueueStandardTest(testFile);
} else if (configuration.runtime.isBrowser) {
var expectationsMap = <String, Set<Expectation>>{};
- if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
+ if (testFile.isMultiHtmlTest) {
// A browser multi-test has multiple expectations for one test file.
// Find all the different sub-test expectations for one entire test
// file.
- var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
+ var subtestNames = testFile.subtestNames;
expectationsMap = <String, Set<Expectation>>{};
for (var subtest in subtestNames) {
expectationsMap[subtest] =
- testExpectations.expectations('$testName/$subtest');
+ testExpectations.expectations('${testFile.name}/$subtest');
}
} else {
- expectationsMap[testName] = testExpectations.expectations(testName);
+ expectationsMap[testFile.name] =
+ testExpectations.expectations(testFile.name);
}
- _enqueueBrowserTest(
- packageRoot, packages, info, testName, expectationsMap);
+ _enqueueBrowserTest(testFile, expectationsMap);
} else {
- enqueueStandardTest(info, testName);
+ enqueueStandardTest(testFile);
}
}
- void enqueueStandardTest(TestInformation info, String testName) {
- var commonArguments =
- commonArgumentsFromFile(info.filePath, info.optionsFromFile);
+ void enqueueStandardTest(TestFile testFile) {
+ var commonArguments = _commonArgumentsFromFile(testFile);
- var vmOptionsList = getVmOptions(info.optionsFromFile);
+ var vmOptionsList = getVmOptions(testFile);
assert(!vmOptionsList.isEmpty);
for (var vmOptionsVariant = 0;
@@ -736,53 +663,44 @@
allVmOptions = vmOptions.toList()..addAll(extraVmOptions);
}
- var expectations = testExpectations.expectations(testName);
+ var expectations = testExpectations.expectations(testFile.name);
var isCrashExpected = expectations.contains(Expectation.crash);
- var commands = makeCommands(info, vmOptionsVariant, allVmOptions,
+ var commands = makeCommands(testFile, vmOptionsVariant, allVmOptions,
commonArguments, isCrashExpected);
- var variantTestName = testName;
+ var variantTestName = testFile.name;
if (vmOptionsList.length > 1) {
- variantTestName = "$testName/$vmOptionsVariant";
+ variantTestName = "${testFile.name}/$vmOptionsVariant";
}
- enqueueNewTestCase(variantTestName, commands, expectations, info);
+ enqueueNewTestCase(testFile, variantTestName, commands, expectations);
}
}
- List<Command> makeCommands(TestInformation info, int vmOptionsVariant,
+ List<Command> makeCommands(TestFile testFile, int vmOptionsVariant,
List<String> vmOptions, List<String> args, bool isCrashExpected) {
var commands = <Command>[];
var compilerConfiguration = configuration.compilerConfiguration;
- var sharedOptions = info.optionsFromFile['sharedOptions'] as List<String>;
- var dartOptions = info.optionsFromFile['dartOptions'] as List<String>;
- var dart2jsOptions = info.optionsFromFile['dart2jsOptions'] as List<String>;
- var ddcOptions = info.optionsFromFile['ddcOptions'] as List<String>;
-
- var isMultitest = info.optionsFromFile["isMultitest"] as bool;
- assert(!isMultitest || dartOptions.isEmpty);
var compileTimeArguments = <String>[];
String tempDir;
if (compilerConfiguration.hasCompiler) {
compileTimeArguments = compilerConfiguration.computeCompilerArguments(
vmOptions,
- sharedOptions,
- dartOptions,
- dart2jsOptions,
- ddcOptions,
+ testFile.sharedOptions,
+ testFile.dartOptions,
+ testFile.dart2jsOptions,
+ testFile.ddcOptions,
args);
// Avoid doing this for analyzer.
- var path = info.filePath;
+ var path = testFile.path;
if (vmOptionsVariant != 0) {
// Ensure a unique directory for each test case.
path = path.join(Path(vmOptionsVariant.toString()));
}
tempDir = createCompilationOutputDirectory(path);
- var otherResources =
- info.optionsFromFile['otherResources'] as List<String>;
- for (var name in otherResources) {
+ for (var name in testFile.otherResources) {
var namePath = Path(name);
- var fromPath = info.filePath.directoryPath.join(namePath);
+ var fromPath = testFile.path.directoryPath.join(namePath);
File('$tempDir/$name').parent.createSync(recursive: true);
File(fromPath.toNativePath()).copySync('$tempDir/$name');
}
@@ -794,7 +712,7 @@
commands.addAll(compilationArtifact.commands);
}
- if (info.hasCompileError &&
+ if (testFile.hasCompileError &&
compilerConfiguration.hasCompiler &&
!compilerConfiguration.runRuntimeDespiteMissingCompileTimeError) {
// Do not attempt to run the compiled result. A compilation
@@ -809,44 +727,22 @@
var runtimeArguments = compilerConfiguration.computeRuntimeArguments(
configuration.runtimeConfiguration,
- info,
+ testFile,
vmOptions,
- sharedOptions,
- dartOptions,
args,
compilationArtifact);
- var environment = environmentOverrides;
- var extraEnv = info.optionsFromFile['environment'] as Map<String, String>;
- if (extraEnv != null) {
- environment = {...environment, ...extraEnv};
- }
+ var environment = {...environmentOverrides, ...?testFile.environment};
return commands
..addAll(configuration.runtimeConfiguration.computeRuntimeCommands(
compilationArtifact,
runtimeArguments,
environment,
- info.optionsFromFile["sharedObjects"] as List<String>,
+ testFile.sharedObjects,
isCrashExpected));
}
- CreateTest makeTestCaseCreator(Map<String, dynamic> optionsFromFile) {
- return (Path filePath, Path originTestPath,
- {bool hasSyntaxError,
- bool hasCompileError,
- bool hasRuntimeError,
- bool hasStaticWarning = false,
- String multitestKey}) {
- // Cache the test information for each test case.
- var info = TestInformation(filePath, originTestPath, optionsFromFile,
- hasSyntaxError, hasCompileError, hasRuntimeError, hasStaticWarning,
- multitestKey: multitestKey);
- cachedTests.add(info);
- enqueueTestCaseFromTestInformation(info);
- };
- }
-
/// Takes a [file], which is either located in the dart or in the build
/// directory, and returns a String representing the relative path to either
/// the dart or the build directory.
@@ -907,26 +803,20 @@
///
/// 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, [testName].
+ /// a single key, [testFile.name].
void _enqueueBrowserTest(
- Path packageRoot,
- Path packages,
- TestInformation info,
- String testName,
- Map<String, Set<Expectation>> expectations) {
- var tempDir = createOutputDirectory(info.filePath);
- var fileName = info.filePath.toNativePath();
- var optionsFromFile = info.optionsFromFile;
- var compilationTempDir = createCompilationOutputDirectory(info.filePath);
- var nameNoExt = info.filePath.filenameWithoutExtension;
+ TestFile testFile, Map<String, Set<Expectation>> expectations) {
+ var tempDir = createOutputDirectory(testFile.path);
+ var compilationTempDir = createCompilationOutputDirectory(testFile.path);
+ var nameNoExt = testFile.path.filenameWithoutExtension;
var outputDir = compilationTempDir;
- var commonArguments =
- commonArgumentsFromFile(info.filePath, optionsFromFile);
+
+ var commonArguments = _commonArgumentsFromFile(testFile);
// Use existing HTML document if available.
String content;
var customHtml = File(
- info.filePath.directoryPath.append('$nameNoExt.html').toNativePath());
+ testFile.path.directoryPath.append('$nameNoExt.html').toNativePath());
if (customHtml.existsSync()) {
outputDir = tempDir;
content = customHtml.readAsStringSync().replaceAll(
@@ -936,7 +826,7 @@
if (configuration.compiler == Compiler.dart2js) {
var scriptPath =
_createUrlPathFromFile(Path('$compilationTempDir/$nameNoExt.js'));
- content = dart2jsHtml(fileName, scriptPath);
+ content = dart2jsHtml(testFile.path.toNativePath(), scriptPath);
} else {
var jsDir =
Path(compilationTempDir).relativeTo(Repository.dir).toString();
@@ -956,33 +846,40 @@
Compiler.dartdevk
};
assert(supportedCompilers.contains(configuration.compiler));
- var sharedOptions = optionsFromFile["sharedOptions"] as List<String>;
- var dart2jsOptions = optionsFromFile["dart2jsOptions"] as List<String>;
- var ddcOptions = optionsFromFile["ddcOptions"] as List<String>;
var args = configuration.compilerConfiguration.computeCompilerArguments(
- null, sharedOptions, null, dart2jsOptions, ddcOptions, commonArguments);
+ null,
+ testFile.sharedOptions,
+ null,
+ testFile.dart2jsOptions,
+ testFile.ddcOptions,
+ commonArguments);
var compilation = configuration.compilerConfiguration
.computeCompilationArtifact(outputDir, args, environmentOverrides);
commands.addAll(compilation.commands);
- if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
+ if (testFile.isMultiHtmlTest) {
// Variables for browser multi-tests.
- var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
+ var subtestNames = testFile.subtestNames;
for (var subtestName in subtestNames) {
- _enqueueSingleBrowserTest(commands, info, '$testName/$subtestName',
- subtestName, expectations[subtestName], htmlPath);
+ _enqueueSingleBrowserTest(
+ commands,
+ testFile,
+ '${testFile.name}/$subtestName',
+ subtestName,
+ expectations[subtestName],
+ htmlPath);
}
} else {
- _enqueueSingleBrowserTest(
- commands, info, testName, null, expectations[testName], htmlPath);
+ _enqueueSingleBrowserTest(commands, testFile, testFile.name, null,
+ expectations[testFile.name], htmlPath);
}
}
/// Enqueues a single browser test, or a single subtest of an HTML multitest.
void _enqueueSingleBrowserTest(
List<Command> commands,
- TestInformation info,
+ TestFile testFile,
String testName,
String subtestName,
Set<Expectation> expectations,
@@ -994,300 +891,66 @@
var fullHtmlPath = _uriForBrowserTest(htmlPathSubtest, subtestName);
commands.add(Command.browserTest(fullHtmlPath, configuration,
- retry: !isNegative(info)));
+ retry: !isNegative(testFile)));
var fullName = testName;
if (subtestName != null) fullName += "/$subtestName";
- enqueueNewTestCase(fullName, commands, expectations, info);
+ enqueueNewTestCase(testFile, fullName, commands, expectations);
}
- List<String> commonArgumentsFromFile(
- Path filePath, Map<String, dynamic> optionsFromFile) {
+ List<String> _commonArgumentsFromFile(TestFile testFile) {
var args = configuration.standardOptions.toList();
- var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
- optionsFromFile['packages'] as String);
+ var packages = packagesArgument(testFile.packageRoot, testFile.packages);
if (packages != null) {
args.add(packages);
}
- args.addAll(additionalOptions(filePath));
+ args.addAll(additionalOptions(testFile.path));
if (configuration.compiler == Compiler.dart2analyzer) {
args.add('--format=machine');
args.add('--no-hints');
- if (filePath.filename.contains("dart2js") ||
- filePath.directoryPath.segments().last.contains('html_common')) {
+ if (testFile.path.filename.contains("dart2js") ||
+ testFile.path.directoryPath.segments().last.contains('html_common')) {
args.add("--use-dart2js-libraries");
}
}
- args.add(filePath.toNativePath());
+ args.add(testFile.path.toNativePath());
return args;
}
- String packagesArgument(String packageRootFromFile, String packagesFromFile) {
- if (packageRootFromFile == 'none' || packagesFromFile == 'none') {
+ String packagesArgument(String packageRoot, String packages) {
+ // If this test is inside a package, we will check if there is a
+ // pubspec.yaml file and if so, create a custom package root for it.
+ if (packageRoot == null && packages == null) {
+ if (configuration.packageRoot != null) {
+ packageRoot = Path(configuration.packageRoot).toNativePath();
+ }
+
+ if (configuration.packages != null) {
+ packages = Path(configuration.packages).toNativePath();
+ }
+ }
+
+ if (packageRoot == 'none' || packages == 'none') {
return null;
- } else if (packagesFromFile != null) {
- return '--packages=$packagesFromFile';
- } else if (packageRootFromFile != null) {
- return '--package-root=$packageRootFromFile';
+ } else if (packages != null) {
+ return '--packages=$packages';
+ } else if (packageRoot != null) {
+ return '--package-root=$packageRoot';
} else {
return null;
}
}
- /// Special options for individual tests are currently specified in various
- /// ways: with comments directly in test files, by using certain imports, or
- /// by creating additional files in the test directories.
- ///
- /// Here is a list of options that are used by 'test.dart' today:
- /// - Flags can be passed to the vm process that runs the test by adding a
- /// comment to the test file:
- ///
- /// // VMOptions=--flag1 --flag2
- ///
- /// - Flags can be passed to dart2js, vm or dartdevc by adding a comment to
- /// the test file:
- ///
- /// // SharedOptions=--flag1 --flag2
- ///
- /// - Flags can be passed to dart2js by adding a comment to the test file:
- ///
- /// // dart2jsOptions=--flag1 --flag2
- ///
- /// - Flags can be passed to the dart script that contains the test also
- /// using comments, as follows:
- ///
- /// // DartOptions=--flag1 --flag2
- ///
- /// - Extra environment variables can be passed to the process that runs
- /// the test by adding comment(s) to the test file:
- ///
- /// // Environment=ENV_VAR1=foo bar
- /// // Environment=ENV_VAR2=bazz
- ///
- /// - Most tests are not web tests, but can (and will be) wrapped within
- /// an HTML file and another script file to test them also on browser
- /// environments (e.g. language and corelib tests are run this way).
- /// We deduce that if a file with the same name as the test, but ending in
- /// .html instead of .dart exists, the test was intended to be a web test
- /// and no wrapping is necessary.
- ///
- /// // SharedObjects=foobar
- ///
- /// - This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be
- /// in the system linker path of the VM.
- ///
- /// - 'test.dart' assumes tests fail if
- /// the process returns a non-zero exit code (in the case of web tests, we
- /// check for PASS/FAIL indications in the test output).
- ///
- /// This method is static as the map is cached and shared amongst
- /// configurations, so it may not use [configuration].
- Map<String, dynamic> readOptionsFromFile(Uri uri) {
- if (uri.path.endsWith('.dill')) {
- return optionsFromKernelFile();
- }
- var testOptionsRegExp = RegExp(r"// VMOptions=(.*)");
- var environmentRegExp = RegExp(r"// Environment=(.*)");
- var otherResourcesRegExp = RegExp(r"// OtherResources=(.*)");
- var sharedObjectsRegExp = RegExp(r"// SharedObjects=(.*)");
- var packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
- var packagesRegExp = RegExp(r"// Packages=(.*)");
- var isolateStubsRegExp = RegExp(r"// IsolateStubs=(.*)");
- // TODO(gram) Clean these up once the old directives are not supported.
- var domImportRegExp = RegExp(
- r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
- multiLine: true);
-
- var bytes = File.fromUri(uri).readAsBytesSync();
- var contents = decodeUtf8(bytes);
- bytes = null;
-
- // Find the options in the file.
- var result = <List<String>>[];
- List<String> dartOptions;
- List<String> sharedOptions;
- List<String> dart2jsOptions;
- List<String> ddcOptions;
- Map<String, String> environment;
- String packageRoot;
- String packages;
-
- List<String> wordSplit(String s) =>
- s.split(' ').where((e) => e != '').toList();
-
- List<String> singleListOfOptions(String name) {
- var matches = RegExp('// $name=(.*)').allMatches(contents);
- List<String> options;
- for (var match in matches) {
- if (options != null) {
- throw Exception(
- 'More than one "// $name=" line in test ${uri.toFilePath()}');
- }
- options = wordSplit(match[1]);
- }
- return options;
- }
-
- var matches = testOptionsRegExp.allMatches(contents);
- for (var match in matches) {
- result.add(wordSplit(match[1]));
- }
- if (result.isEmpty) result.add(<String>[]);
-
- dartOptions = singleListOfOptions('DartOptions');
- sharedOptions = singleListOfOptions('SharedOptions');
- dart2jsOptions = singleListOfOptions('dart2jsOptions');
- ddcOptions = singleListOfOptions('dartdevcOptions');
-
- matches = environmentRegExp.allMatches(contents);
- for (var match in matches) {
- var envDef = match[1];
- var pos = envDef.indexOf('=');
- var name = (pos < 0) ? envDef : envDef.substring(0, pos);
- var value = (pos < 0) ? '' : envDef.substring(pos + 1);
- environment ??= <String, String>{};
- environment[name] = value;
- }
-
- matches = packageRootRegExp.allMatches(contents);
- for (var match in matches) {
- if (packageRoot != null || packages != null) {
- throw Exception(
- 'More than one "// Package... line in test ${uri.toFilePath()}');
- }
- packageRoot = match[1];
- if (packageRoot != 'none') {
- // PackageRoot=none means that no packages or package-root option
- // should be given. Any other value overrides package-root and
- // removes any packages option. Don't use with // Packages=.
- packageRoot = uri.resolveUri(Uri.directory(packageRoot)).toFilePath();
- }
- }
-
- matches = packagesRegExp.allMatches(contents);
- for (var match in matches) {
- if (packages != null || packageRoot != null) {
- throw Exception(
- 'More than one "// Package..." line in test ${uri.toFilePath()}');
- }
- packages = match[1];
- if (packages != 'none') {
- // Packages=none means that no packages or package-root option
- // should be given. Any other value overrides packages and removes
- // any package-root option. Don't use with // PackageRoot=.
- packages = uri.resolveUri(Uri.file(packages)).toFilePath();
- }
- }
-
- var otherResources = <String>[];
- matches = otherResourcesRegExp.allMatches(contents);
- for (var match in matches) {
- otherResources.addAll(wordSplit(match[1]));
- }
-
- var sharedObjects = <String>[];
- matches = sharedObjectsRegExp.allMatches(contents);
- for (var match in matches) {
- sharedObjects.addAll(wordSplit(match[1]));
- }
-
- var isMultitest = _multiTestRegExp.hasMatch(contents);
- var isMultiHtmlTest = _multiHtmlTestRegExp.hasMatch(contents);
- var isolateMatch = isolateStubsRegExp.firstMatch(contents);
- var isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
- var containsDomImport = domImportRegExp.hasMatch(contents);
-
- var subtestNames = <String>[];
- var matchesIter = _multiHtmlTestGroupRegExp.allMatches(contents).iterator;
- while (matchesIter.moveNext() && isMultiHtmlTest) {
- var fullMatch = matchesIter.current.group(0);
- subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
- }
-
- // TODO(rnystrom): During the migration of the existing tests to Dart 2.0,
- // we have a number of tests that used to both generate static type warnings
- // and also validate some runtime behavior in an implementation that
- // ignores those warnings. Those warnings are now errors. The test code
- // validates the runtime behavior can and should be removed, but the code
- // that causes the static warning should still be preserved since that is
- // part of our coverage of the static type system.
- //
- // The test needs to indicate that it should have a static error. We could
- // put that in the status file, but that makes it confusing because it
- // would look like implementations that *don't* report the error are more
- // correct. Eventually, we want to have a notation similar to what front_end
- // is using for the inference tests where we can put a comment inside the
- // test that says "This specific static error should be reported right by
- // this token."
- //
- // That system isn't in place yet, so we do a crude approximation here in
- // test.dart. If a test contains `/*@compile-error=`, which matches the
- // beginning of the tag syntax that front_end uses, then we assume that
- // this test must have a static error somewhere in it.
- //
- // Redo this code once we have a more precise test framework for detecting
- // and locating these errors.
- final hasSyntaxError = contents.contains("@syntax-error");
- final hasCompileError =
- hasSyntaxError || contents.contains("@compile-error");
- final hasRuntimeError = contents.contains("@runtime-error");
- final hasStaticWarning = contents.contains("@static-warning");
-
- return {
- "vmOptions": result,
- "sharedOptions": sharedOptions ?? <String>[],
- "dart2jsOptions": dart2jsOptions ?? <String>[],
- "ddcOptions": ddcOptions ?? <String>[],
- "dartOptions": dartOptions ?? <String>[],
- "environment": environment,
- "packageRoot": packageRoot,
- "packages": packages,
- "hasSyntaxError": hasSyntaxError,
- "hasCompileError": hasCompileError,
- "hasRuntimeError": hasRuntimeError,
- "hasStaticWarning": hasStaticWarning,
- "otherResources": otherResources,
- "sharedObjects": sharedObjects,
- "isMultitest": isMultitest,
- "isMultiHtmlTest": isMultiHtmlTest,
- "subtestNames": subtestNames,
- "isolateStubs": isolateStubs,
- "containsDomImport": containsDomImport
- };
- }
-
- Map<String, dynamic> optionsFromKernelFile() {
- return const {
- "vmOptions": [<String>[]],
- "sharedOptions": <String>[],
- "dart2jsOptions": <String>[],
- "dartOptions": <String>[],
- "packageRoot": null,
- "packages": null,
- "hasSyntaxError": false,
- "hasCompileError": false,
- "hasRuntimeError": false,
- "hasStaticWarning": false,
- "isMultitest": false,
- "isMultiHtmlTest": false,
- "subtestNames": [],
- "isolateStubs": '',
- "containsDomImport": false,
- };
- }
-
- List<List<String>> getVmOptions(Map<String, dynamic> optionsFromFile) {
+ List<List<String>> getVmOptions(TestFile testFile) {
const compilers = [
Compiler.none,
Compiler.dartk,
Compiler.dartkb,
Compiler.dartkp,
- Compiler.precompiler,
- Compiler.appJit,
Compiler.appJitk,
];
@@ -1296,7 +959,7 @@
var needsVmOptions = compilers.contains(configuration.compiler) &&
runtimes.contains(configuration.runtime);
if (!needsVmOptions) return [[]];
- return optionsFromFile['vmOptions'] as List<List<String>>;
+ return testFile.vmOptions;
}
}
@@ -1308,21 +971,20 @@
["$directoryPath/.status"],
recursive: true);
- void _enqueueBrowserTest(Path packageRoot, packages, TestInformation info,
- String testName, Map<String, Set<Expectation>> expectations) {
- var filePath = info.filePath;
- var dir = filePath.directoryPath;
- var nameNoExt = filePath.filenameWithoutExtension;
+ void _enqueueBrowserTest(
+ TestFile testFile, Map<String, Set<Expectation>> expectations) {
+ 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(
- packageRoot, packages, info, testName, expectations);
+ super._enqueueBrowserTest(testFile, expectations);
} else {
var fullPath = _createUrlPathFromFile(customHtmlPath);
var command = Command.browserTest(fullPath, configuration,
- retry: !isNegative(info));
- enqueueNewTestCase(testName, [command], expectations[testName], info);
+ retry: !isNegative(testFile));
+ enqueueNewTestCase(
+ testFile, testFile.name, [command], expectations[testFile.name]);
}
}
}
diff --git a/pkg/test_runner/lib/src/testing_servers.dart b/pkg/test_runner/lib/src/testing_servers.dart
index 92d3949..06a1fc5 100644
--- a/pkg/test_runner/lib/src/testing_servers.dart
+++ b/pkg/test_runner/lib/src/testing_servers.dart
@@ -223,7 +223,7 @@
void _handleEchoRequest(HttpRequest request) {
request.response.headers.set("Access-Control-Allow-Origin", "*");
- request.pipe(request.response).catchError((e) {
+ request.cast<List<int>>().pipe(request.response).catchError((e) {
DebugLogger.warning(
'HttpServer: error while closing the response stream', e);
});
@@ -373,7 +373,7 @@
response.headers.set('Content-Type', 'text/xml');
}
response.headers.removeAll("X-Frame-Options");
- file.openRead().pipe(response).catchError((e) {
+ file.openRead().cast<List<int>>().pipe(response).catchError((e) {
DebugLogger.warning(
'HttpServer: error while closing the response stream', e);
});
diff --git a/pkg/test_runner/lib/src/utils.dart b/pkg/test_runner/lib/src/utils.dart
index 1d1d0a5..121b235 100644
--- a/pkg/test_runner/lib/src/utils.dart
+++ b/pkg/test_runner/lib/src/utils.dart
@@ -424,9 +424,7 @@
}
static void deleteTempSnapshotDirectory(TestConfiguration configuration) {
- if (configuration.compiler == Compiler.appJit ||
- configuration.compiler == Compiler.precompiler ||
- configuration.compiler == Compiler.dartk ||
+ if (configuration.compiler == Compiler.dartk ||
configuration.compiler == Compiler.dartkb ||
configuration.compiler == Compiler.dartkp) {
var checked = configuration.isChecked ? '-checked' : '';
diff --git a/pkg/test_runner/test/test_file_test.dart b/pkg/test_runner/test/test_file_test.dart
new file mode 100644
index 0000000..9d42f3d
--- /dev/null
+++ b/pkg/test_runner/test/test_file_test.dart
@@ -0,0 +1,509 @@
+// 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';
+
+import 'package:expect/expect.dart';
+
+import 'package:test_runner/src/path.dart';
+import 'package:test_runner/src/test_file.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
+// here as significant, so we obfuscate them using seemingly-pointless string
+// escapes here like `\/`.
+
+void main() {
+ testParseDill();
+ testParseVMOptions();
+ testParseOtherOptions();
+ testParseEnvironment();
+ testParsePackages();
+ testParseMultitest();
+ testParseMultiHtmltest();
+ testParseErrorFlags();
+ testParseErrorExpectations();
+ testName();
+ testMultitest();
+}
+
+void testParseDill() {
+ // Handles ".dill" files.
+ var file = parse("", path: "test.dill");
+ Expect.isNotNull(file.vmOptions);
+ Expect.equals(1, file.vmOptions.length);
+ Expect.listEquals(<String>[], file.vmOptions.first);
+
+ 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.isNull(file.environment);
+ Expect.isNull(file.packages);
+
+ Expect.isFalse(file.isMultitest);
+
+ Expect.isFalse(file.hasSyntaxError);
+ Expect.isFalse(file.hasCompileError);
+ Expect.isFalse(file.hasRuntimeError);
+ Expect.isFalse(file.hasStaticWarning);
+ Expect.isFalse(file.hasCrash);
+}
+
+void testParseVMOptions() {
+ expectVMOptions(String source, List<List<String>> expected) {
+ var file = parse(source);
+ Expect.isNotNull(file.vmOptions);
+ Expect.equals(expected.length, file.vmOptions.length);
+ for (var i = 0; i < expected.length; i++) {
+ Expect.listEquals(expected[i], file.vmOptions[i]);
+ }
+ }
+
+ // No options.
+ expectVMOptions("", [[]]);
+
+ // Splits words.
+ expectVMOptions("/\/ VMOptions=--verbose --async", [
+ ["--verbose", "--async"]
+ ]);
+
+ // Allows multiple.
+ expectVMOptions("""
+ /\/ VMOptions=--first one
+ /\/ VMOptions=--second two
+ """, [
+ ["--first", "one"],
+ ["--second", "two"]
+ ]);
+}
+
+void testParseOtherOptions() {
+ // No options.
+ var file = parse("");
+ 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);
+
+ // Single options split into words.
+ file = parse("""
+ /\/ DartOptions=dart options
+ /\/ SharedOptions=shared options
+ /\/ dart2jsOptions=dart2js options
+ /\/ dartdevcOptions=ddc options
+ /\/ OtherResources=other resources
+ /\/ SharedObjects=shared objects
+ """);
+ 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);
+
+ // Disallows multiple lines for some options.
+ expectParseThrows("""
+ /\/ DartOptions=first
+ /\/ DartOptions=second
+ """);
+ expectParseThrows("""
+ /\/ SharedOptions=first
+ /\/ SharedOptions=second
+ """);
+ expectParseThrows("""
+ /\/ dart2jsOptions=first
+ /\/ dart2jsOptions=second
+ """);
+ expectParseThrows("""
+ /\/ dartdevcOptions=first
+ /\/ dartdevcOptions=second
+ """);
+
+ // Merges multiple lines for others.
+ file = parse("""
+ /\/ OtherResources=other resources
+ /\/ OtherResources=even more
+ /\/ SharedObjects=shared objects
+ /\/ SharedObjects=many more
+ """);
+ Expect.listEquals(
+ ["other", "resources", "even", "more"], file.otherResources);
+ Expect.listEquals(["shared", "objects", "many", "more"], file.sharedObjects);
+}
+
+void testParseEnvironment() {
+ // No environment.
+ var file = parse("");
+ Expect.isNull(file.environment);
+
+ // Without values.
+ file = parse("""
+ /\/ Environment=some value
+ /\/ Environment=another one
+ """);
+ Expect.mapEquals({"some value": "", "another one": ""}, file.environment);
+
+ // With values.
+ file = parse("""
+ /\/ Environment=some value=its value
+ /\/ Environment=another one = also value
+ """);
+ Expect.mapEquals(
+ {"some value": "its value", "another one ": " also value"},
+ file.environment);
+}
+
+void testParsePackages() {
+ // No option.
+ var file = parse("");
+ Expect.isNull(file.packages);
+
+ // Single option is converted to a path.
+ file = parse("""
+ /\/ Packages=packages thing
+ """);
+ Expect.isTrue(
+ file.packages.endsWith("${Platform.pathSeparator}packages thing"));
+
+ // "none" is left alone.
+ file = parse("""
+ /\/ Packages=none
+ """);
+ Expect.equals("none", file.packages);
+
+ // Cannot appear more than once.
+ expectParseThrows("""
+ /\/ Packages=first
+ /\/ Packages=second
+ """);
+}
+
+void testParseMultitest() {
+ // Not present.
+ var file = parse("");
+ Expect.isFalse(file.isMultitest);
+
+ // Present.
+ file = parse("""
+ main() {} /\/# 01: compile-time error
+ """);
+ Expect.isTrue(file.isMultitest);
+}
+
+void testParseMultiHtmltest() {
+ // Not present.
+ var file = parse("");
+ 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("""
+ main() {
+ useHtml\IndividualConfiguration();
+ group('pixel_manipulation', () {
+ });
+ group('arc', () {
+ });
+ group('drawImage_image_element', () {
+ });
+ }
+ """);
+ Expect.isTrue(file.isMultiHtmlTest);
+ Expect.listEquals(["pixel_manipulation", "arc", "drawImage_image_element"],
+ file.subtestNames);
+}
+
+void testParseErrorFlags() {
+ // Not present.
+ var file = parse("");
+ Expect.isFalse(file.hasSyntaxError);
+ Expect.isFalse(file.hasCompileError);
+ Expect.isFalse(file.hasRuntimeError);
+ Expect.isFalse(file.hasStaticWarning);
+ Expect.isFalse(file.hasCrash);
+
+ file = parse("@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");
+ Expect.isFalse(file.hasSyntaxError);
+ Expect.isTrue(file.hasCompileError);
+ Expect.isFalse(file.hasRuntimeError);
+ Expect.isFalse(file.hasStaticWarning);
+ Expect.isFalse(file.hasCrash);
+
+ file = parse("@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");
+ Expect.isFalse(file.hasSyntaxError);
+ Expect.isFalse(file.hasCompileError);
+ Expect.isFalse(file.hasRuntimeError);
+ Expect.isTrue(file.hasStaticWarning);
+ Expect.isFalse(file.hasCrash);
+}
+
+void testParseErrorExpectations() {
+ // No errors.
+ expectParseErrorExpectations("""
+main() {}
+""", []);
+
+ // Empty file
+ expectParseErrorExpectations("", []);
+
+ // Multiple errors.
+ expectParseErrorExpectations("""
+int i = "s";
+/\/ ^^^
+/\/ [analyzer] CompileTimeErrorCode.WRONG_TYPE
+/\/ [cfe] Error: Can't assign a string to an int.
+
+num j = "str";
+ /\/ ^^^^^
+/\/ [analyzer] CompileTimeErrorCode.ALSO_WRONG_TYPE
+ /\/ [cfe] Error: Can't assign a string to a num.
+""", [
+ ErrorExpectation(
+ line: 1,
+ column: 9,
+ length: 3,
+ code: "CompileTimeErrorCode.WRONG_TYPE",
+ message: "Error: Can't assign a string to an int."),
+ ErrorExpectation(
+ line: 6,
+ column: 9,
+ length: 5,
+ code: "CompileTimeErrorCode.ALSO_WRONG_TYPE",
+ message: "Error: Can't assign a string to a num.")
+ ]);
+
+ // Explicit error location.
+ expectParseErrorExpectations("""
+/\/ [error line 123, column 45, length 678]
+/\/ [analyzer] CompileTimeErrorCode.FIRST
+/\/ [cfe] First error.
+ /\/ [ error line 23 , column 5 , length 78 ]
+/\/ [analyzer] CompileTimeErrorCode.SECOND
+/\/ [cfe] Second error.
+/\/[error line 9,column 8,length 7]
+/\/ [cfe] Third.
+""", [
+ ErrorExpectation(
+ line: 123,
+ column: 45,
+ length: 678,
+ code: "CompileTimeErrorCode.FIRST",
+ message: "First error."),
+ ErrorExpectation(
+ line: 23,
+ column: 5,
+ length: 78,
+ code: "CompileTimeErrorCode.SECOND",
+ message: "Second error."),
+ ErrorExpectation(line: 9, column: 8, length: 7, message: "Third.")
+ ]);
+
+ // Multi-line error message.
+ expectParseErrorExpectations("""
+int i = "s";
+/\/ ^^^
+/\/ [analyzer] CompileTimeErrorCode.WRONG_TYPE
+/\/ [cfe] First line.
+/\/Second line.
+ /\/ Third line.
+
+/\/ The preceding blank line ends the message.
+""", [
+ ErrorExpectation(
+ line: 1,
+ column: 9,
+ length: 3,
+ code: "CompileTimeErrorCode.WRONG_TYPE",
+ message: "First line.\nSecond line.\nThird line.")
+ ]);
+
+ // Multiple errors attached to same line.
+ expectParseErrorExpectations("""
+main() {}
+int i = "s";
+/\/ ^^^
+/\/ [cfe] First error.
+/\/ ^
+/\/ [analyzer] ErrorCode.second
+/\/ ^^^^^^^
+/\/ [cfe] Third error.
+""", [
+ ErrorExpectation(line: 2, column: 9, length: 3, message: "First error."),
+ ErrorExpectation(line: 2, column: 7, length: 1, code: "ErrorCode.second"),
+ ErrorExpectation(line: 2, column: 5, length: 7, message: "Third error."),
+ ]);
+
+ // Unspecified errors.
+ expectParseErrorExpectations("""
+int i = "s";
+/\/ [unspecified error]
+int j = "s";
+ /\/ [unspecified error] some additional info
+""", [
+ ErrorExpectation(
+ line: 1, column: null, length: null, code: null, message: null),
+ ErrorExpectation(
+ line: 3, column: null, length: null, code: null, message: null)
+ ]);
+
+ // Ignore multitest markers.
+ expectParseErrorExpectations("""
+int i = "s";
+/\/ ^^^ /\/# 0: ok
+/\/ [analyzer] ErrorCode.BAD_THING /\/# 123: continued
+/\/ [cfe] Message. /\/# named: compile-time error
+/\/ More message. /\/# another: ok
+/\/ [error line 12, column 34, length 56] /\/# 3: continued
+/\/ [cfe] Message.
+""", [
+ ErrorExpectation(
+ line: 1,
+ column: 9,
+ length: 3,
+ code: "ErrorCode.BAD_THING",
+ message: "Message.\nMore message."),
+ ErrorExpectation(line: 12, column: 34, length: 56, message: "Message."),
+ ]);
+
+ // Must have either a code or a message.
+ expectFormatError("""
+int i = "s";
+/\/ ^^^
+
+var wrong;
+""");
+
+ // Location must follow some real code.
+ expectFormatError("""
+/\/ [error line 123, column 45, length 678]
+/\/ [analyzer] CompileTimeErrorCode.FIRST
+/\/ ^^^
+/\/ [cfe] This doesn't make sense.
+""");
+
+ // Location at end without code or message.
+ expectFormatError("""
+int i = "s";
+/\/ ^^^
+""");
+
+ // Code cannot follow message.
+ expectFormatError("""
+int i = "s";
+/\/ ^^^
+/\/ [cfe] Error message.
+/\/ [analyzer] ErrorCode.BAD_THING
+""");
+
+ // Analyzer error must look like an error code.
+ expectFormatError("""
+int i = "s";
+/\/ ^^^
+/\/ [analyzer] Not error code.
+""");
+}
+
+void testName() {
+ // Immediately inside suite.
+ var file = TestFile.parse(Path("suite").absolute,
+ Path("suite/a_test.dart").absolute.toNativePath(), "");
+ Expect.equals("a_test", file.name);
+
+ // Inside subdirectory.
+ file = TestFile.parse(Path("suite").absolute,
+ Path("suite/a/b/c_test.dart").absolute.toNativePath(), "");
+ Expect.equals("a/b/c_test", file.name);
+
+ // Multitest.
+ file = file.split(Path("suite/a/b/c_test_00.dart").absolute, "00", "");
+ Expect.equals("a/b/c_test/00", file.name);
+}
+
+void testMultitest() {
+ var file = parse("", path: "origin.dart");
+ Expect.isFalse(file.hasSyntaxError);
+ Expect.isFalse(file.hasCompileError);
+ Expect.isFalse(file.hasRuntimeError);
+ Expect.isFalse(file.hasStaticWarning);
+
+ var a = file.split(Path("a.dart").absolute, "a", "", hasSyntaxError: true);
+ Expect.isTrue(a.originPath.toNativePath().endsWith("origin.dart"));
+ Expect.isTrue(a.path.toNativePath().endsWith("a.dart"));
+ Expect.isTrue(a.hasSyntaxError);
+ Expect.isFalse(a.hasCompileError);
+ Expect.isFalse(a.hasRuntimeError);
+ Expect.isFalse(a.hasStaticWarning);
+
+ var b = file.split(
+ Path("b.dart").absolute,
+ "b",
+ "",
+ hasCompileError: true,
+ );
+ Expect.isTrue(b.originPath.toNativePath().endsWith("origin.dart"));
+ Expect.isTrue(b.path.toNativePath().endsWith("b.dart"));
+ Expect.isFalse(b.hasSyntaxError);
+ Expect.isTrue(b.hasCompileError);
+ Expect.isFalse(b.hasRuntimeError);
+ Expect.isFalse(b.hasStaticWarning);
+
+ var c = file.split(Path("c.dart").absolute, "c", "", hasRuntimeError: true);
+ Expect.isTrue(c.originPath.toNativePath().endsWith("origin.dart"));
+ Expect.isTrue(c.path.toNativePath().endsWith("c.dart"));
+ Expect.isFalse(c.hasSyntaxError);
+ Expect.isFalse(c.hasCompileError);
+ Expect.isTrue(c.hasRuntimeError);
+ Expect.isFalse(c.hasStaticWarning);
+
+ var d = file.split(Path("d.dart").absolute, "d", "", hasStaticWarning: true);
+ Expect.isTrue(d.originPath.toNativePath().endsWith("origin.dart"));
+ Expect.isTrue(d.path.toNativePath().endsWith("d.dart"));
+ Expect.isFalse(d.hasSyntaxError);
+ Expect.isFalse(d.hasCompileError);
+ Expect.isFalse(d.hasRuntimeError);
+ Expect.isTrue(d.hasStaticWarning);
+}
+
+void expectParseErrorExpectations(
+ String source, List<ErrorExpectation> errors) {
+ var file = parse(source);
+ Expect.listEquals(errors.map((error) => error.toString()).toList(),
+ file.expectedErrors.map((error) => error.toString()).toList());
+}
+
+void expectFormatError(String source) {
+ Expect.throwsFormatException(() => parse(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);
+}
diff --git a/pkg/testing/lib/src/run_tests.dart b/pkg/testing/lib/src/run_tests.dart
index ce0849d..5d6e27d 100644
--- a/pkg/testing/lib/src/run_tests.dart
+++ b/pkg/testing/lib/src/run_tests.dart
@@ -82,6 +82,12 @@
String configurationPath;
if (configurationPaths.length == 1) {
configurationPath = configurationPaths.single;
+ File file = new File(configurationPath);
+ if (await file.exists()) {
+ // If [configurationPath] exists as a file, use the absolute URI. This
+ // handles absolute paths on Windows.
+ configurationPath = file.absolute.uri.toString();
+ }
} else {
configurationPath = "testing.json";
if (!await new File(configurationPath).exists()) {
diff --git a/pkg/testing/lib/src/test_dart/status_file_parser.dart b/pkg/testing/lib/src/test_dart/status_file_parser.dart
index c756341..60c39f8 100644
--- a/pkg/testing/lib/src/test_dart/status_file_parser.dart
+++ b/pkg/testing/lib/src/test_dart/status_file_parser.dart
@@ -82,8 +82,11 @@
throw new Exception('Cannot find test status file $path');
}
int lineNumber = 0;
- Stream<String> lines =
- file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+ Stream<String> lines = file
+ .openRead()
+ .cast<List<int>>()
+ .transform(utf8.decoder)
+ .transform(new LineSplitter());
Section currentSection = new Section.always(statusFile, -1);
sections.add(currentSection);
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index fc07655..9d6e345 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -34,6 +34,7 @@
import 'package:kernel/kernel.dart' show Component, Procedure;
import 'package:kernel/target/targets.dart' show TargetFlags;
import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:vm/bytecode/options.dart' show BytecodeOptions;
import 'package:vm/incremental_compiler.dart';
import 'package:vm/kernel_front_end.dart' show runWithFrontEndCompilerContext;
import 'package:vm/http_filesystem.dart';
@@ -147,11 +148,16 @@
await runWithFrontEndCompilerContext(script, options, component, () {
// TODO(alexmarkov): disable source positions, local variables info
// and source files in VM PRODUCT mode.
+ // TODO(alexmarkov): disable asserts if they are not enabled in VM.
+ // TODO(rmacnak): disable annotations if mirrors are not enabled.
generateBytecode(component,
- environmentDefines: options.environmentDefines,
- emitSourcePositions: true,
- emitLocalVarInfo: true,
- emitSourceFiles: true);
+ options: new BytecodeOptions(
+ enableAsserts: true,
+ environmentDefines: options.environmentDefines,
+ emitSourcePositions: true,
+ emitLocalVarInfo: true,
+ emitSourceFiles: true,
+ emitAnnotations: true));
});
}
@@ -528,7 +534,12 @@
assert(incremental,
"Incremental compiler required for use of 'kUpdateSourcesTag'");
compiler = lookupIncrementalCompiler(isolateId);
- assert(compiler != null);
+ if (compiler == null) {
+ port.send(new CompilationResult.errors(
+ ["No incremental compiler available for this isolate."], null)
+ .toResponse());
+ return;
+ }
updateSources(compiler, sourceFiles);
port.send(new CompilationResult.ok(null).toResponse());
return;
diff --git a/pkg/vm/bin/run_binary_size_analysis.dart b/pkg/vm/bin/run_binary_size_analysis.dart
index 4a63676..4c4c9cf 100644
--- a/pkg/vm/bin/run_binary_size_analysis.dart
+++ b/pkg/vm/bin/run_binary_size_analysis.dart
@@ -39,6 +39,7 @@
// a tree.
final symbols = await input
.openRead()
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(json.decoder)
.first;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 387db94..a43e1c1 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -79,6 +79,12 @@
}
}
+ void emitYieldPointSourcePosition() {
+ if (!isUnreachable) {
+ sourcePositions.addYieldPoint(offset, currentSourcePosition);
+ }
+ }
+
void _emitByte(int abyte) {
assert(_isUint8(abyte));
bytecode.add(abyte);
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 244e800..aa73fc3 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,135 +10,94 @@
/// Before bumping current bytecode version format, make sure that
/// all users have switched to a VM which is able to consume new
/// version of bytecode.
-const int currentBytecodeFormatVersion = 10;
-
-/// Version of experimental / bleeding edge bytecode format.
-/// Produced by bytecode generator when --use-future-bytecode-format
-/// option is enabled.
-const int futureBytecodeFormatVersion = currentBytecodeFormatVersion + 1;
+const int currentBytecodeFormatVersion = 12;
enum Opcode {
- // Old instructions, used before bytecode v7.
- // TODO(alexmarkov): remove
-
- kTrap_Old,
-
- // Prologue and stack management.
- kEntry_Old,
- kEntryFixed_Old,
- kEntryOptional_Old,
- kLoadConstant_Old,
- kFrame_Old,
- kCheckFunctionTypeArgs_Old,
- kCheckStack_Old,
-
- // Object allocation.
- kAllocate_Old,
- kAllocateT_Old,
- kCreateArrayTOS_Old,
-
- // Context allocation and access.
- kAllocateContext_Old,
- kCloneContext_Old,
- kLoadContextParent_Old,
- kStoreContextParent_Old,
- kLoadContextVar_Old,
- kStoreContextVar_Old,
-
- // Constants.
- kPushConstant_Old,
- kPushNull_Old,
- kPushTrue_Old,
- kPushFalse_Old,
- kPushInt_Old,
-
- // Locals and expression stack.
- kDrop1_Old,
- kPush_Old,
- kPopLocal_Old,
- kStoreLocal_Old,
-
- // Instance fields and arrays.
- kLoadFieldTOS_Old,
- kStoreFieldTOS_Old,
- kStoreIndexedTOS_Old,
-
- // Static fields.
- kPushStatic_Old,
- kStoreStaticTOS_Old,
-
- // Jumps.
- kJump_Old,
- kJumpIfNoAsserts_Old,
- kJumpIfNotZeroTypeArgs_Old,
- kJumpIfEqStrict_Old,
- kJumpIfNeStrict_Old,
- kJumpIfTrue_Old,
- kJumpIfFalse_Old,
- kJumpIfNull_Old,
- kJumpIfNotNull_Old,
-
- // Calls.
- kUnused00_Old,
- kInterfaceCall_Old,
- kDynamicCall_Old,
- kNativeCall_Old,
- kReturnTOS_Old,
-
- // Types and type checks.
- kAssertAssignable_Old,
- kAssertBoolean_Old,
- kAssertSubtype_Old,
- kLoadTypeArgumentsField_Old,
- kInstantiateType_Old,
- kInstantiateTypeArgumentsTOS_Old,
-
- // Exception handling.
- kThrow_Old,
- kMoveSpecial_Old,
- kSetFrame_Old,
-
- // Bool operations.
- kBooleanNegateTOS_Old,
-
- // Null operations.
- kEqualsNull_Old,
-
- // Int operations.
- kNegateInt_Old,
- kAddInt_Old,
- kSubInt_Old,
- kMulInt_Old,
- kTruncDivInt_Old,
- kModInt_Old,
- kBitAndInt_Old,
- kBitOrInt_Old,
- kBitXorInt_Old,
- kShlInt_Old,
- kShrInt_Old,
- kCompareIntEq_Old,
- kCompareIntGt_Old,
- kCompareIntLt_Old,
- kCompareIntGe_Old,
- kCompareIntLe_Old,
-
- kDirectCall_Old,
-
- kAllocateClosure_Old,
-
- kUncheckedInterfaceCall_Old,
-
- // Double operations.
- kNegateDouble_Old,
- kAddDouble_Old,
- kSubDouble_Old,
- kMulDouble_Old,
- kDivDouble_Old,
- kCompareDoubleEq_Old,
- kCompareDoubleGt_Old,
- kCompareDoubleLt_Old,
- kCompareDoubleGe_Old,
- kCompareDoubleLe_Old,
+ kUnusedOpcode000,
+ kUnusedOpcode001,
+ kUnusedOpcode002,
+ kUnusedOpcode003,
+ kUnusedOpcode004,
+ kUnusedOpcode005,
+ kUnusedOpcode006,
+ kUnusedOpcode007,
+ kUnusedOpcode008,
+ kUnusedOpcode009,
+ kUnusedOpcode010,
+ kUnusedOpcode011,
+ kUnusedOpcode012,
+ kUnusedOpcode013,
+ kUnusedOpcode014,
+ kUnusedOpcode015,
+ kUnusedOpcode016,
+ kUnusedOpcode017,
+ kUnusedOpcode018,
+ kUnusedOpcode019,
+ kUnusedOpcode020,
+ kUnusedOpcode021,
+ kUnusedOpcode022,
+ kUnusedOpcode023,
+ kUnusedOpcode024,
+ kUnusedOpcode025,
+ kUnusedOpcode026,
+ kUnusedOpcode027,
+ kUnusedOpcode028,
+ kUnusedOpcode029,
+ kUnusedOpcode030,
+ kUnusedOpcode031,
+ kUnusedOpcode032,
+ kUnusedOpcode033,
+ kUnusedOpcode034,
+ kUnusedOpcode035,
+ kUnusedOpcode036,
+ kUnusedOpcode037,
+ kUnusedOpcode038,
+ kUnusedOpcode039,
+ kUnusedOpcode040,
+ kUnusedOpcode041,
+ kUnusedOpcode042,
+ kUnusedOpcode043,
+ kUnusedOpcode044,
+ kUnusedOpcode045,
+ kUnusedOpcode046,
+ kUnusedOpcode047,
+ kUnusedOpcode048,
+ kUnusedOpcode049,
+ kUnusedOpcode050,
+ kUnusedOpcode051,
+ kUnusedOpcode052,
+ kUnusedOpcode053,
+ kUnusedOpcode054,
+ kUnusedOpcode055,
+ kUnusedOpcode056,
+ kUnusedOpcode057,
+ kUnusedOpcode058,
+ kUnusedOpcode059,
+ kUnusedOpcode060,
+ kUnusedOpcode061,
+ kUnusedOpcode062,
+ kUnusedOpcode063,
+ kUnusedOpcode064,
+ kUnusedOpcode065,
+ kUnusedOpcode066,
+ kUnusedOpcode067,
+ kUnusedOpcode068,
+ kUnusedOpcode069,
+ kUnusedOpcode070,
+ kUnusedOpcode071,
+ kUnusedOpcode072,
+ kUnusedOpcode073,
+ kUnusedOpcode074,
+ kUnusedOpcode075,
+ kUnusedOpcode076,
+ kUnusedOpcode077,
+ kUnusedOpcode078,
+ kUnusedOpcode079,
+ kUnusedOpcode080,
+ kUnusedOpcode081,
+ kUnusedOpcode082,
+ kUnusedOpcode083,
+ kUnusedOpcode084,
// Bytecode instructions since bytecode format v7:
@@ -686,6 +645,9 @@
// Context IDs are referenced using 8-bit unsigned operands.
const int contextIdLimit = 1 << 8;
+// Number of arguments is encoded as 8-bit unsigned operand.
+const int argumentsLimit = 1 << 8;
+
// Base class for exceptions thrown when certain limit of bytecode
// format is exceeded.
abstract class BytecodeLimitExceededException {}
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index 58827b6..bd14856 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -8,8 +8,7 @@
import 'bytecode_serialization.dart'
show BufferedWriter, BufferedReader, BytecodeSizeStatistics, StringTable;
import 'constant_pool.dart' show ConstantPool;
-import 'dbc.dart'
- show currentBytecodeFormatVersion, futureBytecodeFormatVersion;
+import 'dbc.dart' show currentBytecodeFormatVersion;
import 'disassembler.dart' show BytecodeDisassembler;
import 'exceptions.dart' show ExceptionsTable;
import 'local_variable_table.dart' show LocalVariableTable;
@@ -19,21 +18,26 @@
class LibraryDeclaration {
static const usesDartMirrorsFlag = 1 << 0;
static const usesDartFfiFlag = 1 << 1;
+ static const hasExtensionsFlag = 1 << 2;
ObjectHandle importUri;
final int flags;
final ObjectHandle name;
final ObjectHandle script;
+ final List<ObjectHandle> extensionUris;
final List<ClassDeclaration> classes;
- LibraryDeclaration(
- this.importUri, this.flags, this.name, this.script, this.classes);
+ LibraryDeclaration(this.importUri, this.flags, this.name, this.script,
+ this.extensionUris, this.classes);
void write(BufferedWriter writer) {
final start = writer.offset;
writer.writePackedUInt30(flags);
writer.writePackedObject(name);
writer.writePackedObject(script);
+ if ((flags & hasExtensionsFlag) != 0) {
+ writer.writePackedList(extensionUris);
+ }
writer.writePackedUInt30(classes.length);
for (var cls in classes) {
writer.writePackedObject(cls.name);
@@ -51,7 +55,11 @@
final className = reader.readPackedObject();
return reader.readLinkOffset<ClassDeclaration>()..name = className;
});
- return new LibraryDeclaration(null, flags, name, script, classes);
+ final extensionUris = ((flags & hasExtensionsFlag) != 0)
+ ? reader.readPackedList<ObjectHandle>()
+ : const <ObjectHandle>[];
+ return new LibraryDeclaration(
+ null, flags, name, script, extensionUris, classes);
}
@override
@@ -66,6 +74,9 @@
if ((flags & usesDartFfiFlag) != 0) {
sb.writeln(' uses dart:ffi');
}
+ if ((flags & hasExtensionsFlag) != 0) {
+ sb.writeln(' extensions: $extensionUris');
+ }
sb.writeln();
for (var cls in classes) {
sb.write(cls);
@@ -749,7 +760,7 @@
bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
bool get hasSourcePositions =>
- sourcePositions != null && sourcePositions.mapping.isNotEmpty;
+ sourcePositions != null && sourcePositions.isNotEmpty;
bool get hasLocalVariables =>
localVariables != null && localVariables.isNotEmpty;
bool get hasNullableFields => nullableFields.isNotEmpty;
@@ -890,7 +901,11 @@
static const int hasOptionalNamedParamsFlag = 1 << 1;
static const int hasTypeParamsFlag = 1 << 2;
static const int hasSourcePositionsFlag = 1 << 3;
+ static const int isAsyncFlag = 1 << 4;
+ static const int isAsyncStarFlag = 1 << 5;
+ static const int isSyncStarFlag = 1 << 6;
+ final int flags;
final ObjectHandle parent;
final ObjectHandle name;
final int position;
@@ -903,6 +918,7 @@
ClosureCode code;
ClosureDeclaration(
+ this.flags,
this.parent,
this.name,
this.position,
@@ -914,20 +930,6 @@
this.returnType);
void write(BufferedWriter writer) {
- int flags = 0;
- if (numRequiredParams != parameters.length) {
- if (numNamedParams > 0) {
- flags |= hasOptionalNamedParamsFlag;
- } else {
- flags |= hasOptionalPositionalParamsFlag;
- }
- }
- if (typeParams.isNotEmpty) {
- flags |= hasTypeParamsFlag;
- }
- if (position != TreeNode.noOffset) {
- flags |= hasSourcePositionsFlag;
- }
writer.writePackedUInt30(flags);
writer.writePackedObject(parent);
writer.writePackedObject(name);
@@ -996,7 +998,7 @@
(_) => new NameAndType(
reader.readPackedObject(), reader.readPackedObject()));
final returnType = reader.readPackedObject();
- return new ClosureDeclaration(parent, name, position, endPosition,
+ return new ClosureDeclaration(flags, parent, name, position, endPosition,
typeParams, numRequiredParams, numNamedParams, parameters, returnType);
}
@@ -1004,6 +1006,15 @@
String toString() {
final StringBuffer sb = new StringBuffer();
sb.write('Closure $parent::$name');
+ if ((flags & isAsyncFlag) != 0) {
+ sb.write(' async');
+ }
+ if ((flags & isAsyncStarFlag) != 0) {
+ sb.write(' async*');
+ }
+ if ((flags & isSyncStarFlag) != 0) {
+ sb.write(' sync*');
+ }
if (position != TreeNode.noOffset) {
sb.write(' pos = $position, end-pos = $endPosition');
}
@@ -1045,7 +1056,7 @@
bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
bool get hasSourcePositions =>
- sourcePositions != null && sourcePositions.mapping.isNotEmpty;
+ sourcePositions != null && sourcePositions.isNotEmpty;
bool get hasLocalVariables =>
localVariables != null && localVariables.isNotEmpty;
@@ -1440,8 +1451,6 @@
sb.write("Bytecode (version: ");
if (version == currentBytecodeFormatVersion) {
sb.write("stable");
- } else if (version == futureBytecodeFormatVersion) {
- sb.write("future");
} else {
sb.write("v$version");
}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 01426c5..3684410 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -9,13 +9,19 @@
import 'package:front_end/src/api_prototype/constant_evaluator.dart'
show ConstantEvaluator, EvaluationEnvironment, ErrorReporter;
import 'package:front_end/src/api_unstable/vm.dart'
- show CompilerContext, Severity, templateIllegalRecursiveType;
+ show
+ CompilerContext,
+ Severity,
+ messageBytecodeLimitExceededTooManyArguments,
+ noLength,
+ templateIllegalRecursiveType;
import 'package:kernel/ast.dart' hide MapEntry, Component, FunctionDeclaration;
import 'package:kernel/ast.dart' as ast show Component, FunctionDeclaration;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/external_name.dart' show getExternalName;
+import 'package:kernel/external_name.dart'
+ show getExternalName, getNativeExtensionUris;
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/target/targets.dart' show ConstantsBackend;
import 'package:kernel/type_algebra.dart'
@@ -42,6 +48,7 @@
import 'nullability_detector.dart' show NullabilityDetector;
import 'object_table.dart'
show ObjectHandle, ObjectTable, NameAndType, topLevelClassName;
+import 'options.dart' show BytecodeOptions;
import 'recognized_methods.dart' show RecognizedMethods;
import 'recursive_types_validator.dart' show IllegalRecursiveTypeException;
import 'source_positions.dart' show LineStarts, SourcePositions;
@@ -58,18 +65,12 @@
void generateBytecode(
ast.Component component, {
- bool enableAsserts: true,
- bool emitSourcePositions: false,
- bool emitSourceFiles: false,
- bool emitLocalVarInfo: false,
- bool emitAnnotations: false,
- bool omitAssertSourcePositions: false,
- bool useFutureBytecodeFormat: false,
- Map<String, String> environmentDefines: const <String, String>{},
+ BytecodeOptions options,
ErrorReporter errorReporter,
List<Library> libraries,
ClassHierarchy hierarchy,
}) {
+ options ??= new BytecodeOptions();
verifyBytecodeInstructionDeclarations();
final coreTypes = new CoreTypes(component);
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
@@ -80,21 +81,8 @@
final errorReporter = new ForwardConstantEvaluationErrors();
libraries ??= component.libraries;
try {
- final bytecodeGenerator = new BytecodeGenerator(
- component,
- coreTypes,
- hierarchy,
- typeEnvironment,
- constantsBackend,
- environmentDefines,
- enableAsserts,
- emitSourcePositions,
- emitSourceFiles,
- emitLocalVarInfo,
- emitAnnotations,
- omitAssertSourcePositions,
- useFutureBytecodeFormat,
- errorReporter);
+ final bytecodeGenerator = new BytecodeGenerator(component, coreTypes,
+ hierarchy, typeEnvironment, constantsBackend, options, errorReporter);
for (var library in libraries) {
bytecodeGenerator.visitLibrary(library);
}
@@ -110,14 +98,7 @@
final ClassHierarchy hierarchy;
final TypeEnvironment typeEnvironment;
final ConstantsBackend constantsBackend;
- final Map<String, String> environmentDefines;
- final bool enableAsserts;
- final bool emitSourcePositions;
- final bool emitSourceFiles;
- final bool emitLocalVarInfo;
- final bool emitAnnotations;
- final bool omitAssertSourcePositions;
- final bool useFutureBytecodeFormat;
+ final BytecodeOptions options;
final ErrorReporter errorReporter;
final BytecodeMetadataRepository metadata = new BytecodeMetadataRepository();
final RecognizedMethods recognizedMethods;
@@ -165,19 +146,10 @@
this.hierarchy,
this.typeEnvironment,
this.constantsBackend,
- this.environmentDefines,
- this.enableAsserts,
- this.emitSourcePositions,
- this.emitSourceFiles,
- this.emitLocalVarInfo,
- this.emitAnnotations,
- this.omitAssertSourcePositions,
- this.useFutureBytecodeFormat,
+ this.options,
this.errorReporter)
: recognizedMethods = new RecognizedMethods(typeEnvironment),
- formatVersion = useFutureBytecodeFormat
- ? futureBytecodeFormatVersion
- : currentBytecodeFormatVersion,
+ formatVersion = currentBytecodeFormatVersion,
astUriToSource = component.uriToSource {
nullabilityDetector = new NullabilityDetector(recognizedMethods);
component.addMetadataRepository(metadata);
@@ -243,7 +215,8 @@
ObjectHandle getScript(Uri uri, bool includeSource) {
SourceFile source;
- if (includeSource && (emitSourceFiles || emitSourcePositions)) {
+ if (includeSource &&
+ (options.emitSourceFiles || options.emitSourcePositions)) {
source = bytecodeComponent.uriToSource[uri];
if (source == null) {
final astSource = astUriToSource[uri];
@@ -251,12 +224,12 @@
final importUri =
objectTable.getNameHandle(null, astSource.importUri.toString());
LineStarts lineStarts;
- if (emitSourcePositions) {
+ if (options.emitSourcePositions) {
lineStarts = new LineStarts(astSource.lineStarts);
bytecodeComponent.lineStarts.add(lineStarts);
}
String text = '';
- if (emitSourceFiles) {
+ if (options.emitSourceFiles) {
text = astSource.cachedText ??
utf8.decode(astSource.source, allowMalformed: true);
}
@@ -285,7 +258,14 @@
}
final name = objectTable.getNameHandle(null, library.name ?? '');
final script = getScript(library.fileUri, true);
- return new LibraryDeclaration(importUri, flags, name, script, classes);
+ final extensionUris = getNativeExtensionUris(library)
+ .map((String uri) => objectTable.getNameHandle(null, uri))
+ .toList();
+ if (extensionUris.isNotEmpty) {
+ flags |= LibraryDeclaration.hasExtensionsFlag;
+ }
+ return new LibraryDeclaration(
+ importUri, flags, name, script, extensionUris, classes);
}
ClassDeclaration getClassDeclaration(Class cls, Members members) {
@@ -317,9 +297,9 @@
}
int position = TreeNode.noOffset;
int endPosition = TreeNode.noOffset;
- if (emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
+ if (options.emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
flags |= ClassDeclaration.hasSourcePositionsFlag;
- position = cls.fileOffset;
+ position = cls.startFileOffset;
endPosition = cls.fileEndOffset;
}
Annotations annotations = getAnnotations(cls.annotations);
@@ -357,7 +337,8 @@
Library library, Members members) {
int flags = 0;
int position = TreeNode.noOffset;
- if (emitSourcePositions && library.fileOffset != TreeNode.noOffset) {
+ if (options.emitSourcePositions &&
+ library.fileOffset != TreeNode.noOffset) {
flags |= ClassDeclaration.hasSourcePositionsFlag;
position = library.fileOffset;
}
@@ -398,14 +379,18 @@
}
final savedConstantEvaluator = constantEvaluator;
if (constantEvaluator == null) {
- constantEvaluator = new ConstantEvaluator(constantsBackend,
- environmentDefines, typeEnvironment, enableAsserts, errorReporter)
+ constantEvaluator = new ConstantEvaluator(
+ constantsBackend,
+ options.environmentDefines,
+ typeEnvironment,
+ options.enableAsserts,
+ errorReporter)
..env = new EvaluationEnvironment();
}
List<Constant> constants = nodes.map(_evaluateConstantExpression).toList();
constantEvaluator = savedConstantEvaluator;
bool hasPragma = constants.any(_isPragma);
- if (!emitAnnotations) {
+ if (!options.emitAnnotations) {
if (hasPragma) {
constants = constants.where(_isPragma).toList();
} else {
@@ -463,7 +448,7 @@
}
int position = TreeNode.noOffset;
int endPosition = TreeNode.noOffset;
- if (emitSourcePositions && field.fileOffset != TreeNode.noOffset) {
+ if (options.emitSourcePositions && field.fileOffset != TreeNode.noOffset) {
flags |= FieldDeclaration.hasSourcePositionsFlag;
position = field.fileOffset;
endPosition = field.fileEndOffset;
@@ -475,16 +460,20 @@
flags |= FieldDeclaration.hasPragmaFlag;
}
}
- if (field.fileUri != (field.parent as dynamic).fileUri) {
- // TODO(alexmarkov): support custom scripts
- // flags |= FieldDeclaration.hasCustomScriptFlag;
+ ObjectHandle script;
+ if (field.fileUri != null &&
+ field.fileUri != (field.parent as FileUriNode).fileUri) {
+ final isInAnonymousMixin =
+ enclosingClass != null && enclosingClass.isAnonymousMixin;
+ script = getScript(field.fileUri, !isInAnonymousMixin);
+ flags |= FieldDeclaration.hasCustomScriptFlag;
}
return new FieldDeclaration(
flags,
name,
objectTable.getHandle(field.type),
objectTable.getHandle(value),
- null, // TODO(alexmarkov): script
+ script,
position,
endPosition,
getterName,
@@ -567,9 +556,9 @@
}
int position = TreeNode.noOffset;
int endPosition = TreeNode.noOffset;
- if (emitSourcePositions && member.fileOffset != TreeNode.noOffset) {
+ if (options.emitSourcePositions && member.fileOffset != TreeNode.noOffset) {
flags |= FunctionDeclaration.hasSourcePositionsFlag;
- position = member.fileOffset;
+ position = (member as dynamic).startFileOffset;
endPosition = member.fileEndOffset;
}
Annotations annotations = getAnnotations(member.annotations);
@@ -579,9 +568,15 @@
flags |= FunctionDeclaration.hasPragmaFlag;
}
}
- if (member.fileUri != (member.parent as dynamic).fileUri) {
- // TODO(alexmarkov): support custom scripts
- // flags |= FunctionDeclaration.hasCustomScriptFlag;
+ ObjectHandle script;
+ if (member.fileUri != null &&
+ member.fileUri != (member.parent as FileUriNode).fileUri) {
+ final isInAnonymousMixin =
+ enclosingClass != null && enclosingClass.isAnonymousMixin;
+ final isSynthetic = member is Procedure &&
+ (member.isNoSuchMethodForwarder || member.isSyntheticForwarder);
+ script = getScript(member.fileUri, !isInAnonymousMixin && !isSynthetic);
+ flags |= FunctionDeclaration.hasCustomScriptFlag;
}
final name = objectTable.getNameHandle(member.name.library,
@@ -595,7 +590,7 @@
return new FunctionDeclaration(
flags,
name,
- null, // TODO(alexmarkov): script
+ script,
position,
endPosition,
typeParameters,
@@ -713,15 +708,20 @@
// BytecodeAssembler eliminates this bytecode if it is unreachable.
asm.emitPushNull();
}
+ if (node.function != null) {
+ _recordSourcePosition(node.function.fileEndOffset);
+ }
_genReturnTOS();
}
} else {
throw 'Unexpected member ${node.runtimeType} $node';
}
end(node, hasCode);
- } on BytecodeLimitExceededException {
- // Do not generate bytecode and fall back to using kernel AST.
- // TODO(alexmarkov): issue compile-time error
+ } on TooManyArgumentsException catch (e) {
+ CompilerContext.current.options.report(
+ messageBytecodeLimitExceededTooManyArguments.withLocation(
+ node.fileUri, e.fileOffset, noLength),
+ Severity.error);
hasErrors = true;
end(node, false);
}
@@ -852,12 +852,21 @@
_asyncAwaitCompleterGetFuture ??= libraryIndex.getMember(
'dart:async', '_AsyncAwaitCompleter', 'get:future');
+ Procedure _setAsyncThreadStackTrace;
+ Procedure get setAsyncThreadStackTrace => _setAsyncThreadStackTrace ??=
+ libraryIndex.getTopLevelMember('dart:async', '_setAsyncThreadStackTrace');
+
+ Procedure _clearAsyncThreadStackTrace;
+ Procedure get clearAsyncThreadStackTrace =>
+ _clearAsyncThreadStackTrace ??= libraryIndex.getTopLevelMember(
+ 'dart:async', '_clearAsyncThreadStackTrace');
+
Library _dartFfiLibrary;
Library get dartFfiLibrary =>
_dartFfiLibrary ??= libraryIndex.tryGetLibrary('dart:ffi');
void _recordSourcePosition(int fileOffset) {
- if (emitSourcePositions) {
+ if (options.emitSourcePositions) {
asm.currentSourcePosition = fileOffset;
}
maxSourcePosition = math.max(maxSourcePosition, fileOffset);
@@ -976,22 +985,34 @@
}
void _genReturnTOS() {
+ if (options.causalAsyncStacks &&
+ parentFunction != null &&
+ (parentFunction.dartAsyncMarker == AsyncMarker.Async ||
+ parentFunction.dartAsyncMarker == AsyncMarker.AsyncStar)) {
+ _genDirectCall(
+ clearAsyncThreadStackTrace, objectTable.getArgDescHandle(0), 0);
+ asm.emitDrop1();
+ }
+
asm.emitReturnTOS();
}
void _genDirectCall(Member target, ObjectHandle argDesc, int totalArgCount,
- {bool isGet: false, bool isSet: false}) {
+ {bool isGet: false, bool isSet: false, TreeNode context}) {
assert(!isGet || !isSet);
final kind = isGet
? InvocationKind.getter
: (isSet ? InvocationKind.setter : InvocationKind.method);
final cpIndex = cp.addDirectCall(kind, target, argDesc);
+ if (totalArgCount >= argumentsLimit) {
+ throw new TooManyArgumentsException(context.fileOffset);
+ }
asm.emitDirectCall(cpIndex, totalArgCount);
}
void _genDirectCallWithArgs(Member target, Arguments args,
- {bool hasReceiver: false, bool isFactory: false}) {
+ {bool hasReceiver: false, bool isFactory: false, TreeNode context}) {
final argDesc = objectTable.getArgDescHandleByArguments(args,
hasReceiver: hasReceiver, isFactory: isFactory);
@@ -1005,7 +1026,7 @@
totalArgCount++;
}
- _genDirectCall(target, argDesc, totalArgCount);
+ _genDirectCall(target, argDesc, totalArgCount, context: context);
}
void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
@@ -1321,8 +1342,12 @@
functionTypeParametersSet = functionTypeParameters.toSet();
}
// TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
- constantEvaluator = new ConstantEvaluator(constantsBackend,
- environmentDefines, typeEnvironment, enableAsserts, errorReporter)
+ constantEvaluator = new ConstantEvaluator(
+ constantsBackend,
+ options.environmentDefines,
+ typeEnvironment,
+ options.enableAsserts,
+ errorReporter)
..env = new EvaluationEnvironment();
if (node.isAbstract || node is Field && !hasInitializerCode(node)) {
@@ -1345,11 +1370,19 @@
savedMaxSourcePositions = <int>[];
maxSourcePosition = node.fileOffset;
- locals = new LocalVariables(node, enableAsserts);
+ locals = new LocalVariables(node, options);
locals.enterScope(node);
assert(!locals.isSyncYieldingFrame);
- _recordSourcePosition(node.fileOffset);
+ int position;
+ if (node is Procedure) {
+ position = node.startFileOffset;
+ } else if (node is Constructor) {
+ position = node.startFileOffset;
+ } else {
+ position = node.fileOffset;
+ }
+ _recordSourcePosition(position);
_genPrologue(node, node.function);
_setupInitialContext(node.function);
if (node is Procedure && node.isInstanceMember) {
@@ -1381,7 +1414,7 @@
if (!hasErrors) {
Code code;
if (hasCode) {
- if (emitLocalVarInfo && node.function != null) {
+ if (options.emitLocalVarInfo && node.function != null) {
// Leave the scope which was entered in _setupInitialContext.
asm.localVariableTable
.leaveScope(asm.offset, node.function.fileEndOffset);
@@ -1452,7 +1485,7 @@
}
SourcePositions finalizeSourcePositions() {
- if (asm.sourcePositions.mapping.isEmpty) {
+ if (asm.sourcePositions.isEmpty) {
return null;
}
bytecodeComponent.sourcePositions.add(asm.sourcePositions);
@@ -1593,7 +1626,7 @@
void _setupInitialContext(FunctionNode function) {
_allocateContextIfNeeded();
- if (emitLocalVarInfo && function != null) {
+ if (options.emitLocalVarInfo && function != null) {
// Open scope after allocating context.
asm.localVariableTable.enterScope(
asm.offset, locals.currentContextLevel, function.fileOffset);
@@ -1852,7 +1885,8 @@
}
}
- int _genClosureBytecode(TreeNode node, String name, FunctionNode function) {
+ int _genClosureBytecode(
+ LocalFunction node, String name, FunctionNode function) {
_pushAssemblerState();
locals.enterScope(node);
@@ -1865,15 +1899,6 @@
final savedLoopDepth = currentLoopDepth;
currentLoopDepth = 0;
- int position = TreeNode.noOffset;
- int endPosition = TreeNode.noOffset;
- if (emitSourcePositions) {
- position = (node is ast.FunctionDeclaration)
- ? node.fileOffset
- : function.fileOffset;
- endPosition = function.fileEndOffset;
- }
-
if (function.typeParameters.isNotEmpty) {
functionTypeParameters ??= new List<TypeParameter>();
functionTypeParameters.addAll(function.typeParameters);
@@ -1890,27 +1915,8 @@
locals.sortedNamedParameters.forEach(_evaluateDefaultParameterValue);
final int closureIndex = closures.length;
- objectTable.declareClosure(function, enclosingMember, closureIndex);
- final List<NameAndType> parameters = function.positionalParameters
- .followedBy(function.namedParameters)
- .map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
- objectTable.getHandle(v.type)))
- .toList();
- final ClosureDeclaration closure = new ClosureDeclaration(
- objectTable
- .getHandle(savedIsClosure ? parentFunction : enclosingMember),
- objectTable.getNameHandle(null, name),
- position,
- endPosition,
- function.typeParameters
- .map((tp) => new NameAndType(
- objectTable.getNameHandle(null, tp.name),
- objectTable.getHandle(tp.bound)))
- .toList(),
- function.requiredParameterCount,
- function.namedParameters.length,
- parameters,
- objectTable.getHandle(function.returnType));
+ final closure = getClosureDeclaration(node, function, name, closureIndex,
+ savedIsClosure ? parentFunction : enclosingMember);
closures.add(closure);
final int closureFunctionIndex = cp.addClosureFunction(closureIndex);
@@ -1918,6 +1924,17 @@
_recordSourcePosition(function.fileOffset);
_genPrologue(node, function);
+ if (options.causalAsyncStacks &&
+ parentFunction != null &&
+ (parentFunction.dartAsyncMarker == AsyncMarker.Async ||
+ parentFunction.dartAsyncMarker == AsyncMarker.AsyncStar)) {
+ _genLoadVar(locals.asyncStackTraceVar,
+ currentContextLevel: locals.contextLevelAtEntry);
+ _genDirectCall(
+ setAsyncThreadStackTrace, objectTable.getArgDescHandle(1), 1);
+ asm.emitDrop1();
+ }
+
Label continuationSwitchLabel;
int continuationSwitchVar;
if (locals.isSyncYieldingFrame) {
@@ -1930,21 +1947,19 @@
_setupInitialContext(function);
_checkArguments(function);
- // TODO(alexmarkov): support --causal_async_stacks.
-
_generateNode(function.body);
// BytecodeAssembler eliminates this bytecode if it is unreachable.
+ _recordSourcePosition(function.fileEndOffset);
asm.emitPushNull();
_genReturnTOS();
- _recordSourcePosition(function.fileEndOffset);
if (locals.isSyncYieldingFrame) {
_genSyncYieldingEpilogue(
function, continuationSwitchLabel, continuationSwitchVar);
}
- if (emitLocalVarInfo) {
+ if (options.emitLocalVarInfo) {
// Leave the scope which was entered in _setupInitialContext.
asm.localVariableTable.leaveScope(asm.offset, function.fileEndOffset);
}
@@ -1972,6 +1987,71 @@
return closureFunctionIndex;
}
+ ClosureDeclaration getClosureDeclaration(LocalFunction node,
+ FunctionNode function, String name, int closureIndex, TreeNode parent) {
+ objectTable.declareClosure(function, enclosingMember, closureIndex);
+
+ int flags = 0;
+ int position = TreeNode.noOffset;
+ int endPosition = TreeNode.noOffset;
+ if (options.emitSourcePositions) {
+ position = (node is ast.FunctionDeclaration)
+ ? node.fileOffset
+ : function.fileOffset;
+ endPosition = function.fileEndOffset;
+ if (position != TreeNode.noOffset) {
+ flags |= ClosureDeclaration.hasSourcePositionsFlag;
+ }
+ }
+
+ switch (function.dartAsyncMarker) {
+ case AsyncMarker.Async:
+ flags |= ClosureDeclaration.isAsyncFlag;
+ break;
+ case AsyncMarker.AsyncStar:
+ flags |= ClosureDeclaration.isAsyncStarFlag;
+ break;
+ case AsyncMarker.SyncStar:
+ flags |= ClosureDeclaration.isSyncStarFlag;
+ break;
+ default:
+ break;
+ }
+
+ final List<NameAndType> parameters = function.positionalParameters
+ .followedBy(function.namedParameters)
+ .map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
+ objectTable.getHandle(v.type)))
+ .toList();
+ if (function.requiredParameterCount != parameters.length) {
+ if (function.namedParameters.isNotEmpty) {
+ flags |= ClosureDeclaration.hasOptionalNamedParamsFlag;
+ } else {
+ flags |= ClosureDeclaration.hasOptionalPositionalParamsFlag;
+ }
+ }
+
+ final typeParams = function.typeParameters
+ .map((tp) => new NameAndType(objectTable.getNameHandle(null, tp.name),
+ objectTable.getHandle(tp.bound)))
+ .toList();
+ if (typeParams.isNotEmpty) {
+ flags |= ClosureDeclaration.hasTypeParamsFlag;
+ }
+
+ return new ClosureDeclaration(
+ flags,
+ objectTable.getHandle(parent),
+ objectTable.getNameHandle(null, name),
+ position,
+ endPosition,
+ typeParams,
+ function.requiredParameterCount,
+ function.namedParameters.length,
+ parameters,
+ objectTable.getHandle(function.returnType));
+ }
+
void _genSyncYieldingPrologue(FunctionNode function, Label continuationLabel,
int switchVarIndexInFrame) {
// switch_var = :await_jump_var
@@ -2045,7 +2125,7 @@
asm.emitStoreFieldTOS(cp.addInstanceField(closureContext));
}
- void _genClosure(TreeNode node, String name, FunctionNode function) {
+ void _genClosure(LocalFunction node, String name, FunctionNode function) {
final int closureFunctionIndex = _genClosureBytecode(node, name, function);
_genAllocateClosureInstance(node, closureFunctionIndex, function);
}
@@ -2068,7 +2148,7 @@
void _enterScope(TreeNode node) {
locals.enterScope(node);
_allocateContextIfNeeded();
- if (emitLocalVarInfo) {
+ if (options.emitLocalVarInfo) {
asm.localVariableTable
.enterScope(asm.offset, locals.currentContextLevel, node.fileOffset);
_startRecordingMaxPosition(node.fileOffset);
@@ -2076,7 +2156,7 @@
}
void _leaveScope() {
- if (emitLocalVarInfo) {
+ if (options.emitLocalVarInfo) {
asm.localVariableTable.leaveScope(asm.offset, _endRecordingMaxPosition());
}
if (locals.currentContextSize > 0) {
@@ -2318,7 +2398,7 @@
new Arguments(node.arguments.positional, named: node.arguments.named)
..parent = node;
_genArguments(null, args);
- _genDirectCallWithArgs(node.target, args, hasReceiver: true);
+ _genDirectCallWithArgs(node.target, args, hasReceiver: true, context: node);
asm.emitDrop1();
}
@@ -2328,7 +2408,7 @@
_genArguments(node.receiver, args);
final target = node.target;
if (target is Procedure && !target.isGetter && !target.isSetter) {
- _genDirectCallWithArgs(target, args, hasReceiver: true);
+ _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
} else {
throw new UnsupportedOperationError(
'Unsupported DirectMethodInvocation with target ${target.runtimeType} $target');
@@ -2583,7 +2663,11 @@
}
void _genInstanceCall(
- int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked) {
+ int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked,
+ [TreeNode context]) {
+ if (totalArgCount >= argumentsLimit) {
+ throw new TooManyArgumentsException(context.fileOffset);
+ }
if (isDynamic) {
assert(!isUnchecked);
asm.emitDynamicCall(callCpIndex, totalArgCount);
@@ -2621,7 +2705,7 @@
args.named.length +
1 /* receiver */ +
(args.types.isNotEmpty ? 1 : 0) /* type arguments */;
- _genInstanceCall(totalArgCount, callCpIndex, isDynamic, isUnchecked);
+ _genInstanceCall(totalArgCount, callCpIndex, isDynamic, isUnchecked, node);
}
@override
@@ -2678,7 +2762,7 @@
return;
}
_genArguments(new ThisExpression(), args);
- _genDirectCallWithArgs(target, args, hasReceiver: true);
+ _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
}
@override
@@ -2831,7 +2915,8 @@
..parent = node;
}
_genArguments(null, args);
- _genDirectCallWithArgs(target, args, isFactory: target.isFactory);
+ _genDirectCallWithArgs(target, args,
+ isFactory: target.isFactory, context: node);
}
@override
@@ -2971,7 +3056,7 @@
@override
visitAssertStatement(AssertStatement node) {
- if (!enableAsserts) {
+ if (!options.enableAsserts) {
return;
}
@@ -2980,8 +3065,10 @@
_genConditionAndJumpIf(node.condition, true, done);
- _genPushInt(omitAssertSourcePositions ? 0 : node.conditionStartOffset);
- _genPushInt(omitAssertSourcePositions ? 0 : node.conditionEndOffset);
+ _genPushInt(
+ options.omitAssertSourcePositions ? 0 : node.conditionStartOffset);
+ _genPushInt(
+ options.omitAssertSourcePositions ? 0 : node.conditionEndOffset);
if (node.message != null) {
_generateNode(node.message);
@@ -3004,7 +3091,7 @@
@override
visitAssertBlock(AssertBlock node) {
- if (!enableAsserts) {
+ if (!options.enableAsserts) {
return;
}
@@ -3241,12 +3328,12 @@
_getEnclosingTryFinallyBlocks(node, null);
if (tryFinallyBlocks.isEmpty) {
_generateNode(expr);
- asm.emitReturnTOS();
+ _genReturnTOS();
} else {
if (expr is BasicLiteral) {
_addFinallyBlocks(tryFinallyBlocks, () {
_generateNode(expr);
- asm.emitReturnTOS();
+ _genReturnTOS();
});
} else {
// Keep return value in a variable as try-catch statements
@@ -3256,7 +3343,7 @@
_addFinallyBlocks(tryFinallyBlocks, () {
asm.emitPush(locals.returnVarIndexInFrame);
- asm.emitReturnTOS();
+ _genReturnTOS();
});
}
}
@@ -3564,7 +3651,7 @@
} else {
asm.emitPushNull();
}
- if (emitLocalVarInfo && !asm.isUnreachable && node.name != null) {
+ if (options.emitLocalVarInfo && !asm.isUnreachable && node.name != null) {
_declareLocalVariable(node, maxInitializerPosition + 1);
}
_genStoreVar(node);
@@ -3605,6 +3692,10 @@
return;
}
+ if (options.emitSourcePositions) {
+ asm.emitYieldPointSourcePosition();
+ }
+
// 0 is reserved for normal entry, yield points are counted from 1.
final int yieldIndex = yieldPoints.length + 1;
final Label continuationLabel = new Label(allowsBackwardJumps: true);
@@ -3625,7 +3716,7 @@
// return <expression>
// Note: finally blocks are *not* executed on the way out.
_generateNode(node.expression);
- asm.emitReturnTOS();
+ _genReturnTOS();
asm.bind(continuationLabel);
@@ -3657,7 +3748,7 @@
final args = node.arguments;
assert(args.types.isEmpty);
_genArguments(new ThisExpression(), args);
- _genDirectCallWithArgs(node.target, args, hasReceiver: true);
+ _genDirectCallWithArgs(node.target, args, hasReceiver: true, context: node);
asm.emitDrop1();
}
@@ -3675,7 +3766,7 @@
}
}
assert(target != null);
- _genDirectCallWithArgs(target, args, hasReceiver: true);
+ _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
asm.emitDrop1();
}
@@ -3703,6 +3794,11 @@
String toString() => message;
}
+class TooManyArgumentsException extends BytecodeLimitExceededException {
+ final int fileOffset;
+ TooManyArgumentsException(this.fileOffset);
+}
+
typedef void GenerateContinuation();
class FinallyBlock {
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index c321b4e..401a528 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -9,7 +9,9 @@
import 'package:kernel/ast.dart';
import 'package:kernel/transformations/continuation.dart'
show ContinuationVariables;
+
import 'dbc.dart';
+import 'options.dart' show BytecodeOptions;
class LocalVariables {
final Map<TreeNode, Scope> _scopes = <TreeNode, Scope>{};
@@ -24,7 +26,7 @@
<TreeNode, VariableDeclaration>{};
final Map<ForInStatement, VariableDeclaration> _capturedIteratorVars =
<ForInStatement, VariableDeclaration>{};
- final bool enableAsserts;
+ final BytecodeOptions options;
Scope _currentScope;
Frame _currentFrame;
@@ -137,6 +139,13 @@
.getSyntheticVar(ContinuationVariables.awaitContextVar);
}
+ VariableDeclaration get asyncStackTraceVar {
+ assert(options.causalAsyncStacks);
+ assert(_currentFrame.isSyncYielding);
+ return _currentFrame.parent
+ .getSyntheticVar(ContinuationVariables.asyncStackTraceVar);
+ }
+
VariableDeclaration capturedSavedContextVar(TreeNode node) =>
_capturedSavedContextVars[node];
VariableDeclaration capturedExceptionVar(TreeNode node) =>
@@ -176,7 +185,7 @@
List<VariableDeclaration> get sortedNamedParameters =>
_currentFrame.sortedNamedParameters;
- LocalVariables(Member node, this.enableAsserts) {
+ LocalVariables(Member node, this.options) {
final scopeBuilder = new _ScopeBuilder(this);
node.accept(scopeBuilder);
@@ -230,7 +239,7 @@
bool hasOptionalParameters = false;
bool hasCapturedParameters = false;
bool hasClosures = false;
- bool isDartSync = true;
+ AsyncMarker dartAsyncMarker = AsyncMarker.Sync;
bool isSyncYielding = false;
VariableDeclaration receiverVar;
VariableDeclaration capturedReceiverVar;
@@ -311,7 +320,7 @@
FunctionNode function = (node as dynamic).function;
assert(function != null);
- _currentFrame.isDartSync = function.dartAsyncMarker == AsyncMarker.Sync;
+ _currentFrame.dartAsyncMarker = function.dartAsyncMarker;
_currentFrame.isSyncYielding =
function.asyncMarker == AsyncMarker.SyncYielding;
@@ -363,6 +372,14 @@
.getSyntheticVar(ContinuationVariables.awaitJumpVar));
_useVariable(_currentFrame.parent
.getSyntheticVar(ContinuationVariables.awaitContextVar));
+
+ if (locals.options.causalAsyncStacks &&
+ (_currentFrame.parent.dartAsyncMarker == AsyncMarker.Async ||
+ _currentFrame.parent.dartAsyncMarker ==
+ AsyncMarker.AsyncStar)) {
+ _useVariable(_currentFrame.parent
+ .getSyntheticVar(ContinuationVariables.asyncStackTraceVar));
+ }
}
if (node is Constructor) {
@@ -535,7 +552,8 @@
visitVariableDeclaration(VariableDeclaration node) {
_declareVariable(node);
- if (!_currentFrame.isDartSync && node.name[0] == ':') {
+ if (_currentFrame.dartAsyncMarker != AsyncMarker.Sync &&
+ node.name[0] == ':') {
_currentFrame.syntheticVars ??= <String, VariableDeclaration>{};
assert(_currentFrame.syntheticVars[node.name] == null);
_currentFrame.syntheticVars[node.name] = node;
@@ -610,7 +628,7 @@
@override
visitAssertStatement(AssertStatement node) {
- if (!locals.enableAsserts) {
+ if (!locals.options.enableAsserts) {
return;
}
super.visitAssertStatement(node);
@@ -618,7 +636,7 @@
@override
visitAssertBlock(AssertBlock node) {
- if (!locals.enableAsserts) {
+ if (!locals.options.enableAsserts) {
return;
}
_visitWithScope(node);
@@ -1072,7 +1090,7 @@
@override
visitAssertStatement(AssertStatement node) {
- if (!locals.enableAsserts) {
+ if (!locals.options.enableAsserts) {
return;
}
super.visitAssertStatement(node);
@@ -1080,7 +1098,7 @@
@override
visitAssertBlock(AssertBlock node) {
- if (!locals.enableAsserts) {
+ if (!locals.options.enableAsserts) {
return;
}
_visit(node, scope: true);
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index be1a7ed..6b418e0 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -1543,6 +1543,11 @@
set source(SourceFile sourceFile) {
_source = sourceFile;
+ if (_source != null) {
+ _flags |= flagHasSourceFile;
+ } else {
+ _flags &= ~flagHasSourceFile;
+ }
}
@override
@@ -1571,7 +1576,8 @@
bool operator ==(other) => other is _ScriptHandle && this.uri == other.uri;
@override
- String toString() => "$uri";
+ String toString() =>
+ "$uri${source != null ? '(source ${source.importUri})' : ''}";
}
class ObjectTable implements ObjectWriter, ObjectReader {
diff --git a/pkg/vm/lib/bytecode/options.dart b/pkg/vm/lib/bytecode/options.dart
new file mode 100644
index 0000000..516cf57
--- /dev/null
+++ b/pkg/vm/lib/bytecode/options.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.
+
+library vm.bytecode.options;
+
+/// Collection of options for bytecode generator.
+class BytecodeOptions {
+ static Map<String, String> commandLineFlags = {
+ 'annotations': 'Emit Dart annotations',
+ 'local-var-info': 'Emit debug information about local variables',
+ 'show-bytecode-size-stat': 'Show bytecode size breakdown',
+ 'source-positions': 'Emit source positions',
+ };
+
+ bool enableAsserts;
+ bool causalAsyncStacks;
+ bool emitSourcePositions;
+ bool emitSourceFiles;
+ bool emitLocalVarInfo;
+ bool emitAnnotations;
+ bool omitAssertSourcePositions;
+ bool showBytecodeSizeStatistics;
+ Map<String, String> environmentDefines;
+
+ BytecodeOptions(
+ {this.enableAsserts = false,
+ this.causalAsyncStacks,
+ this.emitSourcePositions = false,
+ this.emitSourceFiles = false,
+ this.emitLocalVarInfo = false,
+ this.emitAnnotations = false,
+ this.omitAssertSourcePositions = false,
+ this.showBytecodeSizeStatistics = false,
+ this.environmentDefines = const <String, String>{}}) {
+ causalAsyncStacks ??=
+ environmentDefines['dart.developer.causal_async_stacks'] == 'true';
+ }
+
+ void parseCommandLineFlags(List<String> flags) {
+ if (flags == null) {
+ return;
+ }
+ for (String flag in flags) {
+ switch (flag) {
+ case 'source-positions':
+ emitSourcePositions = true;
+ break;
+ case 'local-var-info':
+ emitLocalVarInfo = true;
+ break;
+ case 'annotations':
+ emitAnnotations = true;
+ break;
+ case 'show-bytecode-size-stat':
+ showBytecodeSizeStatistics = true;
+ break;
+ default:
+ throw 'Unexpected bytecode flag $flag';
+ }
+ }
+ }
+}
diff --git a/pkg/vm/lib/bytecode/source_positions.dart b/pkg/vm/lib/bytecode/source_positions.dart
index af58534..ec56aa15 100644
--- a/pkg/vm/lib/bytecode/source_positions.dart
+++ b/pkg/vm/lib/bytecode/source_positions.dart
@@ -15,7 +15,10 @@
/// Maintains mapping between bytecode instructions and source positions.
class SourcePositions {
- final Map<int, int> mapping = <int, int>{}; // PC -> fileOffset
+ // Special value of fileOffset which marks yield point.
+ static const yieldPointMarker = -2;
+
+ final List<int> _positions = <int>[]; // Pairs (PC, fileOffset).
int _lastPc = 0;
int _lastOffset = 0;
@@ -25,20 +28,37 @@
assert(pc > _lastPc);
assert(fileOffset >= 0);
if (fileOffset != _lastOffset) {
- mapping[pc] = fileOffset;
+ _positions.add(pc);
+ _positions.add(fileOffset);
_lastPc = pc;
_lastOffset = fileOffset;
}
}
+ void addYieldPoint(int pc, int fileOffset) {
+ assert(pc > _lastPc);
+ assert(fileOffset >= 0);
+ _positions.add(pc);
+ _positions.add(yieldPointMarker);
+ _positions.add(pc);
+ _positions.add(fileOffset);
+ _lastPc = pc;
+ _lastOffset = fileOffset;
+ }
+
+ bool get isEmpty => _positions.isEmpty;
+ bool get isNotEmpty => !isEmpty;
+
void write(BufferedWriter writer) {
- writer.writePackedUInt30(mapping.length);
+ writer.writePackedUInt30(_positions.length ~/ 2);
final encodePC = new PackedUInt30DeltaEncoder();
final encodeOffset = new SLEB128DeltaEncoder();
- mapping.forEach((int pc, int fileOffset) {
+ for (int i = 0; i < _positions.length; i += 2) {
+ final int pc = _positions[i];
+ final int fileOffset = _positions[i + 1];
encodePC.write(writer, pc);
encodeOffset.write(writer, fileOffset);
- });
+ }
}
SourcePositions.read(BufferedReader reader) {
@@ -48,16 +68,29 @@
for (int i = 0; i < length; ++i) {
int pc = decodePC.read(reader);
int fileOffset = decodeOffset.read(reader);
- add(pc, fileOffset);
+ _positions.add(pc);
+ _positions.add(fileOffset);
}
}
@override
- String toString() => mapping.toString();
+ String toString() => _positions.toString();
Map<int, String> getBytecodeAnnotations() {
- return mapping.map((int pc, int fileOffset) =>
- new MapEntry(pc, 'source position $fileOffset'));
+ final map = <int, String>{};
+ for (int i = 0; i < _positions.length; i += 2) {
+ final int pc = _positions[i];
+ final int fileOffset = _positions[i + 1];
+ final entry = (fileOffset == yieldPointMarker)
+ ? 'yield point'
+ : 'source position $fileOffset';
+ if (map[pc] == null) {
+ map[pc] = entry;
+ } else {
+ map[pc] = "${map[pc]}; $entry";
+ }
+ }
+ return map;
}
}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 8402ef8..78a233a 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -48,6 +48,7 @@
import 'bytecode/bytecode_serialization.dart' show BytecodeSizeStatistics;
import 'bytecode/gen_bytecode.dart'
show generateBytecode, createFreshComponentWithBytecode;
+import 'bytecode/options.dart' show BytecodeOptions;
import 'constants_error_reporter.dart' show ForwardConstantEvaluationErrors;
import 'target/install.dart' show installAdditionalTargets;
@@ -111,19 +112,13 @@
'Split resulting kernel file into multiple files (one per package).',
defaultsTo: false);
args.addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false);
- args.addFlag('emit-bytecode-source-positions',
- help: 'Emit source positions in bytecode', defaultsTo: false);
- args.addFlag('emit-bytecode-local-var-info',
- help: 'Emit information about local variables in bytecode',
- defaultsTo: false);
- args.addFlag('emit-bytecode-annotations',
- help: 'Emit Dart annotations in bytecode', defaultsTo: false);
+ args.addMultiOption('bytecode-options',
+ help: 'Specify options for bytecode generation:',
+ valueHelp: 'opt1,opt2,...',
+ allowed: BytecodeOptions.commandLineFlags.keys,
+ allowedHelp: BytecodeOptions.commandLineFlags);
args.addFlag('drop-ast',
- help: 'Drop AST for members with bytecode', defaultsTo: false);
- args.addFlag('show-bytecode-size-stat',
- help: 'Show bytecode size breakdown.', defaultsTo: false);
- args.addFlag('use-future-bytecode-format',
- help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);
+ help: 'Include only bytecode into the output file', defaultsTo: false);
args.addMultiOption('enable-experiment',
help: 'Comma separated list of experimental features to enable.');
args.addFlag('help',
@@ -166,18 +161,13 @@
final bool aot = options['aot'];
final bool tfa = options['tfa'];
final bool linkPlatform = options['link-platform'];
+ final bool embedSources = options['embed-sources'];
final bool genBytecode = options['gen-bytecode'];
- final bool emitBytecodeSourcePositions =
- options['emit-bytecode-source-positions'];
- final bool emitBytecodeLocalVarInfo = options['emit-bytecode-local-var-info'];
- final bool emitBytecodeAnnotations = options['emit-bytecode-annotations'];
final bool dropAST = options['drop-ast'];
- final bool useFutureBytecodeFormat = options['use-future-bytecode-format'];
final bool enableAsserts = options['enable-asserts'];
final bool enableConstantEvaluation = options['enable-constant-evaluation'];
final bool useProtobufTreeShaker = options['protobuf-tree-shaker'];
final bool splitOutputByPackages = options['split-output-by-packages'];
- final bool showBytecodeSizeStat = options['show-bytecode-size-stat'];
final List<String> experimentalFlags = options['enable-experiment'];
final Map<String, String> environmentDefines = {};
@@ -185,6 +175,12 @@
return badUsageExitCode;
}
+ final BytecodeOptions bytecodeOptions = new BytecodeOptions(
+ enableAsserts: enableAsserts,
+ emitSourceFiles: embedSources,
+ environmentDefines: environmentDefines)
+ ..parseCommandLineFlags(options['bytecode-options']);
+
final target = createFrontEndTarget(targetName);
if (target == null) {
print('Failed to create front-end target $targetName.');
@@ -222,18 +218,15 @@
..onDiagnostic = (DiagnosticMessage m) {
errorDetector(m);
}
- ..embedSourceText = options['embed-sources'];
+ ..embedSourceText = embedSources;
final component = await compileToKernel(mainUri, compilerOptions,
aot: aot,
useGlobalTypeFlowAnalysis: tfa,
environmentDefines: environmentDefines,
genBytecode: genBytecode,
- emitBytecodeSourcePositions: emitBytecodeSourcePositions,
- emitBytecodeLocalVarInfo: emitBytecodeLocalVarInfo,
- emitBytecodeAnnotations: emitBytecodeAnnotations,
+ bytecodeOptions: bytecodeOptions,
dropAST: dropAST && !splitOutputByPackages,
- useFutureBytecodeFormat: useFutureBytecodeFormat,
enableAsserts: enableAsserts,
enableConstantEvaluation: enableConstantEvaluation,
useProtobufTreeShaker: useProtobufTreeShaker);
@@ -244,7 +237,7 @@
return compileTimeErrorExitCode;
}
- if (showBytecodeSizeStat && !splitOutputByPackages) {
+ if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
BytecodeSizeStatistics.reset();
}
@@ -253,7 +246,7 @@
printer.writeComponentFile(component);
await sink.close();
- if (showBytecodeSizeStat && !splitOutputByPackages) {
+ if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
BytecodeSizeStatistics.dump();
}
@@ -267,15 +260,9 @@
compilerOptions,
component,
outputFileName,
- environmentDefines: environmentDefines,
genBytecode: genBytecode,
- enableAsserts: enableAsserts,
- emitBytecodeSourcePositions: emitBytecodeSourcePositions,
- emitBytecodeLocalVarInfo: emitBytecodeLocalVarInfo,
- emitBytecodeAnnotations: emitBytecodeAnnotations,
+ bytecodeOptions: bytecodeOptions,
dropAST: dropAST,
- showBytecodeSizeStat: showBytecodeSizeStat,
- useFutureBytecodeFormat: useFutureBytecodeFormat,
);
}
@@ -292,11 +279,8 @@
bool useGlobalTypeFlowAnalysis: false,
Map<String, String> environmentDefines,
bool genBytecode: false,
- bool emitBytecodeSourcePositions: false,
- bool emitBytecodeLocalVarInfo: false,
- bool emitBytecodeAnnotations: false,
+ BytecodeOptions bytecodeOptions,
bool dropAST: false,
- bool useFutureBytecodeFormat: false,
bool enableAsserts: false,
bool enableConstantEvaluation: true,
bool useProtobufTreeShaker: false}) async {
@@ -324,14 +308,7 @@
if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
await runWithFrontEndCompilerContext(source, options, component, () {
- generateBytecode(component,
- enableAsserts: enableAsserts,
- emitSourcePositions: emitBytecodeSourcePositions,
- emitSourceFiles: options.embedSourceText,
- emitLocalVarInfo: emitBytecodeLocalVarInfo,
- emitAnnotations: emitBytecodeAnnotations,
- useFutureBytecodeFormat: useFutureBytecodeFormat,
- environmentDefines: environmentDefines);
+ generateBytecode(component, options: bytecodeOptions);
});
if (dropAST) {
@@ -661,15 +638,9 @@
CompilerOptions compilerOptions,
Component component,
String outputFileName, {
- Map<String, String> environmentDefines,
bool genBytecode: false,
- bool enableAsserts: true,
- bool emitBytecodeSourcePositions: false,
- bool emitBytecodeLocalVarInfo: false,
- bool emitBytecodeAnnotations: false,
+ BytecodeOptions bytecodeOptions,
bool dropAST: false,
- bool showBytecodeSizeStat: false,
- bool useFutureBytecodeFormat: false,
}) async {
// Package sharing: make the encoding not depend on the order in which parts
// of a package are loaded.
@@ -693,7 +664,7 @@
final List<String> packages = packagesSet.toList();
packages.add('main'); // Make sure main package is last.
- if (showBytecodeSizeStat) {
+ if (bytecodeOptions.showBytecodeSizeStatistics) {
BytecodeSizeStatistics.reset();
}
@@ -724,15 +695,9 @@
.where((lib) => packageFor(lib) == package)
.toList();
generateBytecode(component,
+ options: bytecodeOptions,
libraries: libraries,
- hierarchy: hierarchy,
- enableAsserts: enableAsserts,
- emitSourcePositions: emitBytecodeSourcePositions,
- emitSourceFiles: compilerOptions.embedSourceText,
- emitLocalVarInfo: emitBytecodeLocalVarInfo,
- emitAnnotations: emitBytecodeAnnotations,
- useFutureBytecodeFormat: useFutureBytecodeFormat,
- environmentDefines: environmentDefines);
+ hierarchy: hierarchy);
if (dropAST) {
partComponent = createFreshComponentWithBytecode(component);
@@ -750,7 +715,7 @@
}
});
- if (showBytecodeSizeStat) {
+ if (bytecodeOptions.showBytecodeSizeStatistics) {
BytecodeSizeStatistics.dump();
}
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index bcbf5fa..c90cd64 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -16,6 +16,9 @@
/// Represents the (instantiated) ffi.NativeType.
enum NativeType {
+ kNativeType,
+ kNativeInteger,
+ kNativeDouble,
kPointer,
kNativeFunction,
kInt8,
@@ -29,7 +32,8 @@
kIntptr,
kFloat,
kDouble,
- kVoid
+ kVoid,
+ kStruct
}
const NativeType kNativeTypeIntStart = NativeType.kInt8;
@@ -37,6 +41,9 @@
/// The [NativeType] class names, indexed by [NativeType].
const List<String> nativeTypeClassNames = [
+ 'NativeType',
+ '_NativeInteger',
+ '_NativeDouble',
'Pointer',
'NativeFunction',
'Int8',
@@ -50,7 +57,8 @@
'IntPtr',
'Float',
'Double',
- 'Void'
+ 'Void',
+ 'Struct'
];
const int UNKNOWN = 0;
@@ -58,6 +66,9 @@
/// The [NativeType] sizes in bytes, indexed by [NativeType].
const List<int> nativeTypeSizes = [
+ UNKNOWN, // NativeType
+ UNKNOWN, // NativeInteger
+ UNKNOWN, // NativeDouble
WORD_SIZE, // Pointer
UNKNOWN, // NativeFunction
1, // Int8
@@ -72,12 +83,14 @@
4, // Float
8, // Double
UNKNOWN, // Void
+ UNKNOWN, // Struct
];
/// [FfiTransformer] contains logic which is shared between
/// _FfiUseSiteTransformer and _FfiDefinitionTransformer.
class FfiTransformer extends Transformer {
final TypeEnvironment env;
+ final CoreTypes coreTypes;
final LibraryIndex index;
final ClassHierarchy hierarchy;
final DiagnosticReporter diagnosticReporter;
@@ -95,15 +108,18 @@
final Procedure storeMethod;
final Procedure offsetByMethod;
final Procedure asFunctionMethod;
+ final Procedure asFunctionInternal;
final Procedure lookupFunctionMethod;
final Procedure fromFunctionMethod;
- final Field structField;
+ final Field addressOfField;
+ final Constructor structFromPointer;
+ final Procedure libraryLookupMethod;
/// Classes corresponding to [NativeType], indexed by [NativeType].
final List<Class> nativeTypesClasses;
FfiTransformer(
- this.index, CoreTypes coreTypes, this.hierarchy, this.diagnosticReporter)
+ this.index, this.coreTypes, this.hierarchy, this.diagnosticReporter)
: env = new TypeEnvironment(coreTypes, hierarchy),
intClass = coreTypes.intClass,
doubleClass = coreTypes.doubleClass,
@@ -116,15 +132,21 @@
loadMethod = index.getMember('dart:ffi', 'Pointer', 'load'),
storeMethod = index.getMember('dart:ffi', 'Pointer', 'store'),
offsetByMethod = index.getMember('dart:ffi', 'Pointer', 'offsetBy'),
+ addressOfField = index.getMember('dart:ffi', 'Struct', 'addressOf'),
+ structFromPointer =
+ index.getMember('dart:ffi', 'Struct', 'fromPointer'),
asFunctionMethod = index.getMember('dart:ffi', 'Pointer', 'asFunction'),
+ asFunctionInternal =
+ index.getTopLevelMember('dart:ffi', '_asFunctionInternal'),
lookupFunctionMethod =
index.getMember('dart:ffi', 'DynamicLibrary', 'lookupFunction'),
fromFunctionMethod =
- index.getTopLevelMember('dart:ffi', 'fromFunction'),
- structField = index.getTopLevelMember('dart:ffi', 'struct'),
+ index.getMember('dart:ffi', 'Pointer', 'fromFunction'),
+ libraryLookupMethod =
+ index.getMember('dart:ffi', 'DynamicLibrary', 'lookup'),
nativeTypesClasses = nativeTypeClassNames
.map((name) => index.getClass('dart:ffi', name))
- .toList() {}
+ .toList();
/// Computes the Dart type corresponding to a ffi.[NativeType], returns null
/// if it is not a valid NativeType.
@@ -145,19 +167,23 @@
/// T extends [Pointer] -> T
/// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
/// where DartRepresentationOf(Tn) -> Sn
- DartType convertNativeTypeToDartType(DartType nativeType) {
+ DartType convertNativeTypeToDartType(DartType nativeType, bool allowStructs) {
if (nativeType is! InterfaceType) {
return null;
}
- Class nativeClass = (nativeType as InterfaceType).classNode;
- if (env.isSubtypeOf(
- InterfaceType(nativeClass), InterfaceType(pointerClass))) {
- return nativeType;
- }
+ InterfaceType native = nativeType;
+ Class nativeClass = native.classNode;
NativeType nativeType_ = getType(nativeClass);
+
+ if (hierarchy.isSubclassOf(nativeClass, structClass)) {
+ return allowStructs ? nativeType : null;
+ }
if (nativeType_ == null) {
return null;
}
+ if (nativeType_ == NativeType.kPointer) {
+ return nativeType;
+ }
if (kNativeTypeIntStart.index <= nativeType_.index &&
nativeType_.index <= kNativeTypeIntEnd.index) {
return InterfaceType(intClass);
@@ -168,23 +194,26 @@
if (nativeType_ == NativeType.kVoid) {
return VoidType();
}
- if (nativeType_ == NativeType.kNativeFunction) {
- DartType fun = (nativeType as InterfaceType).typeArguments[0];
- if (fun is FunctionType) {
- if (fun.namedParameters.isNotEmpty) return null;
- if (fun.positionalParameters.length != fun.requiredParameterCount)
- return null;
- if (fun.typeParameters.length != 0) return null;
- DartType returnType = convertNativeTypeToDartType(fun.returnType);
- if (returnType == null) return null;
- List<DartType> argumentTypes = fun.positionalParameters
- .map(this.convertNativeTypeToDartType)
- .toList();
- if (argumentTypes.contains(null)) return null;
- return FunctionType(argumentTypes, returnType);
- }
+ if (nativeType_ != NativeType.kNativeFunction ||
+ native.typeArguments[0] is! FunctionType) {
+ return null;
}
- return null;
+
+ FunctionType fun = native.typeArguments[0];
+ if (fun.namedParameters.isNotEmpty) return null;
+ if (fun.positionalParameters.length != fun.requiredParameterCount) {
+ return null;
+ }
+ if (fun.typeParameters.length != 0) return null;
+ // TODO(36730): Structs cannot appear in native function signatures.
+ DartType returnType =
+ convertNativeTypeToDartType(fun.returnType, /*allowStructs=*/ false);
+ if (returnType == null) return null;
+ List<DartType> argumentTypes = fun.positionalParameters
+ .map((t) => convertNativeTypeToDartType(t, /*allowStructs=*/ false))
+ .toList();
+ if (argumentTypes.contains(null)) return null;
+ return FunctionType(argumentTypes, returnType);
}
NativeType getType(Class c) {
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index ad38a18..34d3fa9 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -9,9 +9,10 @@
import 'package:front_end/src/api_unstable/vm.dart'
show
templateFfiFieldAnnotation,
- templateFfiStructAnnotation,
templateFfiTypeMismatch,
- templateFfiFieldInitializer;
+ templateFfiFieldInitializer,
+ templateFfiStructGeneric,
+ templateFfiWrongStructInheritance;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -27,40 +28,37 @@
nativeTypeSizes,
WORD_SIZE;
-/// Checks and expands the dart:ffi @struct and field annotations.
+/// Checks and elaborates the dart:ffi structs and fields.
///
-/// Sample input:
-/// @ffi.struct
-/// class Coord extends ffi.Pointer<Void> {
-/// @ffi.Double()
+/// Input:
+/// class Coord extends Struct<Coord> {
+/// @Double()
/// double x;
///
-/// @ffi.Double()
+/// @Double()
/// double y;
///
-/// @ffi.Pointer()
+/// @Pointer()
/// Coord next;
-///
-/// external static int sizeOf();
/// }
///
-/// Sample output:
-/// class Coordinate extends ffi.Pointer<ffi.Void> {
-/// ffi.Pointer<ffi.Double> get _xPtr => cast();
+/// Output:
+/// class Coord extends Struct<Coord> {
+/// Coord.#fromPointer(Pointer<Coord> coord) : super._(coord);
+///
+/// Pointer<Double> get _xPtr => addressOf.cast();
/// set x(double v) => _xPtr.store(v);
/// double get x => _xPtr.load();
///
-/// ffi.Pointer<ffi.Double> get _yPtr =>
-/// offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
+/// Pointer<Double> get _yPtr => addressOf.offsetBy(...).cast();
/// set y(double v) => _yPtr.store(v);
/// double get y => _yPtr.load();
///
-/// ffi.Pointer<Coordinate> get _nextPtr =>
-/// offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
+/// ffi.Pointer<Coordinate> get _nextPtr => addressof.offsetBy(...).cast();
/// set next(Coordinate v) => _nextPtr.store(v);
/// Coordinate get next => _nextPtr.load();
///
-/// static int sizeOf() => 24;
+/// static final int #sizeOf = 24;
/// }
ReplacedMembers transformLibraries(
Component component,
@@ -71,7 +69,7 @@
final LibraryIndex index = LibraryIndex(
component, const ["dart:ffi", "dart:_internal", "dart:core"]);
if (!index.containsLibrary("dart:ffi")) {
- // if dart:ffi is not loaded, do not do the transformation
+ // If dart:ffi is not loaded, do not do the transformation.
return ReplacedMembers({}, {});
}
final transformer = new _FfiDefinitionTransformer(
@@ -81,7 +79,7 @@
transformer.replacedGetters, transformer.replacedSetters);
}
-/// Checks and expands the dart:ffi @struct and field annotations.
+/// Checks and elaborates the dart:ffi structs and fields.
class _FfiDefinitionTransformer extends FfiTransformer {
final LibraryIndex index;
final Field _internalIs64Bit;
@@ -108,20 +106,19 @@
@override
visitClass(Class node) {
- if (node == pointerClass || !hierarchy.isSubtypeOf(node, pointerClass)) {
+ if (!hierarchy.isSubclassOf(node, structClass) || node == structClass) {
return node;
}
- // Because subtypes of Pointer are only allocated by allocate<Pointer<..>>()
- // and fromAddress<Pointer<..>>() which are not recognized as constructor
- // calls, we need to prevent these classes from being tree shaken out.
- _preventTreeShaking(node);
+ _checkStructClass(node);
- _checkFieldAnnotations(node);
+ // Struct objects are manufactured in the VM by 'allocate' and 'load'.
+ _makeEntryPoint(node);
+
_checkConstructors(node);
+ final bool fieldsValid = _checkFieldAnnotations(node);
- bool isStruct = _checkStructAnnotation(node);
- if (isStruct) {
+ if (fieldsValid) {
int size = _replaceFields(node);
_replaceSizeOfMethod(node, size);
}
@@ -129,19 +126,34 @@
return node;
}
- bool _checkStructAnnotation(Class node) {
- bool isStruct = _hasAnnotation(node);
- if (!isStruct && node.fields.isNotEmpty) {
+ void _checkStructClass(Class node) {
+ if (node.typeParameters.length > 0) {
diagnosticReporter.report(
- templateFfiStructAnnotation.withArguments(node.name),
+ templateFfiStructGeneric.withArguments(node.name),
node.fileOffset,
1,
- node.fileUri);
+ node.location.file);
}
- return isStruct;
+
+ if (node.supertype?.classNode != structClass) {
+ // Not a struct, but extends a struct. The error will be emitted by
+ // _FfiUseSiteTransformer.
+ return;
+ }
+
+ // A struct classes "C" must extend "Struct<C>".
+ DartType structTypeArg = node.supertype.typeArguments[0];
+ if (structTypeArg != InterfaceType(node)) {
+ diagnosticReporter.report(
+ templateFfiWrongStructInheritance.withArguments(node.name),
+ node.fileOffset,
+ 1,
+ node.location.file);
+ }
}
- void _checkFieldAnnotations(Class node) {
+ bool _checkFieldAnnotations(Class node) {
+ bool success = true;
for (Field f in node.fields) {
if (f.initializer is! NullLiteral) {
diagnosticReporter.report(
@@ -161,21 +173,29 @@
DartType dartType = f.type;
DartType nativeType =
InterfaceType(nativeTypesClasses[annos.first.index]);
- DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
- if (!env.isSubtypeOf(dartType, shouldBeDartType)) {
+ // TODO(36730): Support structs inside structs.
+ DartType shouldBeDartType =
+ convertNativeTypeToDartType(nativeType, /*allowStructs=*/ false);
+ if (shouldBeDartType == null ||
+ !env.isSubtypeOf(dartType, shouldBeDartType)) {
diagnosticReporter.report(
templateFfiTypeMismatch.withArguments(
dartType, shouldBeDartType, nativeType),
f.fileOffset,
1,
f.location.file);
+ success = false;
}
}
}
+ return success;
}
void _checkConstructors(Class node) {
List<Initializer> toRemove = [];
+
+ // Constructors cannot have initializers because initializers refer to
+ // fields, and the fields were replaced with getter/setter pairs.
for (Constructor c in node.constructors) {
for (Initializer i in c.initializers) {
if (i is FieldInitializer) {
@@ -192,6 +212,18 @@
for (Initializer i in toRemove) {
i.remove();
}
+
+ // Add a constructor which 'load' can use.
+ // C.#fromPointer(Pointer<Void> address) : super.fromPointer(address);
+ final VariableDeclaration pointer = new VariableDeclaration("#pointer");
+ final Constructor ctor = Constructor(
+ FunctionNode(EmptyStatement(), positionalParameters: [pointer]),
+ name: Name("#fromPointer"),
+ initializers: [
+ SuperInitializer(structFromPointer, Arguments([VariableGet(pointer)]))
+ ]);
+ _makeEntryPoint(ctor);
+ node.addMember(ctor);
}
/// Computes the field offsets in the struct and replaces the fields with
@@ -230,7 +262,7 @@
}
/// Sample output:
- /// ffi.Pointer<ffi.Double> get _xPtr => cast();
+ /// ffi.Pointer<ffi.Double> get _xPtr => addressOf.cast();
/// double get x => _xPtr.load();
/// set x(double v) => _xPtr.store(v);
List<Procedure> _generateMethodsForField(
@@ -241,13 +273,12 @@
DartType pointerType = InterfaceType(pointerClass, [nativeType]);
Name pointerName = Name('#_ptr_${field.name.name}');
- // Sample output for primitives:
- // ffi.Pointer<ffi.Double> get _xPtr => cast<ffi.Pointer<ffi.Double>>();
- // Sample output for structs:
- // ffi.Pointer<Coordinate> get _xPtr => offsetBy(16).cast<...>();
- Expression offsetExpression = ThisExpression();
+ // Sample output:
+ // ffi.Pointer<ffi.Double> get _xPtr => addressOf.offsetBy(...).cast<ffi.Pointer<ffi.Double>>();
+ Expression pointer =
+ PropertyGet(ThisExpression(), addressOfField.name, addressOfField);
if (offset != 0) {
- offsetExpression = MethodInvocation(offsetExpression, offsetByMethod.name,
+ pointer = MethodInvocation(pointer, offsetByMethod.name,
Arguments([IntLiteral(offset)]), offsetByMethod);
}
Procedure pointerGetter = Procedure(
@@ -255,9 +286,9 @@
ProcedureKind.Getter,
FunctionNode(
guardOn32Bit(ReturnStatement(MethodInvocation(
- offsetExpression,
+ pointer,
castMethod.name,
- Arguments([], types: [pointerType]),
+ Arguments([], types: [nativeType]),
castMethod))),
returnType: pointerType));
@@ -276,41 +307,40 @@
// Sample output:
// set x(double v) => _xPtr.store(v);
- VariableDeclaration argument = VariableDeclaration('#v', type: field.type);
- Procedure setter = Procedure(
- field.name,
- ProcedureKind.Setter,
- FunctionNode(
- guardOn32Bit(ReturnStatement(MethodInvocation(
- PropertyGet(ThisExpression(), pointerName, pointerGetter),
- storeMethod.name,
- Arguments([VariableGet(argument)]),
- storeMethod))),
- returnType: VoidType(),
- positionalParameters: [argument]));
+ Procedure setter = null;
+ if (!field.isFinal) {
+ VariableDeclaration argument =
+ VariableDeclaration('#v', type: field.type);
+ setter = Procedure(
+ field.name,
+ ProcedureKind.Setter,
+ FunctionNode(
+ guardOn32Bit(ReturnStatement(MethodInvocation(
+ PropertyGet(ThisExpression(), pointerName, pointerGetter),
+ storeMethod.name,
+ Arguments([VariableGet(argument)]),
+ storeMethod))),
+ returnType: VoidType(),
+ positionalParameters: [argument]));
+ }
replacedGetters[field] = getter;
replacedSetters[field] = setter;
- return [pointerGetter, getter, setter];
+ if (setter != null) {
+ return [pointerGetter, getter, setter];
+ } else {
+ return [pointerGetter, getter];
+ }
}
- /// Sample input:
- /// external static int sizeOf();
- ///
/// Sample output:
- /// static int sizeOf() => 24;
+ /// static int #sizeOf() => 24;
void _replaceSizeOfMethod(Class struct, int size) {
- Procedure sizeOf = _findProcedure(struct, 'sizeOf');
- if (sizeOf == null || !sizeOf.isExternal || !sizeOf.isStatic) {
- return;
- }
-
- // replace in place to avoid going over use sites
- sizeOf.function = FunctionNode(
- guardOn32Bit(ReturnStatement(IntLiteral(size))),
- returnType: InterfaceType(intClass));
- sizeOf.isExternal = false;
+ final Field sizeOf = Field(Name("#sizeOf"),
+ isStatic: true, isFinal: true, initializer: IntLiteral(size));
+ _makeEntryPoint(sizeOf);
+ struct.addMember(sizeOf);
}
// TODO(dacoharkes): move to VM, take into account architecture
@@ -359,25 +389,7 @@
return _align(highestOffset + highestOffsetSize, largestElement);
}
- bool _hasAnnotation(Class node) {
- // Pre constant 2018 update.
- // TODO(dacoharkes): Remove pre constant 2018 after constants change landed.
- for (Expression e in node.annotations) {
- if (e is StaticGet) {
- if (e.target == structField) {
- return true;
- }
- }
- }
- Iterable<Class> postConstant2018 = node.annotations
- .whereType<ConstantExpression>()
- .map((expr) => expr.constant)
- .whereType<InstanceConstant>()
- .map((constant) => constant.classNode);
- return postConstant2018.contains(structClass);
- }
-
- void _preventTreeShaking(Class node) {
+ void _makeEntryPoint(Annotatable node) {
node.addAnnotation(ConstructorInvocation(
pragmaConstructor, Arguments([StringLiteral("vm:entry-point")])));
}
@@ -409,7 +421,3 @@
return postConstant2018.followedBy(preConstant2018);
}
}
-
-/// Finds procedure with name, otherwise returns null.
-Procedure _findProcedure(Class c, String name) =>
- c.procedures.firstWhere((p) => p.name.name == name, orElse: () => null);
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index d61ca95..58b0acd 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -8,8 +8,10 @@
show
templateFfiTypeInvalid,
templateFfiTypeMismatch,
+ templateFfiDartTypeMismatch,
templateFfiTypeUnsized,
- templateFfiNotStatic;
+ templateFfiNotStatic,
+ templateFfiExtendsOrImplementsSealedClass;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -35,7 +37,7 @@
ReplacedMembers replacedFields) {
final index = new LibraryIndex(component, ["dart:ffi"]);
if (!index.containsLibrary("dart:ffi")) {
- // if dart:ffi is not loaded, do not do the transformation
+ // If dart:ffi is not loaded, do not do the transformation.
return;
}
final transformer = new _FfiUseSiteTransformer(
@@ -74,6 +76,7 @@
visitClass(Class node) {
env.thisType = InterfaceType(node);
try {
+ _ensureNotExtendsOrImplementsSealedClass(node);
return super.visitClass(node);
} finally {
env.thisType = null;
@@ -118,20 +121,71 @@
DartType dartType = func.getStaticType(env);
_ensureIsStatic(func);
+ // TODO(36730): Allow passing/returning structs by value.
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
+
+ // Check `exceptionalReturn`'s type.
+ final FunctionType funcType = dartType;
+ final Expression exceptionalReturn = node.arguments.positional[1];
+ final DartType returnType = exceptionalReturn.getStaticType(env);
+
+ if (!env.isSubtypeOf(returnType, funcType.returnType)) {
+ diagnosticReporter.report(
+ templateFfiDartTypeMismatch.withArguments(
+ returnType, funcType.returnType),
+ exceptionalReturn.fileOffset,
+ 1,
+ exceptionalReturn.location.file);
+ }
}
} catch (_FfiStaticTypeError) {}
return node;
}
+ // We need to replace calls to 'DynamicLibrary.lookupFunction' with explicit
+ // Kernel, because we cannot have a generic call to 'asFunction' in its body.
+ //
+ // Below, in 'visitMethodInvocation', we ensure that the type arguments to
+ // 'lookupFunction' are constants, so by inlining the call to 'asFunction' at
+ // the call-site, we ensure that there are no generic calls to 'asFunction'.
+ //
+ // We will not detect dynamic invocations of 'asFunction' -- these are handled
+ // by the stub in 'dynamic_library_patch.dart'. Dynamic invocations of
+ // 'lookupFunction' (and 'asFunction') are not legal and throw a runtime
+ // exception.
+ Expression _replaceLookupFunction(MethodInvocation node) {
+ // The generated code looks like:
+ //
+ // _asFunctionInternal<DS, NS>(lookup<NativeFunction<NS>>(symbolName))
+
+ final DartType nativeSignature = node.arguments.types[0];
+ final DartType dartSignature = node.arguments.types[1];
+
+ final Arguments args = Arguments([
+ node.arguments.positional.single
+ ], types: [
+ InterfaceType(nativeFunctionClass, [nativeSignature])
+ ]);
+
+ final Expression lookupResult = MethodInvocation(
+ node.receiver, Name("lookup"), args, libraryLookupMethod);
+
+ return StaticInvocation(asFunctionInternal,
+ Arguments([lookupResult], types: [dartSignature, nativeSignature]));
+ }
+
@override
visitMethodInvocation(MethodInvocation node) {
super.visitMethodInvocation(node);
Member target = node.interfaceTarget;
try {
+ // We will not detect dynamic invocations of 'asFunction' and
+ // 'lookupFunction' -- these are handled by the 'asFunctionInternal' stub
+ // in 'dynamic_library_patch.dart'. Dynamic invocations of 'asFunction'
+ // and 'lookupFunction' are not legal and throw a runtime exception.
if (target == lookupFunctionMethod) {
DartType nativeType =
InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
@@ -139,14 +193,8 @@
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
+ return _replaceLookupFunction(node);
} else if (target == asFunctionMethod) {
- if (isFfiLibrary) {
- // Library code of dart:ffi uses asFunction to implement
- // lookupFunction. Since we treat lookupFunction as well, this call
- // can be generic and still support AOT.
- return node;
- }
-
DartType dartType = node.arguments.types[0];
DartType pointerType = node.receiver.getStaticType(env);
DartType nativeType = _pointerTypeGetTypeArg(pointerType);
@@ -154,17 +202,23 @@
_ensureNativeTypeValid(pointerType, node);
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
+
+ final DartType nativeSignature =
+ (nativeType as InterfaceType).typeArguments[0];
+ return StaticInvocation(asFunctionInternal,
+ Arguments([node.receiver], types: [dartType, nativeSignature]));
} else if (target == loadMethod) {
- // TODO(dacoharkes): should load and store permitted to be generic?
+ // TODO(dacoharkes): should load and store be generic?
// https://github.com/dart-lang/sdk/issues/35902
DartType dartType = node.arguments.types[0];
DartType pointerType = node.receiver.getStaticType(env);
DartType nativeType = _pointerTypeGetTypeArg(pointerType);
_ensureNativeTypeValid(pointerType, node);
- _ensureNativeTypeValid(nativeType, node);
+ _ensureNativeTypeValid(nativeType, node, allowStructs: true);
_ensureNativeTypeSized(nativeType, node, target.name);
- _ensureNativeTypeToDartType(nativeType, dartType, node);
+ _ensureNativeTypeToDartType(nativeType, dartType, node,
+ allowStructs: true);
} else if (target == storeMethod) {
// TODO(dacoharkes): should load and store permitted to be generic?
// https://github.com/dart-lang/sdk/issues/35902
@@ -172,6 +226,8 @@
DartType pointerType = node.receiver.getStaticType(env);
DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+ // TODO(36730): Allow storing an entire struct to memory.
+ // TODO(36780): Emit a better error message for the struct case.
_ensureNativeTypeValid(pointerType, node);
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeSized(nativeType, node, target.name);
@@ -183,30 +239,30 @@
}
DartType _pointerTypeGetTypeArg(DartType pointerType) {
- if (pointerType is InterfaceType) {
- InterfaceType superType =
- hierarchy.getTypeAsInstanceOf(pointerType, pointerClass);
- return superType?.typeArguments[0];
- }
- return null;
+ return pointerType is InterfaceType ? pointerType.typeArguments[0] : null;
}
void _ensureNativeTypeToDartType(
- DartType nativeType, DartType dartType, Expression node) {
- DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
- if (dartType != shouldBeDartType) {
- diagnosticReporter.report(
- templateFfiTypeMismatch.withArguments(
- dartType, shouldBeDartType, nativeType),
- node.fileOffset,
- 1,
- node.location.file);
- throw _FfiStaticTypeError();
- }
+ DartType containerTypeArg, DartType elementType, Expression node,
+ {bool allowStructs: false}) {
+ final DartType shouldBeElementType =
+ convertNativeTypeToDartType(containerTypeArg, allowStructs);
+ if (elementType == shouldBeElementType) return;
+ // Both subtypes and implicit downcasts are allowed statically.
+ if (env.isSubtypeOf(shouldBeElementType, elementType)) return;
+ if (env.isSubtypeOf(elementType, shouldBeElementType)) return;
+ diagnosticReporter.report(
+ templateFfiTypeMismatch.withArguments(
+ elementType, shouldBeElementType, containerTypeArg),
+ node.fileOffset,
+ 1,
+ node.location.file);
+ throw _FfiStaticTypeError();
}
- void _ensureNativeTypeValid(DartType nativeType, Expression node) {
- if (!_nativeTypeValid(nativeType)) {
+ void _ensureNativeTypeValid(DartType nativeType, Expression node,
+ {bool allowStructs: false}) {
+ if (!_nativeTypeValid(nativeType, allowStructs: allowStructs)) {
diagnosticReporter.report(
templateFfiTypeInvalid.withArguments(nativeType),
node.fileOffset,
@@ -218,8 +274,8 @@
/// The Dart type system does not enforce that NativeFunction return and
/// parameter types are only NativeTypes, so we need to check this.
- bool _nativeTypeValid(DartType nativeType) {
- return convertNativeTypeToDartType(nativeType) != null;
+ bool _nativeTypeValid(DartType nativeType, {bool allowStructs: false}) {
+ return convertNativeTypeToDartType(nativeType, allowStructs) != null;
}
void _ensureNativeTypeSized(
@@ -238,7 +294,7 @@
/// Consequently, [allocate], [Pointer.load], [Pointer.store], and
/// [Pointer.elementAt] are not available.
bool _nativeTypeSized(DartType nativeType) {
- if (!(nativeType is InterfaceType)) {
+ if (nativeType is! InterfaceType) {
return false;
}
Class nativeClass = (nativeType as InterfaceType).classNode;
@@ -246,6 +302,9 @@
InterfaceType(nativeClass), InterfaceType(pointerClass))) {
return true;
}
+ if (hierarchy.isSubclassOf(nativeClass, structClass)) {
+ return true;
+ }
NativeType nativeType_ = getType(nativeClass);
if (nativeType_ == null) {
return false;
@@ -280,6 +339,37 @@
}
return node is ConstantExpression;
}
+
+ Class _extendsOrImplementsSealedClass(Class klass) {
+ final Class superClass = klass.supertype?.classNode;
+
+ // The Struct class can be extended, but subclasses of Struct cannot be (nor
+ // implemented).
+ if (klass != structClass && hierarchy.isSubtypeOf(klass, structClass)) {
+ return superClass != structClass ? superClass : null;
+ }
+
+ if (!nativeTypesClasses.contains(klass)) {
+ for (final parent in nativeTypesClasses) {
+ if (hierarchy.isSubtypeOf(klass, parent)) {
+ return parent;
+ }
+ }
+ }
+ return null;
+ }
+
+ void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
+ Class extended = _extendsOrImplementsSealedClass(klass);
+ if (extended != null) {
+ diagnosticReporter.report(
+ templateFfiExtendsOrImplementsSealedClass
+ .withArguments(extended.name),
+ klass.fileOffset,
+ 1,
+ klass.location.file);
+ }
+ }
}
/// Used internally for abnormal control flow to prevent cascading error
diff --git a/pkg/vm/test/bytecode/gen_bytecode_test.dart b/pkg/vm/test/bytecode/gen_bytecode_test.dart
index 887a8a0..673a16e 100644
--- a/pkg/vm/test/bytecode/gen_bytecode_test.dart
+++ b/pkg/vm/test/bytecode/gen_bytecode_test.dart
@@ -10,6 +10,7 @@
import 'package:kernel/kernel.dart';
import 'package:test/test.dart';
import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:vm/bytecode/options.dart' show BytecodeOptions;
import 'package:vm/kernel_front_end.dart' show runWithFrontEndCompilerContext;
import '../common_test_utils.dart';
@@ -34,7 +35,9 @@
// Need to omit source positions from bytecode as they are different on
// Linux and Windows (due to differences in newline characters).
generateBytecode(component,
- omitAssertSourcePositions: true, libraries: [mainLibrary]);
+ options: new BytecodeOptions(
+ enableAsserts: true, omitAssertSourcePositions: true),
+ libraries: [mainLibrary]);
});
component.libraries.removeWhere((lib) => lib != mainLibrary);
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 32e7ee9..e142924 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -75,7 +75,7 @@
[38] = Reserved
[39] = EndClosureFunctionScope
}
-Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
+Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' async (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
ClosureCode {
EntryFixed 2, 4
CheckStack 0
@@ -1708,7 +1708,7 @@
[38] = Reserved
[39] = EndClosureFunctionScope
}
-Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int >
+Closure #lib::closure::'nested' async () -> dart:async::Future < dart:core::int >
ClosureCode {
EntryFixed 1, 4
CheckStack 0
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index c6f5421..e1d3aae 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -87,11 +87,18 @@
export DART_CONFIGURATION=${DART_CONFIGURATION:-ReleaseX64}
BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
+DART_BINARY="$BIN_DIR"/dart
+PLAT_DIR=$(echo ${BIN_DIR} | sed -e 's/SIMARM_X64$/SIMARM/')
+
+PREBUILT_DART_BINARY="tools/sdks/dart-sdk/bin/dart"
+if [ -x "$PREBUILT_DART_BINARY" ]; then
+ DART_BINARY=$PREBUILT_DART_BINARY
+fi
# Step 1: Generate Kernel binary from the input Dart source.
-"$BIN_DIR"/dart \
+"$DART_BINARY" \
"${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" \
- --platform "${BIN_DIR}/vm_platform_strong.dill" \
+ --platform "${PLAT_DIR}/vm_platform_strong.dill" \
--aot \
"${GEN_KERNEL_OPTIONS[@]}" \
$PACKAGES \
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 20419e7..529da63 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -146,6 +146,10 @@
include_dirs += [ "../third_party/tcmalloc/gperftools/src" ]
}
+ if (dart_platform_bytecode) {
+ defines += [ "DART_USE_BYTECODE" ]
+ }
+
if (is_fuchsia) {
if (using_fuchsia_sdk) {
# TODO(chinmaygarde): Currenty these targets need to be build in the
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 36efb0d..2a0e13b 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -24,9 +24,9 @@
extern const uint8_t kPlatformStrongDill[];
extern intptr_t kPlatformStrongDillSize;
#else
-const uint8_t* kKernelServiceDill = NULL;
+const uint8_t* kKernelServiceDill = nullptr;
intptr_t kKernelServiceDillSize = 0;
-const uint8_t* kPlatformStrongDill = NULL;
+const uint8_t* kPlatformStrongDill = nullptr;
intptr_t kPlatformStrongDillSize = 0;
#endif // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
}
@@ -65,8 +65,8 @@
DFE::DFE()
: use_dfe_(false),
use_incremental_compiler_(false),
- frontend_filename_(NULL),
- application_kernel_buffer_(NULL),
+ frontend_filename_(nullptr),
+ application_kernel_buffer_(nullptr),
application_kernel_buffer_size_(0) {
// The run_vm_tests binary has the DART_PRECOMPILER set in order to allow unit
// tests to exercise JIT and AOT pipeline.
@@ -75,26 +75,30 @@
// need to fall back to the built-in one (if we have it).
#if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) || defined(DART_NO_SNAPSHOT) || \
(defined(DART_PRECOMPILER) && defined(TARGET_ARCH_X64))
- kernel_service_dill_ = NULL;
+ kernel_service_dill_ = nullptr;
kernel_service_dill_size_ = 0;
- platform_strong_dill_ = NULL;
- platform_strong_dill_size_ = 0;
+ platform_strong_dill_for_compilation_ = nullptr;
+ platform_strong_dill_for_compilation_size_ = 0;
+ platform_strong_dill_for_execution_ = nullptr;
+ platform_strong_dill_for_execution_size_ = 0;
#else
kernel_service_dill_ = kKernelServiceDill;
kernel_service_dill_size_ = kKernelServiceDillSize;
- platform_strong_dill_ = kPlatformStrongDill;
- platform_strong_dill_size_ = kPlatformStrongDillSize;
+ platform_strong_dill_for_compilation_ = kPlatformStrongDill;
+ platform_strong_dill_for_compilation_size_ = kPlatformStrongDillSize;
+ platform_strong_dill_for_execution_ = kPlatformStrongDill;
+ platform_strong_dill_for_execution_size_ = kPlatformStrongDillSize;
#endif
}
DFE::~DFE() {
- if (frontend_filename_ != NULL) {
+ if (frontend_filename_ != nullptr) {
free(frontend_filename_);
}
- frontend_filename_ = NULL;
+ frontend_filename_ = nullptr;
free(application_kernel_buffer_);
- application_kernel_buffer_ = NULL;
+ application_kernel_buffer_ = nullptr;
application_kernel_buffer_size_ = 0;
}
@@ -103,7 +107,7 @@
}
void DFE::Init(int target_abi_version) {
- if (platform_strong_dill_ == NULL) {
+ if (platform_strong_dill_for_compilation_ == nullptr) {
return;
}
@@ -111,8 +115,8 @@
return;
}
- Dart_SetDartLibrarySourcesKernel(platform_strong_dill_,
- platform_strong_dill_size_);
+ Dart_SetDartLibrarySourcesKernel(platform_strong_dill_for_compilation_,
+ platform_strong_dill_for_compilation_size_);
}
bool DFE::InitKernelServiceAndPlatformDills(int target_abi_version) {
@@ -120,7 +124,7 @@
const char kKernelServiceDillFile[] = "kernel_service.dill";
const char kPlatformStrongDillFile[] = "vm_platform_strong.dill";
- if (frontend_filename_ != NULL) {
+ if (frontend_filename_ != nullptr) {
return true;
}
@@ -129,18 +133,19 @@
GetDirectoryPrefixFromExeName(), free);
if (target_abi_version != Options::kAbiVersionUnset) {
- kernel_service_dill_ = NULL;
+ kernel_service_dill_ = nullptr;
kernel_service_dill_size_ = 0;
- platform_strong_dill_ = NULL;
- platform_strong_dill_size_ = 0;
+ platform_strong_dill_for_compilation_ = nullptr;
+ platform_strong_dill_for_compilation_size_ = 0;
// Look in the old abi version directory.
char* script_uri =
Utils::SCreate("%s%s/%d/%s", dir_prefix.get(), kAbiVersionsDir,
target_abi_version, kPlatformStrongDillFile);
- if (!TryReadKernelFile(script_uri,
- const_cast<uint8_t**>(&platform_strong_dill_),
- &platform_strong_dill_size_)) {
+ if (!TryReadKernelFile(
+ script_uri,
+ const_cast<uint8_t**>(&platform_strong_dill_for_compilation_),
+ &platform_strong_dill_for_compilation_size_)) {
Syslog::PrintErr("Can't find old ABI dill file: %s\n", script_uri);
free(script_uri);
return false;
@@ -163,27 +168,27 @@
// Look for the frontend snapshot next to the executable.
frontend_filename_ =
Utils::SCreate("%s%s", dir_prefix.get(), kKernelServiceSnapshot);
- if (File::Exists(NULL, frontend_filename_)) {
+ if (File::Exists(nullptr, frontend_filename_)) {
return true;
}
free(frontend_filename_);
- frontend_filename_ = NULL;
+ frontend_filename_ = nullptr;
// If the frontend snapshot is not found next to the executable, then look for
// it in the "snapshots" directory.
frontend_filename_ =
Utils::SCreate("%s%s%s%s", dir_prefix.get(), kSnapshotsDirectory,
File::PathSeparator(), kKernelServiceSnapshot);
- if (File::Exists(NULL, frontend_filename_)) {
+ if (File::Exists(nullptr, frontend_filename_)) {
return true;
}
free(frontend_filename_);
- frontend_filename_ = NULL;
+ frontend_filename_ = nullptr;
return true;
}
bool DFE::KernelServiceDillAvailable() const {
- return kernel_service_dill_ != NULL;
+ return kernel_service_dill_ != nullptr;
}
void DFE::LoadKernelService(const uint8_t** kernel_service_buffer,
@@ -194,13 +199,13 @@
void DFE::LoadPlatform(const uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size) {
- *kernel_buffer = platform_strong_dill_;
- *kernel_buffer_size = platform_strong_dill_size_;
+ *kernel_buffer = platform_strong_dill_for_execution_;
+ *kernel_buffer_size = platform_strong_dill_for_execution_size_;
}
bool DFE::CanUseDartFrontend() const {
- return (platform_strong_dill_ != NULL) &&
- (KernelServiceDillAvailable() || (frontend_filename() != NULL));
+ return (platform_strong_dill_for_compilation_ != nullptr) &&
+ (KernelServiceDillAvailable() || (frontend_filename() != nullptr));
}
class WindowsPathSanitizer {
@@ -217,7 +222,7 @@
// (see builtin.dart#_sanitizeWindowsPath)
intptr_t len = strlen(path);
sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
- if (sanitized_uri_ == NULL) {
+ if (sanitized_uri_ == nullptr) {
OUT_OF_MEMORY();
}
char* s = sanitized_uri_;
@@ -251,9 +256,9 @@
const char* sanitized_uri = script_uri;
#endif
- return Dart_CompileToKernel(sanitized_uri, platform_strong_dill_,
- platform_strong_dill_size_, incremental,
- package_config);
+ return Dart_CompileToKernel(
+ sanitized_uri, platform_strong_dill_for_compilation_,
+ platform_strong_dill_for_compilation_size_, incremental, package_config);
}
void DFE::CompileAndReadScript(const char* script_uri,
@@ -268,7 +273,7 @@
case Dart_KernelCompilationStatus_Ok:
*kernel_buffer = result.kernel;
*kernel_buffer_size = result.kernel_size;
- *error = NULL;
+ *error = nullptr;
*exit_code = 0;
break;
case Dart_KernelCompilationStatus_Error:
@@ -298,18 +303,18 @@
}
if (!Dart_IsKernel(*kernel_buffer, *kernel_buffer_size)) {
free(*kernel_buffer);
- *kernel_buffer = NULL;
+ *kernel_buffer = nullptr;
*kernel_buffer_size = -1;
}
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("DFE::ReadScript", start, end,
- Dart_Timeline_Event_Duration, 0, NULL, NULL);
+ Dart_Timeline_Event_Duration, 0, nullptr, nullptr);
}
// Attempts to treat [buffer] as a in-memory kernel byte representation.
// If successful, returns [true] and places [buffer] into [kernel_ir], byte size
// into [kernel_ir_size].
-// If unsuccessful, returns [false], puts [NULL] into [kernel_ir], -1 into
+// If unsuccessful, returns [false], puts [nullptr] into [kernel_ir], -1 into
// [kernel_ir_size].
static bool TryReadSimpleKernelBuffer(uint8_t* buffer,
uint8_t** p_kernel_ir,
@@ -325,7 +330,7 @@
return true;
}
free(buffer);
- *p_kernel_ir = NULL;
+ *p_kernel_ir = nullptr;
*p_kernel_ir_size = -1;
return false;
}
@@ -337,12 +342,12 @@
static bool TryReadFile(const char* script_uri, uint8_t** buffer,
intptr_t* size) {
void* script_file = DartUtils::OpenFileUri(script_uri, false);
- if (script_file == NULL) {
+ if (script_file == nullptr) {
return false;
}
DartUtils::ReadFile(buffer, size, script_file);
DartUtils::CloseFile(script_file);
- if (*size <= 0 || buffer == NULL) {
+ if (*size <= 0 || buffer == nullptr) {
return false;
}
return true;
@@ -359,7 +364,7 @@
static void Add(KernelIRNode** p_head, KernelIRNode** p_tail,
KernelIRNode* node) {
- if (*p_head == NULL) {
+ if (*p_head == nullptr) {
*p_head = node;
} else {
(*p_tail)->next_ = node;
@@ -370,17 +375,17 @@
static void Merge(KernelIRNode* head, uint8_t** p_bytes,
intptr_t* p_size) {
intptr_t size = 0;
- for (KernelIRNode* node = head; node != NULL; node = node->next_) {
+ for (KernelIRNode* node = head; node != nullptr; node = node->next_) {
size = size + node->kernel_size_;
}
*p_bytes = reinterpret_cast<uint8_t*>(malloc(size));
- if (*p_bytes == NULL) {
+ if (*p_bytes == nullptr) {
OUT_OF_MEMORY();
}
uint8_t* p = *p_bytes;
KernelIRNode* node = head;
- while (node != NULL) {
+ while (node != nullptr) {
memmove(p, node->kernel_ir_, node->kernel_size_);
p += node->kernel_size_;
KernelIRNode* next = node->next_;
@@ -391,7 +396,7 @@
static void Delete(KernelIRNode* head) {
KernelIRNode* node = head;
- while (node != NULL) {
+ while (node != nullptr) {
KernelIRNode* next = node->next_;
delete (node);
node = next;
@@ -402,7 +407,7 @@
uint8_t* kernel_ir_;
intptr_t kernel_size_;
- KernelIRNode* next_ = NULL;
+ KernelIRNode* next_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(KernelIRNode);
};
@@ -435,14 +440,14 @@
uint8_t** kernel_ir,
intptr_t* kernel_ir_size) {
const char* kernel_list_dirname = DartUtils::DirName(script_uri);
- KernelIRNode* kernel_ir_head = NULL;
- KernelIRNode* kernel_ir_tail = NULL;
+ KernelIRNode* kernel_ir_head = nullptr;
+ KernelIRNode* kernel_ir_tail = nullptr;
// Add all kernels to the linked list
char* filename =
reinterpret_cast<char*>(buffer + kernel_list_magic_number.length);
intptr_t filename_size = buffer_size - kernel_list_magic_number.length;
char* tail = reinterpret_cast<char*>(memchr(filename, '\n', filename_size));
- while (tail != NULL) {
+ while (tail != nullptr) {
*tail = '\0';
intptr_t this_kernel_size;
uint8_t* this_buffer;
@@ -461,7 +466,7 @@
&this_kernel_size)) {
// Abandon read if any of the files in the list are invalid.
KernelIRNode::Delete(kernel_ir_head);
- *kernel_ir = NULL;
+ *kernel_ir = nullptr;
*kernel_ir_size = -1;
return false;
}
@@ -481,7 +486,7 @@
bool DFE::TryReadKernelFile(const char* script_uri,
uint8_t** kernel_ir,
intptr_t* kernel_ir_size) {
- *kernel_ir = NULL;
+ *kernel_ir = nullptr;
*kernel_ir_size = -1;
uint8_t* buffer;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 932936f..fc33e64 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -26,7 +26,7 @@
char* frontend_filename() const { return frontend_filename_; }
void set_frontend_filename(const char* name) {
- if (frontend_filename_ != NULL) {
+ if (frontend_filename_ != nullptr) {
free(frontend_filename_);
}
frontend_filename_ = strdup(name);
@@ -107,8 +107,10 @@
char* frontend_filename_;
const uint8_t* kernel_service_dill_;
intptr_t kernel_service_dill_size_;
- const uint8_t* platform_strong_dill_;
- intptr_t platform_strong_dill_size_;
+ const uint8_t* platform_strong_dill_for_compilation_;
+ intptr_t platform_strong_dill_for_compilation_size_;
+ const uint8_t* platform_strong_dill_for_execution_;
+ intptr_t platform_strong_dill_for_execution_size_;
// Kernel binary specified on the cmd line.
uint8_t* application_kernel_buffer_;
diff --git a/runtime/bin/entrypoints_verification_test_extension.cc b/runtime/bin/entrypoints_verification_test_extension.cc
index 1f4eab6..c2c9adb 100644
--- a/runtime/bin/entrypoints_verification_test_extension.cc
+++ b/runtime/bin/entrypoints_verification_test_extension.cc
@@ -20,7 +20,8 @@
#define ASSERT(E) \
if (!(E)) { \
- fprintf(stderr, "Assertion \"" #E "\" failed!"); \
+ fprintf(stderr, "Assertion \"" #E "\" failed at %s:%d!\n", __FILE__, \
+ __LINE__); \
abort(); \
}
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 91c7856..3350088 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -632,13 +632,13 @@
return 0;
}
-DART_EXPORT int TestReturnNull(int32_t fn()) {
- CHECK_EQ(fn(), 0);
+DART_EXPORT int TestReturnNull(int32_t (*fn)()) {
+ CHECK_EQ(fn(), 42);
return 0;
}
DART_EXPORT int TestNullPointers(int64_t* (*fn)(int64_t* ptr)) {
- CHECK_EQ(fn(nullptr), nullptr);
+ CHECK_EQ(fn(nullptr), reinterpret_cast<void*>(sizeof(int64_t)));
int64_t p[2] = {0};
CHECK_EQ(fn(p), p + 1);
return 0;
@@ -662,6 +662,26 @@
return 0;
}
+DART_EXPORT int TestReturnVoid(int (*return_void)()) {
+ CHECK_EQ(return_void(), 0);
+ return 0;
+}
+
+DART_EXPORT int TestThrowExceptionDouble(double (*fn)()) {
+ CHECK_EQ(fn(), 42.0);
+ return 0;
+}
+
+DART_EXPORT int TestThrowExceptionPointer(void* (*fn)()) {
+ CHECK_EQ(fn(), reinterpret_cast<void*>(42));
+ return 0;
+}
+
+DART_EXPORT int TestThrowException(int (*fn)()) {
+ CHECK_EQ(fn(), 42);
+ return 0;
+}
+
struct CallbackTestData {
int success;
void (*callback)();
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index c9edf66..622b326 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -12,7 +12,6 @@
#include "include/dart_embedder_api.h"
#include "include/dart_tools_api.h"
-#include "bin/abi_version.h"
#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/crashpad.h"
@@ -597,8 +596,7 @@
Dart_Isolate isolate = NULL;
#if !defined(DART_PRECOMPILED_RUNTIME)
- if ((!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) ||
- (Options::target_abi_version() != Options::kAbiVersionUnset)) {
+ if (!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) {
const uint8_t* platform_kernel_buffer = NULL;
intptr_t platform_kernel_buffer_size = 0;
dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
diff --git a/runtime/bin/observatory_assets_empty.cc b/runtime/bin/observatory_assets_empty.cc
index e7e1738..5c79cdc 100644
--- a/runtime/bin/observatory_assets_empty.cc
+++ b/runtime/bin/observatory_assets_empty.cc
@@ -5,13 +5,7 @@
// This file is linked into the dart executable when it does not have
// Observatory baked in.
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
#include <stdint.h>
-#endif
-#include <stddef.h>
namespace dart {
namespace bin {
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 70022e8..019522b 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -322,7 +322,7 @@
dart::bin::DartUtils::OpenFile, dart::bin::DartUtils::ReadFile,
dart::bin::DartUtils::WriteFile, dart::bin::DartUtils::CloseFile,
nullptr /* entropy_source */, nullptr /* get_service_assets */,
- start_kernel_isolate);
+ start_kernel_isolate, nullptr /* observer */);
if (error != nullptr) {
Syslog::PrintErr("Failed to initialize VM: %s\n", error);
free(error);
diff --git a/runtime/bin/snapshot_empty.cc b/runtime/bin/snapshot_empty.cc
index 6629e07..b9c89be 100644
--- a/runtime/bin/snapshot_empty.cc
+++ b/runtime/bin/snapshot_empty.cc
@@ -5,17 +5,11 @@
// This file is linked into the dart executable when it does not have a
// snapshot linked into it.
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
#include <stdint.h>
-#endif
-#include <stddef.h>
extern "C" {
-const uint8_t* kDartVmSnapshotData = NULL;
-const uint8_t* kDartVmSnapshotInstructions = NULL;
-const uint8_t* kDartCoreIsolateSnapshotData = NULL;
-const uint8_t* kDartCoreIsolateSnapshotInstructions = NULL;
+const uint8_t* kDartVmSnapshotData = nullptr;
+const uint8_t* kDartVmSnapshotInstructions = nullptr;
+const uint8_t* kDartCoreIsolateSnapshotData = nullptr;
+const uint8_t* kDartCoreIsolateSnapshotInstructions = nullptr;
}
diff --git a/runtime/bin/snapshot_in.cc b/runtime/bin/snapshot_in.cc
index 544d830..bc3047c 100644
--- a/runtime/bin/snapshot_in.cc
+++ b/runtime/bin/snapshot_in.cc
@@ -7,13 +7,7 @@
// This file is linked into the dart executable when it has a snapshot
// linked into it.
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
#include <stdint.h>
-#endif
-#include <stddef.h>
extern "C" {
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 9bb1b94..f5c3a9c 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -1985,6 +1985,6 @@
@pragma("vm:entry-point", "call")
Datagram _makeDatagram(
- List<int> data, String address, Uint8List in_addr, int port) {
+ Uint8List data, String address, Uint8List in_addr, int port) {
return new Datagram(data, new _InternetAddress(address, null, in_addr), port);
}
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index ec77ddc..748ee68 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -298,8 +298,8 @@
String result;
try {
- result = await _service.devfs.handlePutStream(
- fsName, fsPath, fsUri, request.transform(GZIP.decoder));
+ result = await _service.devfs.handlePutStream(fsName, fsPath, fsUri,
+ request.cast<List<int>>().transform(GZIP.decoder));
} catch (e) {
request.response.statusCode = HttpStatus.internalServerError;
request.response.write(e);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 31a7d1b..66a90d8 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -15,6 +15,16 @@
* This reference is generated from the header include/dart_api.h.
*/
+/* __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
+ * enable platform independent printf format specifiers. */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
#ifdef __cplusplus
#define DART_EXTERN_C extern "C"
#else
@@ -24,32 +34,12 @@
#if defined(__CYGWIN__)
#error Tool chain and platform not supported.
#elif defined(_WIN32)
-// Define bool if necessary.
-#ifndef __cplusplus
-typedef unsigned __int8 bool;
-#endif
-// Define integer types.
-typedef signed __int8 int8_t;
-typedef signed __int16 int16_t;
-typedef signed __int32 int32_t;
-typedef signed __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
#if defined(DART_SHARED_LIB)
#define DART_EXPORT DART_EXTERN_C __declspec(dllexport)
#else
#define DART_EXPORT DART_EXTERN_C
#endif
#else
-/* __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
- * enable platform independent printf format specifiers. */
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
-#include <inttypes.h>
-#include <stdbool.h>
#if __GNUC__ >= 4
#if defined(DART_SHARED_LIB)
#define DART_EXPORT \
@@ -70,8 +60,6 @@
#define DART_WARN_UNUSED_RESULT
#endif
-#include <assert.h>
-
/*
* =======
* Handles
@@ -714,7 +702,31 @@
* The current version of the Dart_InitializeFlags. Should be incremented every
* time Dart_InitializeFlags changes in a binary incompatible way.
*/
-#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000003)
+#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000004)
+
+/** Forward declaration */
+struct Dart_CodeObserver;
+
+/**
+ * Callback provided by the embedder that is used by the VM to notify on code
+ * object creation, *before* it is invoked the first time.
+ * This is useful for embedders wanting to e.g. keep track of PCs beyond
+ * the lifetime of the garbage collected code objects.
+ * Note that an address range may be used by more than one code object over the
+ * lifecycle of a process. Clients of this function should record timestamps for
+ * these compilation events and when collecting PCs to disambiguate reused
+ * address ranges.
+ */
+typedef void (*Dart_OnNewCodeCallback)(struct Dart_CodeObserver* observer,
+ const char* name,
+ uintptr_t base,
+ uintptr_t size);
+
+typedef struct Dart_CodeObserver {
+ void* data;
+
+ Dart_OnNewCodeCallback on_new_code;
+} Dart_CodeObserver;
/**
* Describes how to initialize the VM. Used with Dart_Initialize.
@@ -736,6 +748,8 @@
* \param get_service_assets A function to be called by the service isolate when
* it requires the vmservice assets archive.
* See Dart_GetVMServiceAssetsArchive.
+ * \param code_observer An external code observer callback function.
+ * The observer can be invoked as early as during the Dart_Initialize() call.
*/
typedef struct {
int32_t version;
@@ -752,6 +766,7 @@
Dart_EntropySource entropy_source;
Dart_GetVMServiceAssetsArchive get_service_assets;
bool start_kernel_isolate;
+ Dart_CodeObserver* code_observer;
} Dart_InitializeParams;
/**
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index fb2f903..0705214 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -4,7 +4,7 @@
#include "vm/bootstrap_natives.h"
-#include "platform/math.h"
+#include <math.h>
#include "vm/dart_entry.h"
#include "vm/double_conversion.h"
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index f2ac373..9fc29cf 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -8,10 +8,12 @@
#include "platform/globals.h"
#include "vm/bootstrap_natives.h"
#include "vm/class_finalizer.h"
+#include "vm/class_id.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/ffi.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/exceptions.h"
+#include "vm/flags.h"
#include "vm/log.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
@@ -26,66 +28,14 @@
// Some checks are only performed at runtime to allow for generic code, these
// throw ArgumentExceptions.
-static void ThrowTypeArgumentError(const AbstractType& type_arg,
- const char* expected) {
- const String& error = String::Handle(String::NewFormatted(
- "Type argument (%s) should be a %s",
- String::Handle(type_arg.UserVisibleName()).ToCString(), expected));
- Exceptions::ThrowArgumentError(error);
-}
-
static bool IsPointerType(const AbstractType& type) {
- // Do a fast check for predefined types.
- classid_t type_cid = type.type_class_id();
- if (RawObject::IsFfiPointerClassId(type_cid)) {
- return true;
- }
-
- // Do a slow check for subtyping.
- const Class& pointer_class =
- Class::Handle(Isolate::Current()->object_store()->ffi_pointer_class());
- AbstractType& pointer_type =
- AbstractType::Handle(pointer_class.DeclarationType());
- pointer_type = pointer_type.InstantiateFrom(Object::null_type_arguments(),
- Object::null_type_arguments(),
- kNoneFree, NULL, Heap::kNew);
- ASSERT(pointer_type.IsInstantiated());
- ASSERT(type.IsInstantiated());
- return type.IsSubtypeOf(pointer_type, Heap::kNew);
-}
-
-static bool IsConcreteNativeType(const AbstractType& type) {
- // Do a fast check for predefined types.
- classid_t type_cid = type.type_class_id();
- if (RawObject::IsFfiNativeTypeTypeClassId(type_cid)) {
- return false;
- }
- if (RawObject::IsFfiTypeClassId(type_cid)) {
- return true;
- }
-
- // Do a slow check for subtyping.
- const Class& native_type_class = Class::Handle(
- Isolate::Current()->object_store()->ffi_native_type_class());
- AbstractType& native_type_type =
- AbstractType::Handle(native_type_class.DeclarationType());
- return type.IsSubtypeOf(native_type_type, Heap::kNew);
-}
-
-static void CheckIsConcreteNativeType(const AbstractType& type) {
- if (!IsConcreteNativeType(type)) {
- ThrowTypeArgumentError(type, "concrete sub type of NativeType");
- }
-}
-
-static bool IsNativeFunction(const AbstractType& type_arg) {
- classid_t type_cid = type_arg.type_class_id();
- return RawObject::IsFfiTypeNativeFunctionClassId(type_cid);
+ return RawObject::IsFfiPointerClassId(type.type_class_id());
}
static void CheckSized(const AbstractType& type_arg) {
- classid_t type_cid = type_arg.type_class_id();
- if (RawObject::IsFfiTypeVoidClassId(type_cid) ||
+ const classid_t type_cid = type_arg.type_class_id();
+ if (RawObject::IsFfiNativeTypeTypeClassId(type_cid) ||
+ RawObject::IsFfiTypeVoidClassId(type_cid) ||
RawObject::IsFfiTypeNativeFunctionClassId(type_cid)) {
const String& error = String::Handle(String::NewFormatted(
"%s does not have a predefined size (@unsized). "
@@ -98,6 +48,8 @@
}
}
+enum class FfiVariance { kCovariant = 0, kContravariant = 1 };
+
// Checks that a dart type correspond to a [NativeType].
// Because this is checked already in a kernel transformation, it does not throw
// an ArgumentException but a boolean which should be asserted.
@@ -114,11 +66,12 @@
// [Double] -> [double]
// [Float] -> [double]
// [Pointer]<T> -> [Pointer]<T>
-// T extends [Pointer] -> T
+// T extends [Struct] -> T
// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
// where DartRepresentationOf(Tn) -> Sn
static bool DartAndCTypeCorrespond(const AbstractType& native_type,
- const AbstractType& dart_type) {
+ const AbstractType& dart_type,
+ FfiVariance variance) {
classid_t native_type_cid = native_type.type_class_id();
if (RawObject::IsFfiTypeIntClassId(native_type_cid)) {
return dart_type.IsSubtypeOf(AbstractType::Handle(Type::IntType()),
@@ -129,7 +82,11 @@
Heap::kNew);
}
if (RawObject::IsFfiPointerClassId(native_type_cid)) {
- return native_type.Equals(dart_type) || dart_type.IsNullType();
+ return (variance == FfiVariance::kCovariant &&
+ dart_type.IsSubtypeOf(native_type, Heap::kNew)) ||
+ (variance == FfiVariance::kContravariant &&
+ native_type.IsSubtypeOf(dart_type, Heap::kNew)) ||
+ dart_type.IsNullType();
}
if (RawObject::IsFfiTypeNativeFunctionClassId(native_type_cid)) {
if (!dart_type.IsFunctionType()) {
@@ -142,7 +99,8 @@
if (!nativefunction_type_arg.IsFunctionType()) {
return false;
}
- Function& dart_function = Function::Handle(((Type&)dart_type).signature());
+ Function& dart_function =
+ Function::Handle((Type::Cast(dart_type)).signature());
if (dart_function.NumTypeParameters() != 0 ||
dart_function.HasOptionalPositionalParameters() ||
dart_function.HasOptionalNamedParameters()) {
@@ -161,13 +119,14 @@
}
if (!DartAndCTypeCorrespond(
AbstractType::Handle(nativefunction_function.result_type()),
- AbstractType::Handle(dart_function.result_type()))) {
+ AbstractType::Handle(dart_function.result_type()), variance)) {
return false;
}
for (intptr_t i = 0; i < dart_function.NumParameters(); i++) {
if (!DartAndCTypeCorrespond(
AbstractType::Handle(nativefunction_function.ParameterTypeAt(i)),
- AbstractType::Handle(dart_function.ParameterTypeAt(i)))) {
+ AbstractType::Handle(dart_function.ParameterTypeAt(i)),
+ variance)) {
return false;
}
}
@@ -175,20 +134,21 @@
return true;
}
-// The following functions are runtime checks on arguments.
-
-// Note that expected_from and expected_to are inclusive.
-static void CheckRange(const Integer& argument_value,
- intptr_t expected_from,
- intptr_t expected_to,
- const char* argument_name) {
- int64_t value = argument_value.AsInt64Value();
- if (value < expected_from || expected_to < value) {
- Exceptions::ThrowRangeError(argument_name, argument_value, expected_from,
- expected_to);
+static void CheckDartAndCTypeCorrespond(const AbstractType& native_type,
+ const AbstractType& dart_type,
+ FfiVariance variance) {
+ if (!DartAndCTypeCorrespond(native_type, dart_type, variance)) {
+ const String& error = String::Handle(String::NewFormatted(
+ "Expected type '%s' to be different, it should be "
+ "DartRepresentationOf('%s').",
+ String::Handle(dart_type.UserVisibleName()).ToCString(),
+ String::Handle(native_type.UserVisibleName()).ToCString()));
+ Exceptions::ThrowArgumentError(error);
}
}
+// The following functions are runtime checks on arguments.
+
static const Pointer& AsPointer(const Instance& instance) {
if (!instance.IsPointer()) {
const String& error = String::Handle(String::NewFormatted(
@@ -216,50 +176,50 @@
return Double::Cast(instance);
}
+// Calcuate the size of a native type.
+//
+// You must check [IsConcreteNativeType] and [CheckSized] first to verify that
+// this type has a defined size.
+static size_t SizeOf(const AbstractType& type) {
+ if (RawObject::IsFfiTypeClassId(type.type_class_id())) {
+ return compiler::ffi::ElementSizeInBytes(type.type_class_id());
+ } else {
+ Class& struct_class = Class::Handle(type.type_class());
+ Object& result = Object::Handle(
+ struct_class.InvokeGetter(Symbols::SizeOfStructField(),
+ /*throw_nsm_if_absent=*/false,
+ /*respect_reflectable=*/false));
+ ASSERT(!result.IsNull() && result.IsInteger());
+ return Integer::Cast(result).AsInt64Value();
+ }
+}
+
// The remainder of this file implements the dart:ffi native methods.
DEFINE_NATIVE_ENTRY(Ffi_allocate, 1, 1) {
- // TODO(dacoharkes): When we have a way of determining the size of structs in
- // the VM, change the signature so we can allocate structs, subtype of
- // Pointer. https://github.com/dart-lang/sdk/issues/35782
GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- CheckIsConcreteNativeType(type_arg);
CheckSized(type_arg);
+ size_t element_size = SizeOf(type_arg);
GET_NON_NULL_NATIVE_ARGUMENT(Integer, argCount, arguments->NativeArgAt(0));
int64_t count = argCount.AsInt64Value();
- classid_t type_cid = type_arg.type_class_id();
- int64_t max_count = INTPTR_MAX / compiler::ffi::ElementSizeInBytes(type_cid);
- CheckRange(argCount, 1, max_count, "count");
-
- size_t size = compiler::ffi::ElementSizeInBytes(type_cid) * count;
- uint64_t memory = reinterpret_cast<uint64_t>(malloc(size));
+ size_t size = element_size * count; // Truncates overflow.
+ size_t memory = reinterpret_cast<size_t>(malloc(size));
if (memory == 0) {
const String& error = String::Handle(String::NewFormatted(
"allocating (%" Pd ") bytes of memory failed", size));
Exceptions::ThrowArgumentError(error);
}
- RawPointer* result = Pointer::New(
- type_arg, Integer::Handle(zone, Integer::NewFromUint64(memory)));
+ RawPointer* result = Pointer::New(type_arg, memory);
return result;
}
DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
- AbstractType& native_type = AbstractType::Handle(
- type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
- CheckIsConcreteNativeType(native_type);
GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg_ptr, arguments->NativeArgAt(0));
-
- // TODO(dacoharkes): should this return NULL if address is 0?
- // https://github.com/dart-lang/sdk/issues/35756
-
- RawPointer* result =
- Pointer::New(native_type, arg_ptr, type_arg.type_class_id());
- return result;
+ return Pointer::New(type_arg, arg_ptr.AsInt64Value());
}
DEFINE_NATIVE_ENTRY(Ffi_elementAt, 0, 2) {
@@ -268,14 +228,9 @@
AbstractType& pointer_type_arg =
AbstractType::Handle(zone, pointer.type_argument());
CheckSized(pointer_type_arg);
-
- classid_t class_id = pointer_type_arg.type_class_id();
- Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
- address = Integer::New(address.AsInt64Value() +
- index.AsInt64Value() *
- compiler::ffi::ElementSizeInBytes(class_id));
- RawPointer* result = Pointer::New(pointer_type_arg, address);
- return result;
+ return Pointer::New(pointer_type_arg,
+ pointer.NativeAddress() +
+ index.AsInt64Value() * SizeOf(pointer_type_arg));
}
DEFINE_NATIVE_ENTRY(Ffi_offsetBy, 0, 2) {
@@ -284,64 +239,35 @@
AbstractType& pointer_type_arg =
AbstractType::Handle(pointer.type_argument());
- intptr_t address =
- Integer::Handle(zone, pointer.GetCMemoryAddress()).AsInt64Value() +
- offset.AsInt64Value();
- RawPointer* result = Pointer::New(
- pointer_type_arg, Integer::Handle(zone, Integer::New(address)));
- return result;
+ return Pointer::New(pointer_type_arg,
+ pointer.NativeAddress() + offset.AsInt64Value());
}
DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
- AbstractType& native_type = AbstractType::Handle(
- type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
- CheckIsConcreteNativeType(native_type);
-
- const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
- RawPointer* result =
- Pointer::New(native_type, address, type_arg.type_class_id());
- return result;
+ return Pointer::New(type_arg, pointer.NativeAddress());
}
DEFINE_NATIVE_ENTRY(Ffi_free, 0, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
- const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
- free(reinterpret_cast<void*>(address.AsInt64Value()));
- pointer.SetCMemoryAddress(Integer::Handle(zone, Integer::New(0)));
+ free(reinterpret_cast<void*>(pointer.NativeAddress()));
+ pointer.SetNativeAddress(0);
+
return Object::null();
}
DEFINE_NATIVE_ENTRY(Ffi_address, 0, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
- return pointer.GetCMemoryAddress();
+ return Integer::New(pointer.NativeAddress());
}
-static RawInstance* BoxLoadPointer(Zone* zone,
- uint8_t* address,
- const AbstractType& instance_type_arg,
- intptr_t type_cid) {
- // TODO(dacoharkes): should this return NULL if addres is 0?
- // https://github.com/dart-lang/sdk/issues/35756
- if (address == nullptr) {
- return Instance::null();
- }
- AbstractType& type_arg =
- AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
- .TypeAt(Pointer::kNativeTypeArgPos));
- return Pointer::New(
- type_arg,
- Integer::Handle(zone, Integer::New(reinterpret_cast<intptr_t>(address))),
- type_cid);
-}
-
-static RawInstance* LoadValue(Zone* zone,
- uint8_t* address,
- const AbstractType& instance_type_arg) {
+static RawObject* LoadValue(Zone* zone,
+ const Pointer& target,
+ const AbstractType& instance_type_arg) {
classid_t type_cid = instance_type_arg.type_class_id();
+ size_t address = target.NativeAddress();
switch (type_cid) {
case kFfiInt8Cid:
return Integer::New(*reinterpret_cast<int8_t*>(address));
@@ -365,11 +291,39 @@
return Double::New(*reinterpret_cast<float_t*>(address));
case kFfiDoubleCid:
return Double::New(*reinterpret_cast<double_t*>(address));
- case kFfiPointerCid:
- default:
- ASSERT(IsPointerType(instance_type_arg));
- return BoxLoadPointer(zone, *reinterpret_cast<uint8_t**>(address),
- instance_type_arg, type_cid);
+ default: {
+ if (IsPointerType(instance_type_arg)) {
+ const AbstractType& type_arg = AbstractType::Handle(
+ TypeArguments::Handle(instance_type_arg.arguments())
+ .TypeAt(Pointer::kNativeTypeArgPos));
+ return Pointer::New(type_arg, reinterpret_cast<size_t>(
+ *reinterpret_cast<void**>(address)));
+ } else {
+ // Result is a struct class -- find <class name>.#fromPointer
+ // constructor and call it.
+ Class& cls = Class::Handle(zone, instance_type_arg.type_class());
+ const Function& constructor =
+ Function::Handle(cls.LookupFunctionAllowPrivate(String::Handle(
+ String::Concat(String::Handle(String::Concat(
+ String::Handle(cls.Name()), Symbols::Dot())),
+ Symbols::StructFromPointer()))));
+ ASSERT(!constructor.IsNull());
+ ASSERT(constructor.IsGenerativeConstructor());
+ ASSERT(!Object::Handle(constructor.VerifyCallEntryPoint()).IsError());
+ Instance& new_object = Instance::Handle(Instance::New(cls));
+ new_object.SetTypeArguments(
+ TypeArguments::Handle(instance_type_arg.arguments()));
+ ASSERT(cls.is_allocated() ||
+ Dart::vm_snapshot_kind() != Snapshot::kFullAOT);
+ const Array& args = Array::Handle(zone, Array::New(2));
+ args.SetAt(0, new_object);
+ args.SetAt(1, target);
+ Object& constructorResult =
+ Object::Handle(DartEntry::InvokeFunction(constructor, args));
+ ASSERT(!constructorResult.IsError());
+ return new_object.raw();
+ }
+ }
}
}
@@ -379,19 +333,17 @@
AbstractType& pointer_type_arg =
AbstractType::Handle(pointer.type_argument());
CheckSized(pointer_type_arg);
- ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
+ CheckDartAndCTypeCorrespond(pointer_type_arg, type_arg,
+ FfiVariance::kContravariant);
- uint8_t* address = reinterpret_cast<uint8_t*>(
- Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
- return LoadValue(zone, address, pointer_type_arg);
+ return LoadValue(zone, pointer, pointer_type_arg);
}
static void StoreValue(Zone* zone,
const Pointer& pointer,
classid_t type_cid,
const Instance& new_value) {
- uint8_t* address = reinterpret_cast<uint8_t*>(
- Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
+ uint8_t* const address = reinterpret_cast<uint8_t*>(pointer.NativeAddress());
AbstractType& pointer_type_arg =
AbstractType::Handle(pointer.type_argument());
switch (type_cid) {
@@ -436,20 +388,16 @@
case kFfiDoubleCid:
*reinterpret_cast<double*>(address) = AsDouble(new_value).value();
break;
- case kFfiPointerCid:
- default: {
+ case kFfiPointerCid: {
ASSERT(IsPointerType(pointer_type_arg));
- intptr_t new_value_unwrapped = 0;
- if (!new_value.IsNull()) {
- ASSERT(new_value.IsPointer());
- new_value_unwrapped =
- Integer::Handle(AsPointer(new_value).GetCMemoryAddress())
- .AsInt64Value();
- // TODO(dacoharkes): should this return NULL if addres is 0?
- // https://github.com/dart-lang/sdk/issues/35756
- }
- *reinterpret_cast<intptr_t*>(address) = new_value_unwrapped;
- } break;
+ ASSERT(new_value.IsPointer());
+ const void* const stored =
+ reinterpret_cast<void*>(AsPointer(new_value).NativeAddress());
+ *reinterpret_cast<const void**>(address) = stored;
+ break;
+ }
+ default:
+ UNREACHABLE();
}
}
@@ -460,7 +408,14 @@
AbstractType& pointer_type_arg =
AbstractType::Handle(pointer.type_argument());
CheckSized(pointer_type_arg);
- ASSERT(DartAndCTypeCorrespond(pointer_type_arg, arg_type));
+ CheckDartAndCTypeCorrespond(pointer_type_arg, arg_type,
+ FfiVariance::kCovariant);
+
+ if (new_value.IsNull()) {
+ const String& error = String::Handle(
+ String::NewFormatted("Argument to Pointer.store is null."));
+ Exceptions::ThrowArgumentError(error);
+ }
classid_t type_cid = pointer_type_arg.type_class_id();
StoreValue(zone, pointer, type_cid, new_value);
@@ -469,96 +424,17 @@
DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) {
GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- CheckIsConcreteNativeType(type_arg);
CheckSized(type_arg);
- classid_t type_cid = type_arg.type_class_id();
- return Smi::New(compiler::ffi::ElementSizeInBytes(type_cid));
+ return Integer::New(SizeOf(type_arg));
}
-// TODO(dacoharkes): Cache the trampolines.
-// We can possibly address simultaniously with 'precaching' in AOT.
-static RawFunction* TrampolineFunction(const Function& dart_signature,
- const Function& c_signature) {
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- String& name =
- String::ZoneHandle(Symbols::New(Thread::Current(), "FfiTrampoline"));
- const Library& lib = Library::Handle(Library::FfiLibrary());
- const Class& owner_class = Class::Handle(lib.toplevel_class());
- Function& function =
- Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
- /*is_static=*/true,
- /*is_const=*/false,
- /*is_abstract=*/false,
- /*is_external=*/false,
- /*is_native=*/false, owner_class,
- TokenPosition::kMinSource));
- function.set_is_debuggable(false);
- function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
- function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
- function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
-
- // The signature function won't have any names for the parameters. We need to
- // assign unique names for scope building and error messages.
- const intptr_t num_params = dart_signature.num_fixed_parameters();
- const Array& parameter_names = Array::Handle(Array::New(num_params));
- for (intptr_t i = 0; i < num_params; ++i) {
- if (i == 0) {
- name = Symbols::ClosureParameter().raw();
- } else {
- name = Symbols::NewFormatted(thread, ":ffiParam%" Pd, i);
- }
- parameter_names.SetAt(i, name);
- }
- function.set_parameter_names(parameter_names);
- function.SetFfiCSignature(c_signature);
-
- return function.raw();
-}
-
-DEFINE_NATIVE_ENTRY(Ffi_asFunction, 1, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
- AbstractType& pointer_type_arg =
- AbstractType::Handle(pointer.type_argument());
- ASSERT(IsNativeFunction(pointer_type_arg));
- GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
- ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
-
- Function& dart_signature = Function::Handle(Type::Cast(type_arg).signature());
- TypeArguments& nativefunction_type_args =
- TypeArguments::Handle(pointer_type_arg.arguments());
- AbstractType& nativefunction_type_arg =
- AbstractType::Handle(nativefunction_type_args.TypeAt(0));
- Function& c_signature =
- Function::Handle(Type::Cast(nativefunction_type_arg).signature());
- Function& function =
- Function::Handle(TrampolineFunction(dart_signature, c_signature));
-
- // Set the c function pointer in the context of the closure rather than in
- // the function so that we can reuse the function for each c function with
- // the same signature.
- Context& context = Context::Handle(Context::New(1));
- context.SetAt(0, Integer::Handle(zone, pointer.GetCMemoryAddress()));
-
- RawClosure* raw_closure =
- Closure::New(Object::null_type_arguments(), Object::null_type_arguments(),
- function, context, Heap::kOld);
-
- return raw_closure;
-}
-
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) && \
+ !defined(TARGET_ARCH_DBC)
// Generates assembly to trampoline from native code into Dart.
static uword CompileNativeCallback(const Function& c_signature,
- const Function& dart_target) {
-#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
- UNREACHABLE();
-#elif defined(TARGET_ARCH_DBC)
- // https://github.com/dart-lang/sdk/issues/35774
- // FFI is supported, but callbacks are not.
- Exceptions::ThrowUnsupportedError(
- "FFI callbacks are not yet supported on DBC.");
-#else
+ const Function& dart_target,
+ const Instance& exceptional_return) {
Thread* const thread = Thread::Current();
const int32_t callback_id = thread->AllocateFfiCallbackId();
@@ -566,10 +442,9 @@
// library. Note that these functions will never be invoked by Dart, so it
// doesn't matter that they all have the same name.
Zone* const Z = thread->zone();
- const String& name =
- String::ZoneHandle(Symbols::New(Thread::Current(), "FfiCallback"));
- const Library& lib = Library::Handle(Library::FfiLibrary());
- const Class& owner_class = Class::Handle(lib.toplevel_class());
+ const String& name = String::Handle(Symbols::New(thread, "FfiCallback"));
+ const Library& lib = Library::Handle(Z, Library::FfiLibrary());
+ const Class& owner_class = Class::Handle(Z, lib.toplevel_class());
const Function& function =
Function::Handle(Z, Function::New(name, RawFunction::kFfiTrampoline,
/*is_static=*/true,
@@ -586,6 +461,33 @@
function.SetFfiCallbackId(callback_id);
function.SetFfiCallbackTarget(dart_target);
+ // We require that the exceptional return value for functions returning 'Void'
+ // must be 'null', since native code should not look at the result.
+ if (compiler::ffi::NativeTypeIsVoid(
+ AbstractType::Handle(c_signature.result_type())) &&
+ !exceptional_return.IsNull()) {
+ Exceptions::ThrowUnsupportedError(
+ "Only 'null' may be used as the exceptional return value for a "
+ "callback returning void.");
+ }
+
+ // We need to load the exceptional return value as a constant in the generated
+ // function. This means we need to ensure that it's in old space and has no
+ // (transitively) mutable fields. This is done by checking (asserting) that
+ // it's a built-in FFI class, whose fields are all immutable, or a
+ // user-defined Pointer class, which has no fields.
+ //
+ // TODO(36730): We'll need to extend this when we support passing/returning
+ // structs by value.
+ ASSERT(exceptional_return.IsNull() || exceptional_return.IsNumber() ||
+ exceptional_return.IsPointer());
+ if (!exceptional_return.IsSmi() && exceptional_return.IsNew()) {
+ function.SetFfiCallbackExceptionalReturn(
+ Instance::Handle(exceptional_return.CopyShallowToOldSpace(thread)));
+ } else {
+ function.SetFfiCallbackExceptionalReturn(exceptional_return);
+ }
+
// We compile the callback immediately because we need to return a pointer to
// the entry-point. Native calls do not use patching like Dart calls, so we
// cannot compile it lazily.
@@ -600,23 +502,72 @@
thread->SetFfiCallbackCode(callback_id, code);
return code.EntryPoint();
+}
+#endif
+
+// Static invocations to this method are translated directly in streaming FGB
+// and bytecode FGB. However, we can still reach this entrypoint in the bytecode
+// interpreter.
+DEFINE_NATIVE_ENTRY(Ffi_asFunctionInternal, 2, 1) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+ UNREACHABLE();
+#else
+ ASSERT(FLAG_enable_interpreter);
+
+ GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+ GET_NATIVE_TYPE_ARGUMENT(dart_type, arguments->NativeTypeArgAt(0));
+ GET_NATIVE_TYPE_ARGUMENT(native_type, arguments->NativeTypeArgAt(1));
+
+ const Function& dart_signature =
+ Function::Handle(zone, Type::Cast(dart_type).signature());
+ const Function& native_signature =
+ Function::Handle(zone, Type::Cast(native_type).signature());
+ const Function& function = Function::Handle(
+ compiler::ffi::TrampolineFunction(dart_signature, native_signature));
+
+ // Set the c function pointer in the context of the closure rather than in
+ // the function so that we can reuse the function for each c function with
+ // the same signature.
+ const Context& context = Context::Handle(Context::New(1));
+ context.SetAt(0,
+ Integer::Handle(zone, Integer::New(pointer.NativeAddress())));
+
+ return Closure::New(Object::null_type_arguments(),
+ Object::null_type_arguments(), function, context,
+ Heap::kOld);
#endif
}
-DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
+DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 2) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER) || \
+ defined(TARGET_ARCH_DBC)
+ // https://github.com/dart-lang/sdk/issues/37295
+ // FFI is supported, but callbacks are not.
+ Exceptions::ThrowUnsupportedError(
+ "FFI callbacks are not yet supported in AOT or on DBC.");
+#else
GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, exceptional_return,
+ arguments->NativeArgAt(1));
+
+ if (!type_arg.IsInstantiated() || !type_arg.IsFunctionType()) {
+ // TODO(35902): Remove this when dynamic invocations of fromFunction are
+ // prohibited.
+ Exceptions::ThrowUnsupportedError(
+ "Type argument to fromFunction must an instantiated function type.");
+ }
const Function& native_signature =
- Function::Handle(((Type&)type_arg).signature());
+ Function::Handle(Type::Cast(type_arg).signature());
Function& func = Function::Handle(closure.function());
TypeArguments& type_args = TypeArguments::Handle(zone);
type_args = TypeArguments::New(1);
type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
type_args = type_args.Canonicalize();
- Class& native_function_class = Class::Handle(
- Isolate::Current()->class_table()->At(kFfiNativeFunctionCid));
+ Class& native_function_class =
+ Class::Handle(isolate->class_table()->At(kFfiNativeFunctionCid));
native_function_class.EnsureIsFinalized(Thread::Current());
Type& native_function_type = Type::Handle(
@@ -635,12 +586,26 @@
func = func.parent_function();
ASSERT(func.is_static());
- const uword address = CompileNativeCallback(native_signature, func);
+ const AbstractType& return_type =
+ AbstractType::Handle(native_signature.result_type());
+ if (compiler::ffi::NativeTypeIsVoid(return_type)) {
+ if (!exceptional_return.IsNull()) {
+ const String& error = String::Handle(
+ String::NewFormatted("Exceptional return argument to 'fromFunction' "
+ "must be null for functions returning void."));
+ Exceptions::ThrowArgumentError(error);
+ }
+ } else if (!compiler::ffi::NativeTypeIsPointer(return_type) &&
+ exceptional_return.IsNull()) {
+ const String& error = String::Handle(String::NewFormatted(
+ "Exceptional return argument to 'fromFunction' must not be null."));
+ Exceptions::ThrowArgumentError(error);
+ }
- const Pointer& result = Pointer::Handle(Pointer::New(
- native_function_type, Integer::Handle(zone, Integer::New(address))));
-
- return result.raw();
+ return Pointer::New(
+ native_function_type,
+ CompileNativeCallback(native_signature, func, exceptional_return));
+#endif
}
#if defined(TARGET_ARCH_DBC)
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
index 102e1b3..7260b2b 100644
--- a/runtime/lib/ffi_dynamic_library.cc
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -109,14 +109,9 @@
void* handle = dlib.GetHandle();
- const intptr_t pointer = reinterpret_cast<intptr_t>(
- ResolveSymbol(handle, argSymbolName.ToCString()));
-
- // TODO(dacoharkes): should this return Object::null() if address is 0?
- // https://github.com/dart-lang/sdk/issues/35756
- RawPointer* result =
- Pointer::New(type_arg, Integer::Handle(zone, Integer::New(pointer)));
- return result;
+ const uword pointer =
+ reinterpret_cast<uword>(ResolveSymbol(handle, argSymbolName.ToCString()));
+ return Pointer::New(type_arg, pointer);
}
DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
diff --git a/runtime/lib/ffi_dynamic_library_patch.dart b/runtime/lib/ffi_dynamic_library_patch.dart
index 29e8c88..92bffec 100644
--- a/runtime/lib/ffi_dynamic_library_patch.dart
+++ b/runtime/lib/ffi_dynamic_library_patch.dart
@@ -18,6 +18,15 @@
Pointer<T> lookup<T extends NativeType>(String symbolName)
native "Ffi_dl_lookup";
+ // The real implementation of this function lives in FfiUseSitesTransformer
+ // 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";
@@ -32,4 +41,7 @@
int get hashCode {
return getHandle().hashCode;
}
+
+ @patch
+ Pointer<Void> get handle => Pointer.fromAddress(getHandle());
}
diff --git a/runtime/lib/ffi_patch.dart b/runtime/lib/ffi_patch.dart
index 6915d51..4f586cd 100644
--- a/runtime/lib/ffi_patch.dart
+++ b/runtime/lib/ffi_patch.dart
@@ -5,22 +5,35 @@
import "dart:_internal" show patch;
@patch
-Pointer<T> allocate<T extends NativeType>({int count: 1}) native "Ffi_allocate";
-
-@patch
-T fromAddress<T extends Pointer>(int ptr) native "Ffi_fromAddress";
-
-@patch
int sizeOf<T extends NativeType>() native "Ffi_sizeOf";
-@patch
-Pointer<NativeFunction<T>> fromFunction<T extends Function>(
- @DartRepresentationOf("T") Function f) native "Ffi_fromFunction";
+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";
@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
@@ -45,29 +58,13 @@
// fromAddress(address). This would be 2 native calls rather than one.
// What would be better?
@patch
- U cast<U extends Pointer>() native "Ffi_cast";
+ Pointer<U> cast<U extends NativeType>() native "Ffi_cast";
@patch
- R asFunction<R extends Function>() native "Ffi_asFunction";
+ R asFunction<R extends Function>() {
+ throw UnsupportedError("Pointer.asFunction cannot be called dynamically.");
+ }
@patch
void free() native "Ffi_free";
}
-
-// This method gets called when an exception bubbles up to the native -> Dart
-// boundary from an FFI native callback. Since native code does not have any
-// concept of exceptions, the exception cannot be propagated any further.
-// Instead, print a warning with the exception and return 0/0.0 from the
-// callback.
-//
-// TODO(36856): Iron out the story behind exceptions.
-@pragma("vm:entry-point")
-void _handleExposedException(dynamic exception, dynamic stackTrace) {
- print(
- "==================== UNHANDLED EXCEPTION FROM FFI CALLBACK ====================");
- print(
- """ ** Native callbacks should not throw exceptions because they cannot be
- propagated into native code. **""");
- print("EXCEPTION: $exception");
- print(stackTrace);
-}
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 7c28e91..f43d181 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -197,6 +197,10 @@
@pragma("vm:entry-point")
class _SendPortImpl implements SendPort {
+ factory _SendPortImpl._uninstantiable() {
+ throw "Unreachable";
+ }
+
/*--- public interface ---*/
@pragma("vm:entry-point", "call")
void send(var message) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index beb978b..82bd670 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -132,7 +132,7 @@
// hence do not have a token position, and therefore cannot be reparsed.
has_extra_parameter_info = false;
}
- if (func.HasBytecode() && (func.kernel_offset() == 0)) {
+ if (func.is_declared_in_bytecode()) {
// Anonymous closures in bytecode cannot be reparsed.
has_extra_parameter_info = false;
}
@@ -1048,18 +1048,19 @@
GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
- const Library& library = Library::Handle(ref.GetLibraryReferent());
+ const Library& library = Library::Handle(zone, ref.GetLibraryReferent());
library.EnsureTopLevelClassIsFinalized();
- Instance& member_mirror = Instance::Handle();
+ Instance& member_mirror = Instance::Handle(zone);
const GrowableObjectArray& member_mirrors =
- GrowableObjectArray::Handle(GrowableObjectArray::New());
+ GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
- Object& entry = Object::Handle();
+ Object& entry = Object::Handle(zone);
DictionaryIterator entries(library);
- AbstractType& type = AbstractType::Handle();
+ Error& error = Error::Handle(zone);
+ AbstractType& type = AbstractType::Handle(zone);
while (entries.HasNext()) {
entry = entries.GetNext();
@@ -1068,6 +1069,10 @@
// We filter out dynamic.
// TODO(12478): Should not need to filter out dynamic.
if (!klass.IsDynamicClass()) {
+ error = klass.EnsureIsFinalized(thread);
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
type = klass.DeclarationType();
member_mirror = CreateClassMirror(klass, type,
Bool::True(), // is_declaration
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index f79cf3e..7649a04 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -111,14 +111,11 @@
int startFromInBytes, int toCid, int fromCid) native "TypedData_setRange";
}
-abstract class _IntListMixin<SpawnedType extends List<int>>
- implements List<int> {
+mixin _IntListMixin implements List<int> {
int get elementSizeInBytes;
int get offsetInBytes;
_ByteBuffer get buffer;
- SpawnedType _createList(int length);
-
Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
Iterable<int> followedBy(Iterable<int> other) =>
@@ -179,71 +176,6 @@
}
}
- 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 new ArgumentError(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);
- }
-
Iterable<int> where(bool f(int element)) => new WhereIterable<int>(this, f);
Iterable<int> take(int n) => new SubListIterable<int>(this, 0, n);
@@ -442,14 +374,6 @@
throw IterableElementError.tooMany();
}
- 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;
- }
-
void setAll(int index, Iterable<int> iterable) {
final end = iterable.length + index;
setRange(index, end, iterable);
@@ -463,14 +387,89 @@
}
}
-abstract class _DoubleListMixin<SpawnedType extends List<double>>
- implements List<double> {
+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;
- SpawnedType _createList(int length);
-
Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
Iterable<double> followedBy(Iterable<double> other) =>
@@ -531,72 +530,6 @@
}
}
- 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 new ArgumentError(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);
- }
-
Iterable<double> where(bool f(double element)) =>
new WhereIterable<double>(this, f);
@@ -797,14 +730,6 @@
throw IterableElementError.tooMany();
}
- 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;
- }
-
void setAll(int index, Iterable<double> iterable) {
final end = iterable.length + index;
setRange(index, end, iterable);
@@ -818,6 +743,85 @@
}
}
+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;
@@ -893,7 +897,7 @@
assert(false);
}
if (skipCount < 0) {
- throw new ArgumentError(skipCount);
+ throw RangeError.range(skipCount, 0, null, "skipCount");
}
final count = end - start;
@@ -1251,7 +1255,7 @@
assert(false);
}
if (skipCount < 0) {
- throw new ArgumentError(skipCount);
+ throw RangeError.range(skipCount, 0, null, "skipCount");
}
final count = end - start;
@@ -1608,7 +1612,7 @@
assert(false);
}
if (skipCount < 0) {
- throw new ArgumentError(skipCount);
+ throw RangeError.range(skipCount, 0, null, "skipCount");
}
final count = end - start;
@@ -2141,7 +2145,7 @@
@pragma("vm:entry-point")
class _Int8List extends _TypedList
- with _IntListMixin<Int8List>
+ with _IntListMixin, _TypedIntListMixin<Int8List>
implements Int8List {
factory _Int8List._uninstantiable() {
throw "Unreachable";
@@ -2189,7 +2193,7 @@
@pragma("vm:entry-point")
class _Uint8List extends _TypedList
- with _IntListMixin<Uint8List>
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
implements Uint8List {
factory _Uint8List._uninstantiable() {
throw "Unreachable";
@@ -2237,7 +2241,7 @@
@pragma("vm:entry-point")
class _Uint8ClampedList extends _TypedList
- with _IntListMixin<Uint8ClampedList>
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
implements Uint8ClampedList {
factory _Uint8ClampedList._uninstantiable() {
throw "Unreachable";
@@ -2285,7 +2289,7 @@
@pragma("vm:entry-point")
class _Int16List extends _TypedList
- with _IntListMixin<Int16List>
+ with _IntListMixin, _TypedIntListMixin<Int16List>
implements Int16List {
factory _Int16List._uninstantiable() {
throw "Unreachable";
@@ -2352,7 +2356,7 @@
@pragma("vm:entry-point")
class _Uint16List extends _TypedList
- with _IntListMixin<Uint16List>
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
implements Uint16List {
factory _Uint16List._uninstantiable() {
throw "Unreachable";
@@ -2419,7 +2423,7 @@
@pragma("vm:entry-point")
class _Int32List extends _TypedList
- with _IntListMixin<Int32List>
+ with _IntListMixin, _TypedIntListMixin<Int32List>
implements Int32List {
factory _Int32List._uninstantiable() {
throw "Unreachable";
@@ -2474,7 +2478,7 @@
@pragma("vm:entry-point")
class _Uint32List extends _TypedList
- with _IntListMixin<Uint32List>
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
implements Uint32List {
factory _Uint32List._uninstantiable() {
throw "Unreachable";
@@ -2529,7 +2533,7 @@
@pragma("vm:entry-point")
class _Int64List extends _TypedList
- with _IntListMixin<Int64List>
+ with _IntListMixin, _TypedIntListMixin<Int64List>
implements Int64List {
factory _Int64List._uninstantiable() {
throw "Unreachable";
@@ -2584,7 +2588,7 @@
@pragma("vm:entry-point")
class _Uint64List extends _TypedList
- with _IntListMixin<Uint64List>
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
implements Uint64List {
factory _Uint64List._uninstantiable() {
throw "Unreachable";
@@ -2639,7 +2643,7 @@
@pragma("vm:entry-point")
class _Float32List extends _TypedList
- with _DoubleListMixin<Float32List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
implements Float32List {
factory _Float32List._uninstantiable() {
throw "Unreachable";
@@ -2695,7 +2699,7 @@
@pragma("vm:entry-point")
class _Float64List extends _TypedList
- with _DoubleListMixin<Float64List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
implements Float64List {
factory _Float64List._uninstantiable() {
throw "Unreachable";
@@ -2903,7 +2907,7 @@
@pragma("vm:entry-point")
class _ExternalInt8Array extends _TypedList
- with _IntListMixin<Int8List>
+ with _IntListMixin, _TypedIntListMixin<Int8List>
implements Int8List {
factory _ExternalInt8Array._uninstantiable() {
throw "Unreachable";
@@ -2937,7 +2941,7 @@
@pragma("vm:entry-point")
class _ExternalUint8Array extends _TypedList
- with _IntListMixin<Uint8List>
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
implements Uint8List {
factory _ExternalUint8Array._uninstantiable() {
throw "Unreachable";
@@ -2972,7 +2976,7 @@
@pragma("vm:entry-point")
class _ExternalUint8ClampedArray extends _TypedList
- with _IntListMixin<Uint8ClampedList>
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
implements Uint8ClampedList {
factory _ExternalUint8ClampedArray._uninstantiable() {
throw "Unreachable";
@@ -3007,7 +3011,7 @@
@pragma("vm:entry-point")
class _ExternalInt16Array extends _TypedList
- with _IntListMixin<Int16List>
+ with _IntListMixin, _TypedIntListMixin<Int16List>
implements Int16List {
factory _ExternalInt16Array._uninstantiable() {
throw "Unreachable";
@@ -3049,7 +3053,7 @@
@pragma("vm:entry-point")
class _ExternalUint16Array extends _TypedList
- with _IntListMixin<Uint16List>
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
implements Uint16List {
factory _ExternalUint16Array._uninstantiable() {
throw "Unreachable";
@@ -3091,7 +3095,7 @@
@pragma("vm:entry-point")
class _ExternalInt32Array extends _TypedList
- with _IntListMixin<Int32List>
+ with _IntListMixin, _TypedIntListMixin<Int32List>
implements Int32List {
factory _ExternalInt32Array._uninstantiable() {
throw "Unreachable";
@@ -3133,7 +3137,7 @@
@pragma("vm:entry-point")
class _ExternalUint32Array extends _TypedList
- with _IntListMixin<Uint32List>
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
implements Uint32List {
factory _ExternalUint32Array._uninstantiable() {
throw "Unreachable";
@@ -3175,7 +3179,7 @@
@pragma("vm:entry-point")
class _ExternalInt64Array extends _TypedList
- with _IntListMixin<Int64List>
+ with _IntListMixin, _TypedIntListMixin<Int64List>
implements Int64List {
factory _ExternalInt64Array._uninstantiable() {
throw "Unreachable";
@@ -3217,7 +3221,7 @@
@pragma("vm:entry-point")
class _ExternalUint64Array extends _TypedList
- with _IntListMixin<Uint64List>
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
implements Uint64List {
factory _ExternalUint64Array._uninstantiable() {
throw "Unreachable";
@@ -3259,7 +3263,7 @@
@pragma("vm:entry-point")
class _ExternalFloat32Array extends _TypedList
- with _DoubleListMixin<Float32List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
implements Float32List {
factory _ExternalFloat32Array._uninstantiable() {
throw "Unreachable";
@@ -3301,7 +3305,7 @@
@pragma("vm:entry-point")
class _ExternalFloat64Array extends _TypedList
- with _DoubleListMixin<Float64List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
implements Float64List {
factory _ExternalFloat64Array._uninstantiable() {
throw "Unreachable";
@@ -3716,7 +3720,7 @@
@pragma("vm:entry-point")
class _Int8ArrayView extends _TypedListView
- with _IntListMixin<Int8List>
+ with _IntListMixin, _TypedIntListMixin<Int8List>
implements Int8List {
// Constructor.
@pragma("vm:exact-result-type", _Int8ArrayView)
@@ -3753,7 +3757,7 @@
@pragma("vm:entry-point")
class _Uint8ArrayView extends _TypedListView
- with _IntListMixin<Uint8List>
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
implements Uint8List {
// Constructor.
@pragma("vm:exact-result-type", _Uint8ArrayView)
@@ -3790,7 +3794,7 @@
@pragma("vm:entry-point")
class _Uint8ClampedArrayView extends _TypedListView
- with _IntListMixin<Uint8ClampedList>
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
implements Uint8ClampedList {
// Constructor.
@pragma("vm:exact-result-type", _Uint8ClampedArrayView)
@@ -3827,7 +3831,7 @@
@pragma("vm:entry-point")
class _Int16ArrayView extends _TypedListView
- with _IntListMixin<Int16List>
+ with _IntListMixin, _TypedIntListMixin<Int16List>
implements Int16List {
// Constructor.
@pragma("vm:exact-result-type", _Int16ArrayView)
@@ -3876,7 +3880,7 @@
@pragma("vm:entry-point")
class _Uint16ArrayView extends _TypedListView
- with _IntListMixin<Uint16List>
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
implements Uint16List {
// Constructor.
@pragma("vm:exact-result-type", _Uint16ArrayView)
@@ -3926,7 +3930,7 @@
@pragma("vm:entry-point")
class _Int32ArrayView extends _TypedListView
- with _IntListMixin<Int32List>
+ with _IntListMixin, _TypedIntListMixin<Int32List>
implements Int32List {
// Constructor.
@pragma("vm:exact-result-type", _Int32ArrayView)
@@ -3963,7 +3967,7 @@
@pragma("vm:entry-point")
class _Uint32ArrayView extends _TypedListView
- with _IntListMixin<Uint32List>
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
implements Uint32List {
// Constructor.
@pragma("vm:exact-result-type", _Uint32ArrayView)
@@ -4000,7 +4004,7 @@
@pragma("vm:entry-point")
class _Int64ArrayView extends _TypedListView
- with _IntListMixin<Int64List>
+ with _IntListMixin, _TypedIntListMixin<Int64List>
implements Int64List {
// Constructor.
@pragma("vm:exact-result-type", _Int64ArrayView)
@@ -4037,7 +4041,7 @@
@pragma("vm:entry-point")
class _Uint64ArrayView extends _TypedListView
- with _IntListMixin<Uint64List>
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
implements Uint64List {
// Constructor.
@pragma("vm:exact-result-type", _Uint64ArrayView)
@@ -4074,7 +4078,7 @@
@pragma("vm:entry-point")
class _Float32ArrayView extends _TypedListView
- with _DoubleListMixin<Float32List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
implements Float32List {
// Constructor.
@pragma("vm:exact-result-type", _Float32ArrayView)
@@ -4111,7 +4115,7 @@
@pragma("vm:entry-point")
class _Float64ArrayView extends _TypedListView
- with _DoubleListMixin<Float64List>
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
implements Float64List {
// Constructor.
@pragma("vm:exact-result-type", _Float64ArrayView)
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index c6f816e..d19c726 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -8,6 +8,7 @@
import 'dart:async';
import 'package:observatory/models.dart'
show IsolateRef, SourceLocation, Script, ScriptRepository;
+import 'package:observatory/service.dart' as S;
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/helpers/uris.dart';
@@ -48,6 +49,19 @@
_repository.get(_isolate, _location.script.id).then((script) {
_script = script;
_r.dirty();
+ }, onError: (e) {
+ // The script object has expired, likely due to a hot reload.
+ (_isolate as S.Isolate).getScripts().then((scripts) {
+ for (final script in scripts) {
+ if (script.uri == _location.script.uri) {
+ _script = script;
+ _r.dirty();
+ return;
+ }
+ }
+ // Rethrow the original exception if we can't find a match.
+ throw e;
+ });
});
_r.enable();
}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 124cbc2..7f735d3 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1453,6 +1453,12 @@
return isolate.invokeRpc('getObject', params);
}
+ Future<List<Script>> getScripts() async {
+ final response = await invokeRpc('getScripts', {}) as ServiceMap;
+ assert(response.type == 'ScriptList');
+ return response['scripts'].cast<Script>();
+ }
+
Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) async {
return invokeRpcNoUpgrade('getIsolate', {});
}
diff --git a/runtime/observatory/tests/service/break_on_async_function_test.dart b/runtime/observatory/tests/service/break_on_async_function_test.dart
new file mode 100644
index 0000000..b5bf200
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_async_function_test.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.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 13;
+
+Future<String> testFunction() async {
+ await new Future.delayed(new Duration(milliseconds: 1));
+ return "Done";
+}
+
+testMain() async {
+ debugger();
+ var str = await testFunction();
+ print(str);
+}
+
+var tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+
+// Add breakpoint at the entry of async function
+ (Isolate isolate) async {
+ Library rootLib = await isolate.rootLibrary.load();
+ var function =
+ rootLib.functions.singleWhere((f) => f.name == 'testFunction');
+
+ var bpt = await isolate.addBreakpointAtEntry(function);
+ expect(bpt is Breakpoint, isTrue);
+ print(bpt);
+ },
+
+ resumeIsolate,
+
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
index 3233420..faa2fa6 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
@@ -12,7 +12,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(utf8.decoder).listen((String data) {
+ response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
index 891a8f7..8126f45 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
@@ -12,7 +12,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(utf8.decoder).listen((String data) {
+ response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
diff --git a/runtime/observatory/tests/service/dev_fs_uri_test.dart b/runtime/observatory/tests/service/dev_fs_uri_test.dart
index 8446316..2fda4d7 100644
--- a/runtime/observatory/tests/service/dev_fs_uri_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_uri_test.dart
@@ -12,7 +12,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(utf8.decoder).listen((String data) {
+ response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index a5f9a4f..de073bf 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(20));
+ expect(result['minor'], equals(21));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart
new file mode 100644
index 0000000..e8fa8e6
--- /dev/null
+++ b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.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.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = <VMTest>[
+ (VM vm) async {
+ var result = await vm.invokeRpcNoUpgrade('getVMTimelineMicros', {});
+ expect(result['type'], equals('Timestamp'));
+ expect(result['timestamp'], isPositive);
+ },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
index 30a0112..06c47dc 100644
--- a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
@@ -22,6 +22,7 @@
final requestUri = serverUri.replace(pathSegments: pathSegments);
var request = await httpClient.getUrl(requestUri);
Map response = await (await request.close())
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(json.decoder)
.first;
@@ -55,6 +56,7 @@
try {
var request = await httpClient.getUrl(requestUri);
Map response = await (await request.close())
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(json.decoder)
.first;
diff --git a/runtime/observatory/tests/service/http_get_vm_rpc_common.dart b/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
index b193dc9..7298b3d 100644
--- a/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
@@ -31,6 +31,7 @@
try {
var request = await httpClient.getUrl(requestUri);
Map response = await (await request.close())
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(json.decoder)
.first;
diff --git a/runtime/observatory/tests/service/next_through_simple_async_test.dart b/runtime/observatory/tests/service/next_through_simple_async_test.dart
index 9ed99ed..fd1bcdb 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_test.dart
@@ -30,8 +30,10 @@
"$file:${LINE_A+1}:16", // on File
"$file:${LINE_A+2}:31", // on 'lastModified'
"$file:${LINE_A+2}:23", // on 'await'
+ "$file:${LINE_A+2}:21", // on '='
"$file:${LINE_A+3}:25", // on 'exists'
"$file:${LINE_A+3}:17", // on 'await'
+ "$file:${LINE_A+3}:15", // on '='
"$file:${LINE_A+4}:47", // on ')', i.e. before ';'
"$file:${LINE_A+4}:3", // on call to 'print'
"$file:${LINE_A+5}:3", // on call to 'foo'
diff --git a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
index c112a29..ea773c4 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
@@ -31,6 +31,7 @@
"$file:${LINE_A+1}:16", // on 'File'
"$file:${LINE_A+2}:25", // on 'exists'
"$file:${LINE_A+2}:17", // on 'await'
+ "$file:${LINE_A+2}:15", // on '='
"$file:${LINE_A+4}:5" // on 'return'
];
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 2340759..d733673 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -15,28 +15,6 @@
[ $arch == arm ]
process_service_test: Pass, Fail # Issue 24344
-[ $compiler == app_jit ]
-bad_reload_test: RuntimeError # Issue 27806
-complex_reload_test: RuntimeError # Issue 27806
-debugger_location_second_test: Skip # Issue 28180
-evaluate_activation_test/instance: RuntimeError # Issue 27806
-evaluate_activation_test/scope: RuntimeError # Issue 27806
-get_object_rpc_test: RuntimeError # Issue 27806
-get_source_report_test: RuntimeError # Issue 27806
-next_through_closure_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_create_list_and_map_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_for_each_loop_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_implicit_call_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-pause_on_unhandled_async_exceptions2_test: Pass, RuntimeError, Timeout, Crash # Issue 29178
-process_service_test: RuntimeError # Spawned process runs in Dart2 mode
-set_name_rpc_test: RuntimeError # Issue 27806
-simple_reload_test: RuntimeError # Issue 27806
-step_through_constructor_calls_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_function_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_switch_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_switch_with_continue_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-unused_changes_in_last_reload_test: RuntimeError # Issue 27806
-
# Tests with known analyzer issues
[ $compiler == dart2analyzer ]
developer_extension_test: SkipByDesign
@@ -47,9 +25,6 @@
add_breakpoint_rpc_kernel_test: SkipByDesign # kernel specific version of add_breakpoint_rpc_test
evaluate_function_type_parameters_test: SkipByDesign # only supported in kernel
-[ $compiler == precompiler ]
-*: Skip # Issue 24651
-
# Service protocol is not supported in product mode.
[ $mode == product ]
*: SkipByDesign
@@ -62,6 +37,10 @@
[ $compiler == none && $runtime == vm && $system == fuchsia ]
*: Skip # Not yet triaged.
+[ $compiler == none && ($runtime == dart_precompiled || $runtime == vm) ]
+evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
+evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
+
[ $mode == debug && $system == windows && $checked ]
async_scope_test: Pass, Slow
@@ -74,10 +53,6 @@
[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
*: Skip
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
-evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
-
[ $arch != ia32 || $arch != x64 || $system != linux ]
get_native_allocation_samples_test: Skip # Unsupported.
diff --git a/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart b/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
index 8eed4c1..8495d65 100644
--- a/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
+++ b/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
@@ -34,6 +34,7 @@
"$file:${LINE + 9}:3", // on yield
"$file:${LINE + 1}:38", // on '{' in 'for' line
+ "$file:${LINE + 1}:12", // on 'datapoint'
"$file:${LINE + 2}:5", // on 'print'
"$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
@@ -42,6 +43,7 @@
"$file:${LINE + 10}:3", // on yield
"$file:${LINE + 1}:38", // on '{' in 'for' line
+ "$file:${LINE + 1}:12", // on 'datapoint'
"$file:${LINE + 2}:5", // on 'print'
"$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
diff --git a/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart b/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
index b390dcf..f36a1e2 100644
--- a/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
+++ b/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
@@ -35,6 +35,7 @@
"$file:${LINE + 9}:3", // on yield
"$file:${LINE + 1}:38", // on '{' in 'for' line
+ "$file:${LINE + 1}:12", // on 'datapoint'
"$file:${LINE + 2}:5", // on 'print'
"$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
@@ -43,6 +44,7 @@
"$file:${LINE + 11}:3", // on yield
"$file:${LINE + 1}:38", // on '{' in 'for' line
+ "$file:${LINE + 1}:12", // on 'datapoint'
"$file:${LINE + 2}:5", // on 'print'
"$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
index 16d8592..8ed70cb 100644
--- a/runtime/observatory/web/timeline.js
+++ b/runtime/observatory/web/timeline.js
@@ -648,7 +648,7 @@
':' +
parser.port +
parser.pathname.replace(/\/ws$/, "") +
- '/_getVMTimeline';
+ '/getVMTimeline';
fetchUri(requestUri, function(event) {
// Grab the response.
var xhr = event.target;
diff --git a/runtime/platform/c99_support_win.h b/runtime/platform/c99_support_win.h
deleted file mode 100644
index 5fd6016..0000000
--- a/runtime/platform/c99_support_win.h
+++ /dev/null
@@ -1,79 +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.
-
-#ifndef RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
-#define RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
-
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-
-// Before Visual Studio 2013 Visual C++ was missing a bunch of C99 math macros
-// and functions. Define them here.
-
-#include <float.h>
-#include <string.h>
-
-#include <cmath>
-
-static const unsigned __int64 kQuietNaNMask =
- static_cast<unsigned __int64>(0xfff) << 51;
-
-#ifndef va_copy
-#define va_copy(dst, src) (memmove(&(dst), &(src), sizeof(dst)))
-#endif /* va_copy */
-
-#define NAN *reinterpret_cast<const double*>(&kQuietNaNMask)
-
-namespace std {
-
-static inline int isinf(double x) {
- return (_fpclass(x) & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0;
-}
-
-static inline int isnan(double x) {
- return _isnan(x);
-}
-
-static inline int signbit(double x) {
- if (x == 0) {
- return _fpclass(x) & _FPCLASS_NZ;
- } else {
- return x < 0;
- }
-}
-
-} // namespace std
-
-static inline double trunc(double x) {
- if (x < 0) {
- return ceil(x);
- } else {
- return floor(x);
- }
-}
-
-static inline double round(double x) {
- if (!_finite(x)) {
- return x;
- }
-
- double intpart;
- double fractpart = modf(x, &intpart);
-
- if (fractpart >= 0.5) {
- return intpart + 1;
- } else if (fractpart > -0.5) {
- return intpart;
- } else {
- return intpart - 1;
- }
-}
-
-// Windows does not have strtoll defined.
-#if defined(_MSC_VER)
-#define strtoll _strtoi64
-#endif
-
-#endif
-
-#endif // RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index a3632e8..0803ea3 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -62,28 +62,25 @@
#if !defined(_WIN32)
#include <arpa/inet.h>
-#include <inttypes.h>
-#include <stdint.h>
#include <unistd.h>
#endif // !defined(_WIN32)
#include <float.h>
+#include <inttypes.h>
#include <limits.h>
+#include <math.h>
#include <stdarg.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if defined(_WIN32)
-#include "platform/c99_support_win.h"
#include "platform/floating_point_win.h"
-#include "platform/inttypes_support_win.h"
#endif // defined(_WIN32)
-#include "platform/math.h"
-
#if !defined(_WIN32)
#include "platform/floating_point.h"
#endif // !defined(_WIN32)
@@ -337,12 +334,16 @@
#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
#if !defined(ARCH_IS_64_BIT)
#error Mismatched Host/Target architectures.
-#endif
+#endif // !defined(ARCH_IS_64_BIT)
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
-#if !defined(ARCH_IS_32_BIT)
+#if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
+// This is simarm_x64, which is the only case where host/target architecture
+// mismatch is allowed.
+#define IS_SIMARM_X64 1
+#elif !defined(ARCH_IS_32_BIT)
#error Mismatched Host/Target architectures.
-#endif
-#endif
+#endif // !defined(ARCH_IS_32_BIT)
+#endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
// Determine whether we will be using the simulator.
#if defined(TARGET_ARCH_IA32)
@@ -351,8 +352,11 @@
// No simulator used.
#elif defined(TARGET_ARCH_ARM)
#if !defined(HOST_ARCH_ARM)
+#define TARGET_HOST_MISMATCH 1
+#if !defined(IS_SIMARM_X64)
#define USING_SIMULATOR 1
#endif
+#endif
#elif defined(TARGET_ARCH_ARM64)
#if !defined(HOST_ARCH_ARM64)
@@ -366,6 +370,12 @@
#error Unknown architecture.
#endif
+#if defined(ARCH_IS_32_BIT) || defined(IS_SIMARM_X64)
+#define TARGET_ARCH_IS_32_BIT 1
+#elif defined(ARCH_IS_64_BIT)
+#define TARGET_ARCH_IS_64_BIT 1
+#endif
+
// Determine whether HOST_ARCH equals TARGET_ARCH.
#if defined(HOST_ARCH_ARM) && defined(TARGET_ARCH_ARM)
#define HOST_ARCH_EQUALS_TARGET_ARCH 1
diff --git a/runtime/platform/inttypes_support_win.h b/runtime/platform/inttypes_support_win.h
deleted file mode 100644
index 19a64db6..0000000
--- a/runtime/platform/inttypes_support_win.h
+++ /dev/null
@@ -1,35 +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.
-
-#ifndef RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
-#define RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
-
-typedef signed __int8 int8_t;
-typedef signed __int16 int16_t;
-typedef signed __int32 int32_t;
-typedef signed __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-
-// Printf format specifiers for intptr_t and uintptr_t.
-#define PRIdPTR "Id"
-#define PRIuPTR "Iu"
-#define PRIxPTR "Ix"
-#define PRIXPTR "IX"
-
-// Printf format specifiers for int64_t and uint64_t.
-#define PRId64 "I64d"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-#define PRIX64 "I64X"
-
-// Printf format specifiers for int32_t and uint32_t.
-#define PRId32 "I32d"
-#define PRIu32 "I32u"
-#define PRIx32 "I32x"
-#define PRIX32 "I32X"
-
-#endif // RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
diff --git a/runtime/platform/math.h b/runtime/platform/math.h
deleted file mode 100644
index 1926625..0000000
--- a/runtime/platform/math.h
+++ /dev/null
@@ -1,23 +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.
-
-#ifndef RUNTIME_PLATFORM_MATH_H_
-#define RUNTIME_PLATFORM_MATH_H_
-
-// We must take these math functions from the C++ header file as long as we
-// are using the STL. Otherwise the Android build will break due to confusion
-// between C++ and C headers when math.h is also included.
-#if !defined(HOST_OS_FUCHSIA)
-#include <cmath>
-
-#define isinf(val) std::isinf(val)
-#define isnan(val) std::isnan(val)
-#define signbit(val) std::signbit(val)
-#define isfinite(val) std::isfinite(val)
-#else
-// TODO(zra): When Fuchsia has STL, do the same thing as above.
-#include <math.h>
-#endif
-
-#endif // RUNTIME_PLATFORM_MATH_H_
diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni
index 9d53c4b..8a1b83e 100644
--- a/runtime/platform/platform_sources.gni
+++ b/runtime/platform/platform_sources.gni
@@ -15,7 +15,6 @@
"atomic_linux.h",
"atomic_macos.h",
"atomic_win.h",
- "c99_support_win.h",
"floating_point.h",
"floating_point_win.cc",
"floating_point_win.h",
@@ -23,7 +22,6 @@
"growable_array.h",
"hashmap.cc",
"hashmap.h",
- "inttypes_support_win.h",
"memory_sanitizer.h",
"safe_stack.h",
"signal_blocker.h",
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 2193a05..7093b19 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -98,6 +98,7 @@
uint32_t Utils::WordHash(intptr_t key) {
// TODO(iposva): Need to check hash spreading.
// This example is from http://www.concentric.net/~Ttwang/tech/inthash.htm
+ // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
uword a = static_cast<uword>(key);
a = (a + 0x7ed55d16) + (a << 12);
a = (a ^ 0xc761c23c) ^ (a >> 19);
diff --git a/runtime/tests/vm/dart/issue_31959_31960_test.dart b/runtime/tests/vm/dart/issue_31959_31960_test.dart
index 3990fb6..fddff48 100644
--- a/runtime/tests/vm/dart/issue_31959_31960_test.dart
+++ b/runtime/tests/vm/dart/issue_31959_31960_test.dart
@@ -10,7 +10,7 @@
import 'package:async_helper/async_helper.dart' show asyncStart, asyncEnd;
import 'package:expect/expect.dart';
-Uint8List generateSampleList(final size) {
+Uint8List generateSampleList(final int size) {
final list = Uint8List(size);
for (int i = 0; i < size; i++) {
list[i] = i % 243;
@@ -18,7 +18,7 @@
return list;
}
-void validateReceivedList(final expectedSize, final list) {
+void validateReceivedList(final int expectedSize, final list) {
Expect.equals(expectedSize, list.length);
// probe few elements
for (int i = 0; i < list.length; i += max<num>(1, expectedSize ~/ 1000)) {
@@ -56,7 +56,7 @@
main() async {
asyncStart();
- int bignum = 100 * 1000 * 1000;
+ int bignum = 10 * 1000 * 1000;
await testSend(false, bignum, 1); // none
await testSend(true, bignum, 1); // 31959tr
await testSend(false, bignum, 1); // 31960
diff --git a/runtime/tests/vm/dart/regress_flutter35121_test.dart b/runtime/tests/vm/dart/regress_flutter35121_test.dart
new file mode 100644
index 0000000..a4d21b6
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_flutter35121_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+// This is a regression test for
+// https://github.com/flutter/flutter/issues/35121
+
+class A {
+ static List<int> values = const [1, 2, 3];
+ static int get length => values.length;
+}
+
+main() {
+ print(A.length);
+}
diff --git a/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart b/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart
new file mode 100644
index 0000000..58bac74
--- /dev/null
+++ b/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart
@@ -0,0 +1,21 @@
+// 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 Issue https://github.com/dart-lang/sdk/issues/37264.
+typedef SomeCb = T Function<T>(T val);
+
+class A<T> {
+ final SomeCb cb;
+
+ A(this.cb);
+
+ factory A.b(SomeCb cb) {
+ return A(cb);
+ }
+}
+
+main() {
+ // VM should not crash on this case
+ A<int>.b(<String>(v) => v);
+}
diff --git a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
index fa99a62..e3393a3 100644
--- a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
+++ b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
@@ -113,6 +113,7 @@
await for (String line in File(rawObjectFieldsPath)
.openRead()
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(LineSplitter())) {
Match match = matchComplete(fieldEntry, line);
@@ -133,6 +134,7 @@
bool hasMissingFields = false;
await for (String line in File(rawObjectPath)
.openRead()
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(LineSplitter())) {
Match match = matchComplete(classStart, line);
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 0c6a32b..44a6971 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -24,6 +24,7 @@
dart/transferable_throws_oom_test: SkipByDesign # This test tries to allocate too much memory on purpose. Still dartbug.com/37188
[ $builder_tag == optimization_counter_threshold ]
+cc/*: Skip # Many tests want see unoptimized code running
dart/appjit*: SkipByDesign # Test needs to a particular opt-counter value
dart/kernel_determinism_test: SkipSlow
@@ -35,7 +36,7 @@
dart/entrypoints/aot/*: SkipByDesign
[ $compiler == dartkb ]
-cc/*: Skip # Bytecode modes are not properly hooked up in run_vm_tests.
+cc/*: Skip # Too many timeouts and crashes for infrastructure to handle.
[ $compiler == dartkp ]
dart/v8_snapshot_profile_writer_test: Pass, Slow # Can be slow due to re-invoking the precompiler.
@@ -43,9 +44,6 @@
[ $compiler == fasta ]
dart/data_uri_import_test/badencodeddate: CompileTimeError
-[ $compiler == precompiler ]
-dart/byte_array_test: SkipByDesign # Incompatible flag --disable_alloc_stubs_after_gc
-
[ $mode == debug ]
cc/CorelibIsolateStartup: SkipByDesign # This is a benchmark that is not informative in debug mode.
cc/IRTest_TypedDataAOT_FunctionalGetSet: Skip # run_vm_tests contains JIT/AOT but FLAG_precompiled_mode is not always correct. This causes this test to fail in debug mode, hitting an assertion. See http://dartbug.com/36521
@@ -54,9 +52,11 @@
dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
dart/spawn_shutdown_test: Pass, Slow # VM Shutdown test, It can take some time for all the isolates to shutdown in a Debug build.
-[ $runtime == dart_precompiled ]
-dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
-dart/issue32950_test: SkipByDesign # uses spawnUri.
+[ $mode == product ]
+cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
+cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
+cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
+dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
[ $system == fuchsia ]
cc/CorelibIsolateStartup: Skip # OOM crash can bring down the OS.
@@ -106,7 +106,6 @@
dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
[ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
-dart/issue32950_test: SkipByDesign # uses spawnUri.
dart/redirection_type_shuffling_test: SkipByDesign # Includes dart:mirrors.
dart/spawn_shutdown_test: SkipSlow
@@ -140,7 +139,6 @@
dart/redirection_type_shuffling_test/00: MissingCompileTimeError
[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-cc/Class_ComputeEndTokenPos: Crash
cc/DartAPI_LoadLibrary: Fail, Crash # Issue 33048.
cc/DebuggerAPI_BreakpointStubPatching: Fail
cc/DebuggerAPI_GetClosureInfo: Fail
@@ -174,7 +172,6 @@
[ ($arch == simarm || $arch == simarm64 || $arch == simdbc || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
dart/appjit*: SkipSlow # DFE too slow
-dart/issue_31959_31960_test: SkipSlow
# Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
@@ -257,15 +254,17 @@
[ $compiler != dartkp || $hot_reload || $hot_reload_rollback || $arch != arm && $arch != simarm && $arch != x64 ]
dart/entrypoints/aot/*: SkipByDesign # Only supported in the Dart 2 JIT and AOT, and test optimizations - hence disabled on hotreload bots.
-[ $compiler == precompiler || $mode == product ]
-cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
-cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
-cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
-dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
-
[ $mode == debug || $runtime != dart_precompiled || $system == android ]
dart/use_bare_instructions_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
+dart/issue32950_test: SkipByDesign # uses spawnUri.
+
[ $runtime != dart_precompiled || $system == android ]
dart/bare_instructions_trampolines_test: SkipByDesign # This test is for VM AOT only (android fails due to listing interfaces).
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index fafbcfe..aa27ca4 100755
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -85,13 +85,7 @@
''' % date.today().year)
out.write('''
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
#include <stdint.h>
-#endif
-#include <stddef.h>
''')
out.write('namespace %s {\n' % outer_namespace)
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 1b38ff7..0cf802f 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -4,6 +4,8 @@
#include "vm/bootstrap.h"
+#include <memory>
+
#include "include/dart_api.h"
#include "vm/class_finalizer.h"
@@ -50,11 +52,18 @@
Class& cls = Class::Handle(zone, object_store->closure_class());
ClassFinalizer::LoadClassMembers(cls);
+ // Make sure _Closure fields are not marked as unboxing candidates
+ // as they are accessed with plain loads.
+ const Array& fields = Array::Handle(zone, cls.fields());
+ Field& field = Field::Handle(zone);
+ for (intptr_t i = 0; i < fields.Length(); ++i) {
+ field ^= fields.At(i);
+ field.set_is_unboxing_candidate(false);
+ }
+
#if defined(DEBUG)
// Verify that closure field offsets are identical in Dart and C++.
- const Array& fields = Array::Handle(zone, cls.fields());
ASSERT(fields.Length() == 6);
- Field& field = Field::Handle(zone);
field ^= fields.At(0);
ASSERT(field.Offset() == Closure::instantiator_type_arguments_offset());
field ^= fields.At(1);
@@ -79,7 +88,7 @@
intptr_t kernel_buffer_size) {
Zone* zone = thread->zone();
const char* error = nullptr;
- kernel::Program* program = kernel::Program::ReadFromBuffer(
+ std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
kernel_buffer, kernel_buffer_size, &error);
if (program == nullptr) {
const intptr_t kMessageBufferSize = 512;
@@ -89,7 +98,7 @@
const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
return ApiError::New(msg, Heap::kOld);
}
- kernel::KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
+ kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
Isolate* isolate = thread->isolate();
@@ -111,7 +120,7 @@
// The platform binary may contain other libraries (e.g., dart:_builtin or
// dart:io) that will not be bundled with application. Load them now.
const Object& result = Object::Handle(zone, loader.LoadProgram());
- delete program;
+ program.reset();
if (result.IsError()) {
return Error::Cast(result).raw();
}
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 98c6129..24b6af2 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -383,8 +383,8 @@
V(Ffi_offsetBy, 2) \
V(Ffi_cast, 1) \
V(Ffi_sizeOf, 0) \
- V(Ffi_asFunction, 1) \
- V(Ffi_fromFunction, 1) \
+ V(Ffi_asFunctionInternal, 1) \
+ V(Ffi_fromFunction, 2) \
V(Ffi_dl_open, 1) \
V(Ffi_dl_lookup, 2) \
V(Ffi_dl_getHandle, 1) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 688f192..970c7c5 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -195,14 +195,19 @@
#if defined(DEBUG)
for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
- ASSERT(cls.is_declaration_loaded());
+ ASSERT(cls.is_declared_in_bytecode() || cls.is_declaration_loaded());
}
#endif
// Finalize types in all classes.
for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
- FinalizeTypesInClass(cls);
+ if (cls.is_declared_in_bytecode()) {
+ cls.EnsureDeclarationLoaded();
+ ASSERT(cls.is_type_finalized());
+ } else {
+ FinalizeTypesInClass(cls);
+ }
}
if (FLAG_print_classes) {
@@ -407,6 +412,7 @@
// The type class does not need to be finalized in order to finalize the type.
// Also, the type parameters of the type class must be finalized.
Class& type_class = Class::Handle(zone, type.type_class());
+ type_class.EnsureDeclarationLoaded();
if (!type_class.is_type_finalized()) {
FinalizeTypeParameters(type_class, pending_types);
}
@@ -1003,7 +1009,7 @@
void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
Thread* thread = Thread::Current();
HANDLESCOPE(thread);
- ASSERT(cls.is_declaration_loaded());
+ cls.EnsureDeclarationLoaded();
if (cls.is_type_finalized()) {
return;
}
@@ -1190,21 +1196,9 @@
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (!cls.is_declaration_loaded()) {
- // Loading of class declaration can be postponed until needed
- // if class comes from bytecode.
- ASSERT(cls.is_declared_in_bytecode());
- kernel::BytecodeReader::LoadClassDeclaration(cls);
- }
+ cls.EnsureDeclarationLoaded();
#endif
- // TODO(36584) : We expect is_type_finalized to be true for all classes
- // here, but with eager reading of the constant table we get into
- // situations where we see classes whose types have not been finalized yet,
- // the real solution is to implement lazy evaluation of constants. This is
- // a temporary workaround until lazy evaluation is implemented.
- if (!cls.is_type_finalized()) {
- FinalizeTypesInClass(cls);
- }
+ ASSERT(cls.is_type_finalized());
ClassFinalizer::FinalizeClass(cls);
return Error::null();
} else {
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 4e23dea..ae9bfd0 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -128,7 +128,8 @@
V(NativeFunction) \
CLASS_LIST_FFI_TYPE_MARKER(V) \
V(NativeType) \
- V(DynamicLibrary)
+ V(DynamicLibrary) \
+ V(Struct)
#define DART_CLASS_LIST_TYPED_DATA(V) \
V(Int8) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index eade6cc..aef1813 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -7,8 +7,8 @@
#include "platform/assert.h"
#include "vm/bootstrap.h"
#include "vm/class_id.h"
+#include "vm/code_observers.h"
#include "vm/compiler/backend/code_statistics.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/relocation.h"
#include "vm/dart.h"
#include "vm/heap/heap.h"
@@ -186,6 +186,7 @@
s->Write<int16_t>(cls->ptr()->num_type_arguments_);
s->Write<uint16_t>(cls->ptr()->num_native_fields_);
s->WriteTokenPosition(cls->ptr()->token_pos_);
+ s->WriteTokenPosition(cls->ptr()->end_token_pos_);
s->Write<uint32_t>(cls->ptr()->state_bits_);
}
@@ -247,6 +248,7 @@
cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
cls->ptr()->token_pos_ = d->ReadTokenPosition();
+ cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
cls->ptr()->state_bits_ = d->Read<uint32_t>();
}
@@ -273,6 +275,7 @@
cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
cls->ptr()->token_pos_ = d->ReadTokenPosition();
+ cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
cls->ptr()->state_bits_ = d->Read<uint32_t>();
table->AllocateIndex(class_id);
@@ -1358,14 +1361,6 @@
info.set_libraries_cache(array);
array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
info.set_classes_cache(array);
-
- static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
- array = info.bytecode_component();
- if (!array.IsNull()) {
- kernel::BytecodeReader::UseBytecodeVersion(
- kernel::BytecodeComponentData(&array).GetVersion());
- }
}
}
};
@@ -1581,6 +1576,17 @@
code->ptr()->state_bits_ = d->Read<int32_t>();
}
}
+
+#if !(defined(DART_PRECOMPILED_RUNTIME) || defined(PRODUCT))
+ void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+ if (!CodeObservers::AreActive()) return;
+ Code& code = Code::Handle(zone);
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ code ^= refs.At(id);
+ Code::NotifyCodeObservers(code, code.is_optimized());
+ }
+ }
+#endif // !DART_PRECOMPILED_RUNTIME
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1606,7 +1612,7 @@
}
void WriteFill(Serializer* s) {
- ASSERT(s->kind() == Snapshot::kFullJIT);
+ ASSERT(s->kind() != Snapshot::kFullAOT);
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawBytecode* bytecode = objects_[i];
@@ -1639,7 +1645,7 @@
}
void ReadFill(Deserializer* d) {
- ASSERT(d->kind() == Snapshot::kFullJIT);
+ ASSERT(d->kind() != Snapshot::kFullAOT);
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
@@ -1878,7 +1884,8 @@
}
uint32_t offset = s->GetDataOffset(object);
s->TraceDataOffset(offset);
- ASSERT(Utils::IsAligned(offset, kObjectAlignment));
+ ASSERT(Utils::IsAligned(
+ offset, compiler::target::ObjectAlignment::kObjectAlignment));
ASSERT(offset > running_offset);
s->WriteUnsigned((offset - running_offset) >>
compiler::target::ObjectAlignment::kObjectAlignmentLog2);
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 7832900..6aab6e7 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -15,6 +15,30 @@
intptr_t CodeObservers::observers_length_ = 0;
CodeObserver** CodeObservers::observers_ = NULL;
+class ExternalCodeObserverAdapter : public CodeObserver {
+ public:
+ explicit ExternalCodeObserverAdapter(Dart_CodeObserver* delegate)
+ : delegate_(delegate) {}
+
+ virtual bool IsActive() const { return true; }
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized,
+ const CodeComments* comments) {
+ return delegate_->on_new_code(delegate_, name, base, size);
+ }
+
+ private:
+ Dart_CodeObserver* delegate_;
+};
+
+void CodeObservers::RegisterExternal(Dart_CodeObserver* observer) {
+ if (observer != nullptr) Register(new ExternalCodeObserverAdapter(observer));
+}
+
void CodeObservers::Register(CodeObserver* observer) {
observers_length_++;
observers_ = reinterpret_cast<CodeObserver**>(
diff --git a/runtime/vm/code_observers.h b/runtime/vm/code_observers.h
index aa6221d..3664a02 100644
--- a/runtime/vm/code_observers.h
+++ b/runtime/vm/code_observers.h
@@ -8,6 +8,8 @@
#include "vm/allocation.h"
#include "vm/globals.h"
+#include "include/dart_api.h"
+
namespace dart {
#ifndef PRODUCT
@@ -55,6 +57,8 @@
public:
static void Init();
+ static void RegisterExternal(Dart_CodeObserver* observer);
+
static void Register(CodeObserver* observer);
// Notify all active code observers about a newly created code object.
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 1c06796..0898d42 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -131,7 +131,8 @@
Address ad) {
ASSERT(rd != kNoRegister);
ASSERT(cond != kNoCondition);
- ASSERT(!ad.has_writeback() || (ad.rn() != rd)); // Unpredictable.
+ // Unpredictable, illegal on some microarchitectures.
+ ASSERT(!ad.has_writeback() || (ad.rn() != rd));
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B26 |
(ad.kind() == Address::Immediate ? 0 : B25) |
@@ -146,6 +147,9 @@
Address ad) {
ASSERT(rd != kNoRegister);
ASSERT(cond != kNoCondition);
+ // Unpredictable, illegal on some microarchitectures.
+ ASSERT(!ad.has_writeback() || (ad.rn() != rd));
+
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | mode |
ArmEncode::Rd(rd) | ad.encoding3();
Emit(encoding);
@@ -158,6 +162,8 @@
RegList regs) {
ASSERT(base != kNoRegister);
ASSERT(cond != kNoCondition);
+ // Unpredictable, illegal on some microarchitectures.
+ ASSERT(!Address::has_writeback(am) || !(regs & (1 << base)));
int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
am | (load ? L : 0) | ArmEncode::Rn(base) | regs;
Emit(encoding);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 19ba44f..13ea001 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -310,6 +310,21 @@
(mode() == NegPreIndex) || (mode() == NegPostIndex);
}
+ static bool has_writeback(BlockAddressMode am) {
+ switch (am) {
+ case DA:
+ case IA:
+ case DB:
+ case IB:
+ return false;
+ case DA_W:
+ case IA_W:
+ case DB_W:
+ case IB_W:
+ return true;
+ }
+ }
+
uint32_t encoding() const { return encoding_; }
// Encoding for addressing mode 3.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index b8808f5..26f8cb9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -110,6 +110,17 @@
Unknown,
};
+ // If we are doing pre-/post-indexing, and the base and result registers are
+ // the same, then the result is unpredictable. This kind of instruction is
+ // actually illegal on some microarchitectures.
+ bool can_writeback_to(Register r) const {
+ if (type() == PreIndex || type() == PostIndex || type() == PairPreIndex ||
+ type() == PairPostIndex) {
+ return base() != r;
+ }
+ return true;
+ }
+
// Offset is in bytes. For the unsigned imm12 case, we unscale based on the
// operand size, and assert that offset is aligned accordingly.
// For the smaller signed imm9 case, the offset is the number of bytes, but
@@ -869,12 +880,6 @@
ASSERT(sz == kDoubleWord);
EmitLoadRegLiteral(LDRpc, rt, a, sz);
} else {
- // If we are doing pre-/post-indexing, and the base and result registers
- // are the same, then the result of the load will be clobbered by the
- // writeback, which is unlikely to be useful.
- ASSERT(((a.type() != Address::PreIndex) &&
- (a.type() != Address::PostIndex)) ||
- (rt != a.base()));
if (IsSignedOperand(sz)) {
EmitLoadStoreReg(LDRS, rt, a, sz);
} else {
@@ -2067,6 +2072,9 @@
Register rt,
Address a,
OperandSize sz) {
+ // Unpredictable, illegal on some microarchitectures.
+ ASSERT((op != LDR && op != STR && op != LDRS) || a.can_writeback_to(rt));
+
const int32_t size = Log2OperandSizeBytes(sz);
const int32_t encoding =
op | ((size & 0x3) << kSzShift) | Arm64Encode::Rt(rt) | a.encoding();
@@ -2089,6 +2097,10 @@
Register rt2,
Address a,
OperandSize sz) {
+ // Unpredictable, illegal on some microarchitectures.
+ ASSERT(a.can_writeback_to(rt) && a.can_writeback_to(rt2));
+ ASSERT(op != LDP || rt != rt2);
+
ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
ASSERT((rt != CSP) && (rt != R31));
ASSERT((rt2 != CSP) && (rt2 != R31));
diff --git a/runtime/vm/compiler/assembler/disassembler_arm.cc b/runtime/vm/compiler/assembler/disassembler_arm.cc
index 888f97b..b82632d 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm.cc
@@ -1500,12 +1500,15 @@
}
*object = NULL;
+ // TODO(36839): Make DecodeLoadObjectFromPoolOrThread work on simarm_x64.
+#if !defined(IS_SIMARM_X64)
if (!code.IsNull()) {
*object = &Object::Handle();
if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
*object = NULL;
}
}
+#endif // !defined(IS_SIMARM_X64)
}
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index edd8506..85c6f48 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -160,32 +160,6 @@
Apply(&buf, &size, instr, op1, x, "");
}
-static void FormatA_D(char* buf,
- intptr_t size,
- KernelBytecode::Opcode opcode,
- const KBCInstr* instr,
- Fmt op1,
- Fmt op2,
- Fmt op3) {
- const int32_t a = KernelBytecode::DecodeA(instr);
- const int32_t bc = KernelBytecode::DecodeD(instr);
- Apply(&buf, &size, instr, op1, a, ", ");
- Apply(&buf, &size, instr, op2, bc, "");
-}
-
-static void FormatA_X(char* buf,
- intptr_t size,
- KernelBytecode::Opcode opcode,
- const KBCInstr* instr,
- Fmt op1,
- Fmt op2,
- Fmt op3) {
- const int32_t a = KernelBytecode::DecodeA(instr);
- const int32_t bc = KernelBytecode::DecodeX(instr);
- Apply(&buf, &size, instr, op1, a, ", ");
- Apply(&buf, &size, instr, op2, bc, "");
-}
-
static void FormatA_E(char* buf,
intptr_t size,
KernelBytecode::Opcode opcode,
@@ -257,21 +231,6 @@
static intptr_t GetConstantPoolIndex(const KBCInstr* instr) {
switch (KernelBytecode::DecodeOpcode(instr)) {
- case KernelBytecode::kLoadConstant_Old:
- case KernelBytecode::kInstantiateTypeArgumentsTOS_Old:
- case KernelBytecode::kAssertAssignable_Old:
- case KernelBytecode::kPushConstant_Old:
- case KernelBytecode::kStoreStaticTOS_Old:
- case KernelBytecode::kPushStatic_Old:
- case KernelBytecode::kAllocate_Old:
- case KernelBytecode::kAllocateClosure_Old:
- case KernelBytecode::kInstantiateType_Old:
- case KernelBytecode::kDirectCall_Old:
- case KernelBytecode::kInterfaceCall_Old:
- case KernelBytecode::kUncheckedInterfaceCall_Old:
- case KernelBytecode::kDynamicCall_Old:
- return KernelBytecode::DecodeD(instr);
-
case KernelBytecode::kLoadConstant:
case KernelBytecode::kLoadConstant_Wide:
case KernelBytecode::kInstantiateTypeArgumentsTOS:
@@ -378,7 +337,8 @@
sizeof(human_buffer), &instruction_length, bytecode,
&object, pc);
formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
- sizeof(human_buffer), object, pc);
+ sizeof(human_buffer), object,
+ FLAG_disassemble_relative ? pc - start : pc);
pc += instruction_length;
}
#else
@@ -393,7 +353,8 @@
Zone* zone = Thread::Current()->zone();
const Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode());
THR_Print("Bytecode for function '%s' {\n", function_fullname);
- uword start = bytecode.PayloadStart();
+ const uword start = bytecode.PayloadStart();
+ const uword base = FLAG_disassemble_relative ? 0 : start;
DisassembleToStdout stdout_formatter;
LogBlock lb;
Disassemble(start, start + bytecode.Size(), &stdout_formatter, bytecode);
@@ -415,29 +376,59 @@
const int addr_width = (kBitsPerWord / 4) + 2;
// "*" in a printf format specifier tells it to read the field width from
// the printf argument list.
- THR_Print("%-*s\ttok-ix\n", addr_width, "pc");
+ THR_Print("%-*s\tpos\n", addr_width, "pc");
kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
while (iter.MoveNext()) {
- THR_Print("%#-*" Px "\t%s\n", addr_width,
- bytecode.PayloadStart() + iter.PcOffset(),
+ THR_Print("%#-*" Px "\t%s\n", addr_width, base + iter.PcOffset(),
iter.TokenPos().ToCString());
}
THR_Print("}\n");
}
+ if (FLAG_print_variable_descriptors && bytecode.HasLocalVariablesInfo()) {
+ THR_Print("Local variables info for function '%s' {\n", function_fullname);
+ kernel::BytecodeLocalVariablesIterator iter(zone, bytecode);
+ while (iter.MoveNext()) {
+ switch (iter.Kind()) {
+ case kernel::BytecodeLocalVariablesIterator::kScope: {
+ THR_Print("scope 0x%" Px "-0x%" Px " pos %s-%s\tlev %" Pd "\n",
+ base + iter.StartPC(), base + iter.EndPC(),
+ iter.StartTokenPos().ToCString(),
+ iter.EndTokenPos().ToCString(), iter.ContextLevel());
+ } break;
+ case kernel::BytecodeLocalVariablesIterator::kVariableDeclaration: {
+ THR_Print("var 0x%" Px "-0x%" Px " pos %s-%s\tidx %" Pd
+ "\tdecl %s\t%s %s %s\n",
+ base + iter.StartPC(), base + iter.EndPC(),
+ iter.StartTokenPos().ToCString(),
+ iter.EndTokenPos().ToCString(), iter.Index(),
+ iter.DeclarationTokenPos().ToCString(),
+ String::Handle(
+ zone, AbstractType::Handle(zone, iter.Type()).Name())
+ .ToCString(),
+ String::Handle(zone, iter.Name()).ToCString(),
+ iter.IsCaptured() ? "captured" : "");
+ } break;
+ case kernel::BytecodeLocalVariablesIterator::kContextVariable: {
+ THR_Print("ctxt 0x%" Px "\tidx %" Pd "\n", base + iter.StartPC(),
+ iter.Index());
+ } break;
+ }
+ }
+ THR_Print("}\n");
+
+ THR_Print("Local variable descriptors for function '%s' {\n",
+ function_fullname);
+ const auto& var_descriptors =
+ LocalVarDescriptors::Handle(zone, bytecode.GetLocalVarDescriptors());
+ THR_Print("%s}\n", var_descriptors.ToCString());
+ }
+
THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
const ExceptionHandlers& handlers =
ExceptionHandlers::Handle(zone, bytecode.exception_handlers());
THR_Print("%s}\n", handlers.ToCString());
- if (FLAG_print_variable_descriptors) {
- THR_Print("Local variable descriptors for function '%s' {\n",
- function_fullname);
- const auto& var_descriptors =
- LocalVarDescriptors::Handle(zone, bytecode.GetLocalVarDescriptors());
- THR_Print("%s\n}\n", var_descriptors.ToCString());
- }
-
#else
UNREACHABLE();
#endif
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 94b566a..28c5d1e 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -30,7 +30,7 @@
template <typename T>
T* AddDefinition(T* def) {
- def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+ flow_graph_->AllocateSSAIndexes(def);
AddInstruction(def);
return def;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 4660d82..7d20887 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -351,6 +351,23 @@
// ASSERT(constant->GetBlock() == flow_graph_->graph_entry());
}
+void FlowGraphChecker::VisitInstanceCall(InstanceCallInstr* instr) {
+ const Function& function = flow_graph_->function();
+
+ // Force-optimized functions may not have instance calls inside them because
+ // we do not reset ICData for these.
+ ASSERT(!function.ForceOptimize());
+}
+
+void FlowGraphChecker::VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* instr) {
+ const Function& function = flow_graph_->function();
+
+ // Force-optimized functions may not have instance calls inside them because
+ // we do not reset ICData for these.
+ ASSERT(!function.ForceOptimize());
+}
+
void FlowGraphChecker::VisitPhi(PhiInstr* phi) {
// Make sure the definition of each input value of a Phi dominates
// the corresponding incoming edge, as defined by order.
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.h b/runtime/vm/compiler/backend/flow_graph_checker.h
index 088ad3e..63a77bd 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.h
+++ b/runtime/vm/compiler/backend/flow_graph_checker.h
@@ -56,6 +56,9 @@
void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
void VisitBranch(BranchInstr* branch) override;
void VisitRedefinition(RedefinitionInstr* def) override;
+ void VisitInstanceCall(InstanceCallInstr* instr) override;
+ void VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* instr) override;
FlowGraph* const flow_graph_;
BlockEntryInstr* current_block_;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index d6e6059..b207ce7 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3197,7 +3197,7 @@
ConstantInstr* c = value()->definition()->AsConstant();
if ((c != NULL) && c->value().IsSmi()) {
- if (!is_truncating() && (kSmiBits > 32)) {
+ if (!is_truncating()) {
// Check that constant fits into 32-bit integer.
const int64_t value = static_cast<int64_t>(Smi::Cast(c->value()).Value());
if (!Utils::IsInt(32, value)) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 21d4bf9..bee636b 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5109,9 +5109,6 @@
DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
};
-// TODO(vegorov) the name of the instruction is confusing. At some point
-// it used to allocate uninitialized storage, but this is no longer true.
-// These days it allocates null initialized storage.
class AllocateUninitializedContextInstr
: public TemplateAllocation<0, NoThrow> {
public:
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index a219c2a..1e56f5a 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -45,6 +45,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);
+
Thread* thread = Thread::Current();
Dart_Handle api_lib = Api::NewHandle(thread, lib.raw());
TransitionVMToNative transition(thread);
diff --git a/runtime/vm/compiler/backend/loops_test.cc b/runtime/vm/compiler/backend/loops_test.cc
index 4b208f8..b2b2e23 100644
--- a/runtime/vm/compiler/backend/loops_test.cc
+++ b/runtime/vm/compiler/backend/loops_test.cc
@@ -307,7 +307,7 @@
" WRAP(-99, LIN(0 + -1 * i))\n" // d
" LIN(1 + 1 * i)\n" // add
" ]\n";
- EXPECT_STREQ(ComputeInduction(thread, script_chars), expected);
+ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
}
ISOLATE_UNIT_TEST_CASE(PeriodicAndDerived) {
@@ -342,7 +342,7 @@
" PERIOD(95, 5)\n" // p2
" LIN(1 + 1 * i)\n" // add
" ]\n";
- EXPECT_STREQ(ComputeInduction(thread, script_chars), expected);
+ EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
}
//
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 1b93d0d..420bdbf 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1088,6 +1088,11 @@
intptr_t cid = value().GetClassId();
+ if (cid == kSmiCid && !compiler::target::IsSmi(Smi::Cast(value()).Value())) {
+ return CompileType::Create(kMintCid,
+ AbstractType::ZoneHandle(Type::MintType()));
+ }
+
if ((cid != kTypeArgumentsCid) && value().IsInstance()) {
// Allocate in old-space since this may be invoked from the
// background compiler.
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 7cf2dc1..0626731 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1692,7 +1692,11 @@
}
void TypedDataSpecializer::VisitStaticCall(StaticCallInstr* call) {
- TryInlineCall(call);
+ const Function& function = call->function();
+ if (!function.is_static()) {
+ ASSERT(call->ArgumentCount() > 0);
+ TryInlineCall(call);
+ }
}
void TypedDataSpecializer::TryInlineCall(TemplateDartCall<0>* call) {
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index bac526c..2d8c1f2 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -152,9 +152,12 @@
#
# Not that this diverges from our convention to build every file on every OS
# but have ifdef guards which make the files empty on some configurations.
-if (is_linux || is_mac) {
+if (!is_win) {
# MASM on Windows does not support c preproccesor style flags.
- compiler_sources += [ "ffi_dbc_trampoline_x64_linux_mac.S" ]
+ compiler_sources += [
+ "ffi_dbc_trampoline_arm64.S",
+ "ffi_dbc_trampoline_x64_linux_mac.S",
+ ]
}
compiler_sources_tests = [
diff --git a/runtime/vm/compiler/ffi.cc b/runtime/vm/compiler/ffi.cc
index 665382a..a2e83a7 100644
--- a/runtime/vm/compiler/ffi.cc
+++ b/runtime/vm/compiler/ffi.cc
@@ -10,7 +10,9 @@
#include "vm/compiler/backend/locations.h"
#include "vm/compiler/runtime_api.h"
#include "vm/growable_array.h"
+#include "vm/object_store.h"
#include "vm/stack_frame.h"
+#include "vm/symbols.h"
namespace dart {
@@ -71,8 +73,10 @@
return kUnboxedInt64;
case kFfiIntPtrCid:
case kFfiPointerCid:
- default: // Subtypes of Pointer.
+ case kFfiVoidCid:
return kUnboxedFfiIntPtr;
+ default:
+ UNREACHABLE();
}
}
@@ -96,24 +100,7 @@
}
bool NativeTypeIsPointer(const AbstractType& result_type) {
- switch (result_type.type_class_id()) {
- case kFfiVoidCid:
- case kFfiFloatCid:
- case kFfiDoubleCid:
- case kFfiInt8Cid:
- case kFfiInt16Cid:
- case kFfiInt32Cid:
- case kFfiUint8Cid:
- case kFfiUint16Cid:
- case kFfiUint32Cid:
- case kFfiInt64Cid:
- case kFfiUint64Cid:
- case kFfiIntPtrCid:
- return false;
- case kFfiPointerCid:
- default:
- return true;
- }
+ return result_type.type_class_id() == kFfiPointerCid;
}
// Converts a Ffi [signature] to a list of Representations.
@@ -442,6 +429,45 @@
#endif
}
+// TODO(36607): Cache the trampolines.
+RawFunction* TrampolineFunction(const Function& dart_signature,
+ const Function& c_signature) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
+ const Library& lib = Library::Handle(zone, Library::FfiLibrary());
+ const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
+ Function& function =
+ Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+ /*is_static=*/true,
+ /*is_const=*/false,
+ /*is_abstract=*/false,
+ /*is_external=*/false,
+ /*is_native=*/false, owner_class,
+ TokenPosition::kMinSource));
+ function.set_is_debuggable(false);
+ function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
+ function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
+ function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
+
+ // The signature function won't have any names for the parameters. We need to
+ // assign unique names for scope building and error messages.
+ const intptr_t num_params = dart_signature.num_fixed_parameters();
+ const Array& parameter_names = Array::Handle(Array::New(num_params));
+ for (intptr_t i = 0; i < num_params; ++i) {
+ if (i == 0) {
+ name = Symbols::ClosureParameter().raw();
+ } else {
+ name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i);
+ }
+ parameter_names.SetAt(i, name);
+ }
+ function.set_parameter_names(parameter_names);
+ function.SetFfiCSignature(c_signature);
+
+ return function.raw();
+}
+
// Accounts for alignment, where some stack slots are used as padding.
template <class Location>
intptr_t TemplateNumStackSlots(const ZoneGrowableArray<Location>& locations) {
@@ -547,6 +573,27 @@
#endif // defined(TARGET_ARCH_DBC)
+bool IsAsFunctionInternal(Zone* zone, Isolate* isolate, const Function& func) {
+ Object& asFunctionInternal =
+ Object::Handle(zone, isolate->object_store()->ffi_as_function_internal());
+ if (asFunctionInternal.raw() == Object::null()) {
+ // Cache the reference.
+ Library& ffi =
+ Library::Handle(zone, isolate->object_store()->ffi_library());
+ asFunctionInternal =
+ ffi.LookupFunctionAllowPrivate(Symbols::AsFunctionInternal());
+ // Cannot assert that 'asFunctionInternal' is found because it may have been
+ // tree-shaken.
+ if (asFunctionInternal.IsNull()) {
+ // Set the entry in the object store to a sentinel so we don't try to look
+ // it up again.
+ asFunctionInternal = Object::sentinel().raw();
+ }
+ isolate->object_store()->set_ffi_as_function_internal(asFunctionInternal);
+ }
+ return func.raw() == asFunctionInternal.raw();
+}
+
#endif // !defined(DART_PRECOMPILED_RUNTIME)
} // namespace ffi
diff --git a/runtime/vm/compiler/ffi.h b/runtime/vm/compiler/ffi.h
index 846775a..9c9810a 100644
--- a/runtime/vm/compiler/ffi.h
+++ b/runtime/vm/compiler/ffi.h
@@ -41,6 +41,9 @@
// Location for the result of a C signature function.
Location ResultLocation(Representation result_rep);
+RawFunction* TrampolineFunction(const Function& dart_signature,
+ const Function& c_signature);
+
#if !defined(TARGET_ARCH_DBC)
// Unboxed representations of the arguments to a C signature function.
@@ -133,6 +136,8 @@
intptr_t argument_slots_required_ = 0;
};
+bool IsAsFunctionInternal(Zone* zone, Isolate* isolate, const Function& func);
+
} // namespace ffi
} // namespace compiler
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline.h b/runtime/vm/compiler/ffi_dbc_trampoline.h
index 656d1e1..578fc7f 100644
--- a/runtime/vm/compiler/ffi_dbc_trampoline.h
+++ b/runtime/vm/compiler/ffi_dbc_trampoline.h
@@ -9,7 +9,8 @@
namespace dart {
-#if defined(HOST_ARCH_X64) && !defined(HOST_OS_WINDOWS)
+#if !defined(HOST_OS_WINDOWS) && \
+ (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
// Generic Trampoline for DBC dart:ffi calls. Argument needs to be layed out as
// a FfiMarshalledArguments.
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S b/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S
new file mode 100644
index 0000000..3c24411
--- /dev/null
+++ b/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S
@@ -0,0 +1,76 @@
+#if defined(__aarch64__) /* HOST_ARCH_ARM64 */
+
+.text
+
+#if defined(__ANDROID__) || defined(__linux__) || defined(__FreeBSD__)
+/* HOST_OS_ANDROID || HOST_OS_LINUX */
+.global FfiTrampolineCall
+.align 2
+FfiTrampolineCall:
+#else /* HOST_OS_MACOS */
+.global _FfiTrampolineCall
+.align 2
+_FfiTrampolineCall:
+#endif
+
+/* Save argument in scratch register. */
+stp x19, x20, [sp, #-16]! /* Push x19 and x20, we use x19 as scratch. */
+mov x19, x0 /* Save argument in scratch register. */
+
+/* Enter frame. */
+stp fp, lr, [sp, #-16]!
+mov fp, sp
+
+/* Reserve framespace for arguments. */
+ldr x9, [x19, #(8*18)] /* Load number of stack arguments. */
+lsl x9, x9, #3 /* Multiply by size (8 bytes). */
+sub sp, sp, x9 /* Reserve num_stack_args stack slots. */
+
+/* Stack alignment. */
+ldr x10, [x19, #(8*17)] /* Load stack alignment mask. */
+mov x11, sp
+and x11, x11, x10 /* Align stack. */
+mov sp, x11
+
+/* Copy stack arguments. */
+cmp x9, #0 /* Check if number of stack arguments is 0. */
+beq .done /* Skip loop if no stack arguments. */
+add x19, x19, #(8*19) /* Offset r19 to point to stack arguments. */
+.align 2
+.loop: /* Copy stack arguments loop. */
+sub x9, x9, #8 /* Decrement stack argument iterator. */
+ldr x10, [x19, x9] /* Load value from ffi_marshalled_args. */
+str x10, [sp, x9] /* Store value on stack. */
+cmp x9, #0 /* Compare iterator with 0 */
+bne .loop /* Loop while iterator is not 0 */
+sub x19, x19, #(8*19) /* Restore r19 to original value. */
+.align 2
+.done: /* End stack arguments loop. */
+
+/* Copy registers and fpu registers. */
+ldp x0, x1, [x19, #(8*1)] /* and #(8*2) */
+ldp x2, x3, [x19, #(8*3)] /* and #(8*4) */
+ldp x4, x5, [x19, #(8*5)] /* ... */
+ldp x6, x7, [x19, #(8*7)]
+ldp d0, d1, [x19, #(8*9)]
+ldp d2, d3, [x19, #(8*11)]
+ldp d4, d5, [x19, #(8*13)]
+ldp d6, d7, [x19, #(8*15)]
+
+/* Do call. */
+ldr x9, [x19] /* Load function address. */
+blr x9 /* Call the function. */
+
+/* Copy results back. */
+str x0, [x19, #(8*0)] /* Move integer result in kOffsetIntResult. */
+str d0, [x19, #(8*1)] /* Move double result in kOffsetDoubleResult. */
+
+/* Leave frame. */
+mov sp, fp
+ldp fp, lr, [sp], #16
+
+/* Restore caller saved register. */
+ldp x19, x20, [sp], #16 /* Pop x19 and x20. */
+ret
+
+#endif /* HOST_ARCH_ARM64 */
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index c133f75..0753967 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -601,9 +601,14 @@
Value::AddToList(new (Z) Value(definition), &stack_);
}
-Definition* BaseFlowGraphBuilder::Peek() {
- ASSERT(stack_ != NULL);
- return stack_->definition();
+Definition* BaseFlowGraphBuilder::Peek(intptr_t depth) {
+ Value* head = stack_;
+ for (intptr_t i = 0; i < depth; ++i) {
+ ASSERT(head != nullptr);
+ head = head->next_use();
+ }
+ ASSERT(head != nullptr);
+ return head->definition();
}
Value* BaseFlowGraphBuilder::Pop() {
@@ -813,6 +818,62 @@
return Fragment(load);
}
+Fragment BaseFlowGraphBuilder::AllocateObject(TokenPosition position,
+ const Class& klass,
+ intptr_t argument_count) {
+ ArgumentArray arguments = GetArguments(argument_count);
+ AllocateObjectInstr* allocate =
+ new (Z) AllocateObjectInstr(position, klass, arguments);
+ Push(allocate);
+ return Fragment(allocate);
+}
+
+Fragment BaseFlowGraphBuilder::BuildFfiAsFunctionInternalCall(
+ const TypeArguments& signatures) {
+ ASSERT(signatures.IsInstantiated() && signatures.Length() == 2);
+
+ const AbstractType& dart_type = AbstractType::Handle(signatures.TypeAt(0));
+ const AbstractType& native_type = AbstractType::Handle(signatures.TypeAt(1));
+
+ ASSERT(dart_type.IsFunctionType() && native_type.IsFunctionType());
+ const Function& target =
+ Function::ZoneHandle(compiler::ffi::TrampolineFunction(
+ Function::Handle(Z, Type::Cast(dart_type).signature()),
+ Function::Handle(Z, Type::Cast(native_type).signature())));
+
+ Fragment code;
+ code += LoadNativeField(Slot::Pointer_c_memory_address());
+ LocalVariable* address = MakeTemporary();
+
+ auto& context_variables = CompilerState::Current().GetDummyContextVariables(
+ /*context_id=*/0, /*num_variables=*/1);
+ code += AllocateContext(context_variables);
+ LocalVariable* context = MakeTemporary();
+
+ code += LoadLocal(context);
+ code += LoadLocal(address);
+ code += StoreInstanceField(
+ TokenPosition::kNoSource,
+ Slot::GetContextVariableSlotFor(thread_, *context_variables[0]));
+
+ code += AllocateClosure(TokenPosition::kNoSource, target);
+ LocalVariable* closure = MakeTemporary();
+
+ code += LoadLocal(closure);
+ code += LoadLocal(context);
+ code += StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_context());
+
+ code += LoadLocal(closure);
+ code += Constant(target);
+ code +=
+ StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_function());
+
+ // Drop address and context.
+ code += DropTempsPreserveTop(2);
+
+ return code;
+}
+
} // namespace kernel
} // namespace dart
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index a800743..330b03a 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -169,7 +169,7 @@
Fragment StoreIndexed(intptr_t class_id);
void Push(Definition* definition);
- Definition* Peek();
+ Definition* Peek(intptr_t depth = 0);
Value* Pop();
Fragment Drop();
// Drop given number of temps from the stack but preserve top of the stack.
@@ -292,6 +292,15 @@
return stack_ == nullptr ? 0 : stack_->definition()->temp_index() + 1;
}
+ // Builds the graph for an invocation of '_asFunctionInternal'.
+ //
+ // 'signatures' contains the pair [<dart signature>, <native signature>].
+ Fragment BuildFfiAsFunctionInternalCall(const TypeArguments& signatures);
+
+ Fragment AllocateObject(TokenPosition position,
+ const Class& klass,
+ intptr_t argument_count);
+
protected:
intptr_t AllocateBlockId() { return ++last_used_block_id_; }
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index fd2dd5d..5cd23a4 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -5,6 +5,7 @@
#include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/ffi.h"
#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/frontend/prologue_builder.h"
#include "vm/compiler/jit/compiler.h"
@@ -252,6 +253,110 @@
parsed_function()->SetRawParameters(parameters);
}
+const KBCInstr*
+BytecodeFlowGraphBuilder::AllocateParametersAndLocalsForEntryOptional() {
+ ASSERT(KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_));
+
+ const intptr_t num_fixed_params = DecodeOperandA().value();
+ const intptr_t num_opt_pos_params = DecodeOperandB().value();
+ const intptr_t num_opt_named_params = DecodeOperandC().value();
+
+ ASSERT(num_fixed_params == function().num_fixed_parameters());
+ ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters());
+ ASSERT(num_opt_named_params == function().NumOptionalNamedParameters());
+
+ ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
+ const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
+
+ const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_);
+ const KBCInstr* frame_instr = instr;
+ for (intptr_t i = 0; i < num_load_const; ++i) {
+ frame_instr = KernelBytecode::Next(frame_instr);
+ }
+ ASSERT(KernelBytecode::IsFrameOpcode(frame_instr));
+ const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr);
+ const intptr_t num_params =
+ num_fixed_params + num_opt_pos_params + num_opt_named_params;
+ const intptr_t total_locals = num_params + num_extra_locals;
+
+ AllocateLocalVariables(Operand(total_locals), num_params);
+
+ ZoneGrowableArray<const Instance*>* default_values =
+ new (Z) ZoneGrowableArray<const Instance*>(
+ Z, num_opt_pos_params + num_opt_named_params);
+ ZoneGrowableArray<LocalVariable*>* raw_parameters =
+ new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
+
+ intptr_t param = 0;
+ for (; param < num_fixed_params; ++param) {
+ LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+ raw_parameters->Add(param_var);
+ }
+
+ for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
+ const KBCInstr* load_value_instr = instr;
+ instr = KernelBytecode::Next(instr);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
+ ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
+ const Object& default_value =
+ ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value();
+
+ LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+ raw_parameters->Add(param_var);
+ default_values->Add(
+ &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())));
+ }
+
+ if (num_opt_named_params > 0) {
+ default_values->EnsureLength(num_opt_named_params, nullptr);
+ raw_parameters->EnsureLength(num_params, nullptr);
+
+ ASSERT(scratch_var_ != nullptr);
+
+ for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
+ const KBCInstr* load_name_instr = instr;
+ const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr);
+ instr = KernelBytecode::Next(load_value_instr);
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
+ ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
+ const String& param_name = String::Cast(
+ ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr)))
+ .value());
+ ASSERT(param_name.IsSymbol());
+ const Object& default_value =
+ ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr)))
+ .value();
+
+ intptr_t param_index = num_fixed_params;
+ for (; param_index < num_params; ++param_index) {
+ if (function().ParameterNameAt(param_index) == param_name.raw()) {
+ break;
+ }
+ }
+ ASSERT(param_index < num_params);
+
+ ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
+ (*default_values)[param_index - num_fixed_params] =
+ &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()));
+
+ const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr);
+ ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr));
+
+ LocalVariable* param_var =
+ AllocateParameter(param_index, VariableIndex(-param));
+ ASSERT(raw_parameters->At(param_index) == nullptr);
+ (*raw_parameters)[param_index] = param_var;
+ }
+ }
+
+ ASSERT(instr == frame_instr);
+
+ parsed_function()->set_default_parameter_values(default_values);
+ parsed_function()->SetRawParameters(raw_parameters);
+
+ return KernelBytecode::Next(frame_instr);
+}
+
LocalVariable* BytecodeFlowGraphBuilder::LocalVariableAt(intptr_t local_index) {
ASSERT(!is_generating_interpreter());
if (local_index < 0) {
@@ -388,12 +493,10 @@
#define BUILD_BYTECODE_CASE(name, encoding, kind, op1, op2, op3) \
BUILD_BYTECODE_CASE_##kind(name, encoding)
-#define BUILD_BYTECODE_CASE_OLD(name, encoding)
#define BUILD_BYTECODE_CASE_WIDE(name, encoding)
#define BUILD_BYTECODE_CASE_RESV(name, encoding)
#define BUILD_BYTECODE_CASE_ORDN(name, encoding) \
case KernelBytecode::k##name: \
- case KernelBytecode::k##name##_Old: \
WIDE_CASE_##encoding(name) Build##name(); \
break;
@@ -410,7 +513,6 @@
#undef WIDE_CASE_D_F
#undef WIDE_CASE_A_B_C
#undef BUILD_BYTECODE_CASE
-#undef BUILD_BYTECODE_CASE_OLD
#undef BUILD_BYTECODE_CASE_WIDE
#undef BUILD_BYTECODE_CASE_RESV
#undef BUILD_BYTECODE_CASE_ORDN
@@ -472,104 +574,14 @@
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
}
- const intptr_t num_fixed_params = DecodeOperandA().value();
- const intptr_t num_opt_pos_params = DecodeOperandB().value();
- const intptr_t num_opt_named_params = DecodeOperandC().value();
- ASSERT(num_fixed_params == function().num_fixed_parameters());
- ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters());
- ASSERT(num_opt_named_params == function().NumOptionalNamedParameters());
+ const KBCInstr* next_instr = AllocateParametersAndLocalsForEntryOptional();
- ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
- const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
-
- const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_);
- const KBCInstr* frame_instr = instr;
- for (intptr_t i = 0; i < num_load_const; ++i) {
- frame_instr = KernelBytecode::Next(frame_instr);
- }
- ASSERT(KernelBytecode::IsFrameOpcode(frame_instr));
- const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr);
- const intptr_t num_params =
- num_fixed_params + num_opt_pos_params + num_opt_named_params;
- const intptr_t total_locals = num_params + num_extra_locals;
-
- AllocateLocalVariables(Operand(total_locals), num_params);
-
- ZoneGrowableArray<const Instance*>* default_values =
- new (Z) ZoneGrowableArray<const Instance*>(
- Z, num_opt_pos_params + num_opt_named_params);
- ZoneGrowableArray<LocalVariable*>* raw_parameters =
- new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
LocalVariable* temp_var = nullptr;
-
- intptr_t param = 0;
- for (; param < num_fixed_params; ++param) {
- LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
- raw_parameters->Add(param_var);
- }
-
- for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
- const KBCInstr* load_value_instr = instr;
- instr = KernelBytecode::Next(instr);
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
- ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
- const Object& default_value =
- ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value();
-
- LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
- raw_parameters->Add(param_var);
- default_values->Add(
- &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())));
- }
-
- if (num_opt_named_params > 0) {
- default_values->EnsureLength(num_opt_named_params, nullptr);
- raw_parameters->EnsureLength(num_params, nullptr);
-
+ if (function().HasOptionalNamedParameters()) {
ASSERT(scratch_var_ != nullptr);
temp_var = scratch_var_;
-
- for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
- const KBCInstr* load_name_instr = instr;
- const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr);
- instr = KernelBytecode::Next(load_value_instr);
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
- ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
- const String& param_name = String::Cast(
- ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr)))
- .value());
- ASSERT(param_name.IsSymbol());
- const Object& default_value =
- ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr)))
- .value();
-
- intptr_t param_index = num_fixed_params;
- for (; param_index < num_params; ++param_index) {
- if (function().ParameterNameAt(param_index) == param_name.raw()) {
- break;
- }
- }
- ASSERT(param_index < num_params);
-
- ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
- (*default_values)[param_index - num_fixed_params] =
- &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()));
-
- const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr);
- ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr));
-
- LocalVariable* param_var =
- AllocateParameter(param_index, VariableIndex(-param));
- ASSERT(raw_parameters->At(param_index) == nullptr);
- (*raw_parameters)[param_index] = param_var;
- }
}
- ASSERT(instr == frame_instr);
-
- parsed_function()->set_default_parameter_values(default_values);
- parsed_function()->SetRawParameters(raw_parameters);
-
Fragment copy_args_prologue;
// Code generated for EntryOptional is considered a prologue code.
@@ -602,7 +614,7 @@
PrologueInfo(prologue_entry->block_id(), prologue_exit->block_id() - 1);
// Skip LoadConstant and Frame instructions.
- next_pc_ = pc_ + (KernelBytecode::Next(instr) - bytecode_instr_);
+ next_pc_ = pc_ + (next_instr - bytecode_instr_);
ASSERT(IsStackEmpty());
}
@@ -765,6 +777,11 @@
const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
const intptr_t argc = DecodeOperandF().value();
+ if (compiler::ffi::IsAsFunctionInternal(Z, Isolate::Current(), target)) {
+ BuildFfiAsFunction();
+ return;
+ }
+
// Recognize identical() call.
// Note: similar optimization is performed in AST flow graph builder - see
// StreamingFlowGraphBuilder::BuildStaticInvocation, special_case_identical.
@@ -895,194 +912,17 @@
}
ASSERT(function().is_native());
+ B->InlineBailout("BytecodeFlowGraphBuilder::BuildNativeCall");
- // TODO(alexmarkov): find a way to avoid code duplication with
- // FlowGraphBuilder::NativeFunctionBody.
- const MethodRecognizer::Kind kind =
- MethodRecognizer::RecognizeKind(function());
- switch (kind) {
- case MethodRecognizer::kObjectEquals:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StrictCompare(Token::kEQ_STRICT);
- break;
- case MethodRecognizer::kStringBaseLength:
- case MethodRecognizer::kStringBaseIsEmpty:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::String_length());
- if (kind == MethodRecognizer::kStringBaseIsEmpty) {
- code_ += B->IntConstant(0);
- code_ += B->StrictCompare(Token::kEQ_STRICT);
- }
- break;
- case MethodRecognizer::kGrowableArrayLength:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::GrowableObjectArray_length());
- break;
- case MethodRecognizer::kObjectArrayLength:
- case MethodRecognizer::kImmutableArrayLength:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::Array_length());
- break;
- case MethodRecognizer::kTypedListLength:
- case MethodRecognizer::kTypedListViewLength:
- case MethodRecognizer::kByteDataViewLength:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::TypedDataBase_length());
- break;
- case MethodRecognizer::kClassIDgetID:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadClassId();
- break;
- case MethodRecognizer::kGrowableArrayCapacity:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::GrowableObjectArray_data());
- code_ += B->LoadNativeField(Slot::Array_length());
- break;
- case MethodRecognizer::kListFactory: {
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric() &&
- function().HasOptionalParameters());
- ASSERT(scratch_var_ != nullptr);
- // Generate code that performs:
- //
- // factory List<E>([int length]) {
- // return (:arg_desc.positional_count == 2) ? new _List<E>(length)
- // : new _GrowableList<E>(0);
- // }
- const auto& core_lib = Library::Handle(Z, Library::CoreLibrary());
-
- TargetEntryInstr *allocate_non_growable, *allocate_growable;
-
- code_ += B->Drop(); // Drop 'length'.
- code_ += B->Drop(); // Drop 'type arguments'.
- code_ += B->LoadArgDescriptor();
- code_ += B->LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
- code_ += B->IntConstant(2);
- code_ +=
- B->BranchIfStrictEqual(&allocate_non_growable, &allocate_growable);
-
- JoinEntryInstr* join = B->BuildJoinEntry();
-
- {
- const auto& cls = Class::Handle(
- Z, core_lib.LookupClass(
- Library::PrivateCoreLibName(Symbols::_List())));
- ASSERT(!cls.IsNull());
- const auto& func = Function::ZoneHandle(
- Z, cls.LookupFactoryAllowPrivate(Symbols::_ListFactory()));
- ASSERT(!func.IsNull());
-
- code_ = Fragment(allocate_non_growable);
- code_ += B->LoadLocal(LocalVariableAt(0));
- code_ += B->LoadLocal(LocalVariableAt(1));
- auto* call = new (Z) StaticCallInstr(
- TokenPosition::kNoSource, func, 0, Array::null_array(),
- GetArguments(2), *ic_data_array_, B->GetNextDeoptId(),
- ICData::kStatic);
- code_ <<= call;
- B->Push(call);
- code_ += B->StoreLocal(TokenPosition::kNoSource, scratch_var_);
- code_ += B->Drop();
- code_ += B->Goto(join);
- }
-
- {
- const auto& cls = Class::Handle(
- Z, core_lib.LookupClass(
- Library::PrivateCoreLibName(Symbols::_GrowableList())));
- ASSERT(!cls.IsNull());
- const auto& func = Function::ZoneHandle(
- Z, cls.LookupFactoryAllowPrivate(Symbols::_GrowableListFactory()));
- ASSERT(!func.IsNull());
-
- code_ = Fragment(allocate_growable);
- code_ += B->LoadLocal(LocalVariableAt(0));
- code_ += B->IntConstant(0);
- auto* call = new (Z) StaticCallInstr(
- TokenPosition::kNoSource, func, 0, Array::null_array(),
- GetArguments(2), *ic_data_array_, B->GetNextDeoptId(),
- ICData::kStatic);
- code_ <<= call;
- B->Push(call);
- code_ += B->StoreLocal(TokenPosition::kNoSource, scratch_var_);
- code_ += B->Drop();
- code_ += B->Goto(join);
- }
-
- code_ = Fragment(join);
- code_ += B->LoadLocal(scratch_var_);
- break;
- }
- case MethodRecognizer::kObjectArrayAllocate:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->CreateArray();
- break;
- case MethodRecognizer::kLinkedHashMap_getIndex:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::LinkedHashMap_index());
- break;
- case MethodRecognizer::kLinkedHashMap_setIndex:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StoreInstanceField(TokenPosition::kNoSource,
- Slot::LinkedHashMap_index());
- code_ += B->NullConstant();
- break;
- case MethodRecognizer::kLinkedHashMap_getData:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::LinkedHashMap_data());
- break;
- case MethodRecognizer::kLinkedHashMap_setData:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StoreInstanceField(TokenPosition::kNoSource,
- Slot::LinkedHashMap_data());
- code_ += B->NullConstant();
- break;
- case MethodRecognizer::kLinkedHashMap_getHashMask:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::LinkedHashMap_hash_mask());
- break;
- case MethodRecognizer::kLinkedHashMap_setHashMask:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StoreInstanceField(TokenPosition::kNoSource,
- Slot::LinkedHashMap_hash_mask(),
- kNoStoreBarrier);
- code_ += B->NullConstant();
- break;
- case MethodRecognizer::kLinkedHashMap_getUsedData:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::LinkedHashMap_used_data());
- break;
- case MethodRecognizer::kLinkedHashMap_setUsedData:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StoreInstanceField(TokenPosition::kNoSource,
- Slot::LinkedHashMap_used_data(),
- kNoStoreBarrier);
- code_ += B->NullConstant();
- break;
- case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
- ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
- code_ += B->LoadNativeField(Slot::LinkedHashMap_deleted_keys());
- break;
- case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
- ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
- code_ += B->StoreInstanceField(TokenPosition::kNoSource,
- Slot::LinkedHashMap_deleted_keys(),
- kNoStoreBarrier);
- code_ += B->NullConstant();
- break;
- default: {
- B->InlineBailout("BytecodeFlowGraphBuilder::BuildNativeCall");
- const auto& name = String::ZoneHandle(Z, function().native_name());
- const intptr_t num_args =
- function().NumParameters() + (function().IsGeneric() ? 1 : 0);
- ArgumentArray arguments = GetArguments(num_args);
- auto* call =
- new (Z) NativeCallInstr(&name, &function(), FLAG_link_natives_lazily,
- function().end_token_pos(), arguments);
- code_ <<= call;
- B->Push(call);
- break;
- }
- }
+ const auto& name = String::ZoneHandle(Z, function().native_name());
+ const intptr_t num_args =
+ function().NumParameters() + (function().IsGeneric() ? 1 : 0);
+ ArgumentArray arguments = GetArguments(num_args);
+ auto* call =
+ new (Z) NativeCallInstr(&name, &function(), FLAG_link_natives_lazily,
+ function().end_token_pos(), arguments);
+ code_ <<= call;
+ B->Push(call);
}
void BytecodeFlowGraphBuilder::BuildAllocate() {
@@ -1726,6 +1566,22 @@
code_ += B->AllocateClosure(position_, target);
}
+// Builds graph for a call to 'dart:ffi::_asFunctionInternal'. The stack must
+// look like:
+//
+// <receiver> => pointer argument
+// <type arguments vector> => signatures
+// ...
+void BytecodeFlowGraphBuilder::BuildFfiAsFunction() {
+ // The bytecode FGB doesn't eagerly insert PushArguments, so the type
+ // arguments won't be wrapped in a PushArgumentsInstr.
+ const TypeArguments& type_args =
+ TypeArguments::Cast(B->Peek(/*depth=*/1)->AsConstant()->value());
+ // Drop type arguments, preserving pointer.
+ code_ += B->DropTempsPreserveTop(1);
+ code_ += B->BuildFfiAsFunctionInternalCall(type_args);
+}
+
static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) {
return false;
@@ -1804,16 +1660,13 @@
bool BytecodeFlowGraphBuilder::RequiresScratchVar(const KBCInstr* instr) {
switch (KernelBytecode::DecodeOpcode(instr)) {
case KernelBytecode::kEntryOptional:
- case KernelBytecode::kEntryOptional_Old:
return KernelBytecode::DecodeC(instr) > 0;
case KernelBytecode::kEqualsNull:
- case KernelBytecode::kEqualsNull_Old:
return true;
case KernelBytecode::kNativeCall:
case KernelBytecode::kNativeCall_Wide:
- case KernelBytecode::kNativeCall_Old:
return MethodRecognizer::RecognizeKind(function()) ==
MethodRecognizer::kListFactory;
@@ -1900,6 +1753,25 @@
}
}
+void BytecodeFlowGraphBuilder::CreateParameterVariables() {
+ const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
+ object_pool_ = bytecode.object_pool();
+ bytecode_instr_ = reinterpret_cast<const KBCInstr*>(bytecode.PayloadStart());
+
+ if (KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_)) {
+ scratch_var_ = parsed_function_->EnsureExpressionTemp();
+ AllocateParametersAndLocalsForEntryOptional();
+ } else if (KernelBytecode::IsEntryOpcode(bytecode_instr_)) {
+ AllocateLocalVariables(DecodeOperandD());
+ AllocateFixedParameters();
+ } else if (KernelBytecode::IsEntryFixedOpcode(bytecode_instr_)) {
+ AllocateLocalVariables(DecodeOperandE());
+ AllocateFixedParameters();
+ } else {
+ UNREACHABLE();
+ }
+}
+
FlowGraph* BytecodeFlowGraphBuilder::BuildGraph() {
const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 833deb2..e03a502 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -44,6 +44,9 @@
FlowGraph* BuildGraph();
+ // Create parameter variables without building a flow graph.
+ void CreateParameterVariables();
+
protected:
// Returns `true` if building a flow graph for a bytecode interpreter, or
// `false` if compiling a function from bytecode.
@@ -122,6 +125,12 @@
LocalVariable* AllocateParameter(intptr_t param_index,
VariableIndex var_index);
void AllocateFixedParameters();
+
+ // Allocates parameters and local variables in case of EntryOptional.
+ // Returns pointer to the instruction after EntryOptional/LoadConstant/Frame
+ // bytecodes.
+ const KBCInstr* AllocateParametersAndLocalsForEntryOptional();
+
LocalVariable* LocalVariableAt(intptr_t local_index);
void StoreLocal(Operand local_index);
void LoadLocal(Operand local_index);
@@ -141,6 +150,7 @@
void BuildInterfaceCallCommon(bool is_unchecked_call);
void BuildInstruction(KernelBytecode::Opcode opcode);
+ void BuildFfiAsFunction();
#define DECLARE_BUILD_METHOD(name, encoding, kind, op1, op2, op3) \
void Build##name();
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 5d3ba7d..660375c 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -137,7 +137,7 @@
&Array::Handle(helper_->zone_, GetBytecodeComponent()));
BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
AlternativeReadingScope alt(&bytecode_reader.reader(),
- library.bytecode_offset());
+ bytecode_component.GetLibraryIndexOffset());
bytecode_reader.FindAndReadSpecificLibrary(
library, bytecode_component.GetNumLibraries());
}
@@ -472,6 +472,9 @@
const int kHasOptionalNamedParamsFlag = 1 << 1;
const int kHasTypeParamsFlag = 1 << 2;
const int kHasSourcePositionsFlag = 1 << 3;
+ const int kIsAsyncFlag = 1 << 4;
+ const int kIsAsyncStarFlag = 1 << 5;
+ const int kIsSyncStarFlag = 1 << 6;
const intptr_t flags = reader_.ReadUInt();
@@ -499,6 +502,19 @@
closure.set_is_declared_in_bytecode(true);
closure.set_end_token_pos(end_position);
+ if ((flags & kIsSyncStarFlag) != 0) {
+ closure.set_modifier(RawFunction::kSyncGen);
+ } else if ((flags & kIsAsyncFlag) != 0) {
+ closure.set_modifier(RawFunction::kAsync);
+ closure.set_is_inlinable(!FLAG_causal_async_stacks);
+ } else if ((flags & kIsAsyncStarFlag) != 0) {
+ closure.set_modifier(RawFunction::kAsyncGen);
+ closure.set_is_inlinable(!FLAG_causal_async_stacks);
+ }
+ if (Function::Cast(parent).IsAsyncOrGenerator()) {
+ closure.set_is_generated_body(true);
+ }
+
closures_->SetAt(closureIndex, closure);
Type& signature_type = Type::Handle(
@@ -511,6 +527,35 @@
closure.SetSignatureType(signature_type);
}
+static bool IsNonCanonical(const AbstractType& type) {
+ return type.IsTypeRef() || (type.IsType() && !type.IsCanonical());
+}
+
+static bool HasNonCanonicalTypes(Zone* zone, const Function& func) {
+ auto& type = AbstractType::Handle(zone);
+ for (intptr_t i = 0; i < func.NumParameters(); ++i) {
+ type = func.ParameterTypeAt(i);
+ if (IsNonCanonical(type)) {
+ return true;
+ }
+ }
+ type = func.result_type();
+ if (IsNonCanonical(type)) {
+ return true;
+ }
+ const auto& type_params = TypeArguments::Handle(zone, func.type_parameters());
+ if (!type_params.IsNull()) {
+ for (intptr_t i = 0; i < type_params.Length(); ++i) {
+ type = type_params.TypeAt(i);
+ type = TypeParameter::Cast(type).bound();
+ if (IsNonCanonical(type)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
RawType* BytecodeReaderHelper::ReadFunctionSignature(
const Function& func,
bool has_optional_positional_params,
@@ -565,7 +610,14 @@
// Finalize function type.
type = func.SignatureType();
- type = ClassFinalizer::FinalizeType(*(active_class_->klass), type);
+ ClassFinalizer::FinalizationKind finalization = ClassFinalizer::kCanonicalize;
+ if (pending_recursive_types_ != nullptr && HasNonCanonicalTypes(Z, func)) {
+ // This function type is a part of recursive type. Avoid canonicalization
+ // as not all TypeRef objects are filled up at this point.
+ finalization = ClassFinalizer::kFinalize;
+ }
+ type =
+ ClassFinalizer::FinalizeType(*(active_class_->klass), type, finalization);
return Type::Cast(type).raw();
}
@@ -809,15 +861,8 @@
TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
"BytecodeReaderHelper::ReadBytecode");
#endif // defined(SUPPORT_TIMELINE)
- intptr_t size = reader_.ReadUInt();
- intptr_t offset = reader_.offset();
-
- static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
- if (bytecode_component_->GetVersion() < 7) {
- const intptr_t kAlignment = 4;
- offset = Utils::RoundUp(offset, kAlignment);
- }
+ const intptr_t size = reader_.ReadUInt();
+ const intptr_t offset = reader_.offset();
const uint8_t* data = reader_.BufferAt(offset);
reader_.set_offset(offset + size);
@@ -843,10 +888,6 @@
ExceptionHandlerList* exception_handlers_list =
new (Z) ExceptionHandlerList();
- static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
- const int kPCShifter = (bytecode_component_->GetVersion() < 7) ? 2 : 0;
-
// Encoding of ExceptionsTable is described in
// pkg/vm/lib/bytecode/exceptions.dart.
for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
@@ -854,13 +895,13 @@
intptr_t outer_try_index = outer_try_index_plus1 - 1;
// PcDescriptors are expressed in terms of return addresses.
intptr_t start_pc =
- KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+ KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
/* is_return_address = */ true);
intptr_t end_pc =
- KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+ KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
/* is_return_address = */ true);
intptr_t handler_pc =
- KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+ KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
/* is_return_address = */ false);
uint8_t flags = reader_.ReadByte();
const uint8_t kFlagNeedsStackTrace = 1 << 0;
@@ -941,6 +982,10 @@
case MethodRecognizer::kTypedListLength:
case MethodRecognizer::kTypedListViewLength:
case MethodRecognizer::kByteDataViewLength:
+ case MethodRecognizer::kByteDataViewOffsetInBytes:
+ case MethodRecognizer::kTypedDataViewOffsetInBytes:
+ case MethodRecognizer::kByteDataViewTypedData:
+ case MethodRecognizer::kTypedDataViewTypedData:
case MethodRecognizer::kClassIDgetID:
case MethodRecognizer::kGrowableArrayCapacity:
case MethodRecognizer::kListFactory:
@@ -1015,7 +1060,6 @@
version, KernelBytecode::kMinSupportedBytecodeFormatVersion,
KernelBytecode::kMaxSupportedBytecodeFormatVersion);
}
- BytecodeReader::UseBytecodeVersion(version);
reader_.ReadUInt32(); // Skip stringTable.numItems
const intptr_t string_table_offset = start_offset + reader_.ReadUInt32();
@@ -1240,7 +1284,7 @@
}
return cls;
}
- RawClass* cls = library.LookupClassAllowPrivate(class_name);
+ RawClass* cls = library.LookupLocalClass(class_name);
NoSafepointScope no_safepoint_scope(thread_);
if (cls == Class::null()) {
FATAL2("Unable to find class %s in %s", class_name.ToCString(),
@@ -1577,10 +1621,7 @@
return AbstractType::void_type().raw();
case kSimpleType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- if (!cls.is_declaration_loaded()) {
- ASSERT(cls.is_declared_in_bytecode());
- BytecodeReader::LoadClassDeclaration(cls);
- }
+ cls.EnsureDeclarationLoaded();
return cls.DeclarationType();
}
case kTypeParameter: {
@@ -1611,10 +1652,7 @@
}
case kGenericType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- if (!cls.is_declaration_loaded()) {
- ASSERT(cls.is_declared_in_bytecode());
- BytecodeReader::LoadClassDeclaration(cls);
- }
+ cls.EnsureDeclarationLoaded();
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
const Type& type = Type::Handle(
@@ -1625,10 +1663,7 @@
case kRecursiveGenericType: {
const intptr_t id = reader_.ReadUInt();
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- if (!cls.is_declaration_loaded()) {
- ASSERT(cls.is_declared_in_bytecode());
- BytecodeReader::LoadClassDeclaration(cls);
- }
+ cls.EnsureDeclarationLoaded();
const auto saved_pending_recursive_types = pending_recursive_types_;
if (id == 0) {
pending_recursive_types_ = &GrowableObjectArray::Handle(
@@ -1639,8 +1674,10 @@
TypeRef::Handle(Z, TypeRef::New(AbstractType::null_abstract_type()));
pending_recursive_types_->Add(type_ref);
+ reading_type_arguments_of_recursive_type_ = true;
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
+ reading_type_arguments_of_recursive_type_ = false;
ASSERT(id == pending_recursive_types_->Length() - 1);
ASSERT(pending_recursive_types_->At(id) == type_ref.raw());
@@ -1651,6 +1688,11 @@
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
type_ref.set_type(type);
type.SetIsFinalized();
+ if (id != 0) {
+ // Do not canonicalize non-root recursive types
+ // as not all TypeRef objects are filled up at this point.
+ return type.raw();
+ }
return type.Canonicalize();
}
case kRecursiveTypeRef: {
@@ -1766,6 +1808,8 @@
}
RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments() {
+ const bool is_recursive = reading_type_arguments_of_recursive_type_;
+ reading_type_arguments_of_recursive_type_ = false;
const intptr_t length = reader_.ReadUInt();
TypeArguments& type_arguments =
TypeArguments::ZoneHandle(Z, TypeArguments::New(length));
@@ -1774,6 +1818,14 @@
type ^= ReadObject();
type_arguments.SetTypeAt(i, type);
}
+ if (is_recursive) {
+ // Avoid canonicalization of type arguments of recursive type
+ // as not all TypeRef objects are filled up at this point.
+ // Type arguments will be canoncialized when the root recursive
+ // type is canonicalized.
+ ASSERT(pending_recursive_types_ != nullptr);
+ return type_arguments.raw();
+ }
return type_arguments.Canonicalize();
}
@@ -2217,22 +2269,28 @@
// Its cid is set in Class::New / Isolate::RegisterClass /
// ClassTable::Register, unless it was loaded for expression evaluation.
ASSERT(cls.is_declared_in_bytecode());
- ASSERT(!cls.is_declaration_loaded());
+ ASSERT(!cls.is_declaration_loaded() || loading_native_wrappers_library_);
const intptr_t flags = reader_.ReadUInt();
const bool has_pragma = (flags & kHasPragmaFlag) != 0;
// Set early to enable access to type_parameters().
- cls.set_is_declaration_loaded();
+ // TODO(alexmarkov): revise early stamping of native wrapper classes
+ // as loaded.
+ if (!cls.is_declaration_loaded()) {
+ cls.set_is_declaration_loaded();
+ }
const auto& script = Script::CheckedHandle(Z, ReadObject());
cls.set_script(script);
TokenPosition position = TokenPosition::kNoSource;
+ TokenPosition end_position = TokenPosition::kNoSource;
if ((flags & kHasSourcePositionsFlag) != 0) {
position = reader_.ReadPosition();
- reader_.ReadPosition(); // end_position
+ end_position = reader_.ReadPosition();
cls.set_token_pos(position);
+ cls.set_end_token_pos(end_position);
}
cls.set_has_pragma(has_pragma);
@@ -2288,13 +2346,6 @@
library.AddClassMetadata(cls, top_level_class, TokenPosition::kNoSource,
0, annotations_offset);
- if (has_pragma) {
- // TODO(alexmarkov): read annotations right away using
- // annotations_offset.
- NoOOBMessageScope no_msg_scope(thread_);
- NoReloadScope no_reload_scope(thread_->isolate(), thread_);
- library.GetMetadata(cls);
- }
}
}
}
@@ -2304,7 +2355,11 @@
bytecode_component_->GetMembersOffset());
// All types are finalized if loading from bytecode.
- cls.set_is_type_finalized();
+ // TODO(alexmarkov): revise early stamping of native wrapper classes
+ // as type-finalized.
+ if (!cls.is_type_finalized()) {
+ cls.set_is_type_finalized();
+ }
// TODO(alexmarkov): move this to class finalization.
ClassFinalizer::RegisterClassInHierarchy(Z, cls);
@@ -2316,6 +2371,7 @@
// pkg/vm/lib/bytecode/declarations.dart.
const int kUsesDartMirrorsFlag = 1 << 0;
const int kUsesDartFfiFlag = 1 << 1;
+ const int kHasExtensionsFlag = 1 << 2;
ASSERT(library.is_declared_in_bytecode());
ASSERT(!library.Loaded());
@@ -2342,6 +2398,28 @@
const auto& script = Script::CheckedHandle(Z, ReadObject());
+ if ((flags & kHasExtensionsFlag) != 0) {
+ const intptr_t num_extensions = reader_.ReadUInt();
+ auto& import_namespace = Namespace::Handle(Z);
+ auto& native_library = Library::Handle(Z);
+ for (intptr_t i = 0; i < num_extensions; ++i) {
+ name ^= ReadObject();
+ ASSERT(name.StartsWith(Symbols::DartExtensionScheme()));
+
+ // Create a dummy library and add it as an import to the current library.
+ // Actual loading occurs in KernelLoader::LoadNativeExtensionLibraries().
+ // This also allows later to discover and reload this native extension,
+ // e.g. when running from an app-jit snapshot.
+ // See Loader::ReloadNativeExtensions(...) which relies on
+ // Dart_GetImportsOfScheme('dart-ext').
+ native_library = Library::New(name);
+ import_namespace = Namespace::New(native_library, Array::null_array(),
+ Array::null_array());
+ library.AddImport(import_namespace);
+ }
+ H.AddPotentialExtensionLibrary(library);
+ }
+
// The bootstrapper will take care of creating the native wrapper classes,
// but we will add the synthetic constructors to them here.
if (name.raw() ==
@@ -2373,10 +2451,11 @@
}
} else {
if (lookup_classes) {
- cls = library.LookupClassAllowPrivate(name);
+ cls = library.LookupLocalClass(name);
}
if (lookup_classes && !cls.IsNull()) {
- ASSERT(!cls.is_declaration_loaded());
+ ASSERT(!cls.is_declaration_loaded() ||
+ loading_native_wrappers_library_);
cls.set_script(script);
} else {
cls = Class::New(library, name, script, TokenPosition::kNoSource,
@@ -2389,6 +2468,13 @@
cls.set_is_declared_in_bytecode(true);
cls.set_bytecode_offset(class_offset);
+
+ if (loading_native_wrappers_library_ || !register_class) {
+ AlternativeReadingScope alt(&reader_, class_offset);
+ ReadClassDeclaration(cls);
+ AlternativeReadingScope alt2(&reader_, cls.bytecode_offset());
+ ReadMembers(cls, /* discard_fields = */ false);
+ }
}
ASSERT(!library.Loaded());
@@ -3064,7 +3150,6 @@
function.token_pos() <= var_info.end_pos) ||
(function.token_pos() <= var_info.begin_pos &&
var_info.begin_pos <= function.end_token_pos()))) {
- var_info.scope_id++; // One level higher in the context chain.
vars.Add(
VarDesc{&String::Handle(zone, parent_vars.GetName(i)), var_info});
}
@@ -3093,6 +3178,7 @@
desc.info.scope_id = scope_id;
if (local_vars.Index() < 0) {
// Parameter
+ ASSERT(local_vars.Index() < -kKBCParamEndSlotFromFp);
desc.info.set_index(-local_vars.Index() - kKBCParamEndSlotFromFp);
} else {
desc.info.set_index(-local_vars.Index());
@@ -3132,28 +3218,6 @@
}
#endif // !defined(PRODUCT)
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
-void BytecodeReader::UseBytecodeVersion(intptr_t version) {
- Isolate* isolate = Isolate::Current();
- bool using_old = isolate->is_using_old_bytecode_instructions();
- bool using_new = isolate->is_using_new_bytecode_instructions();
- if (version < 7) {
- using_old = true;
- isolate->set_is_using_old_bytecode_instructions(true);
- } else {
- using_new = true;
- isolate->set_is_using_new_bytecode_instructions(true);
- }
-
- if (using_old && using_new) {
- FATAL1(
- "Unable to use both new and old bytecode instructions in the same Dart "
- "isolate (%s)",
- isolate->name());
- }
-}
-
bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
Zone* zone) {
ASSERT(function.kind() == RawFunction::kImplicitStaticGetter);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 1a8440c..386dece 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -225,6 +225,7 @@
Class& scoped_function_class_;
Library* expression_evaluation_library_ = nullptr;
bool loading_native_wrappers_library_ = false;
+ bool reading_type_arguments_of_recursive_type_ = false;
DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper);
};
@@ -326,20 +327,19 @@
const Function& function,
const Bytecode& bytecode);
#endif
-
- static void UseBytecodeVersion(intptr_t version);
};
class BytecodeSourcePositionsIterator : ValueObject {
public:
+ // This constant should match corresponding constant in class SourcePositions
+ // (pkg/vm/lib/bytecode/source_positions.dart).
+ static const intptr_t kYieldPointMarker = -2;
+
BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode)
: reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))) {
if (bytecode.HasSourcePositions()) {
reader_.set_offset(bytecode.source_positions_binary_offset());
pairs_remaining_ = reader_.ReadUInt();
- if (Isolate::Current()->is_using_old_bytecode_instructions()) {
- pc_shifter_ = 2;
- }
}
}
@@ -349,8 +349,14 @@
}
ASSERT(pairs_remaining_ > 0);
--pairs_remaining_;
- cur_bci_ += reader_.ReadUInt() << pc_shifter_;
+ cur_bci_ += reader_.ReadUInt();
cur_token_pos_ += reader_.ReadSLEB128();
+ is_yield_point_ = false;
+ if (cur_token_pos_ == kYieldPointMarker) {
+ const bool result = MoveNext();
+ is_yield_point_ = true;
+ return result;
+ }
return true;
}
@@ -358,12 +364,14 @@
TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
+ bool IsYieldPoint() const { return is_yield_point_; }
+
private:
Reader reader_;
intptr_t pairs_remaining_ = 0;
- intptr_t pc_shifter_ = 0;
intptr_t cur_bci_ = 0;
intptr_t cur_token_pos_ = 0;
+ bool is_yield_point_ = false;
};
#if !defined(PRODUCT)
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index a69ee37..669bdae 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -168,10 +168,12 @@
EvaluateNullLiteral();
break;
case kConstantExpression:
- EvaluateConstantExpression(tag);
+ helper_->ReadPosition();
+ helper_->SkipDartType();
+ result_ = EvaluateConstantExpression(helper_->ReadUInt());
break;
case kDeprecated_ConstantExpression:
- EvaluateConstantExpression(tag);
+ result_ = EvaluateConstantExpression(helper_->ReadUInt());
break;
default:
H.ReportError(
@@ -291,6 +293,245 @@
return metadata_values.raw();
}
+RawInstance* ConstantEvaluator::EvaluateConstantExpression(
+ intptr_t constant_offset) {
+ ASSERT(!H.constants().IsNull());
+ ASSERT(!H.constants_table().IsNull()); // raw bytes
+
+ // For kernel-level cache (in contrast with script-level caching),
+ // we need to access the raw constants array inside the shared
+ // KernelProgramInfo directly, so that all scripts will see the
+ // results after new insertions. These accesses at kernel-level
+ // must be locked since mutator and background compiler can
+ // access the array at the same time.
+ {
+ SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+ KernelConstantsMap constant_map(H.info().constants());
+ result_ ^= constant_map.GetOrNull(constant_offset);
+ ASSERT(constant_map.Release().raw() == H.info().constants());
+ }
+
+ // On miss, evaluate, and insert value.
+ if (result_.IsNull()) {
+ result_ = EvaluateConstant(constant_offset);
+ SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+ KernelConstantsMap constant_map(H.info().constants());
+ auto insert = constant_map.InsertNewOrGetValue(constant_offset, result_);
+ ASSERT(insert == result_.raw());
+ H.info().set_constants(constant_map.Release()); // update!
+ }
+ return result_.raw();
+}
+
+RawInstance* ConstantEvaluator::EvaluateConstant(intptr_t constant_offset) {
+ // Get reader directly into raw bytes of constant table.
+ KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
+ reader.ReadUInt(); // skip variable-sized int for adjusted constant offset
+ reader.SetOffset(reader.ReaderOffset() + constant_offset);
+ // Construct constant from raw bytes.
+ Instance& instance = Instance::Handle(Z);
+ const intptr_t constant_tag = reader.ReadByte();
+ switch (constant_tag) {
+ case kNullConstant:
+ instance = Instance::null();
+ break;
+ case kBoolConstant:
+ instance = reader.ReadByte() == 1 ? Object::bool_true().raw()
+ : Object::bool_false().raw();
+ break;
+ case kIntConstant: {
+ uint8_t payload = 0;
+ Tag integer_tag = reader.ReadTag(&payload); // read tag.
+ switch (integer_tag) {
+ case kBigIntLiteral: {
+ const String& value = H.DartString(reader.ReadStringReference());
+ instance = Integer::New(value, Heap::kOld);
+ break;
+ }
+ case kSpecializedIntLiteral: {
+ const int64_t value =
+ static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
+ instance = Integer::New(value, Heap::kOld);
+ break;
+ }
+ case kNegativeIntLiteral: {
+ const int64_t value = -static_cast<int64_t>(reader.ReadUInt());
+ instance = Integer::New(value, Heap::kOld);
+ break;
+ }
+ case kPositiveIntLiteral: {
+ const int64_t value = reader.ReadUInt();
+ instance = Integer::New(value, Heap::kOld);
+ break;
+ }
+ default:
+ H.ReportError(
+ script_, TokenPosition::kNoSource,
+ "Cannot lazily read integer: unexpected kernel tag %s (%d)",
+ Reader::TagName(integer_tag), integer_tag);
+ }
+ break;
+ }
+ case kDoubleConstant:
+ instance = Double::New(reader.ReadDouble(), Heap::kOld);
+ break;
+ case kStringConstant:
+ instance = H.DartSymbolPlain(reader.ReadStringReference()).raw();
+ break;
+ case kSymbolConstant: {
+ Library& library = Library::Handle(Z);
+ library = Library::InternalLibrary();
+ const auto& symbol_class =
+ Class::Handle(Z, library.LookupClass(Symbols::Symbol()));
+ const auto& symbol_name_field = Field::Handle(
+ Z, symbol_class.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+ ASSERT(!symbol_name_field.IsNull());
+ const NameIndex index = reader.ReadCanonicalNameReference();
+ if (index == -1) {
+ library = Library::null();
+ } else {
+ library = H.LookupLibraryByKernelLibrary(index);
+ }
+ const String& symbol =
+ H.DartIdentifier(library, reader.ReadStringReference());
+ instance = Instance::New(symbol_class, Heap::kOld);
+ instance.SetField(symbol_name_field, symbol);
+ break;
+ }
+ case kListConstant: {
+ const auto& corelib = Library::Handle(Z, Library::CoreLibrary());
+ const auto& list_class =
+ Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
+ // Build type from the raw bytes (needs temporary translator).
+ TypeTranslator type_translator(&reader, active_class_, true);
+ auto& type_arguments =
+ TypeArguments::Handle(Z, TypeArguments::New(1, Heap::kOld));
+ AbstractType& type = type_translator.BuildType();
+ type_arguments.SetTypeAt(0, type);
+ // Instantiate class.
+ type = Type::New(list_class, type_arguments, TokenPosition::kNoSource);
+ type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+ ClassFinalizer::kCanonicalize);
+ type_arguments = type.arguments();
+ // Fill array with constant elements.
+ const intptr_t length = reader.ReadUInt();
+ const Array& array =
+ Array::Handle(Z, ImmutableArray::New(length, Heap::kOld));
+ array.SetTypeArguments(type_arguments);
+ Instance& constant = Instance::Handle(Z);
+ for (intptr_t j = 0; j < length; ++j) {
+ // Recurse into lazily evaluating all "sub" constants
+ // needed to evaluate the current constant.
+ const intptr_t entry_offset = reader.ReadUInt();
+ ASSERT(entry_offset < constant_offset); // DAG!
+ constant = EvaluateConstantExpression(entry_offset);
+ array.SetAt(j, constant);
+ }
+ instance = array.raw();
+ break;
+ }
+ case kInstanceConstant: {
+ const NameIndex index = reader.ReadCanonicalNameReference();
+ const auto& klass = Class::Handle(Z, H.LookupClassByKernelClass(index));
+ const auto& obj = Object::Handle(Z, klass.EnsureIsFinalized(H.thread()));
+ ASSERT(obj.IsNull());
+ instance = Instance::New(klass, Heap::kOld);
+ // Build type from the raw bytes (needs temporary translator).
+ TypeTranslator type_translator(&reader, active_class_, true);
+ const intptr_t number_of_type_arguments = reader.ReadUInt();
+ if (klass.NumTypeArguments() > 0) {
+ auto& type_arguments = TypeArguments::Handle(
+ Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+ for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+ type_arguments.SetTypeAt(j, type_translator.BuildType());
+ }
+ // Instantiate class.
+ auto& type = AbstractType::Handle(
+ Z, Type::New(klass, type_arguments, TokenPosition::kNoSource));
+ type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+ ClassFinalizer::kCanonicalize);
+ type_arguments = type.arguments();
+ instance.SetTypeArguments(type_arguments);
+ } else {
+ ASSERT(number_of_type_arguments == 0);
+ }
+ // Set the fields.
+ const intptr_t number_of_fields = reader.ReadUInt();
+ Field& field = Field::Handle(Z);
+ Instance& constant = Instance::Handle(Z);
+ for (intptr_t j = 0; j < number_of_fields; ++j) {
+ field = H.LookupFieldByKernelField(reader.ReadCanonicalNameReference());
+ // Recurse into lazily evaluating all "sub" constants
+ // needed to evaluate the current constant.
+ const intptr_t entry_offset = reader.ReadUInt();
+ ASSERT(entry_offset < constant_offset); // DAG!
+ constant = EvaluateConstantExpression(entry_offset);
+ instance.SetField(field, constant);
+ }
+ break;
+ }
+ case kPartialInstantiationConstant: {
+ // Recurse into lazily evaluating the "sub" constant
+ // needed to evaluate the current constant.
+ const intptr_t entry_offset = reader.ReadUInt();
+ ASSERT(entry_offset < constant_offset); // DAG!
+ const auto& constant =
+ Instance::Handle(Z, EvaluateConstantExpression(entry_offset));
+ ASSERT(!constant.IsNull());
+
+ // Build type from the raw bytes (needs temporary translator).
+ TypeTranslator type_translator(&reader, active_class_, true);
+ const intptr_t number_of_type_arguments = reader.ReadUInt();
+ ASSERT(number_of_type_arguments > 0);
+ auto& type_arguments = TypeArguments::Handle(
+ Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+ for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+ type_arguments.SetTypeAt(j, type_translator.BuildType());
+ }
+ type_arguments = type_arguments.Canonicalize();
+ // Make a copy of the old closure, and set delayed type arguments.
+ Closure& closure = Closure::Handle(Z, Closure::RawCast(constant.raw()));
+ Function& function = Function::Handle(Z, closure.function());
+ const auto& type_arguments2 =
+ TypeArguments::Handle(Z, closure.instantiator_type_arguments());
+ // The function type arguments are used for type parameters from enclosing
+ // closures. Though inner closures cannot be constants. We should
+ // therefore see `null here.
+ ASSERT(closure.function_type_arguments() == TypeArguments::null());
+ Context& context = Context::Handle(Z, closure.context());
+ instance = Closure::New(type_arguments2, Object::null_type_arguments(),
+ type_arguments, function, context, Heap::kOld);
+ break;
+ }
+ case kTearOffConstant: {
+ const NameIndex index = reader.ReadCanonicalNameReference();
+ Function& function =
+ Function::Handle(Z, H.LookupStaticMethodByKernelProcedure(index));
+ function = function.ImplicitClosureFunction();
+ instance = function.ImplicitStaticClosure();
+ break;
+ }
+ case kTypeLiteralConstant: {
+ // Build type from the raw bytes (needs temporary translator).
+ TypeTranslator type_translator(&reader, active_class_, true);
+ instance = type_translator.BuildType().raw();
+ break;
+ }
+ default:
+ // Set literals (kSetConstant) are currently desugared in the frontend
+ // and will not reach the VM. See http://dartbug.com/35124 for some
+ // discussion. Map constants (kMapConstant ) are already lowered to
+ // InstanceConstant or ListConstant. We should never see unevaluated
+ // constants (kUnevaluatedConstant) in the constant table, they should
+ // have been fully evaluated before we get them.
+ H.ReportError(script_, TokenPosition::kNoSource,
+ "Cannot lazily read constant: unexpected kernel tag (%" Pd
+ ")",
+ constant_tag);
+ }
+ return H.Canonicalize(instance);
+}
+
void ConstantEvaluator::BailoutIfBackgroundCompilation() {
if (Compiler::IsBackgroundCompilation()) {
Compiler::AbortBackgroundCompilation(
@@ -331,7 +572,7 @@
TokenPosition position) {
EvaluateExpression(expression_offset);
if (result_.IsString()) {
- const String& str = String::Handle(Z, String::RawCast(result_.raw()));
+ const auto& str = String::Handle(Z, String::RawCast(result_.raw()));
result_ = Integer::New(str.Length(), H.allocation_space());
} else {
H.ReportError(
@@ -382,7 +623,7 @@
ASSERT(Error::Handle(Z, H.thread()->sticky_error()).IsNull());
if (H.IsField(target)) {
- const Field& field = Field::Handle(Z, H.LookupFieldByKernelField(target));
+ const auto& field = Field::Handle(Z, H.LookupFieldByKernelField(target));
if (!field.is_const()) {
H.ReportError(script_, position, "Not a constant field.");
}
@@ -394,7 +635,7 @@
H.ReportError(script_, position, "Not a constant expression.");
} else if (field.StaticValue() == Object::sentinel().raw()) {
field.SetStaticValue(Object::transition_sentinel());
- const Object& value = Object::Handle(Z, field.EvaluateInitializer());
+ const auto& value = Object::Handle(Z, field.EvaluateInitializer());
if (value.IsError()) {
field.SetStaticValue(Object::null_instance());
H.ReportError(Error::Cast(value), script_, position,
@@ -418,12 +659,12 @@
result_ = field.StaticValue();
}
} else if (H.IsProcedure(target)) {
- const Function& function =
- Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
+ const auto& function =
+ Function::Handle(Z, H.LookupStaticMethodByKernelProcedure(target));
if (H.IsMethod(target)) {
- Function& closure_function =
- Function::ZoneHandle(Z, function.ImplicitClosureFunction());
+ const auto& closure_function =
+ Function::Handle(Z, function.ImplicitClosureFunction());
result_ = closure_function.ImplicitStaticClosure();
result_ = H.Canonicalize(result_);
} else if (H.IsGetter(target)) {
@@ -437,7 +678,7 @@
void ConstantEvaluator::EvaluateMethodInvocation() {
TokenPosition position = helper_->ReadPosition(); // read position.
// This method call wasn't cached, so receiver et al. isn't cached either.
- const Instance& receiver = Instance::Handle(
+ const auto& receiver = Instance::Handle(
Z, EvaluateExpression(helper_->ReaderOffset(), false)); // read receiver.
Class& klass =
Class::Handle(Z, isolate_->class_table()->At(receiver.GetClassId()));
@@ -463,13 +704,13 @@
void ConstantEvaluator::EvaluateDirectMethodInvocation() {
TokenPosition position = helper_->ReadPosition(); // read position.
- const Instance& receiver = Instance::Handle(
+ const auto& receiver = Instance::Handle(
Z, EvaluateExpression(helper_->ReaderOffset(), false)); // read receiver.
NameIndex kernel_name =
helper_->ReadCanonicalNameReference(); // read target_reference.
- const Function& function = Function::ZoneHandle(
+ const auto& function = Function::Handle(
Z, H.LookupMethodByMember(kernel_name, H.DartProcedureName(kernel_name)));
// Read arguments, run the method and canonicalize the result.
@@ -493,7 +734,7 @@
ASSERT(!klass.IsNull());
const String& method_name = helper_->ReadNameAsMethodName(); // read name.
- Function& function =
+ const auto& function =
Function::Handle(Z, H.LookupDynamicFunction(klass, method_name));
// The frontend should guarantee that [MethodInvocation]s inside constant
@@ -513,7 +754,7 @@
NameIndex procedure_reference =
helper_->ReadCanonicalNameReference(); // read procedure reference.
- const Function& function = Function::ZoneHandle(
+ const auto& function = Function::Handle(
Z, H.LookupStaticMethodByKernelProcedure(procedure_reference));
Class& klass = Class::Handle(Z, function.Owner());
@@ -535,7 +776,7 @@
TokenPosition position = helper_->ReadPosition(); // read position.
NameIndex target = helper_->ReadCanonicalNameReference(); // read target.
- const Function& constructor =
+ const auto& constructor =
Function::Handle(Z, H.LookupConstructorByKernelConstructor(target));
Class& klass = Class::Handle(Z, constructor.Owner());
@@ -547,12 +788,12 @@
TranslateTypeArguments(constructor, &klass); // read argument types.
if (klass.NumTypeArguments() > 0 && !klass.IsGeneric()) {
- Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw());
+ auto& type = Type::Handle(Z, T.ReceiverType(klass).raw());
// TODO(27590): Can we move this code into [ReceiverType]?
type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type,
ClassFinalizer::kFinalize);
- TypeArguments& canonicalized_type_arguments =
- TypeArguments::ZoneHandle(Z, type.arguments());
+ auto& canonicalized_type_arguments =
+ TypeArguments::Handle(Z, type.arguments());
canonicalized_type_arguments = canonicalized_type_arguments.Canonicalize();
type_arguments = &canonicalized_type_arguments;
}
@@ -627,7 +868,7 @@
const AbstractType& type = T.BuildType();
if (!type.IsInstantiated()) {
- const String& type_str = String::Handle(type.UserVisibleName());
+ const auto& type_str = String::Handle(type.UserVisibleName());
H.ReportError(
script_, position,
"Not a constant expression: right hand side of an implicit "
@@ -635,14 +876,14 @@
type_str.ToCString());
}
- const TypeArguments& instantiator_type_arguments = TypeArguments::Handle();
- const TypeArguments& function_type_arguments = TypeArguments::Handle();
+ const auto& instantiator_type_arguments = TypeArguments::Handle();
+ const auto& function_type_arguments = TypeArguments::Handle();
if (!result_.IsInstanceOf(type, instantiator_type_arguments,
function_type_arguments)) {
const AbstractType& rtype =
AbstractType::Handle(result_.GetType(Heap::kNew));
- const String& result_str = String::Handle(rtype.UserVisibleName());
- const String& type_str = String::Handle(type.UserVisibleName());
+ const auto& result_str = String::Handle(rtype.UserVisibleName());
+ const auto& type_str = String::Handle(type.UserVisibleName());
H.ReportError(
script_, position,
"Not a constant expression: Type '%s' is not a subtype of type '%s'",
@@ -683,13 +924,13 @@
const Class& cls =
Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase()));
ASSERT(!cls.IsNull());
- const Function& func = Function::Handle(
+ const auto& func = Function::Handle(
Z, cls.LookupStaticFunction(
Library::PrivateCoreLibName(Symbols::Interpolate())));
ASSERT(!func.IsNull());
// Build argument array to pass to the interpolation function.
- const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
+ const auto& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
interpolate_arg.SetAt(0, strings);
// Run and canonicalize.
@@ -704,9 +945,9 @@
const Library& lib = Library::Handle(Z, owner.library());
String& symbol_value = H.DartIdentifier(lib, helper_->ReadStringReference());
const Class& symbol_class =
- Class::ZoneHandle(Z, I->object_store()->symbol_class());
+ Class::Handle(Z, I->object_store()->symbol_class());
ASSERT(!symbol_class.IsNull());
- const Function& symbol_constructor = Function::ZoneHandle(
+ const auto& symbol_constructor = Function::Handle(
Z, symbol_class.LookupConstructor(Symbols::SymbolCtor()));
ASSERT(!symbol_constructor.IsNull());
result_ ^= EvaluateConstConstructorCall(
@@ -722,8 +963,7 @@
helper_->ReadPosition(); // read position.
const TypeArguments& type_arguments = T.BuildTypeArguments(1); // read type.
intptr_t length = helper_->ReadListLength(); // read list length.
- const Array& const_list =
- Array::ZoneHandle(Z, Array::New(length, Heap::kOld));
+ const auto& const_list = Array::Handle(Z, Array::New(length, Heap::kOld));
const_list.SetTypeArguments(type_arguments);
Instance& expression = Instance::Handle(Z);
for (intptr_t i = 0; i < length; ++i) {
@@ -797,7 +1037,7 @@
void ConstantEvaluator::EvaluatePartialTearoffInstantiation() {
// This method call wasn't cached, so receiver et al. isn't cached either.
- const Instance& receiver = Instance::Handle(
+ const auto& receiver = Instance::Handle(
Z, EvaluateExpression(helper_->ReaderOffset(), false)); // read receiver.
if (!receiver.IsClosure()) {
H.ReportError(script_, TokenPosition::kNoSource, "Expected closure.");
@@ -868,20 +1108,6 @@
result_ = Instance::null();
}
-void ConstantEvaluator::EvaluateConstantExpression(Tag tag) {
- // Please note that this constants array is constructed exactly once, see
- // ReadConstantTable() and is immutable from that point on, so there is no
- // need to guard against concurrent access between mutator and background
- // compiler.
- KernelConstantsMap constant_map(H.constants().raw());
- if (tag == kConstantExpression) {
- helper_->ReadPosition();
- helper_->SkipDartType();
- }
- result_ ^= constant_map.GetOrDie(helper_->ReadUInt());
- ASSERT(constant_map.Release().raw() == H.constants().raw());
-}
-
// This depends on being about to read the list of positionals on arguments.
const Object& ConstantEvaluator::RunFunction(TokenPosition position,
const Function& function,
@@ -901,7 +1127,7 @@
(receiver != NULL ? 1 : 0) + (type_args != NULL ? 1 : 0);
// Build up arguments.
- const Array& arguments = Array::Handle(
+ const auto& arguments = Array::Handle(
Z, Array::New(extra_arguments + argument_count, H.allocation_space()));
intptr_t pos = 0;
if (receiver != NULL) {
@@ -941,9 +1167,9 @@
const Array& names) {
// We do not support generic methods yet.
const int kTypeArgsLen = 0;
- const Array& args_descriptor = Array::Handle(
+ const auto& args_descriptor = Array::Handle(
Z, ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length(), names));
- const Object& result = Object::Handle(
+ const auto& result = Object::Handle(
Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
if (result.IsError()) {
H.ReportError(Error::Cast(result), script_, position,
@@ -1003,7 +1229,7 @@
const Array& args_descriptor =
Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, argument_count,
Object::empty_array()));
- const Object& result = Object::Handle(
+ const auto& result = Object::Handle(
Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor));
ASSERT(!result.IsError());
if (constructor.IsFactory()) {
@@ -1093,7 +1319,7 @@
const intptr_t kInitialConstMapSize = 16;
ASSERT(!script_.InVMIsolateHeap());
if (script_.compile_time_constants() == Array::null()) {
- const Array& array = Array::Handle(
+ const auto& array = Array::Handle(
HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew));
script_.set_compile_time_constants(array);
}
@@ -1109,273 +1335,6 @@
}
}
-ConstantHelper::ConstantHelper(Zone* zone,
- KernelReaderHelper* helper,
- TypeTranslator* type_translator,
- ActiveClass* active_class,
- NameIndex skip_vmservice_library)
- : zone_(zone),
- helper_(*helper),
- type_translator_(*type_translator),
- active_class_(active_class),
- const_evaluator_(helper, type_translator, active_class, nullptr),
- translation_helper_(helper->translation_helper_),
- skip_vmservice_library_(skip_vmservice_library),
- symbol_class_(Class::Handle(zone)),
- symbol_name_field_(Field::Handle(zone)),
- temp_type_(AbstractType::Handle(zone)),
- temp_type_arguments_(TypeArguments::Handle(zone)),
- temp_type_arguments2_(TypeArguments::Handle(zone)),
- temp_type_arguments3_(TypeArguments::Handle(zone)),
- temp_object_(Object::Handle(zone)),
- temp_string_(String::Handle(zone)),
- temp_array_(Array::Handle(zone)),
- temp_instance_(Instance::Handle(zone)),
- temp_field_(Field::Handle(zone)),
- temp_class_(Class::Handle(zone)),
- temp_library_(Library::Handle(zone)),
- temp_function_(Function::Handle(zone)),
- temp_closure_(Closure::Handle(zone)),
- temp_context_(Context::Handle(zone)),
- temp_integer_(Integer::Handle(zone)) {
- temp_library_ = Library::InternalLibrary();
- ASSERT(!temp_library_.IsNull());
-
- symbol_class_ = temp_library_.LookupClass(Symbols::Symbol());
- ASSERT(!symbol_class_.IsNull());
-
- symbol_name_field_ =
- symbol_class_.LookupInstanceFieldAllowPrivate(Symbols::_name());
- ASSERT(!symbol_name_field_.IsNull());
-}
-
-const Array& ConstantHelper::ReadConstantTable() {
- const intptr_t number_of_constants = helper_.ReadUInt();
- if (number_of_constants == 0) {
- return Array::empty_array();
- }
-
- const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
- const Class& list_class =
- Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
-
- // Eagerly finalize _ImmutableList (instead of doing it on every list
- // constant).
- temp_class_ = I->class_table()->At(kImmutableArrayCid);
- temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
- ASSERT(temp_object_.IsNull());
-
- KernelConstantsMap constants(
- HashTables::New<KernelConstantsMap>(number_of_constants, Heap::kOld));
-
- const intptr_t start_offset = helper_.ReaderOffset();
-
- for (intptr_t i = 0; i < number_of_constants; ++i) {
- const intptr_t offset = helper_.ReaderOffset();
- const intptr_t constant_tag = helper_.ReadByte();
- switch (constant_tag) {
- case kNullConstant:
- temp_instance_ = Instance::null();
- break;
- case kBoolConstant:
- temp_instance_ = helper_.ReadByte() == 1 ? Object::bool_true().raw()
- : Object::bool_false().raw();
- break;
- case kIntConstant: {
- temp_instance_ = const_evaluator_.EvaluateExpression(
- helper_.ReaderOffset(), false /* reset position */);
- break;
- }
- case kDoubleConstant: {
- temp_instance_ = Double::New(helper_.ReadDouble(), Heap::kOld);
- temp_instance_ = H.Canonicalize(temp_instance_);
- break;
- }
- case kStringConstant: {
- temp_instance_ =
- H.Canonicalize(H.DartString(helper_.ReadStringReference()));
- break;
- }
- case kSymbolConstant: {
- const NameIndex index = helper_.ReadCanonicalNameReference();
- if (index == -1) {
- temp_library_ = Library::null();
- } else {
- temp_library_ = H.LookupLibraryByKernelLibrary(index);
- }
- const String& symbol =
- H.DartIdentifier(temp_library_, helper_.ReadStringReference());
- temp_instance_ = Instance::New(symbol_class_, Heap::kOld);
- temp_instance_.SetField(symbol_name_field_, symbol);
- temp_instance_ = H.Canonicalize(temp_instance_);
- break;
- }
- case kListConstant: {
- temp_type_arguments_ = TypeArguments::New(1, Heap::kOld);
- const AbstractType& type = type_translator_.BuildType();
- temp_type_arguments_.SetTypeAt(0, type);
- InstantiateTypeArguments(list_class, &temp_type_arguments_);
-
- const intptr_t length = helper_.ReadUInt();
- temp_array_ = ImmutableArray::New(length, Heap::kOld);
- temp_array_.SetTypeArguments(temp_type_arguments_);
- for (intptr_t j = 0; j < length; ++j) {
- const intptr_t entry_offset = helper_.ReadUInt();
- ASSERT(entry_offset < (offset - start_offset)); // We have a DAG!
- temp_object_ = constants.GetOrDie(entry_offset);
- temp_array_.SetAt(j, temp_object_);
- }
-
- temp_instance_ = H.Canonicalize(temp_array_);
- break;
- }
- case kSetConstant:
- // Set literals are currently desugared in the frontend and will not
- // reach the VM. See http://dartbug.com/35124 for discussion.
- H.ReportError(script(), TokenPosition::kNoSource,
- "Unexpected set constant, this constant"
- " is expected to be evaluated at this point (%" Pd ")",
- constant_tag);
- break;
- case kInstanceConstant: {
- const NameIndex index = helper_.ReadCanonicalNameReference();
- if (ShouldSkipConstant(index)) {
- temp_instance_ = Instance::null();
- break;
- }
-
- temp_class_ = H.LookupClassByKernelClass(index);
- temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
- ASSERT(temp_object_.IsNull());
-
- temp_instance_ = Instance::New(temp_class_, Heap::kOld);
-
- const intptr_t number_of_type_arguments = helper_.ReadUInt();
- if (temp_class_.NumTypeArguments() > 0) {
- temp_type_arguments_ =
- TypeArguments::New(number_of_type_arguments, Heap::kOld);
- for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
- temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
- }
- InstantiateTypeArguments(temp_class_, &temp_type_arguments_);
- temp_instance_.SetTypeArguments(temp_type_arguments_);
- } else {
- ASSERT(number_of_type_arguments == 0);
- }
-
- const intptr_t number_of_fields = helper_.ReadUInt();
- for (intptr_t j = 0; j < number_of_fields; ++j) {
- temp_field_ =
- H.LookupFieldByKernelField(helper_.ReadCanonicalNameReference());
- const intptr_t entry_offset = helper_.ReadUInt();
- ASSERT(entry_offset < (offset - start_offset)); // We have a DAG!
- temp_object_ = constants.GetOrDie(entry_offset);
- temp_instance_.SetField(temp_field_, temp_object_);
- }
-
- temp_instance_ = H.Canonicalize(temp_instance_);
- break;
- }
- case kPartialInstantiationConstant: {
- const intptr_t entry_offset = helper_.ReadUInt();
- ASSERT(entry_offset < (offset - start_offset)); // We have a DAG!
- temp_object_ = constants.GetOrDie(entry_offset);
-
- // Happens if the tearoff was in the vmservice library and we have
- // [skip_vm_service_library] enabled.
- if (temp_object_.IsNull()) {
- temp_instance_ = Instance::null();
- break;
- }
-
- const intptr_t number_of_type_arguments = helper_.ReadUInt();
- ASSERT(number_of_type_arguments > 0);
- temp_type_arguments_ =
- TypeArguments::New(number_of_type_arguments, Heap::kOld);
- for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
- temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
- }
- temp_type_arguments_ = temp_type_arguments_.Canonicalize();
-
- // Make a copy of the old closure, with the delayed type arguments
- // set to [temp_type_arguments_].
- temp_closure_ = Closure::RawCast(temp_object_.raw());
- temp_function_ = temp_closure_.function();
- temp_type_arguments2_ = temp_closure_.instantiator_type_arguments();
- temp_type_arguments3_ = temp_closure_.function_type_arguments();
- temp_context_ = temp_closure_.context();
- temp_closure_ = Closure::New(
- temp_type_arguments2_, Object::null_type_arguments(),
- temp_type_arguments_, temp_function_, temp_context_, Heap::kOld);
- temp_instance_ = H.Canonicalize(temp_closure_);
- break;
- }
- case kTearOffConstant: {
- const NameIndex index = helper_.ReadCanonicalNameReference();
- if (ShouldSkipConstant(index)) {
- temp_instance_ = Instance::null();
- break;
- }
-
- temp_function_ = H.LookupStaticMethodByKernelProcedure(index);
- temp_function_ = temp_function_.ImplicitClosureFunction();
- temp_instance_ = temp_function_.ImplicitStaticClosure();
- temp_instance_ = H.Canonicalize(temp_instance_);
- break;
- }
- case kTypeLiteralConstant: {
- temp_instance_ = type_translator_.BuildType().raw();
- break;
- }
- case kMapConstant:
- // Note: This is already lowered to InstanceConstant/ListConstant.
- H.ReportError(script(), TokenPosition::kNoSource,
- "Unexpected map constant, this constant"
- " is expected to be evaluated at this point (%" Pd ")",
- constant_tag);
- break;
- case kUnevaluatedConstant:
- // We should not see unevaluated constants in the constant table, they
- // should have been fully evaluated before we get them.
- H.ReportError(
- script(), TokenPosition::kNoSource,
- "Unexpected unevaluated constant, All constant expressions"
- " are expected to be evaluated at this point (%" Pd ")",
- constant_tag);
- break;
- default:
- UNREACHABLE();
- }
- constants.InsertNewOrGetValue(offset - start_offset, temp_instance_);
- }
- return Array::Handle(Z, constants.Release().raw());
-}
-
-void ConstantHelper::InstantiateTypeArguments(const Class& receiver_class,
- TypeArguments* type_arguments) {
- // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
- // finalize the argument types.
- // (This can for example make the [type_arguments] vector larger)
- temp_type_ =
- Type::New(receiver_class, *type_arguments, TokenPosition::kNoSource);
- temp_type_ = ClassFinalizer::FinalizeType(*active_class_->klass, temp_type_,
- ClassFinalizer::kCanonicalize);
- *type_arguments = temp_type_.arguments();
-}
-
-// If [index] has `dart:vm_service` as a parent and we are skipping the VM
-// service library, this method returns `true`, otherwise `false`.
-bool ConstantHelper::ShouldSkipConstant(NameIndex index) {
- if (index == NameIndex::kInvalidName) {
- return false;
- }
- while (!H.IsLibrary(index)) {
- index = H.CanonicalNameParent(index);
- }
- ASSERT(H.IsLibrary(index));
- return index == skip_vmservice_library_;
-}
-
} // namespace kernel
} // namespace dart
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.h b/runtime/vm/compiler/frontend/constant_evaluator.h
index 0483baa..7981835 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.h
+++ b/runtime/vm/compiler/frontend/constant_evaluator.h
@@ -56,7 +56,13 @@
RawObject* EvaluateExpressionSafe(intptr_t offset);
RawObject* EvaluateAnnotations();
+ // Evaluates a constant at the given offset (possibly by recursing
+ // into sub-constants).
+ RawInstance* EvaluateConstantExpression(intptr_t constant_offset);
+
private:
+ RawInstance* EvaluateConstant(intptr_t constant_offset);
+
void BailoutIfBackgroundCompilation();
bool IsBuildingFlowGraph() const;
@@ -88,7 +94,6 @@
void EvaluateDoubleLiteral();
void EvaluateBoolLiteral(bool value);
void EvaluateNullLiteral();
- void EvaluateConstantExpression(Tag tag);
void EvaluateGetStringLength(intptr_t expression_offset,
TokenPosition position);
@@ -140,59 +145,6 @@
DISALLOW_COPY_AND_ASSIGN(ConstantEvaluator);
};
-// Helper class that reads a kernel Constant from binary.
-class ConstantHelper {
- public:
- ConstantHelper(Zone* zone,
- KernelReaderHelper* helper,
- TypeTranslator* type_translator,
- ActiveClass* active_class,
- NameIndex skip_vmservice_library);
-
- // Reads the constant table from the binary.
- //
- // This method assumes the Reader is positioned already at the constant table
- // and an active class scope is setup.
- const Array& ReadConstantTable();
-
- private:
- const Script& script() const { return helper_.script_; }
-
- void InstantiateTypeArguments(const Class& receiver_class,
- TypeArguments* type_arguments);
-
- // If [index] has `dart:vm_service` as a parent and we are skipping the VM
- // service library, this method returns `true`, otherwise `false`.
- bool ShouldSkipConstant(NameIndex index);
-
- Zone* zone_;
- KernelReaderHelper& helper_;
- TypeTranslator& type_translator_;
- ActiveClass* const active_class_;
- ConstantEvaluator const_evaluator_;
- TranslationHelper& translation_helper_;
- NameIndex skip_vmservice_library_;
- Class& symbol_class_;
- Field& symbol_name_field_;
- AbstractType& temp_type_;
- TypeArguments& temp_type_arguments_;
- TypeArguments& temp_type_arguments2_;
- TypeArguments& temp_type_arguments3_;
- Object& temp_object_;
- String& temp_string_;
- Array& temp_array_;
- Instance& temp_instance_;
- Field& temp_field_;
- Class& temp_class_;
- Library& temp_library_;
- Function& temp_function_;
- Closure& temp_closure_;
- Context& temp_context_;
- Integer& temp_integer_;
-
- DISALLOW_COPY_AND_ASSIGN(ConstantHelper);
-};
-
class KernelConstMapKeyEqualsTraits : public AllStatic {
public:
static const char* Name() { return "KernelConstMapKeyEqualsTraits"; }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d018655..b046ba6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4,6 +4,7 @@
#include "vm/compiler/frontend/kernel_binary_flowgraph.h"
+#include "vm/compiler/ffi.h"
#include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/frontend/flow_graph_builder.h" // For dart::FlowGraphBuilder::SimpleInstanceOfType.
@@ -774,12 +775,6 @@
bool is_constructor) {
const Function& dart_function = parsed_function()->function();
- // The prologue builder needs the default parameter values.
- SetupDefaultParameterValues();
- // TypeArgumentsHandling / BuildDefaultTypeHandling needs
- // default function type arguments.
- ReadDefaultFunctionTypeArguments(dart_function);
-
intptr_t type_parameters_offset = 0;
LocalVariable* first_parameter = nullptr;
TokenPosition token_position = TokenPosition::kNoSource;
@@ -961,9 +956,16 @@
}
ASSERT(function.HasBytecode());
+
BytecodeFlowGraphBuilder bytecode_compiler(
flow_graph_builder_, parsed_function(),
&(flow_graph_builder_->ic_data_array_));
+
+ if (B->IsRecognizedMethodForFlowGraph(function)) {
+ bytecode_compiler.CreateParameterVariables();
+ return B->BuildGraphOfRecognizedMethod(function);
+ }
+
return bytecode_compiler.BuildGraph();
}
@@ -983,13 +985,12 @@
case RawFunction::kRegularFunction:
case RawFunction::kGetterFunction:
case RawFunction::kSetterFunction:
- case RawFunction::kClosureFunction: {
- ReadUntilFunctionNode();
- return BuildGraphOfFunction(false);
- }
+ case RawFunction::kClosureFunction:
case RawFunction::kConstructor: {
- ReadUntilFunctionNode();
- return BuildGraphOfFunction(!function.IsFactory());
+ if (B->IsRecognizedMethodForFlowGraph(function)) {
+ return B->BuildGraphOfRecognizedMethod(function);
+ }
+ return BuildGraphOfFunction(function.IsGenerativeConstructor());
}
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitStaticGetter:
@@ -1053,6 +1054,11 @@
case RawFunction::kSetterFunction:
case RawFunction::kClosureFunction:
case RawFunction::kConstructor:
+ case RawFunction::kImplicitClosureFunction:
+ ReadUntilFunctionNode();
+ SetupDefaultParameterValues();
+ ReadDefaultFunctionTypeArguments(function);
+ break;
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitStaticGetter:
case RawFunction::kImplicitSetter:
@@ -1062,11 +1068,6 @@
case RawFunction::kInvokeFieldDispatcher:
case RawFunction::kFfiTrampoline:
break;
- case RawFunction::kImplicitClosureFunction:
- ReadUntilFunctionNode();
- SetupDefaultParameterValues();
- ReadDefaultFunctionTypeArguments(function);
- break;
case RawFunction::kDynamicInvocationForwarder:
if (PeekTag() != kField) {
ReadUntilFunctionNode();
@@ -3048,6 +3049,10 @@
++argument_count;
}
+ if (compiler::ffi::IsAsFunctionInternal(Z, Isolate::Current(), target)) {
+ return BuildFfiAsFunctionInternal();
+ }
+
Fragment instructions;
LocalVariable* instance_variable = NULL;
@@ -3776,10 +3781,8 @@
}
if (position != nullptr) *position = p;
const intptr_t constant_offset = ReadUInt();
- KernelConstantsMap constant_map(H.constants().raw());
- Fragment result =
- Constant(Object::ZoneHandle(Z, constant_map.GetOrDie(constant_offset)));
- ASSERT(constant_map.Release().raw() == H.constants().raw());
+ Fragment result = Constant(Object::ZoneHandle(
+ Z, constant_evaluator_.EvaluateConstantExpression(constant_offset)));
return result;
}
@@ -5002,6 +5005,25 @@
return instructions;
}
+Fragment StreamingFlowGraphBuilder::BuildFfiAsFunctionInternal() {
+ const intptr_t argc = ReadUInt(); // read argument count.
+ ASSERT(argc == 1); // pointer
+ const intptr_t list_length = ReadListLength(); // read types list length.
+ ASSERT(list_length == 2); // dart signature, then native signature
+ const TypeArguments& type_arguments =
+ T.BuildTypeArguments(list_length); // read types.
+ Fragment code;
+ const intptr_t positional_count =
+ ReadListLength(); // read positional argument count
+ ASSERT(positional_count == 1);
+ code += BuildExpression(); // build first positional argument (pointer)
+ const intptr_t named_args_len =
+ ReadListLength(); // skip (empty) named arguments list
+ ASSERT(named_args_len == 0);
+ code += B->BuildFfiAsFunctionInternalCall(type_arguments);
+ return code;
+}
+
} // namespace kernel
} // namespace dart
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 2006924..ad86af8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -350,6 +350,10 @@
Fragment BuildFunctionNode(TokenPosition parent_position,
StringIndex name_index);
+ // Build build FG for '_asFunctionInternal'. Reads an Arguments from the
+ // Kernel buffer and pushes the resulting closure.
+ Fragment BuildFfiAsFunctionInternal();
+
FlowGraphBuilder* flow_graph_builder_;
ActiveClass* const active_class_;
TypeTranslator type_translator_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 8fa5799..04f2e53 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -216,16 +216,6 @@
return instructions;
}
-Fragment FlowGraphBuilder::AllocateObject(TokenPosition position,
- const Class& klass,
- intptr_t argument_count) {
- ArgumentArray arguments = GetArguments(argument_count);
- AllocateObjectInstr* allocate =
- new (Z) AllocateObjectInstr(position, klass, arguments);
- Push(allocate);
- return Fragment(allocate);
-}
-
Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
intptr_t handler_index,
bool needs_stacktrace,
@@ -741,13 +731,99 @@
Fragment FlowGraphBuilder::NativeFunctionBody(const Function& function,
LocalVariable* first_parameter) {
ASSERT(function.is_native());
- // We explicitly build the graph for native functions in the same way that the
- // from-source backend does. We should find a way to have a single component
- // to build these graphs so that this code is not duplicated.
+ ASSERT(!IsRecognizedMethodForFlowGraph(function));
Fragment body;
+ String& name = String::ZoneHandle(Z, function.native_name());
+ if (function.IsGeneric()) {
+ body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
+ body += PushArgument();
+ }
+ for (intptr_t i = 0; i < function.NumParameters(); ++i) {
+ body += LoadLocal(parsed_function_->RawParameterVariable(i));
+ body += PushArgument();
+ }
+ body += NativeCall(&name, &function);
+ // We typecheck results of native calls for type safety.
+ body +=
+ Return(TokenPosition::kNoSource, /* omit_result_type_check = */ false);
+ return body;
+}
+
+bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
+ const Function& function) {
const MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
- bool omit_result_type_check = true;
+
+ switch (kind) {
+// On simdbc we fall back to natives.
+#if !defined(TARGET_ARCH_DBC)
+ case MethodRecognizer::kTypedData_ByteDataView_factory:
+ case MethodRecognizer::kTypedData_Int8ArrayView_factory:
+ case MethodRecognizer::kTypedData_Uint8ArrayView_factory:
+ case MethodRecognizer::kTypedData_Uint8ClampedArrayView_factory:
+ case MethodRecognizer::kTypedData_Int16ArrayView_factory:
+ case MethodRecognizer::kTypedData_Uint16ArrayView_factory:
+ case MethodRecognizer::kTypedData_Int32ArrayView_factory:
+ case MethodRecognizer::kTypedData_Uint32ArrayView_factory:
+ case MethodRecognizer::kTypedData_Int64ArrayView_factory:
+ case MethodRecognizer::kTypedData_Uint64ArrayView_factory:
+ case MethodRecognizer::kTypedData_Float32ArrayView_factory:
+ case MethodRecognizer::kTypedData_Float64ArrayView_factory:
+ case MethodRecognizer::kTypedData_Float32x4ArrayView_factory:
+ case MethodRecognizer::kTypedData_Int32x4ArrayView_factory:
+ case MethodRecognizer::kTypedData_Float64x2ArrayView_factory:
+#endif // !defined(TARGET_ARCH_DBC)
+ case MethodRecognizer::kObjectEquals:
+ case MethodRecognizer::kStringBaseLength:
+ case MethodRecognizer::kStringBaseIsEmpty:
+ case MethodRecognizer::kGrowableArrayLength:
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ case MethodRecognizer::kTypedListLength:
+ case MethodRecognizer::kTypedListViewLength:
+ case MethodRecognizer::kByteDataViewLength:
+ case MethodRecognizer::kByteDataViewOffsetInBytes:
+ case MethodRecognizer::kTypedDataViewOffsetInBytes:
+ case MethodRecognizer::kByteDataViewTypedData:
+ case MethodRecognizer::kTypedDataViewTypedData:
+ case MethodRecognizer::kClassIDgetID:
+ case MethodRecognizer::kGrowableArrayCapacity:
+ case MethodRecognizer::kListFactory:
+ case MethodRecognizer::kObjectArrayAllocate:
+ case MethodRecognizer::kLinkedHashMap_getIndex:
+ case MethodRecognizer::kLinkedHashMap_setIndex:
+ case MethodRecognizer::kLinkedHashMap_getData:
+ case MethodRecognizer::kLinkedHashMap_setData:
+ case MethodRecognizer::kLinkedHashMap_getHashMask:
+ case MethodRecognizer::kLinkedHashMap_setHashMask:
+ case MethodRecognizer::kLinkedHashMap_getUsedData:
+ case MethodRecognizer::kLinkedHashMap_setUsedData:
+ case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
+ case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+ return true;
+ default:
+ return false;
+ }
+}
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
+ const Function& function) {
+ ASSERT(IsRecognizedMethodForFlowGraph(function));
+
+ graph_entry_ =
+ new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
+
+ auto normal_entry = BuildFunctionEntry(graph_entry_);
+ graph_entry_->set_normal_entry(normal_entry);
+
+ PrologueInfo prologue_info(-1, -1);
+ BlockEntryInstr* instruction_cursor =
+ BuildPrologue(normal_entry, &prologue_info);
+
+ Fragment body(instruction_cursor);
+ body += CheckStackOverflowInPrologue(function.token_pos());
+
+ const MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
switch (kind) {
// On simdbc we fall back to natives.
#if !defined(TARGET_ARCH_DBC)
@@ -812,13 +888,13 @@
break;
#endif // !defined(TARGET_ARCH_DBC)
case MethodRecognizer::kObjectEquals:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body += StrictCompare(Token::kEQ_STRICT);
break;
case MethodRecognizer::kStringBaseLength:
case MethodRecognizer::kStringBaseIsEmpty:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::String_length());
if (kind == MethodRecognizer::kStringBaseIsEmpty) {
body += IntConstant(0);
@@ -826,36 +902,36 @@
}
break;
case MethodRecognizer::kGrowableArrayLength:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::GrowableObjectArray_length());
break;
case MethodRecognizer::kObjectArrayLength:
case MethodRecognizer::kImmutableArrayLength:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::Array_length());
break;
case MethodRecognizer::kTypedListLength:
case MethodRecognizer::kTypedListViewLength:
case MethodRecognizer::kByteDataViewLength:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::TypedDataBase_length());
break;
case MethodRecognizer::kByteDataViewOffsetInBytes:
case MethodRecognizer::kTypedDataViewOffsetInBytes:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::TypedDataView_offset_in_bytes());
break;
case MethodRecognizer::kByteDataViewTypedData:
case MethodRecognizer::kTypedDataViewTypedData:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::TypedDataView_data());
break;
case MethodRecognizer::kClassIDgetID:
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadClassId();
break;
case MethodRecognizer::kGrowableArrayCapacity:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::GrowableObjectArray_data());
body += LoadNativeField(Slot::Array_length());
break;
@@ -885,9 +961,9 @@
ASSERT(!func.IsNull());
Fragment allocate(allocate_non_growable);
- allocate += LoadLocal(scopes_->type_arguments_variable);
+ allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
allocate += PushArgument();
- allocate += LoadLocal(first_parameter);
+ allocate += LoadLocal(parsed_function_->RawParameterVariable(1));
allocate += PushArgument();
allocate +=
StaticCall(TokenPosition::kNoSource, func, 2, ICData::kStatic);
@@ -907,7 +983,7 @@
ASSERT(!func.IsNull());
Fragment allocate(allocate_growable);
- allocate += LoadLocal(scopes_->type_arguments_variable);
+ allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
allocate += PushArgument();
allocate += IntConstant(0);
allocate += PushArgument();
@@ -924,85 +1000,78 @@
break;
}
case MethodRecognizer::kObjectArrayAllocate:
- body += LoadLocal(scopes_->type_arguments_variable);
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body += CreateArray();
break;
case MethodRecognizer::kLinkedHashMap_getIndex:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::LinkedHashMap_index());
break;
case MethodRecognizer::kLinkedHashMap_setIndex:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body += StoreInstanceField(TokenPosition::kNoSource,
Slot::LinkedHashMap_index());
body += NullConstant();
break;
case MethodRecognizer::kLinkedHashMap_getData:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::LinkedHashMap_data());
break;
case MethodRecognizer::kLinkedHashMap_setData:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body += StoreInstanceField(TokenPosition::kNoSource,
Slot::LinkedHashMap_data());
body += NullConstant();
break;
case MethodRecognizer::kLinkedHashMap_getHashMask:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::LinkedHashMap_hash_mask());
break;
case MethodRecognizer::kLinkedHashMap_setHashMask:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body +=
StoreInstanceField(TokenPosition::kNoSource,
Slot::LinkedHashMap_hash_mask(), kNoStoreBarrier);
body += NullConstant();
break;
case MethodRecognizer::kLinkedHashMap_getUsedData:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::LinkedHashMap_used_data());
break;
case MethodRecognizer::kLinkedHashMap_setUsedData:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body +=
StoreInstanceField(TokenPosition::kNoSource,
Slot::LinkedHashMap_used_data(), kNoStoreBarrier);
body += NullConstant();
break;
case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
- body += LoadLocal(parsed_function_->receiver_var());
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
body += LoadNativeField(Slot::LinkedHashMap_deleted_keys());
break;
case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
- body += LoadLocal(parsed_function_->receiver_var());
- body += LoadLocal(first_parameter);
+ body += LoadLocal(parsed_function_->RawParameterVariable(0));
+ body += LoadLocal(parsed_function_->RawParameterVariable(1));
body += StoreInstanceField(TokenPosition::kNoSource,
Slot::LinkedHashMap_deleted_keys(),
kNoStoreBarrier);
body += NullConstant();
break;
default: {
- String& name = String::ZoneHandle(Z, function.native_name());
- if (function.IsGeneric()) {
- body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
- body += PushArgument();
- }
- for (intptr_t i = 0; i < function.NumParameters(); ++i) {
- body += LoadLocal(parsed_function_->RawParameterVariable(i));
- body += PushArgument();
- }
- body += NativeCall(&name, &function);
- // We typecheck results of native calls for type safety.
- omit_result_type_check = false;
+ UNREACHABLE();
break;
}
}
- return body + Return(TokenPosition::kNoSource, omit_result_type_check);
+
+ body += Return(TokenPosition::kNoSource, /* omit_result_type_check = */ true);
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
+ prologue_info);
}
Fragment FlowGraphBuilder::BuildTypedDataViewFactoryConstructor(
@@ -1148,8 +1217,7 @@
if (definition->IsAllocateObject()) {
return !definition->AsAllocateObject()->closure_function().IsNull();
}
- return definition->IsLoadLocal() &&
- !definition->AsLoadLocal()->local().IsInternal();
+ return definition->IsLoadLocal();
}
Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) {
@@ -2405,38 +2473,6 @@
return Fragment(unbox);
}
-Fragment FlowGraphBuilder::LoadAddressFromFfiPointer() {
- Fragment test;
- TargetEntryInstr* null_entry;
- TargetEntryInstr* not_null_entry;
- JoinEntryInstr* join = BuildJoinEntry();
-
- LocalVariable* result = parsed_function_->expression_temp_var();
-
- LocalVariable* pointer = MakeTemporary();
- test += LoadLocal(pointer);
- test += BranchIfNull(&null_entry, ¬_null_entry);
-
- Fragment load_0(null_entry);
- load_0 += IntConstant(0);
- load_0 += StoreLocal(TokenPosition::kNoSource, result);
- load_0 += Drop();
- load_0 += Goto(join);
-
- Fragment unbox(not_null_entry);
- unbox += LoadLocal(pointer);
- unbox += LoadNativeField(Slot::Pointer_c_memory_address());
- unbox += StoreLocal(TokenPosition::kNoSource, result);
- unbox += Drop();
- unbox += Goto(join);
-
- Fragment done{test.entry, join};
- done += Drop();
- done += LoadLocal(result);
-
- return done;
-}
-
Fragment FlowGraphBuilder::Box(Representation from) {
BoxInstr* box = BoxInstr::Create(from, Pop());
Push(box);
@@ -2455,22 +2491,6 @@
return Fragment(extend);
}
-Fragment FlowGraphBuilder::FfiExceptionalReturnValue(
- const AbstractType& result_type,
- Representation representation) {
- ASSERT(optimizing_);
- Object& result = Object::ZoneHandle(Z, Object::null());
- if (representation == kUnboxedFloat || representation == kUnboxedDouble) {
- result = Double::New(0.0, Heap::kOld);
- } else {
- result = Integer::New(0, Heap::kOld);
- }
- Fragment code;
- code += Constant(result);
- code += UnboxTruncate(representation);
- return code;
-}
-
#if !defined(TARGET_ARCH_DBC)
Fragment FlowGraphBuilder::NativeReturn(Representation result) {
auto* instr = new (Z)
@@ -2481,58 +2501,35 @@
#endif
Fragment FlowGraphBuilder::FfiPointerFromAddress(const Type& result_type) {
- Fragment test;
- TargetEntryInstr* null_entry;
- TargetEntryInstr* not_null_entry;
- JoinEntryInstr* join = BuildJoinEntry();
-
LocalVariable* address = MakeTemporary();
LocalVariable* result = parsed_function_->expression_temp_var();
- test += LoadLocal(address);
- test += IntConstant(0);
- test += BranchIfEqual(&null_entry, ¬_null_entry);
+ Class& result_class = Class::ZoneHandle(Z, result_type.type_class());
+ // This class might only be instantiated as a return type of ffi calls.
+ result_class.EnsureIsFinalized(thread_);
- // If the result is 0, we return null because "0 means null".
- Fragment load_null(null_entry);
- {
- load_null += NullConstant();
- load_null += StoreLocal(TokenPosition::kNoSource, result);
- load_null += Drop();
- load_null += Goto(join);
- }
+ TypeArguments& args = TypeArguments::ZoneHandle(Z, result_type.arguments());
- Fragment box(not_null_entry);
- {
- Class& result_class = Class::ZoneHandle(Z, result_type.type_class());
- // This class might only be instantiated as a return type of ffi calls.
- result_class.EnsureIsFinalized(thread_);
+ // A kernel transform for FFI in the front-end ensures that type parameters
+ // do not appear in the type arguments to a any Pointer classes in an FFI
+ // signature.
+ ASSERT(args.IsNull() || args.IsInstantiated());
- TypeArguments& args = TypeArguments::ZoneHandle(Z, result_type.arguments());
+ Fragment code;
+ code += Constant(args);
+ code += PushArgument();
+ code += AllocateObject(TokenPosition::kNoSource, result_class, 1);
+ LocalVariable* pointer = MakeTemporary();
+ code += LoadLocal(pointer);
+ code += LoadLocal(address);
+ code += StoreInstanceField(TokenPosition::kNoSource,
+ Slot::Pointer_c_memory_address());
+ code += StoreLocal(TokenPosition::kNoSource, result);
+ code += Drop(); // StoreLocal^
+ code += Drop(); // address
+ code += LoadLocal(result);
- // A kernel transform for FFI in the front-end ensures that type parameters
- // do not appear in the type arguments to a any Pointer classes in an FFI
- // signature.
- ASSERT(args.IsNull() || args.IsInstantiated());
-
- box += Constant(args);
- box += PushArgument();
- box += AllocateObject(TokenPosition::kNoSource, result_class, 1);
- LocalVariable* pointer = MakeTemporary();
- box += LoadLocal(pointer);
- box += LoadLocal(address);
- box += StoreInstanceField(TokenPosition::kNoSource,
- Slot::Pointer_c_memory_address());
- box += StoreLocal(TokenPosition::kNoSource, result);
- box += Drop();
- box += Goto(join);
- }
-
- Fragment rest(test.entry, join);
- rest += Drop();
- rest += LoadLocal(result);
-
- return rest;
+ return code;
}
Fragment FlowGraphBuilder::BitCast(Representation from, Representation to) {
@@ -2569,16 +2566,22 @@
const AbstractType& ffi_type,
const Representation native_representation) {
Fragment body;
- // Check for 'null'. Only ffi.Pointers are allowed to be null.
- if (!compiler::ffi::NativeTypeIsPointer(ffi_type)) {
- body += LoadLocal(MakeTemporary());
- body <<=
- new (Z) CheckNullInstr(Pop(), String::ZoneHandle(Z, function.name()),
- GetNextDeoptId(), TokenPosition::kNoSource);
+
+ // Return 0 for void.
+ if (compiler::ffi::NativeTypeIsVoid(ffi_type)) {
+ body += Drop();
+ body += IntConstant(0);
+ body += UnboxTruncate(kUnboxedFfiIntPtr);
+ return body;
}
+ // Check for 'null'.
+ body += LoadLocal(MakeTemporary());
+ body <<= new (Z) CheckNullInstr(Pop(), String::ZoneHandle(Z, function.name()),
+ GetNextDeoptId(), TokenPosition::kNoSource);
+
if (compiler::ffi::NativeTypeIsPointer(ffi_type)) {
- body += LoadAddressFromFfiPointer();
+ body += LoadNativeField(Slot::Pointer_c_memory_address());
body += UnboxTruncate(kUnboxedFfiIntPtr);
} else {
Representation from_rep = compiler::ffi::TypeRepresentation(ffi_type);
@@ -2725,24 +2728,12 @@
++catch_depth_;
Fragment catch_body =
CatchBlockEntry(Array::empty_array(), try_handler_index,
- /*needs_stacktrace=*/true, /*is_synthesized=*/true);
+ /*needs_stacktrace=*/false, /*is_synthesized=*/true);
- catch_body += LoadLocal(CurrentException());
- catch_body += PushArgument();
- catch_body += LoadLocal(CurrentStackTrace());
- catch_body += PushArgument();
-
- // Find '_handleExposedException(e, st)' from ffi_patch.dart and call it.
- const Library& ffi_lib =
- Library::Handle(Z, Library::LookupLibrary(thread_, Symbols::DartFfi()));
- const Function& handler = Function::ZoneHandle(
- Z, ffi_lib.LookupFunctionAllowPrivate(Symbols::HandleExposedException()));
- ASSERT(!handler.IsNull());
- catch_body += StaticCall(TokenPosition::kNoSource, handler, /*num_args=*/2,
- /*arg_names=*/Array::empty_array(), ICData::kStatic);
- catch_body += Drop();
-
- catch_body += FfiExceptionalReturnValue(ffi_type, result_rep);
+ // Return the "exceptional return" value given in 'fromFunction'.
+ catch_body += Constant(
+ Instance::ZoneHandle(Z, function.FfiCallbackExceptionalReturn()));
+ catch_body += FfiConvertArgumentToNative(function, ffi_type, result_rep);
catch_body += NativeReturn(result_rep);
--catch_depth_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 9ccc1a94..5b7c662 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -107,6 +107,9 @@
Fragment NativeFunctionBody(const Function& function,
LocalVariable* first_parameter);
+ bool IsRecognizedMethodForFlowGraph(const Function& function);
+ FlowGraph* BuildGraphOfRecognizedMethod(const Function& function);
+
Fragment BuildTypedDataViewFactoryConstructor(const Function& function,
classid_t cid);
@@ -124,9 +127,6 @@
Fragment TranslateInstantiatedTypeArguments(
const TypeArguments& type_arguments);
- Fragment AllocateObject(TokenPosition position,
- const Class& klass,
- intptr_t argument_count);
Fragment CatchBlockEntry(const Array& handler_types,
intptr_t handler_index,
bool needs_stacktrace,
@@ -226,16 +226,7 @@
Fragment FfiUnboxedExtend(Representation representation,
const AbstractType& ffi_type);
- // Pops an 'ffi.Pointer' off the stack.
- // If it's null, pushes 0.
- // Otherwise pushes the address (in boxed representation).
- Fragment LoadAddressFromFfiPointer();
-
- // Reverse of 'LoadPointerFromFfiPointer':
- // Pops an integer off the the stack.
- // If it's zero, pushes null.
- // If it's nonzero, creates an 'ffi.Pointer' holding the address and pushes
- // the pointer.
+ // Creates an ffi.Pointer holding a given address (TOS).
Fragment FfiPointerFromAddress(const Type& result_type);
// Pushes an (unboxed) bogus value returned when a native -> Dart callback
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 35c0178..938a22a 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -32,6 +32,7 @@
metadata_payloads_(ExternalTypedData::Handle(Z)),
metadata_mappings_(ExternalTypedData::Handle(Z)),
constants_(Array::Handle(Z)),
+ constants_table_(ExternalTypedData::Handle(Z)),
info_(KernelProgramInfo::Handle(Z)),
name_index_handle_(Smi::Handle(Z)) {}
@@ -46,6 +47,7 @@
metadata_payloads_(ExternalTypedData::Handle(Z)),
metadata_mappings_(ExternalTypedData::Handle(Z)),
constants_(Array::Handle(Z)),
+ constants_table_(ExternalTypedData::Handle(Z)),
info_(KernelProgramInfo::Handle(Z)),
name_index_handle_(Smi::Handle(Z)) {}
@@ -79,6 +81,7 @@
SetMetadataPayloads(ExternalTypedData::Handle(Z, info.metadata_payloads()));
SetMetadataMappings(ExternalTypedData::Handle(Z, info.metadata_mappings()));
SetConstants(Array::Handle(Z, info.constants()));
+ SetConstantsTable(ExternalTypedData::Handle(Z, info.constants_table()));
SetKernelProgramInfo(info);
}
@@ -92,6 +95,23 @@
return funcs.raw();
}
+void TranslationHelper::AddPotentialExtensionLibrary(const Library& library) {
+ if (potential_extension_libraries_ == nullptr) {
+ potential_extension_libraries_ =
+ &GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+ }
+ potential_extension_libraries_->Add(library);
+}
+
+RawGrowableObjectArray* TranslationHelper::GetPotentialExtensionLibraries() {
+ if (potential_extension_libraries_ != nullptr) {
+ GrowableObjectArray* result = potential_extension_libraries_;
+ potential_extension_libraries_ = nullptr;
+ return result->raw();
+ }
+ return GrowableObjectArray::null();
+}
+
void TranslationHelper::SetStringOffsets(const TypedData& string_offsets) {
ASSERT(string_offsets_.IsNull());
string_offsets_ = string_offsets.raw();
@@ -126,6 +146,12 @@
constants_ = constants.raw();
}
+void TranslationHelper::SetConstantsTable(
+ const ExternalTypedData& constants_table) {
+ ASSERT(constants_table_.IsNull());
+ constants_table_ = constants_table.raw();
+}
+
void TranslationHelper::SetKernelProgramInfo(const KernelProgramInfo& info) {
info_ = info.raw();
}
@@ -2900,9 +2926,10 @@
}
parameter_index -= class_types.Length();
}
-
+ // Factory function should not be considered as procedure.
intptr_t procedure_type_parameter_count =
- active_class_->MemberIsProcedure()
+ (active_class_->MemberIsProcedure() &&
+ !active_class_->MemberIsFactoryProcedure())
? active_class_->MemberTypeParameterCount(Z)
: 0;
if (procedure_type_parameter_count > 0) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 1dc3f3c4..3e4340d 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -41,26 +41,40 @@
Heap::Space allocation_space() { return allocation_space_; }
// Access to strings.
- const TypedData& string_offsets() { return string_offsets_; }
+ const TypedData& string_offsets() const { return string_offsets_; }
void SetStringOffsets(const TypedData& string_offsets);
- const ExternalTypedData& string_data() { return string_data_; }
+ const ExternalTypedData& string_data() const { return string_data_; }
void SetStringData(const ExternalTypedData& string_data);
- const TypedData& canonical_names() { return canonical_names_; }
+ const TypedData& canonical_names() const { return canonical_names_; }
void SetCanonicalNames(const TypedData& canonical_names);
- const ExternalTypedData& metadata_payloads() { return metadata_payloads_; }
+ const ExternalTypedData& metadata_payloads() const {
+ return metadata_payloads_;
+ }
void SetMetadataPayloads(const ExternalTypedData& metadata_payloads);
- const ExternalTypedData& metadata_mappings() { return metadata_mappings_; }
+ const ExternalTypedData& metadata_mappings() const {
+ return metadata_mappings_;
+ }
void SetMetadataMappings(const ExternalTypedData& metadata_mappings);
+ // Access to previously evaluated constants from the constants table.
const Array& constants() { return constants_; }
void SetConstants(const Array& constants);
+ // Access to the raw bytes of the constants table.
+ const ExternalTypedData& constants_table() const { return constants_table_; }
+ void SetConstantsTable(const ExternalTypedData& constants_table);
+
+ KernelProgramInfo& info() { return info_; }
+
RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
+ void AddPotentialExtensionLibrary(const Library& library);
+ RawGrowableObjectArray* GetPotentialExtensionLibraries();
+
void SetKernelProgramInfo(const KernelProgramInfo& info);
const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
@@ -206,8 +220,10 @@
ExternalTypedData& metadata_payloads_;
ExternalTypedData& metadata_mappings_;
Array& constants_;
+ ExternalTypedData& constants_table_;
KernelProgramInfo& info_;
Smi& name_index_handle_;
+ GrowableObjectArray* potential_extension_libraries_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(TranslationHelper);
};
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 66e293f..16b59b8 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -98,9 +98,6 @@
FLAG_background_compilation = false;
FLAG_enable_mirrors = false;
- // TODO(dacoharkes): Ffi support in AOT
- // https://github.com/dart-lang/sdk/issues/35765
- FLAG_enable_ffi = false;
FLAG_fields_may_be_reset = true;
FLAG_interpret_irregexp = true;
FLAG_lazy_dispatchers = false;
@@ -378,9 +375,7 @@
// CreateDeoptInfo uses the object pool and needs to be done before
// FinalizeCode.
Array& deopt_info_array = Array::Handle(zone, Object::empty_array().raw());
- if (!function.ForceOptimize()) {
- deopt_info_array = graph_compiler->CreateDeoptInfo(assembler);
- }
+ deopt_info_array = graph_compiler->CreateDeoptInfo(assembler);
// Allocates instruction object. Since this occurs only at safepoint,
// there can be no concurrent access to the instruction page.
@@ -408,9 +403,8 @@
if (function.ForceOptimize()) {
ASSERT(optimized() && thread()->IsMutatorThread());
- code.set_is_optimized(false);
+ code.set_is_force_optimized(true);
function.AttachCode(code);
- function.set_unoptimized_code(code);
function.SetWasCompiled(true);
} else if (optimized()) {
// Installs code while at safepoint.
@@ -947,6 +941,7 @@
RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
const Function& function) {
+ ASSERT(!function.ForceOptimize());
if (function.unoptimized_code() != Object::null()) {
return Error::null();
}
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index aec5b3e..af363e6 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -275,8 +275,9 @@
offset_into_target += (entry_point - destination_payload);
- const intptr_t text_offset =
- code_text_offset + Instructions::HeaderSize() + offset;
+ const intptr_t text_offset = code_text_offset +
+ compiler::target::Instructions::HeaderSize() +
+ offset;
UnresolvedCall unresolved_call(code.raw(), offset, text_offset,
destination_.raw(), offset_into_target);
if (!TryResolveBackwardsCall(&unresolved_call)) {
@@ -502,7 +503,8 @@
const RawInstructions* destination,
intptr_t offset_into_target) {
auto destination_offset = text_offsets_.LookupValue(destination);
- return destination_offset + Instructions::HeaderSize() + offset_into_target;
+ return destination_offset + compiler::target::Instructions::HeaderSize() +
+ offset_into_target;
}
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 0c35ced..ff30fd9 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/compiler/runtime_api.h"
+#include "platform/utils.h"
namespace dart {
namespace compiler {
@@ -10,6 +11,10 @@
#include "vm/compiler/runtime_offsets_extracted.h"
+bool IsSmi(int64_t v) {
+ return Utils::IsInt(kSmiBits + 1, v);
+}
+
} // namespace target
} // namespace compiler
} // namespace dart
@@ -561,11 +566,7 @@
"Expected that size of Smi on HOST is at least as large as on target.");
bool IsSmi(const dart::Object& a) {
- return a.IsSmi() && Utils::IsInt(kSmiBits + 1, dart::Smi::Cast(a).Value());
-}
-
-bool IsSmi(int64_t v) {
- return Utils::IsInt(kSmiBits + 1, v);
+ return a.IsSmi() && IsSmi(dart::Smi::Cast(a).Value());
}
word ToRawSmi(const dart::Object& a) {
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index bf791bc..a3ceb18 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -74,10 +74,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -427,10 +427,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -781,10 +781,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1130,10 +1130,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1487,10 +1487,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
112;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 186;
+ 190;
static constexpr dart::compiler::target::word Class_super_type_offset = 88;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 176;
+ Class_type_arguments_field_offset_in_words_offset = 180;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
@@ -1771,10 +1771,10 @@
static constexpr dart::compiler::target::word Class_declaration_type_offset =
56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 102;
+ 106;
static constexpr dart::compiler::target::word Class_super_type_offset = 44;
static constexpr dart::compiler::target::word
- Class_type_arguments_field_offset_in_words_offset = 92;
+ Class_type_arguments_field_offset_in_words_offset = 96;
static constexpr dart::compiler::target::word
ClassHeapStats_TraceAllocationMask = 1;
static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 2f3b1b0..26d8c00 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -782,6 +782,12 @@
COMPILE_ASSERT(R25 > CODE_REG);
__ ldr(R25, Address(FP, 2 * target::kWordSize));
__ str(R25, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+ } else if (r == R15) {
+ // Because we save registers in decreasing order, IP0 will already be
+ // saved.
+ COMPILE_ASSERT(IP0 == R16);
+ __ mov(IP0, R15);
+ __ str(IP0, Address(SP, -1 * target::kWordSize, Address::PreIndex));
} else {
__ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
}
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 8bf0e39..e0b1193 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -202,8 +202,7 @@
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_Handle obj_handle =
Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL);
- EXPECT(!Dart_IsNull(obj_handle));
- EXPECT(!Dart_IsError(obj_handle));
+ EXPECT_VALID(obj_handle);
TransitionNativeToVM transition(thread);
const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
EXPECT(!obj.IsNull());
diff --git a/runtime/vm/constants_kbc.cc b/runtime/vm/constants_kbc.cc
index d5ed600..adbe0421 100644
--- a/runtime/vm/constants_kbc.cc
+++ b/runtime/vm/constants_kbc.cc
@@ -7,10 +7,6 @@
namespace dart {
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
-static const intptr_t kOldInstructionSize = 4;
-
static const intptr_t kInstructionSize0 = 1;
static const intptr_t kInstructionSizeA = 2;
static const intptr_t kInstructionSizeD = 2;
@@ -28,13 +24,11 @@
static const intptr_t kInstructionSizeA_B_C = 4;
const intptr_t KernelBytecode::kInstructionSize[] = {
-#define SIZE_OLD(encoding) kOldInstructionSize
#define SIZE_ORDN(encoding) kInstructionSize##encoding
#define SIZE_WIDE(encoding) kInstructionSizeWide##encoding
#define SIZE_RESV(encoding) SIZE_ORDN(encoding)
#define SIZE(name, encoding, kind, op1, op2, op3) SIZE_##kind(encoding),
KERNEL_BYTECODES_LIST(SIZE)
-#undef SIZE_OLD
#undef SIZE_ORDN
#undef SIZE_WIDE
#undef SIZE_RESV
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 5c422d8..0849572 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -453,9 +453,9 @@
// V(BytecodeName, OperandForm, BytecodeKind, Op1, Op2, Op3)
//
// - OperandForm specifies operand encoding and should be one of 0, A, D, X, T,
-// A_D (old), A_X (old), A_E, A_Y, D_F or A_B_C (see ENCODING section above).
+// A_E, A_Y, D_F or A_B_C (see ENCODING section above).
//
-// - BytecodeKind is one of OLD, WIDE, RESV (reserved), ORDN (ordinary)
+// - BytecodeKind is one of WIDE, RESV (reserved), ORDN (ordinary)
//
// - Op1, Op2, Op3 specify operand meaning. Possible values:
//
@@ -471,91 +471,91 @@
// and before decoding.
//
#define PUBLIC_KERNEL_BYTECODES_LIST(V) \
- V(Trap_Old, 0, OLD, ___, ___, ___) \
- V(Entry_Old, D, OLD, num, ___, ___) \
- V(EntryFixed_Old, A_D, OLD, num, num, ___) \
- V(EntryOptional_Old, A_B_C, OLD, num, num, num) \
- V(LoadConstant_Old, A_D, OLD, reg, lit, ___) \
- V(Frame_Old, D, OLD, num, ___, ___) \
- V(CheckFunctionTypeArgs_Old, A_D, OLD, num, reg, ___) \
- V(CheckStack_Old, A, OLD, num, ___, ___) \
- V(Allocate_Old, D, OLD, lit, ___, ___) \
- V(AllocateT_Old, 0, OLD, ___, ___, ___) \
- V(CreateArrayTOS_Old, 0, OLD, ___, ___, ___) \
- V(AllocateContext_Old, D, OLD, num, ___, ___) \
- V(CloneContext_Old, D, OLD, num, ___, ___) \
- V(LoadContextParent_Old, 0, OLD, ___, ___, ___) \
- V(StoreContextParent_Old, 0, OLD, ___, ___, ___) \
- V(LoadContextVar_Old, D, OLD, num, ___, ___) \
- V(StoreContextVar_Old, D, OLD, num, ___, ___) \
- V(PushConstant_Old, D, OLD, lit, ___, ___) \
- V(PushNull_Old, 0, OLD, ___, ___, ___) \
- V(PushTrue_Old, 0, OLD, ___, ___, ___) \
- V(PushFalse_Old, 0, OLD, ___, ___, ___) \
- V(PushInt_Old, X, OLD, num, ___, ___) \
- V(Drop1_Old, 0, OLD, ___, ___, ___) \
- V(Push_Old, X, OLD, xeg, ___, ___) \
- V(PopLocal_Old, X, OLD, xeg, ___, ___) \
- V(StoreLocal_Old, X, OLD, xeg, ___, ___) \
- V(LoadFieldTOS_Old, D, OLD, lit, ___, ___) \
- V(StoreFieldTOS_Old, D, OLD, lit, ___, ___) \
- V(StoreIndexedTOS_Old, 0, OLD, ___, ___, ___) \
- V(PushStatic_Old, D, OLD, lit, ___, ___) \
- V(StoreStaticTOS_Old, D, OLD, lit, ___, ___) \
- V(Jump_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfNoAsserts_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfNotZeroTypeArgs_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfEqStrict_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfNeStrict_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfTrue_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfFalse_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfNull_Old, T, OLD, tgt, ___, ___) \
- V(JumpIfNotNull_Old, T, OLD, tgt, ___, ___) \
- V(Unused00_Old, 0, RESV, num, num, ___) \
- V(InterfaceCall_Old, A_D, OLD, num, num, ___) \
- V(DynamicCall_Old, A_D, OLD, num, num, ___) \
- V(NativeCall_Old, D, OLD, lit, ___, ___) \
- V(ReturnTOS_Old, 0, OLD, ___, ___, ___) \
- V(AssertAssignable_Old, A_D, OLD, num, lit, ___) \
- V(AssertBoolean_Old, A, OLD, num, ___, ___) \
- V(AssertSubtype_Old, 0, OLD, ___, ___, ___) \
- V(LoadTypeArgumentsField_Old, D, OLD, lit, ___, ___) \
- V(InstantiateType_Old, D, OLD, lit, ___, ___) \
- V(InstantiateTypeArgumentsTOS_Old, A_D, OLD, num, lit, ___) \
- V(Throw_Old, A, OLD, num, ___, ___) \
- V(MoveSpecial_Old, A_X, OLD, num, xeg, ___) \
- V(SetFrame_Old, A, OLD, num, ___, num) \
- V(BooleanNegateTOS_Old, 0, OLD, ___, ___, ___) \
- V(EqualsNull_Old, 0, OLD, ___, ___, ___) \
- V(NegateInt_Old, 0, OLD, ___, ___, ___) \
- V(AddInt_Old, 0, OLD, ___, ___, ___) \
- V(SubInt_Old, 0, OLD, ___, ___, ___) \
- V(MulInt_Old, 0, OLD, ___, ___, ___) \
- V(TruncDivInt_Old, 0, OLD, ___, ___, ___) \
- V(ModInt_Old, 0, OLD, ___, ___, ___) \
- V(BitAndInt_Old, 0, OLD, ___, ___, ___) \
- V(BitOrInt_Old, 0, OLD, ___, ___, ___) \
- V(BitXorInt_Old, 0, OLD, ___, ___, ___) \
- V(ShlInt_Old, 0, OLD, ___, ___, ___) \
- V(ShrInt_Old, 0, OLD, ___, ___, ___) \
- V(CompareIntEq_Old, 0, OLD, ___, ___, ___) \
- V(CompareIntGt_Old, 0, OLD, ___, ___, ___) \
- V(CompareIntLt_Old, 0, OLD, ___, ___, ___) \
- V(CompareIntGe_Old, 0, OLD, ___, ___, ___) \
- V(CompareIntLe_Old, 0, OLD, ___, ___, ___) \
- V(DirectCall_Old, A_D, OLD, num, num, ___) \
- V(AllocateClosure_Old, D, OLD, lit, ___, ___) \
- V(UncheckedInterfaceCall_Old, A_D, OLD, num, num, ___) \
- V(NegateDouble_Old, 0, OLD, ___, ___, ___) \
- V(AddDouble_Old, 0, OLD, ___, ___, ___) \
- V(SubDouble_Old, 0, OLD, ___, ___, ___) \
- V(MulDouble_Old, 0, OLD, ___, ___, ___) \
- V(DivDouble_Old, 0, OLD, ___, ___, ___) \
- V(CompareDoubleEq_Old, 0, OLD, ___, ___, ___) \
- V(CompareDoubleGt_Old, 0, OLD, ___, ___, ___) \
- V(CompareDoubleLt_Old, 0, OLD, ___, ___, ___) \
- V(CompareDoubleGe_Old, 0, OLD, ___, ___, ___) \
- V(CompareDoubleLe_Old, 0, OLD, ___, ___, ___) \
+ V(UnusedOpcode000, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode001, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode002, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode003, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode004, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode005, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode006, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode007, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode008, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode009, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode010, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode011, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode012, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode013, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode014, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode015, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode016, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode017, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode018, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode019, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode020, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode021, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode022, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode023, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode024, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode025, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode026, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode027, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode028, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode029, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode030, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode031, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode032, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode033, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode034, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode035, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode036, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode037, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode038, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode039, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode040, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode041, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode042, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode043, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode044, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode045, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode046, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode047, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode048, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode049, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode050, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode051, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode052, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode053, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode054, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode055, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode056, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode057, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode058, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode059, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode060, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode061, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode062, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode063, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode064, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode065, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode066, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode067, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode068, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode069, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode070, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode071, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode072, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode073, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode074, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode075, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode076, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode077, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode078, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode079, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode080, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode081, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode082, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode083, 0, RESV, ___, ___, ___) \
+ V(UnusedOpcode084, 0, RESV, ___, ___, ___) \
V(Trap, 0, ORDN, ___, ___, ___) \
V(Entry, D, ORDN, num, ___, ___) \
V(Entry_Wide, D, WIDE, num, ___, ___) \
@@ -579,18 +579,18 @@
V(CreateArrayTOS, 0, ORDN, ___, ___, ___) \
V(AllocateClosure, D, ORDN, lit, ___, ___) \
V(AllocateClosure_Wide, D, WIDE, lit, ___, ___) \
- V(AllocateContext, A_E, ORDN, num, ___, ___) \
- V(AllocateContext_Wide, A_E, WIDE, num, ___, ___) \
- V(CloneContext, A_E, ORDN, num, ___, ___) \
- V(CloneContext_Wide, A_E, WIDE, num, ___, ___) \
+ V(AllocateContext, A_E, ORDN, num, num, ___) \
+ V(AllocateContext_Wide, A_E, WIDE, num, num, ___) \
+ V(CloneContext, A_E, ORDN, num, num, ___) \
+ V(CloneContext_Wide, A_E, WIDE, num, num, ___) \
V(LoadContextParent, 0, ORDN, ___, ___, ___) \
V(StoreContextParent, 0, ORDN, ___, ___, ___) \
- V(LoadContextVar, A_E, ORDN, num, ___, ___) \
- V(LoadContextVar_Wide, A_E, WIDE, num, ___, ___) \
+ V(LoadContextVar, A_E, ORDN, num, num, ___) \
+ V(LoadContextVar_Wide, A_E, WIDE, num, num, ___) \
V(Unused04, 0, RESV, ___, ___, ___) \
V(Unused05, 0, RESV, ___, ___, ___) \
- V(StoreContextVar, A_E, ORDN, num, ___, ___) \
- V(StoreContextVar_Wide, A_E, WIDE, num, ___, ___) \
+ V(StoreContextVar, A_E, ORDN, num, num, ___) \
+ V(StoreContextVar_Wide, A_E, WIDE, num, num, ___) \
V(PushConstant, D, ORDN, lit, ___, ___) \
V(PushConstant_Wide, D, WIDE, lit, ___, ___) \
V(Unused06, 0, RESV, ___, ___, ___) \
@@ -745,11 +745,11 @@
// Magic value of bytecode files.
static const intptr_t kMagicValue = 0x44424332; // 'DBC2'
// Minimum bytecode format version supported by VM.
- static const intptr_t kMinSupportedBytecodeFormatVersion = 3;
+ static const intptr_t kMinSupportedBytecodeFormatVersion = 7;
// Maximum bytecode format version supported by VM.
// The range of supported versions should include version produced by bytecode
// generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
- static const intptr_t kMaxSupportedBytecodeFormatVersion = 10;
+ static const intptr_t kMaxSupportedBytecodeFormatVersion = 12;
enum Opcode {
#define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,
@@ -777,12 +777,6 @@
private:
static const intptr_t kWideModifier = 1;
- static_assert(kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
- DART_FORCE_INLINE static bool IsOld(const KBCInstr* instr) {
- return DecodeOpcode(instr) < kTrap;
- }
-
// Should be used only on instructions with wide variants.
DART_FORCE_INLINE static bool IsWide(const KBCInstr* instr) {
return ((DecodeOpcode(instr) & kWideModifier) != 0);
@@ -796,9 +790,7 @@
DART_FORCE_INLINE static uint8_t DecodeC(const KBCInstr* bc) { return bc[3]; }
DART_FORCE_INLINE static uint32_t DecodeD(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return static_cast<uint32_t>(bc[1]) |
(static_cast<uint32_t>(bc[2]) << 8) |
(static_cast<uint32_t>(bc[3]) << 16) |
@@ -809,10 +801,7 @@
}
DART_FORCE_INLINE static int32_t DecodeX(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
- (static_cast<uint16_t>(bc[3]) << 8));
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return static_cast<int32_t>(static_cast<uint32_t>(bc[1]) |
(static_cast<uint32_t>(bc[2]) << 8) |
(static_cast<uint32_t>(bc[3]) << 16) |
@@ -823,12 +812,7 @@
}
DART_FORCE_INLINE static int32_t DecodeT(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
- (static_cast<uint32_t>(bc[2]) << 16) |
- (static_cast<uint32_t>(bc[3]) << 24)) >>
- (8 - 2);
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
(static_cast<uint32_t>(bc[2]) << 16) |
(static_cast<uint32_t>(bc[3]) << 24)) >>
@@ -839,9 +823,7 @@
}
DART_FORCE_INLINE static uint32_t DecodeE(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return static_cast<uint32_t>(bc[2]) |
(static_cast<uint32_t>(bc[3]) << 8) |
(static_cast<uint32_t>(bc[4]) << 16) |
@@ -852,10 +834,7 @@
}
DART_FORCE_INLINE static int32_t DecodeY(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
- (static_cast<uint16_t>(bc[3]) << 8));
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return static_cast<int32_t>(static_cast<uint32_t>(bc[2]) |
(static_cast<uint32_t>(bc[3]) << 8) |
(static_cast<uint32_t>(bc[4]) << 16) |
@@ -866,9 +845,7 @@
}
DART_FORCE_INLINE static uint8_t DecodeF(const KBCInstr* bc) {
- if (IsOld(bc)) {
- return bc[1];
- } else if (IsWide(bc)) {
+ if (IsWide(bc)) {
return bc[5];
} else {
return bc[2];
@@ -885,15 +862,6 @@
DART_FORCE_INLINE static bool IsJumpOpcode(const KBCInstr* instr) {
switch (DecodeOpcode(instr)) {
- case KernelBytecode::kJump_Old:
- case KernelBytecode::kJumpIfNoAsserts_Old:
- case KernelBytecode::kJumpIfNotZeroTypeArgs_Old:
- case KernelBytecode::kJumpIfEqStrict_Old:
- case KernelBytecode::kJumpIfNeStrict_Old:
- case KernelBytecode::kJumpIfTrue_Old:
- case KernelBytecode::kJumpIfFalse_Old:
- case KernelBytecode::kJumpIfNull_Old:
- case KernelBytecode::kJumpIfNotNull_Old:
case KernelBytecode::kJump:
case KernelBytecode::kJump_Wide:
case KernelBytecode::kJumpIfNoAsserts:
@@ -923,7 +891,6 @@
switch (DecodeOpcode(instr)) {
case KernelBytecode::kLoadConstant:
case KernelBytecode::kLoadConstant_Wide:
- case KernelBytecode::kLoadConstant_Old:
return true;
default:
return false;
@@ -931,9 +898,23 @@
}
DART_FORCE_INLINE static bool IsCheckStackOpcode(const KBCInstr* instr) {
+ return DecodeOpcode(instr) == KernelBytecode::kCheckStack;
+ }
+
+ DART_FORCE_INLINE static bool IsEntryOpcode(const KBCInstr* instr) {
switch (DecodeOpcode(instr)) {
- case KernelBytecode::kCheckStack:
- case KernelBytecode::kCheckStack_Old:
+ case KernelBytecode::kEntry:
+ case KernelBytecode::kEntry_Wide:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ DART_FORCE_INLINE static bool IsEntryFixedOpcode(const KBCInstr* instr) {
+ switch (DecodeOpcode(instr)) {
+ case KernelBytecode::kEntryFixed:
+ case KernelBytecode::kEntryFixed_Wide:
return true;
default:
return false;
@@ -941,20 +922,13 @@
}
DART_FORCE_INLINE static bool IsEntryOptionalOpcode(const KBCInstr* instr) {
- switch (DecodeOpcode(instr)) {
- case KernelBytecode::kEntryOptional:
- case KernelBytecode::kEntryOptional_Old:
- return true;
- default:
- return false;
- }
+ return DecodeOpcode(instr) == KernelBytecode::kEntryOptional;
}
DART_FORCE_INLINE static bool IsFrameOpcode(const KBCInstr* instr) {
switch (DecodeOpcode(instr)) {
case KernelBytecode::kFrame:
case KernelBytecode::kFrame_Wide:
- case KernelBytecode::kFrame_Old:
return true;
default:
return false;
@@ -962,33 +936,13 @@
}
DART_FORCE_INLINE static bool IsSetFrameOpcode(const KBCInstr* instr) {
- switch (DecodeOpcode(instr)) {
- case KernelBytecode::kSetFrame:
- case KernelBytecode::kSetFrame_Old:
- return true;
- default:
- return false;
- }
- }
-
- DART_FORCE_INLINE static bool IsCallOpcode_Old(const KBCInstr* instr) {
- switch (DecodeOpcode(instr)) {
- case KernelBytecode::kDirectCall_Old:
- case KernelBytecode::kInterfaceCall_Old:
- case KernelBytecode::kUncheckedInterfaceCall_Old:
- case KernelBytecode::kDynamicCall_Old:
- return true;
-
- default:
- return false;
- }
+ return DecodeOpcode(instr) == KernelBytecode::kSetFrame;
}
DART_FORCE_INLINE static bool IsNativeCallOpcode(const KBCInstr* instr) {
switch (DecodeOpcode(instr)) {
case KernelBytecode::kNativeCall:
case KernelBytecode::kNativeCall_Wide:
- case KernelBytecode::kNativeCall_Old:
return true;
default:
return false;
@@ -1026,19 +980,6 @@
static const uint8_t kNativeCallToGrowableListArgc = 2;
- DART_FORCE_INLINE static uint8_t DecodeArgc_Old(const KBCInstr* ret_addr) {
- const intptr_t kOldInstructionSize = 4;
- const KBCInstr* call = ret_addr - kOldInstructionSize;
- ASSERT(IsOld(call));
- if (DecodeOpcode(call) == KernelBytecode::kNativeCall_Old) {
- // The only NativeCall redirecting to a bytecode function is the call
- // to new _GrowableList<E>(0).
- return kNativeCallToGrowableListArgc;
- }
- ASSERT(IsCallOpcode_Old(call));
- return DecodeA(call);
- }
-
// Returns a fake return address which points after the 2-argument
// bytecode call, followed by ReturnTOS instructions.
static const KBCInstr* GetNativeCallToGrowableListReturnTrampoline();
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 4910847..53d63d0 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -15,7 +15,7 @@
#include "vm/object.h"
#include "vm/simulator.h"
-#if !defined(USING_SIMULATOR)
+#if !defined(TARGET_HOST_MISMATCH)
#include <sys/syscall.h> /* NOLINT */
#include <unistd.h> /* NOLINT */
#endif
@@ -81,7 +81,7 @@
"Use integer division instruction if supported");
#endif
-#if defined(USING_SIMULATOR)
+#if defined(TARGET_HOST_MISMATCH)
#if defined(TARGET_ARCH_ARM_5TE) || defined(TARGET_OS_ANDROID) \
|| defined(TARGET_OS_IOS)
DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the hardfp ABI.");
@@ -96,7 +96,7 @@
UNREACHABLE();
#endif
-#if !defined(USING_SIMULATOR) && !HOST_OS_IOS
+#if !defined(TARGET_HOST_MISMATCH) && HOST_ARCH_ARM && !HOST_OS_IOS
// Nothing to do. Flushing no instructions.
if (size == 0) {
return;
@@ -120,9 +120,9 @@
const char* CPU::Id() {
return
-#if defined(USING_SIMULATOR)
+#if defined(TARGET_HOST_MISMATCH)
"sim"
-#endif // defined(USING_SIMULATOR)
+#endif // defined(TARGET_HOST_MISMATCH)
"arm";
}
@@ -137,7 +137,7 @@
bool HostCPUFeatures::initialized_ = false;
#endif
-#if !defined(USING_SIMULATOR)
+#if !defined(TARGET_HOST_MISMATCH)
#if HOST_OS_IOS
void HostCPUFeatures::Init() {
// TODO(24743): Actually check the CPU features and fail if we're missing
@@ -292,7 +292,7 @@
hardware_ = NULL;
CpuInfo::Cleanup();
}
-#endif // !defined(USING_SIMULATOR)
+#endif // !defined(TARGET_HOST_MISMATCH)
} // namespace dart
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index ce05348..e43381d 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -87,6 +87,7 @@
};
static void CheckOffsets() {
+#if !defined(IS_SIMARM_X64)
// These offsets are embedded in precompiled instructions. We need the
// compiler and the runtime to agree.
bool ok = true;
@@ -124,6 +125,7 @@
#undef CHECK_RANGE
#undef CHECK_CONSTANT
#undef CHECK_OFFSET
+#endif // !defined(IS_SIMARM_X64)
}
char* Dart::Init(const uint8_t* vm_isolate_snapshot,
@@ -138,7 +140,8 @@
Dart_FileCloseCallback file_close,
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
- bool start_kernel_isolate) {
+ bool start_kernel_isolate,
+ Dart_CodeObserver* observer) {
CheckOffsets();
// TODO(iposva): Fix race condition here.
if (vm_isolate_ != NULL || !Flags::Initialized()) {
@@ -192,6 +195,7 @@
set_entropy_source_callback(entropy_source);
OS::Init();
NOT_IN_PRODUCT(CodeObservers::Init());
+ NOT_IN_PRODUCT(CodeObservers::RegisterExternal(observer));
start_time_micros_ = OS::GetCurrentMonotonicMicros();
VirtualMemory::Init();
OSThread::Init();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index aba4a28..64d10f9 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -38,7 +38,8 @@
Dart_FileCloseCallback file_close,
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
- bool start_kernel_isolate);
+ bool start_kernel_isolate,
+ Dart_CodeObserver* observer);
// Returns null if cleanup succeeds, otherwise returns an error message
// (caller owns error message and has to free it).
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index ee31194..35306a3 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5,6 +5,8 @@
#include "include/dart_api.h"
#include "include/dart_native_api.h"
+#include <memory>
+
#include "lib/stacktrace.h"
#include "platform/assert.h"
#include "vm/class_finalizer.h"
@@ -1009,7 +1011,7 @@
params->thread_exit, params->file_open, params->file_read,
params->file_write, params->file_close,
params->entropy_source, params->get_service_assets,
- params->start_kernel_isolate);
+ params->start_kernel_isolate, params->code_observer);
}
DART_EXPORT char* Dart_Cleanup() {
@@ -5042,13 +5044,13 @@
BumpAllocateScope bump_allocate_scope(T);
const char* error = nullptr;
- kernel::Program* program =
+ std::unique_ptr<kernel::Program> program =
kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
if (program == nullptr) {
return Api::NewError("Can't load Kernel binary: %s.", error);
}
- const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
- delete program;
+ const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
+ program.reset();
if (tmp.IsError()) {
return Api::NewHandle(T, tmp.raw());
@@ -5104,6 +5106,7 @@
return Api::NewError("Class '%s' not found in library '%s'.",
cls_name.ToCString(), lib_name.ToCString());
}
+ cls.EnsureDeclarationLoaded();
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
return Api::NewHandle(T, cls.RareType());
}
@@ -5133,6 +5136,7 @@
return Api::NewError("Type '%s' not found in library '%s'.",
name_str.ToCString(), lib_name.ToCString());
}
+ cls.EnsureDeclarationLoaded();
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
if (cls.NumTypeArguments() == 0) {
if (number_of_type_arguments != 0) {
@@ -5288,14 +5292,14 @@
BumpAllocateScope bump_allocate_scope(T);
const char* error = nullptr;
- kernel::Program* program =
+ std::unique_ptr<kernel::Program> program =
kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
if (program == nullptr) {
return Api::NewError("Can't load Kernel binary: %s.", error);
}
const Object& result =
- kernel::KernelLoader::LoadEntireProgram(program, false);
- delete program;
+ kernel::KernelLoader::LoadEntireProgram(program.get(), false);
+ program.reset();
return Api::NewHandle(T, result.raw());
#endif // defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index ca74fa7..2d8ad35 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -300,8 +300,9 @@
#if defined(TARGET_ARCH_DBC) && !defined(ARCH_IS_64_BIT)
// TODO(36809): Support SimDBC32.
return false;
-#elif defined(TARGET_ARCH_DBC) && !defined(HOST_ARCH_X64)
- // TODO(35773): Support ia32, arm64, and arm.
+#elif defined(TARGET_ARCH_DBC) && \
+ !(defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
+ // TODO(36809): Support ia32 and arm.
return false;
#elif defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_X64) && \
defined(HOST_OS_WINDOWS)
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 4841f0d..2035e4a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -57,6 +57,37 @@
EXPECT(Dart_Cleanup() == NULL);
}
+UNIT_TEST_CASE(DartAPI_DartInitializeCallsCodeObserver) {
+ EXPECT(Dart_SetVMFlags(TesterState::argc, TesterState::argv) == NULL);
+ Dart_InitializeParams params;
+ memset(¶ms, 0, sizeof(Dart_InitializeParams));
+ params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+ params.vm_snapshot_data = TesterState::vm_snapshot_data;
+ params.create = TesterState::create_callback;
+ params.shutdown = TesterState::shutdown_callback;
+ params.cleanup = TesterState::cleanup_callback;
+ params.start_kernel_isolate = true;
+
+ bool was_called = false;
+ Dart_CodeObserver code_observer;
+ code_observer.data = &was_called;
+ code_observer.on_new_code = [](Dart_CodeObserver* observer, const char* name,
+ uintptr_t base, uintptr_t size) {
+ *static_cast<bool*>(observer->data) = true;
+ };
+ params.code_observer = &code_observer;
+
+ // Reinitialize and ensure we can execute Dart code.
+ EXPECT(Dart_Initialize(¶ms) == NULL);
+
+ // Wait for 5 seconds to let the kernel service load the snapshot,
+ // which should trigger calls to the code observer.
+ OS::Sleep(5);
+
+ EXPECT(was_called);
+ EXPECT(Dart_Cleanup() == NULL);
+}
+
TEST_CASE(DartAPI_ErrorHandleBasics) {
const char* kScriptChars =
"void testMain() {\n"
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 43f2d64..13bd393 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -391,6 +391,21 @@
current_ += len;
}
+ void WriteTargetWord(uword value) {
+#if defined(IS_SIMARM_X64)
+ RELEASE_ASSERT(Utils::IsInt(32, static_cast<word>(value)));
+ const intptr_t len = sizeof(uint32_t);
+ if ((end_ - current_) < len) {
+ Resize(len);
+ }
+ ASSERT((end_ - current_) >= len);
+ *reinterpret_cast<uint32_t*>(current_) = static_cast<uint32_t>(value);
+ current_ += len;
+#else // defined(IS_SIMARM_X64)
+ WriteWord(value);
+#endif // defined(IS_SIMARM_X64)
+ }
+
void Print(const char* format, ...) {
va_list args;
va_start(args, format);
@@ -430,6 +445,17 @@
WriteByte(static_cast<uint8_t>(v + kEndByteMarker));
}
+ template <typename T>
+ void WriteFixed(T value) {
+ const intptr_t len = sizeof(T);
+ if ((end_ - current_) < len) {
+ Resize(len);
+ }
+ ASSERT((end_ - current_) >= len);
+ *reinterpret_cast<T*>(current_) = static_cast<T>(value);
+ current_ += len;
+ }
+
private:
DART_FORCE_INLINE void WriteByte(uint8_t value) {
if (current_ >= end_) {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index af1ca5c..5a8709b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -304,6 +304,8 @@
}
#endif
if (bytecode_.IsNull()) {
+ // Force-optimize functions should not be debuggable.
+ ASSERT(!function_.ForceOptimize());
function_.EnsureHasCompiledUnoptimizedCode();
code_ = function_.unoptimized_code();
}
@@ -732,14 +734,17 @@
PrintDescriptorsError("Missing local variables info");
}
intptr_t pc_offset = pc_ - bytecode.PayloadStart();
+ // Look for innermost scope, i.e. with the highest context level.
+ // Since scopes are ordered by StartPC(), the last scope which includes
+ // pc_offset will be the innermost one.
kernel::BytecodeLocalVariablesIterator local_vars(zone, bytecode);
while (local_vars.MoveNext()) {
if (local_vars.Kind() ==
kernel::BytecodeLocalVariablesIterator::kScope) {
if (local_vars.StartPC() <= pc_offset &&
pc_offset < local_vars.EndPC()) {
+ ASSERT(context_level_ <= local_vars.ContextLevel());
context_level_ = local_vars.ContextLevel();
- break;
}
}
}
@@ -747,7 +752,6 @@
// Obtain the context level from the parent function.
// TODO(alexmarkov): Define scope which includes the whole closure body.
Function& parent = Function::Handle(zone, function().parent_function());
- intptr_t depth = 1;
do {
bytecode = parent.bytecode();
kernel::BytecodeLocalVariablesIterator local_vars(zone, bytecode);
@@ -756,14 +760,13 @@
kernel::BytecodeLocalVariablesIterator::kScope) {
if (local_vars.StartTokenPos() <= TokenPos() &&
TokenPos() <= local_vars.EndTokenPos()) {
- context_level_ = local_vars.ContextLevel() + depth;
- break;
+ ASSERT(context_level_ <= local_vars.ContextLevel());
+ context_level_ = local_vars.ContextLevel();
}
}
}
if (context_level_ >= 0) break;
parent = parent.parent_function();
- depth++;
} while (!parent.IsNull());
}
if (context_level_ < 0) {
@@ -946,23 +949,7 @@
return false;
}
-void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
- // Attempt to determine the token pos and try index from the async closure.
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- const Script& script = Script::Handle(zone, function().script());
-
- ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
- // This should only be called on frames that aren't active on the stack.
- ASSERT(fp() == 0);
-
- 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;
- }
+intptr_t ActivationFrame::GetAwaitJumpVariable() {
GetVarDescriptors();
intptr_t var_desc_len = var_descriptors_.Length();
intptr_t await_jump_var = -1;
@@ -978,6 +965,59 @@
await_jump_var = Smi::Cast(await_jump_index).Value();
}
}
+ return await_jump_var;
+}
+
+void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
+ // Attempt to determine the token pos and try index from the async closure.
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ const Script& script = Script::Handle(zone, function().script());
+
+ ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
+ // This should only be called on frames that aren't active on the stack.
+ ASSERT(fp() == 0);
+
+ if (function_.is_declared_in_bytecode()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ const auto& bytecode = Bytecode::Handle(zone, function_.bytecode());
+ if (!bytecode.HasSourcePositions()) {
+ return;
+ }
+ const intptr_t await_jump_var = GetAwaitJumpVariable();
+ if (await_jump_var < 0) {
+ return;
+ }
+ // Yield points are counted from 1 (0 is reserved for normal entry).
+ intptr_t yield_point_index = 1;
+ kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
+ while (iter.MoveNext()) {
+ if (iter.IsYieldPoint()) {
+ if (yield_point_index == await_jump_var) {
+ token_pos_ = iter.TokenPos();
+ token_pos_initialized_ = true;
+ try_index_ = bytecode.GetTryIndexAtPc(bytecode.PayloadStart() +
+ iter.PcOffset());
+ return;
+ }
+ ++yield_point_index;
+ }
+ }
+ return;
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+
+ 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;
}
@@ -1009,29 +1049,6 @@
ASSERT(token_pos.IsSmi());
token_pos_ = TokenPosition(Smi::Cast(token_pos).Value());
token_pos_initialized_ = true;
- if (IsInterpreted()) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
- // In order to determine the try index, we need to map the token position
- // to a pc offset, and then a pc offset to the try index.
- // TODO(regis): Should we set the token position fields in pc descriptors?
- uword pc_offset = kUwordMax;
- kernel::BytecodeSourcePositionsIterator iter(zone, bytecode());
- while (iter.MoveNext()) {
- // PcOffsets are monotonic in source positions, so we get the lowest one.
- if (iter.TokenPos() == token_pos_) {
- pc_offset = iter.PcOffset();
- break;
- }
- }
- if (pc_offset < kUwordMax) {
- try_index_ =
- bytecode().GetTryIndexAtPc(bytecode().PayloadStart() + pc_offset);
- }
-#else
- UNREACHABLE();
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
- return;
- }
GetPcDescriptors();
PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
while (iter.MoveNext()) {
@@ -1985,6 +2002,12 @@
for (intptr_t pos = 0; pos < num_functions; pos++) {
function ^= functions.At(pos);
ASSERT(!function.IsNull());
+ // Force-optimized functions don't have unoptimized code and can't
+ // deoptimize. Their optimized codes are still valid.
+ if (function.ForceOptimize()) {
+ ASSERT(!function.HasImplicitClosureFunction());
+ continue;
+ }
if (function.HasOptimizedCode()) {
function.SwitchToUnoptimizedCode();
}
@@ -2316,6 +2339,7 @@
Thread::Current(),
StackFrameIterator::kNoCrossThreadIteration);
+ Object& code_object = Object::Handle(zone);
Code& code = Code::Handle(zone);
Bytecode& bytecode = Bytecode::Handle(zone);
Smi& offset = Smi::Handle(zone);
@@ -2513,17 +2537,24 @@
// the readability of the trace.
i++;
} else {
- code = Code::RawCast(async_stack_trace.CodeAtFrame(i));
+ code_object = async_stack_trace.CodeAtFrame(i);
offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
- uword pc = code.PayloadStart() + offset.Value();
- if (code.is_optimized()) {
- for (InlinedFunctionsIterator it(code, pc); !it.Done();
- it.Advance()) {
- inlined_code = it.code();
- stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
- }
+ if (code_object.IsBytecode()) {
+ bytecode ^= code_object.raw();
+ uword pc = bytecode.PayloadStart() + offset.Value();
+ stack_trace->AddAsyncCausalFrame(pc, bytecode);
} else {
- stack_trace->AddAsyncCausalFrame(pc, code);
+ code ^= code_object.raw();
+ uword pc = code.PayloadStart() + offset.Value();
+ if (code.is_optimized()) {
+ for (InlinedFunctionsIterator it(code, pc); !it.Done();
+ it.Advance()) {
+ inlined_code = it.code();
+ stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
+ }
+ } else {
+ stack_trace->AddAsyncCausalFrame(pc, code);
+ }
}
}
}
@@ -3523,7 +3554,11 @@
Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
bool single_shot) {
ASSERT(!target_function.IsNull());
- if (!target_function.is_debuggable()) {
+ // AsyncFunction is marked not debuggable. When target_function is an async
+ // function, it is actually referring the inner async_op. Allow the
+ // breakpoint to be set, it will get resolved correctly when inner async_op
+ // gets compiled.
+ if (!target_function.is_debuggable() && !target_function.IsAsyncFunction()) {
return NULL;
}
const Script& script = Script::Handle(target_function.script());
@@ -4154,6 +4189,23 @@
if (!closure_or_null.IsNull()) {
ASSERT(closure_or_null.IsInstance());
ASSERT(Instance::Cast(closure_or_null).IsClosure());
+ if (top_frame->function().is_declared_in_bytecode()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ const auto& bytecode =
+ Bytecode::Handle(zone, top_frame->function().bytecode());
+ const TokenPosition token_pos = top_frame->TokenPos();
+ kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
+ while (iter.MoveNext()) {
+ if (iter.IsYieldPoint() && (iter.TokenPos() == token_pos)) {
+ return true;
+ }
+ }
+ return false;
+#else
+ UNREACHABLE();
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+ 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)?
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 39a2c89..09e6c83 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -388,6 +388,7 @@
RawObject* GetAsyncStreamControllerStream();
RawObject* GetAsyncCompleterAwaiter(const Object& completer);
RawObject* GetAsyncCompleter();
+ intptr_t GetAwaitJumpVariable();
void ExtractTokenPositionFromAsyncClosure();
bool IsAsyncMachinery() const;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 1a71bf6..b28c397 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -1165,6 +1165,7 @@
deopt_instr =
new (zone()) DeoptUint32Instr(ToCpuRegisterSource(source_loc));
break;
+ case kUnboxedFloat:
case kUnboxedDouble:
deopt_instr = new (zone()) DeoptDoubleInstr(
ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 2852a43..eb8434a 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -32,6 +32,12 @@
constexpr bool kDartPrecompiledRuntime = false;
#endif
+#if defined(DART_USE_BYTECODE)
+constexpr bool kDartUseBytecode = true;
+#else
+constexpr bool kDartUseBytecode = false;
+#endif
+
// List of all flags in the VM.
// Flags can be one of three categories:
// * P roduct flags: Can be set in any of the deployment modes, including in
@@ -191,7 +197,7 @@
D(trace_zones, bool, false, "Traces allocation sizes in the zone.") \
P(truncating_left_shift, bool, true, \
"Optimize left shift to truncate if possible") \
- P(use_bytecode_compiler, bool, false, "Compile from bytecode") \
+ P(use_bytecode_compiler, bool, kDartUseBytecode, "Compile from bytecode") \
P(use_compactor, bool, false, "Compact the heap during old-space GC.") \
P(use_cha_deopt, bool, true, \
"Use class hierarchy analysis even if it can cause deoptimization.") \
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 1734984c..682ee90 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -96,7 +96,7 @@
#define SUPPORT_TIMELINE 1
#endif
-#if defined(ARCH_IS_64_BIT)
+#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_X64)
#define HASH_IN_OBJECT_HEADER 1
#endif
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index fe46279..f216ef0 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -182,9 +182,88 @@
return offset;
}
+#if defined(IS_SIMARM_X64)
+static intptr_t StackMapSizeInSnapshot(intptr_t len_in_bits) {
+ const intptr_t len_in_bytes =
+ Utils::RoundUp(len_in_bits, kBitsPerByte) / kBitsPerByte;
+ const intptr_t unrounded_size_in_bytes =
+ 3 * compiler::target::kWordSize + len_in_bytes;
+ return Utils::RoundUp(unrounded_size_in_bytes,
+ compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t StringPayloadSize(intptr_t len, bool isOneByteString) {
+ return len * (isOneByteString ? OneByteString::kBytesPerElement
+ : TwoByteString::kBytesPerElement);
+}
+
+static intptr_t StringSizeInSnapshot(intptr_t len, bool isOneByteString) {
+ const intptr_t unrounded_size_in_bytes =
+ (String::kSizeofRawString / 2) + StringPayloadSize(len, isOneByteString);
+ return Utils::RoundUp(unrounded_size_in_bytes,
+ compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t CodeSourceMapSizeInSnapshot(intptr_t len) {
+ const intptr_t unrounded_size_in_bytes =
+ 2 * compiler::target::kWordSize + len;
+ return Utils::RoundUp(unrounded_size_in_bytes,
+ compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t PcDescriptorsSizeInSnapshot(intptr_t len) {
+ const intptr_t unrounded_size_in_bytes =
+ 2 * compiler::target::kWordSize + len;
+ return Utils::RoundUp(unrounded_size_in_bytes,
+ compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static constexpr intptr_t kSimarmX64InstructionsAlignment =
+ 2 * compiler::target::ObjectAlignment::kObjectAlignment;
+static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
+ const intptr_t header_size = Utils::RoundUp(3 * compiler::target::kWordSize,
+ kSimarmX64InstructionsAlignment);
+ return header_size + Utils::RoundUp(len, kSimarmX64InstructionsAlignment);
+}
+
+intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
+ const classid_t cid = raw_object->GetClassId();
+
+ switch (cid) {
+ case kStackMapCid: {
+ RawStackMap* raw_map = static_cast<RawStackMap*>(raw_object);
+ return StackMapSizeInSnapshot(raw_map->ptr()->length_);
+ }
+ case kOneByteStringCid:
+ case kTwoByteStringCid: {
+ RawString* raw_str = static_cast<RawString*>(raw_object);
+ return StringSizeInSnapshot(Smi::Value(raw_str->ptr()->length_),
+ cid == kOneByteStringCid);
+ }
+ case kCodeSourceMapCid: {
+ RawCodeSourceMap* raw_map = static_cast<RawCodeSourceMap*>(raw_object);
+ return CodeSourceMapSizeInSnapshot(raw_map->ptr()->length_);
+ }
+ case kPcDescriptorsCid: {
+ RawPcDescriptors* raw_desc = static_cast<RawPcDescriptors*>(raw_object);
+ return PcDescriptorsSizeInSnapshot(raw_desc->ptr()->length_);
+ }
+ case kInstructionsCid: {
+ RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
+ return InstructionsSizeInSnapshot(Instructions::Size(raw_insns));
+ }
+ default: {
+ const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
+ FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
+ return 0;
+ }
+ }
+}
+#else // defined(IS_SIMARM_X64)
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
return raw_object->HeapSize();
}
+#endif // defined(IS_SIMARM_X64)
bool ImageWriter::GetSharedDataOffsetFor(RawObject* raw_object,
uint32_t* offset) {
@@ -348,12 +427,76 @@
#if defined(HASH_IN_OBJECT_HEADER)
marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32;
#endif
+
+#if defined(IS_SIMARM_X64)
+ if (obj.IsStackMap()) {
+ const StackMap& map = StackMap::Cast(obj);
+
+ // Header layout is the same between 32-bit and 64-bit architecture, but
+ // we need to recalcuate the size in words.
+ const intptr_t len_in_bits = map.Length();
+ const intptr_t len_in_bytes =
+ Utils::RoundUp(len_in_bits, kBitsPerByte) / kBitsPerByte;
+ const intptr_t size_in_bytes = StackMapSizeInSnapshot(len_in_bits);
+ marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+ stream->WriteTargetWord(marked_tags);
+ stream->WriteFixed<uint32_t>(map.PcOffset());
+ stream->WriteFixed<uint16_t>(map.Length());
+ stream->WriteFixed<uint16_t>(map.SlowPathBitCount());
+ stream->WriteBytes(map.raw()->ptr()->data(), len_in_bytes);
+ stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+
+ } else if (obj.IsString()) {
+ const String& str = String::Cast(obj);
+ RELEASE_ASSERT(String::GetCachedHash(str.raw()) != 0);
+ RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());
+ const intptr_t size_in_bytes =
+ StringSizeInSnapshot(str.Length(), str.IsOneByteString());
+ marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+ stream->WriteTargetWord(marked_tags);
+ stream->WriteTargetWord(
+ reinterpret_cast<uword>(str.raw()->ptr()->length_));
+ stream->WriteTargetWord(reinterpret_cast<uword>(str.raw()->ptr()->hash_));
+ stream->WriteBytes(
+ reinterpret_cast<const void*>(start + String::kSizeofRawString),
+ StringPayloadSize(str.Length(), str.IsOneByteString()));
+ stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+ } else if (obj.IsCodeSourceMap()) {
+ const CodeSourceMap& map = CodeSourceMap::Cast(obj);
+
+ const intptr_t size_in_bytes = CodeSourceMapSizeInSnapshot(map.Length());
+ marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+ stream->WriteTargetWord(marked_tags);
+ stream->WriteTargetWord(map.Length());
+ stream->WriteBytes(map.Data(), map.Length());
+ stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+ } else if (obj.IsPcDescriptors()) {
+ const PcDescriptors& desc = PcDescriptors::Cast(obj);
+
+ const intptr_t size_in_bytes = PcDescriptorsSizeInSnapshot(desc.Length());
+ marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+ stream->WriteTargetWord(marked_tags);
+ stream->WriteTargetWord(desc.Length());
+ stream->WriteBytes(desc.raw()->ptr()->data(), desc.Length());
+ stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+ } else {
+ const Class& clazz = Class::Handle(obj.clazz());
+ FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
+ }
+ USE(start);
+ USE(end);
+#else // defined(IS_SIMARM_X64)
stream->WriteWord(marked_tags);
start += sizeof(uword);
for (uword* cursor = reinterpret_cast<uword*>(start);
cursor < reinterpret_cast<uword*>(end); cursor++) {
stream->WriteWord(*cursor);
}
+#endif // defined(IS_SIMARM_X64)
}
}
@@ -774,10 +917,28 @@
marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
#endif
+#if defined(IS_SIMARM_X64)
+ const intptr_t start_offset = instructions_blob_stream_.bytes_written();
+ const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.Size());
+ marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+ instructions_blob_stream_.WriteTargetWord(marked_tags);
+ instructions_blob_stream_.WriteFixed<uint32_t>(
+ insns.raw_ptr()->size_and_flags_);
+ instructions_blob_stream_.WriteFixed<uint32_t>(
+ insns.raw_ptr()->unchecked_entrypoint_pc_offset_);
+ instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
+ instructions_blob_stream_.WriteBytes(
+ reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
+ instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
+ const intptr_t end_offset = instructions_blob_stream_.bytes_written();
+ text_offset += (end_offset - start_offset);
+ USE(end);
+#else // defined(IS_SIMARM_X64)
instructions_blob_stream_.WriteWord(marked_tags);
text_offset += sizeof(uword);
beginning += sizeof(uword);
text_offset += WriteByteSequence(beginning, end);
+#endif // defined(IS_SIMARM_X64)
ASSERT((text_offset - instr_start) ==
ImageWriter::SizeInSnapshot(insns.raw()));
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index c83e454..b466015 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -256,6 +256,28 @@
return RawObject::FromAddr(addr);
}
+DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
+ intptr_t class_id,
+ intptr_t instance_size,
+ RawObject** result) {
+ const uword start = thread->top();
+#ifndef PRODUCT
+ ClassTable* table = thread->isolate()->class_table();
+ if (UNLIKELY(table->TraceAllocationFor(class_id))) {
+ return false;
+ }
+#endif
+ if (LIKELY((start + instance_size) < thread->end())) {
+ thread->set_top(start + instance_size);
+#ifndef PRODUCT
+ table->UpdateAllocatedNew(class_id, instance_size);
+#endif
+ *result = InitializeHeader(start, class_id, instance_size);
+ return true;
+ }
+ return false;
+}
+
void LookupCache::Clear() {
for (intptr_t i = 0; i < kNumEntries; i++) {
entries_[i].receiver_cid = kIllegalCid;
@@ -382,9 +404,9 @@
Thread* thread = Thread::Current();
Interpreter* interpreter = thread->interpreter();
if (interpreter == nullptr) {
- TransitionGeneratedToVM transition(thread);
+ NoSafepointScope no_safepoint;
interpreter = new Interpreter();
- Thread::Current()->set_interpreter(interpreter);
+ thread->set_interpreter(interpreter);
}
return interpreter;
}
@@ -910,20 +932,11 @@
#define BYTECODE_ENTRY_LABEL(Name) bc##Name:
#define BYTECODE_WIDE_ENTRY_LABEL(Name) bc##Name##_Wide:
-#define BYTECODE_OLD_ENTRY_LABEL(Name) bc##Name##_Old:
#define BYTECODE_IMPL_LABEL(Name) bc##Name##Impl:
#define GOTO_BYTECODE_IMPL(Name) goto bc##Name##Impl;
// Define entry point that handles bytecode Name with the given operand format.
-#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands##_WITH_OLD(Name)
-
-// TODO(alexmarkov): switch BYTECODE macro to BYTECODE_NEW implementation
-// and replace BYTECODE_NEW with BYTECODE when old instructions are gone.
-// Cleanup BYTECODE_HEADER_*_WITH_OLD macros and drop _WITH_OLD.
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
-
-#define BYTECODE_NEW(Name, Operands) BYTECODE_HEADER_##Operands(Name)
+#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands(Name)
// Helpers to decode common instruction formats. Used in conjunction with
// BYTECODE() macro.
@@ -932,32 +945,16 @@
BYTECODE_ENTRY_LABEL(Name) \
pc += 1;
-#define BYTECODE_HEADER_0_WITH_OLD(Name) \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
- BYTECODE_HEADER_0(Name) \
- BYTECODE_IMPL_LABEL(Name)
-
-#define BYTECODE_HEADER_A_WITH_OLD(Name) \
+#define BYTECODE_HEADER_A(Name) \
uint32_t rA; \
USE(rA); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rA = pc[1]; \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_ENTRY_LABEL(Name) \
rA = pc[1]; \
- pc += 2; \
- BYTECODE_IMPL_LABEL(Name)
+ pc += 2;
-#define BYTECODE_HEADER_D_WITH_OLD(Name) \
+#define BYTECODE_HEADER_D(Name) \
uint32_t rD; \
USE(rD); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) | \
(static_cast<uint32_t>(pc[3]) << 16) | \
@@ -969,14 +966,9 @@
pc += 2; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_X_WITH_OLD(Name) \
+#define BYTECODE_HEADER_X(Name) \
int32_t rX; \
USE(rX); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rX = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) | \
- (static_cast<uint16_t>(pc[3]) << 8)); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rX = static_cast<int32_t>(static_cast<uint32_t>(pc[1]) | \
(static_cast<uint32_t>(pc[2]) << 8) | \
@@ -989,16 +981,9 @@
pc += 2; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_T_WITH_OLD(Name) \
+#define BYTECODE_HEADER_T(Name) \
const KBCInstr* rT; \
USE(rT); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) | \
- (static_cast<uint32_t>(pc[2]) << 16) | \
- (static_cast<uint32_t>(pc[3]) << 24)) >> \
- (8 - 2)); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) | \
(static_cast<uint32_t>(pc[2]) << 16) | \
@@ -1011,15 +996,10 @@
pc += 2; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_A_E_WITH_OLD(Name) \
+#define BYTECODE_HEADER_A_E(Name) \
uint32_t rA, rE; \
USE(rA); \
USE(rE); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rA = pc[1]; \
- rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rA = pc[1]; \
rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8) | \
@@ -1033,17 +1013,11 @@
pc += 3; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_A_Y_WITH_OLD(Name) \
+#define BYTECODE_HEADER_A_Y(Name) \
uint32_t rA; \
int32_t rY; \
USE(rA); \
USE(rY); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rA = pc[1]; \
- rY = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) | \
- (static_cast<uint16_t>(pc[3]) << 8)); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rA = pc[1]; \
rY = static_cast<int32_t>(static_cast<uint32_t>(pc[2]) | \
@@ -1058,15 +1032,10 @@
pc += 3; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_D_F_WITH_OLD(Name) \
+#define BYTECODE_HEADER_D_F(Name) \
uint32_t rD, rF; \
USE(rD); \
USE(rF); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
- rF = pc[1]; \
- rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8); \
- pc += 4; \
- GOTO_BYTECODE_IMPL(Name); \
BYTECODE_WIDE_ENTRY_LABEL(Name) \
rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) | \
(static_cast<uint32_t>(pc[3]) << 16) | \
@@ -1080,12 +1049,11 @@
pc += 3; \
BYTECODE_IMPL_LABEL(Name)
-#define BYTECODE_HEADER_A_B_C_WITH_OLD(Name) \
+#define BYTECODE_HEADER_A_B_C(Name) \
uint32_t rA, rB, rC; \
USE(rA); \
USE(rB); \
USE(rC); \
- BYTECODE_OLD_ENTRY_LABEL(Name) \
BYTECODE_ENTRY_LABEL(Name) \
rA = pc[1]; \
rB = pc[2]; \
@@ -1405,12 +1373,9 @@
RawObject** FP,
RawObject** SP) {
ASSERT(!Smi::IsValid(value));
- const intptr_t instance_size = Mint::InstanceSize();
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawMint* result =
- Mint::RawCast(InitializeHeader(start, kMintCid, instance_size));
+ RawMint* result;
+ if (TryAllocate(thread, kMintCid, Mint::InstanceSize(),
+ reinterpret_cast<RawObject**>(&result))) {
result->ptr()->value_ = value;
SP[0] = result;
return true;
@@ -1435,12 +1400,9 @@
const KBCInstr* pc,
RawObject** FP,
RawObject** SP) {
- const intptr_t instance_size = Double::InstanceSize();
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawDouble* result =
- Double::RawCast(InitializeHeader(start, kDoubleCid, instance_size));
+ RawDouble* result;
+ if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(),
+ reinterpret_cast<RawObject**>(&result))) {
result->ptr()->value_ = value;
SP[0] = result;
return true;
@@ -1465,12 +1427,9 @@
const KBCInstr* pc,
RawObject** FP,
RawObject** SP) {
- const intptr_t instance_size = Float32x4::InstanceSize();
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawFloat32x4* result = Float32x4::RawCast(
- InitializeHeader(start, kFloat32x4Cid, instance_size));
+ RawFloat32x4* result;
+ if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(),
+ reinterpret_cast<RawObject**>(&result))) {
value.writeTo(result->ptr()->value_);
SP[0] = result;
return true;
@@ -1495,12 +1454,9 @@
const KBCInstr* pc,
RawObject** FP,
RawObject** SP) {
- const intptr_t instance_size = Float64x2::InstanceSize();
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawFloat64x2* result = Float64x2::RawCast(
- InitializeHeader(start, kFloat64x2Cid, instance_size));
+ RawFloat64x2* result;
+ if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(),
+ reinterpret_cast<RawObject**>(&result))) {
value.writeTo(result->ptr()->value_);
SP[0] = result;
return true;
@@ -1529,12 +1485,9 @@
if (LIKELY(!length_object->IsHeapObject())) {
const intptr_t length = Smi::Value(Smi::RawCast(length_object));
if (LIKELY(Array::IsValidLength(length))) {
- const intptr_t instance_size = Array::InstanceSize(length);
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawArray* result =
- Array::RawCast(InitializeHeader(start, kArrayCid, instance_size));
+ RawArray* result;
+ if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length),
+ reinterpret_cast<RawObject**>(&result))) {
result->ptr()->type_arguments_ = type_args;
result->ptr()->length_ = Smi::New(length);
for (intptr_t i = 0; i < length; i++) {
@@ -1561,19 +1514,15 @@
const KBCInstr* pc,
RawObject** FP,
RawObject** SP) {
- const intptr_t instance_size = Context::InstanceSize(num_context_variables);
- ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawContext* result =
- Context::RawCast(InitializeHeader(start, kContextCid, instance_size));
+ RawContext* result;
+ if (TryAllocate(thread, kContextCid,
+ Context::InstanceSize(num_context_variables),
+ reinterpret_cast<RawObject**>(&result))) {
result->ptr()->num_variables_ = num_context_variables;
RawObject* null_value = Object::null();
result->ptr()->parent_ = static_cast<RawContext*>(null_value);
- for (intptr_t offset = sizeof(RawContext); offset < instance_size;
- offset += kWordSize) {
- *reinterpret_cast<RawObject**>(start + offset) = null_value;
+ for (intptr_t i = 0; i < num_context_variables; i++) {
+ result->ptr()->data()[i] = null_value;
}
SP[0] = result;
return true;
@@ -1593,11 +1542,10 @@
RawObject** FP,
RawObject** SP) {
const intptr_t instance_size = Closure::InstanceSize();
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawClosure* result =
- Closure::RawCast(InitializeHeader(start, kClosureCid, instance_size));
+ RawClosure* result;
+ if (TryAllocate(thread, kClosureCid, instance_size,
+ reinterpret_cast<RawObject**>(&result))) {
+ uword start = RawObject::ToAddr(result);
RawObject* null_value = Object::null();
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
offset += kWordSize) {
@@ -2112,32 +2060,38 @@
}
} break;
case MethodRecognizer::kGrowableArrayLength: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
- instance->ptr())[GrowableObjectArray::length_offset() / kWordSize];
+ RawGrowableObjectArray* instance =
+ reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+ SP[0] = instance->ptr()->length_;
} break;
case MethodRecognizer::kObjectArrayLength:
case MethodRecognizer::kImmutableArrayLength: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
- instance->ptr())[Array::length_offset() / kWordSize];
+ RawArray* instance = reinterpret_cast<RawArray*>(SP[0]);
+ SP[0] = instance->ptr()->length_;
} break;
case MethodRecognizer::kTypedListLength:
case MethodRecognizer::kTypedListViewLength:
case MethodRecognizer::kByteDataViewLength: {
- RawInstance* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
- SP[0] = reinterpret_cast<RawObject**>(
- instance->ptr())[TypedDataBase::length_offset() / kWordSize];
+ RawTypedDataBase* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
+ SP[0] = instance->ptr()->length_;
+ } break;
+ case MethodRecognizer::kByteDataViewOffsetInBytes:
+ case MethodRecognizer::kTypedDataViewOffsetInBytes: {
+ RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+ SP[0] = instance->ptr()->offset_in_bytes_;
+ } break;
+ case MethodRecognizer::kByteDataViewTypedData:
+ case MethodRecognizer::kTypedDataViewTypedData: {
+ RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+ SP[0] = instance->ptr()->typed_data_;
} break;
case MethodRecognizer::kClassIDgetID: {
SP[0] = InterpreterHelpers::GetClassIdAsSmi(SP[0]);
} break;
case MethodRecognizer::kGrowableArrayCapacity: {
- RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
- instance = reinterpret_cast<RawInstance**>(
- instance->ptr())[GrowableObjectArray::data_offset() / kWordSize];
- SP[0] = reinterpret_cast<RawObject**>(
- instance->ptr())[Array::length_offset() / kWordSize];
+ RawGrowableObjectArray* instance =
+ reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+ SP[0] = instance->ptr()->data_->ptr()->length_;
} break;
case MethodRecognizer::kListFactory: {
// factory List<E>([int length]) {
@@ -2161,12 +2115,10 @@
// Change the ArgumentsDescriptor of the call with a new cached one.
argdesc_ = ArgumentsDescriptor::New(
0, KernelBytecode::kNativeCallToGrowableListArgc);
- if (!thread->isolate()->is_using_old_bytecode_instructions()) {
- // Replace PC to the return trampoline so ReturnTOS would see
- // a call bytecode at return address and will be able to get argc
- // via DecodeArgc.
- pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline();
- }
+ // Replace PC to the return trampoline so ReturnTOS would see
+ // a call bytecode at return address and will be able to get argc
+ // via DecodeArgc.
+ pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline();
if (!Invoke(thread, SP - 1, SP + 1, &pc, &FP, &SP)) {
HANDLE_EXCEPTION;
}
@@ -2317,9 +2269,7 @@
}
// Look at the caller to determine how many arguments to pop.
- const uint8_t argc = thread->isolate()->is_using_old_bytecode_instructions()
- ? KernelBytecode::DecodeArgc_Old(pc)
- : KernelBytecode::DecodeArgc(pc);
+ const uint8_t argc = KernelBytecode::DecodeArgc(pc);
// Restore SP, FP and PP. Push result and dispatch.
SP = FrameArguments(FP, argc);
@@ -2536,10 +2486,9 @@
const intptr_t class_id = cls->ptr()->id_;
const intptr_t instance_size = cls->ptr()->instance_size_in_words_
<< kWordSizeLog2;
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawObject* result = InitializeHeader(start, class_id, instance_size);
+ RawObject* result;
+ if (TryAllocate(thread, class_id, instance_size, &result)) {
+ uword start = RawObject::ToAddr(result);
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
offset += kWordSize) {
*reinterpret_cast<RawObject**>(start + offset) = null_value;
@@ -2567,10 +2516,9 @@
const intptr_t class_id = cls->ptr()->id_;
const intptr_t instance_size = cls->ptr()->instance_size_in_words_
<< kWordSizeLog2;
- const uword start = thread->top();
- if (LIKELY((start + instance_size) < thread->end())) {
- thread->set_top(start + instance_size);
- RawObject* result = InitializeHeader(start, class_id, instance_size);
+ RawObject* result;
+ if (TryAllocate(thread, class_id, instance_size, &result)) {
+ uword start = RawObject::ToAddr(result);
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
offset += kWordSize) {
*reinterpret_cast<RawObject**>(start + offset) = null_value;
@@ -3070,51 +3018,27 @@
}
{
- BYTECODE(Trap, 0);
- BYTECODE(Unused00, 0);
- BYTECODE_NEW(Unused01, 0);
- BYTECODE_NEW(Unused02, 0);
- BYTECODE_NEW(Unused03, 0);
- BYTECODE_NEW(Unused04, 0);
- BYTECODE_NEW(Unused05, 0);
- BYTECODE_NEW(Unused06, 0);
- BYTECODE_NEW(Unused07, 0);
- BYTECODE_NEW(Unused08, 0);
- BYTECODE_NEW(Unused09, 0);
- BYTECODE_NEW(Unused10, 0);
- BYTECODE_NEW(Unused11, 0);
- BYTECODE_NEW(Unused12, 0);
- BYTECODE_NEW(Unused13, 0);
- BYTECODE_NEW(Unused14, 0);
- BYTECODE_NEW(Unused15, 0);
- BYTECODE_NEW(Unused16, 0);
- BYTECODE_NEW(Unused17, 0);
- BYTECODE_NEW(Unused18, 0);
- BYTECODE_NEW(Unused19, 0);
- BYTECODE_NEW(Unused20, 0);
- BYTECODE_NEW(Unused21, 0);
- BYTECODE_NEW(Unused22, 0);
- BYTECODE_NEW(Unused23, 0);
- BYTECODE_NEW(Unused24, 0);
- BYTECODE_NEW(Unused25, 0);
- BYTECODE_NEW(Unused26, 0);
- BYTECODE_NEW(Unused27, 0);
- BYTECODE_NEW(Unused28, 0);
- BYTECODE_NEW(Unused29, 0);
- BYTECODE_NEW(Unused30, 0);
- BYTECODE_NEW(Unused31, 0);
- BYTECODE_NEW(Unused32, 0);
- BYTECODE_NEW(Unused33, 0);
- BYTECODE_NEW(Unused34, 0);
- BYTECODE_NEW(Unused35, 0);
- BYTECODE_NEW(Unused36, 0);
- BYTECODE_NEW(Unused37, 0);
+ BYTECODE_ENTRY_LABEL(Trap);
+
+#define UNIMPLEMENTED_LABEL_ORDN(Name)
+#define UNIMPLEMENTED_LABEL_WIDE(Name)
+#define UNIMPLEMENTED_LABEL_RESV(Name) BYTECODE_ENTRY_LABEL(Name)
+#define UNIMPLEMENTED_LABEL(name, encoding, kind, op1, op2, op3) \
+ UNIMPLEMENTED_LABEL_##kind(name)
+
+ KERNEL_BYTECODES_LIST(UNIMPLEMENTED_LABEL)
+
+#undef UNIMPLEMENTED_LABEL_ORDN
+#undef UNIMPLEMENTED_LABEL_WIDE
+#undef UNIMPLEMENTED_LABEL_RESV
+#undef UNIMPLEMENTED_LABEL
+
UNIMPLEMENTED();
DISPATCH();
}
{
- BYTECODE_NEW(VMInternal_ImplicitGetter, 0);
+ BYTECODE(VMInternal_ImplicitGetter, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kImplicitGetter);
@@ -3163,7 +3087,7 @@
}
{
- BYTECODE_NEW(VMInternal_ImplicitSetter, 0);
+ BYTECODE(VMInternal_ImplicitSetter, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kImplicitSetter);
@@ -3284,7 +3208,7 @@
}
{
- BYTECODE_NEW(VMInternal_ImplicitStaticGetter, 0);
+ BYTECODE(VMInternal_ImplicitStaticGetter, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kImplicitStaticGetter);
@@ -3316,7 +3240,7 @@
}
{
- BYTECODE_NEW(VMInternal_MethodExtractor, 0);
+ BYTECODE(VMInternal_MethodExtractor, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kMethodExtractor);
@@ -3356,7 +3280,7 @@
}
{
- BYTECODE_NEW(VMInternal_InvokeClosure, 0);
+ BYTECODE(VMInternal_InvokeClosure, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3378,7 +3302,7 @@
}
{
- BYTECODE_NEW(VMInternal_InvokeField, 0);
+ BYTECODE(VMInternal_InvokeField, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3482,7 +3406,7 @@
}
{
- BYTECODE_NEW(VMInternal_ForwardDynamicInvocation, 0);
+ BYTECODE(VMInternal_ForwardDynamicInvocation, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) ==
RawFunction::kDynamicInvocationForwarder);
@@ -3584,14 +3508,14 @@
}
{
- BYTECODE_NEW(VMInternal_NoSuchMethodDispatcher, 0);
+ BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
goto NoSuchMethodFromPrologue;
}
{
- BYTECODE_NEW(VMInternal_ImplicitStaticClosure, 0);
+ BYTECODE(VMInternal_ImplicitStaticClosure, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
UNIMPLEMENTED();
@@ -3599,7 +3523,7 @@
}
{
- BYTECODE_NEW(VMInternal_ImplicitInstanceClosure, 0);
+ BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
RawFunction* function = FrameFunction(FP);
ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
UNIMPLEMENTED();
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 11e65e9..000375c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2561,6 +2561,7 @@
!had_isolate_reload_context ? 0 : reload_context()->start_time_micros();
#endif // !defined(DART_PRECOMPILED_RUNTIME)
bool resume = false;
+ bool handle_non_service_messages = false;
while (true) {
// Handle all available vm service messages, up to a resume
// request.
@@ -2571,6 +2572,8 @@
}
if (resume) {
break;
+ } else {
+ handle_non_service_messages = true;
}
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -2589,6 +2592,13 @@
Monitor::WaitResult res = ml.Wait();
ASSERT(res == Monitor::kNotified);
}
+ // If any non-service messages came in, we need to notify the registered
+ // message notify callback to check for unhandled messages. Otherwise, events
+ // may be left unhandled until the next event comes in. See
+ // https://github.com/dart-lang/sdk/issues/37312.
+ if ((saved_notify_callback != nullptr) && handle_non_service_messages) {
+ saved_notify_callback(Api::CastIsolate(this));
+ }
set_message_notify_callback(saved_notify_callback);
Dart_ExitScope();
}
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 5d76a92..6c6ee8e 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -781,23 +781,6 @@
return !unsafe_trust_strong_mode_types();
}
- static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup support for old bytecode format versions");
- bool is_using_old_bytecode_instructions() const {
- return UsingOldBytecodeInstructionsBit::decode(isolate_flags_);
- }
- void set_is_using_old_bytecode_instructions(bool value) {
- isolate_flags_ =
- UsingOldBytecodeInstructionsBit::update(value, isolate_flags_);
- }
- bool is_using_new_bytecode_instructions() const {
- return UsingNewBytecodeInstructionsBit::decode(isolate_flags_);
- }
- void set_is_using_new_bytecode_instructions(bool value) {
- isolate_flags_ =
- UsingNewBytecodeInstructionsBit::update(value, isolate_flags_);
- }
-
bool has_attempted_stepping() const {
return HasAttemptedSteppingBit::decode(isolate_flags_);
}
@@ -930,13 +913,7 @@
V(Obfuscate) \
V(CompactionInProgress) \
V(ShouldLoadVmService) \
- V(UnsafeTrustStrongModeTypes) \
- V(UsingOldBytecodeInstructions) \
- V(UsingNewBytecodeInstructions)
-
- static_assert(
- KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
- "Cleanup UsingOldBytecodeInstructions and UsingNewBytecodeInstructions");
+ V(UnsafeTrustStrongModeTypes)
// Isolate specific flags.
enum FlagBits {
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 75273e8..c261bba 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -4,6 +4,8 @@
#include "vm/isolate_reload.h"
+#include <memory>
+
#include "vm/bit_vector.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_api_impl.h"
@@ -171,10 +173,10 @@
for (intptr_t i = 0; i < new_fields_->length(); i++) {
// Create a function that returns the expression.
const Field* field = new_fields_->At(i);
- if (field->kernel_offset() > 0) {
- eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
+ if (field->is_declared_in_bytecode()) {
+ UNIMPLEMENTED();
} else {
- UNREACHABLE();
+ eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
}
for (intptr_t j = 0; j < after_->length(); j++) {
@@ -526,17 +528,6 @@
return (a_length - a_cursor);
}
-template <class T>
-class ResourceHolder : ValueObject {
- T* resource_;
-
- public:
- ResourceHolder() : resource_(NULL) {}
- void set(T* resource) { resource_ = resource; }
- T* get() { return resource_; }
- ~ResourceHolder() { delete (resource_); }
-};
-
static void AcceptCompilation(Thread* thread) {
TransitionVMToNative transition(thread);
Dart_KernelCompilationResult result = KernelIsolate::AcceptCompilation();
@@ -582,7 +573,7 @@
}
Object& result = Object::Handle(thread->zone());
- ResourceHolder<kernel::Program> kernel_program;
+ std::unique_ptr<kernel::Program> kernel_program;
String& packages_url = String::Handle();
if (packages_url_ != NULL) {
packages_url = String::New(packages_url_);
@@ -609,10 +600,10 @@
// root_script_url is a valid .dill file. If that's the case, a Program*
// is returned. Otherwise, this is likely a source file that needs to be
// compiled, so ReadKernelFromFile returns NULL.
- kernel_program.set(kernel::Program::ReadFromFile(root_script_url));
- if (kernel_program.get() != NULL) {
- num_received_libs_ = kernel_program.get()->library_count();
- bytes_received_libs_ = kernel_program.get()->kernel_data_size();
+ kernel_program = kernel::Program::ReadFromFile(root_script_url);
+ if (kernel_program != nullptr) {
+ num_received_libs_ = kernel_program->library_count();
+ bytes_received_libs_ = kernel_program->kernel_data_size();
p_num_received_classes = &num_received_classes_;
p_num_received_procedures = &num_received_procedures_;
} else {
@@ -669,7 +660,7 @@
// into the middle of c-allocated buffer and don't have a finalizer).
I->RetainKernelBlob(typed_data);
- kernel_program.set(kernel::Program::ReadFromTypedData(typed_data));
+ kernel_program = kernel::Program::ReadFromTypedData(typed_data);
}
kernel::KernelLoader::FindModifiedLibraries(
@@ -808,6 +799,8 @@
// Other errors (e.g. a parse error) are captured by the reload system.
if (result.IsError()) {
FinalizeFailedLoad(Error::Cast(result));
+ } else {
+ ReportSuccess();
}
}
@@ -933,7 +926,11 @@
if (frame->IsDartFrame() && !frame->is_interpreted()) {
func = frame->LookupDartFunction();
ASSERT(!func.IsNull());
- func.EnsureHasCompiledUnoptimizedCode();
+ // Force-optimized functions don't need unoptimized code because their
+ // optimized code cannot deopt.
+ if (!func.ForceOptimize()) {
+ func.EnsureHasCompiledUnoptimizedCode();
+ }
}
}
}
@@ -1900,7 +1897,7 @@
bytecode.ResetICDatas(zone);
} else {
code = frame->LookupDartCode();
- if (code.is_optimized()) {
+ if (code.is_optimized() && !code.is_force_optimized()) {
// If this code is optimized, we need to reset the ICs in the
// corresponding unoptimized code, which will be executed when the stack
// unwinds to the optimized code.
@@ -2314,6 +2311,9 @@
for (intptr_t i = 1; i < num_cids; i++) {
if (class_table->HasValidClassAt(i)) {
cls = class_table->At(i);
+ if (!cls.is_declaration_loaded()) {
+ continue; // Can't have any subclasses or implementors yet.
+ }
subclasses = cls.direct_subclasses();
if (!subclasses.IsNull()) {
cls.ClearDirectSubclasses();
@@ -2337,6 +2337,9 @@
for (intptr_t i = 1; i < num_cids; i++) {
if (class_table->HasValidClassAt(i)) {
cls = class_table->At(i);
+ if (!cls.is_declaration_loaded()) {
+ continue; // Will register itself later when loaded.
+ }
super_type = cls.super_type();
if (!super_type.IsNull() && !super_type.IsObjectType()) {
super_cls = cls.SuperClass();
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 32f975f..9afdc32 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -5,6 +5,8 @@
#ifndef RUNTIME_VM_KERNEL_H_
#define RUNTIME_VM_KERNEL_H_
+#include <memory>
+
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/globals.h"
@@ -62,15 +64,16 @@
// Read a kernel Program from the given Reader. Note the returned Program
// can potentially contain several "sub programs", though the library count
// etc will reference the last "sub program" only.
- static Program* ReadFrom(Reader* reader, const char** error = nullptr);
+ static std::unique_ptr<Program> ReadFrom(Reader* reader,
+ const char** error = nullptr);
- static Program* ReadFromFile(const char* script_uri,
- const char** error = nullptr);
- static Program* ReadFromBuffer(const uint8_t* buffer,
- intptr_t buffer_length,
- const char** error = nullptr);
- static Program* ReadFromTypedData(const ExternalTypedData& typed_data,
- const char** error = nullptr);
+ static std::unique_ptr<Program> ReadFromFile(const char* script_uri,
+ const char** error = nullptr);
+ static std::unique_ptr<Program> ReadFromBuffer(const uint8_t* buffer,
+ intptr_t buffer_length,
+ const char** error = nullptr);
+ static std::unique_ptr<Program> ReadFromTypedData(
+ const ExternalTypedData& typed_data, const char** error = nullptr);
bool is_single_program() { return single_program_; }
uint32_t binary_version() { return binary_version_; }
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index d974b31..eda3858 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -81,7 +81,7 @@
const char* kKernelInvalidSizeIndicated =
"Invalid kernel binary: Indicated size is invalid";
-Program* Program::ReadFrom(Reader* reader, const char** error) {
+std::unique_ptr<Program> Program::ReadFrom(Reader* reader, const char** error) {
if (reader->size() < 60) {
// A kernel file currently contains at least the following:
// * Magic number (32)
@@ -120,7 +120,7 @@
return nullptr;
}
- Program* program = new Program();
+ std::unique_ptr<Program> program(new Program());
program->binary_version_ = formatVersion;
program->kernel_data_ = reader->buffer();
program->kernel_data_size_ = reader->size();
@@ -136,7 +136,6 @@
if (error != nullptr) {
*error = kKernelInvalidSizeIndicated;
}
- delete program;
return nullptr;
}
++subprogram_count;
@@ -164,13 +163,13 @@
return program;
}
-Program* Program::ReadFromFile(const char* script_uri,
- const char** error /* = nullptr */) {
+std::unique_ptr<Program> Program::ReadFromFile(
+ const char* script_uri, const char** error /* = nullptr */) {
Thread* thread = Thread::Current();
if (script_uri == NULL) {
- return NULL;
+ return nullptr;
}
- kernel::Program* kernel_program = NULL;
+ std::unique_ptr<kernel::Program> kernel_program;
const String& uri = String::Handle(String::New(script_uri));
const Object& ret = Object::Handle(thread->isolate()->CallTagHandler(
@@ -204,15 +203,15 @@
return kernel_program;
}
-Program* Program::ReadFromBuffer(const uint8_t* buffer,
- intptr_t buffer_length,
- const char** error) {
+std::unique_ptr<Program> Program::ReadFromBuffer(const uint8_t* buffer,
+ intptr_t buffer_length,
+ const char** error) {
kernel::Reader reader(buffer, buffer_length);
return kernel::Program::ReadFrom(&reader, error);
}
-Program* Program::ReadFromTypedData(const ExternalTypedData& typed_data,
- const char** error) {
+std::unique_ptr<Program> Program::ReadFromTypedData(
+ const ExternalTypedData& typed_data, const char** error) {
kernel::Reader reader(typed_data);
return kernel::Program::ReadFrom(&reader, error);
}
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index d37c67d..681783d 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -6,6 +6,8 @@
#include <string.h>
+#include <memory>
+
#include "vm/compiler/frontend/constant_evaluator.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
#include "vm/dart_api_impl.h"
@@ -190,6 +192,7 @@
zone_(thread_->zone()),
isolate_(thread_->isolate()),
patch_classes_(Array::ZoneHandle(zone_)),
+ active_class_(),
library_kernel_offset_(-1), // Set to the correct value in LoadLibrary
correction_offset_(-1), // Set to the correct value in LoadLibrary
loading_native_wrappers_library_(false),
@@ -206,9 +209,9 @@
bytecode_metadata_helper_(&helper_, &active_class_),
external_name_class_(Class::Handle(Z)),
external_name_field_(Field::Handle(Z)),
+ evaluating_(GrowableObjectArray::Handle(Z)),
potential_natives_(GrowableObjectArray::Handle(Z)),
potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
- potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
pragma_class_(Class::Handle(Z)),
name_index_handle_(Smi::Handle(Z)),
expression_evaluation_library_(Library::Handle(Z)),
@@ -292,17 +295,15 @@
reader.set_raw_buffer(program->kernel_data() + subprogram_start);
reader.set_size(subprogram_end - subprogram_start);
reader.set_offset(0);
- Program* subprogram = Program::ReadFrom(&reader);
+ std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
ASSERT(subprogram->is_single_program());
- KernelLoader loader(subprogram, &uri_to_source_table);
+ KernelLoader loader(subprogram.get(), &uri_to_source_table);
Object& load_result = Object::Handle(loader.LoadProgram(false));
if (load_result.IsError()) return load_result;
if (load_result.IsLibrary()) {
library ^= load_result.raw();
}
-
- delete subprogram;
}
if (process_pending_classes && !ClassFinalizer::ProcessPendingClasses()) {
@@ -455,9 +456,9 @@
bytecode_metadata_helper_(&helper_, &active_class_),
external_name_class_(Class::Handle(Z)),
external_name_field_(Field::Handle(Z)),
+ evaluating_(GrowableObjectArray::Handle(Z)),
potential_natives_(GrowableObjectArray::Handle(Z)),
potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
- potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
pragma_class_(Class::Handle(Z)),
name_index_handle_(Smi::Handle(Z)),
expression_evaluation_library_(Library::Handle(Z)),
@@ -472,32 +473,6 @@
H.InitFromKernelProgramInfo(kernel_program_info_);
}
-const Array& KernelLoader::ReadConstantTable() {
- if (program_->library_count() == 0) {
- return Array::empty_array();
- }
- // We use the very first library's toplevel class as an owner for an
- // [ActiveClassScope]
- //
- // Though since constants cannot refer to types containing type parameter
- // references, the only purpose of the class is to serve as an owner for
- // signature functions (which get created for function types).
- const dart::Library& owner_library =
- Library::Handle(Z, LookupLibrary(library_canonical_name(0)));
- const dart::Class& toplevel_class =
- Class::Handle(Z, owner_library.toplevel_class());
- ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
-
- helper_.SetOffset(program_->constant_table_offset());
- TypeTranslator type_translator_(&helper_, &active_class_,
- true /* finalize */);
- ASSERT(type_translator_.active_class_ == &active_class_);
-
- ConstantHelper helper(Z, &helper_, &type_translator_, &active_class_,
- skip_vmservice_library_);
- return helper.ReadConstantTable();
-}
-
void KernelLoader::EvaluateDelayedPragmas() {
potential_pragma_functions_ =
kernel_program_info_.potential_pragma_functions();
@@ -522,66 +497,68 @@
GrowableObjectArray::Handle(Z));
}
-void KernelLoader::AnnotateNativeProcedures(const Array& constant_table_array) {
- KernelConstantsMap constant_table(constant_table_array.raw());
+void KernelLoader::AnnotateNativeProcedures() {
potential_natives_ = kernel_program_info_.potential_natives();
const intptr_t length =
!potential_natives_.IsNull() ? potential_natives_.Length() : 0;
- if (length > 0) {
- // Obtain `dart:_internal::ExternalName.name`.
- EnsureExternalClassIsLookedUp();
- Instance& constant = Instance::Handle(Z);
- String& native_name = String::Handle(Z);
+ if (length == 0) return;
- // Start scanning all candidates in [potential_natives] for the annotation
- // constant. If the annotation is found, flag the [Function] as native and
- // attach the native name to it.
- Function& function = Function::Handle(Z);
- for (intptr_t i = 0; i < length; ++i) {
- function ^= potential_natives_.At(i);
- helper_.SetOffset(function.KernelDataProgramOffset() +
- function.kernel_offset());
- {
- ProcedureHelper procedure_helper(&helper_);
- procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
- }
+ // Prepare lazy constant reading.
+ ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+ &active_class_);
- const intptr_t annotation_count = helper_.ReadListLength();
- for (intptr_t j = 0; j < annotation_count; ++j) {
- const intptr_t tag = helper_.PeekTag();
- if (tag == kConstantExpression ||
- tag == kDeprecated_ConstantExpression) {
- helper_.ReadByte(); // Skip the tag.
+ // Obtain `dart:_internal::ExternalName.name`.
+ EnsureExternalClassIsLookedUp();
+ Instance& constant = Instance::Handle(Z);
+ String& native_name = String::Handle(Z);
- // We have a candiate. Let's look if it's an instance of the
- // ExternalName class.
- if (tag == kConstantExpression) {
- helper_.ReadPosition(); // Skip fileOffset.
- helper_.SkipDartType(); // Skip type.
- }
- const intptr_t constant_table_offset = helper_.ReadUInt();
- constant ^= constant_table.GetOrDie(constant_table_offset);
- if (constant.clazz() == external_name_class_.raw()) {
- // We found the annotation, let's flag the function as native and
- // set the native name!
- native_name ^= constant.GetField(external_name_field_);
- function.set_is_native(true);
- function.set_native_name(native_name);
- function.set_is_external(false);
- break;
- }
- } else {
- helper_.SkipExpression();
- }
- }
+ // Start scanning all candidates in [potential_natives] for the annotation
+ // constant. If the annotation is found, flag the [Function] as native and
+ // attach the native name to it.
+ Function& function = Function::Handle(Z);
+ for (intptr_t i = 0; i < length; ++i) {
+ function ^= potential_natives_.At(i);
+ helper_.SetOffset(function.KernelDataProgramOffset() +
+ function.kernel_offset());
+ {
+ ProcedureHelper procedure_helper(&helper_);
+ procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
}
- // Clear out the list of [Function] objects which might need their native
- // name to be set after reading the constant table from the kernel blob.
- potential_natives_ = GrowableObjectArray::null();
- kernel_program_info_.set_potential_natives(potential_natives_);
+ const intptr_t annotation_count = helper_.ReadListLength();
+ for (intptr_t j = 0; j < annotation_count; ++j) {
+ const intptr_t tag = helper_.PeekTag();
+ if (tag == kConstantExpression || tag == kDeprecated_ConstantExpression) {
+ helper_.ReadByte(); // Skip the tag.
+
+ // We have a candidate. Let's look if it's an instance of the
+ // ExternalName class.
+ if (tag == kConstantExpression) {
+ helper_.ReadPosition(); // Skip fileOffset.
+ helper_.SkipDartType(); // Skip type.
+ }
+ const intptr_t constant_table_offset = helper_.ReadUInt();
+ constant = constant_evaluator.EvaluateConstantExpression(
+ constant_table_offset);
+ if (constant.clazz() == external_name_class_.raw()) {
+ // We found the annotation, let's flag the function as native and
+ // set the native name!
+ native_name ^= constant.GetField(external_name_field_);
+ function.set_is_native(true);
+ function.set_native_name(native_name);
+ function.set_is_external(false);
+ break;
+ }
+ } else {
+ helper_.SkipExpression();
+ }
+ }
}
- ASSERT(constant_table.Release().raw() == constant_table_array.raw());
+
+ // Clear out the list of [Function] objects which might need their native
+ // name to be set after reading the constant table from the kernel blob.
+ potential_natives_ = GrowableObjectArray::null();
+ kernel_program_info_.set_potential_natives(potential_natives_);
}
RawString* KernelLoader::DetectExternalNameCtor() {
@@ -638,14 +615,16 @@
return IsClassName(annotation_class, Symbols::DartCore(), Symbols::Pragma());
}
-void KernelLoader::LoadNativeExtensionLibraries(
- const Array& constant_table_array) {
- const intptr_t length = !potential_extension_libraries_.IsNull()
- ? potential_extension_libraries_.Length()
- : 0;
- if (length == 0) return;
+void KernelLoader::LoadNativeExtensionLibraries() {
+ const auto& potential_extension_libraries =
+ GrowableObjectArray::Handle(Z, H.GetPotentialExtensionLibraries());
+ if (potential_extension_libraries.IsNull()) {
+ return;
+ }
- KernelConstantsMap constant_table(constant_table_array.raw());
+ // Prepare lazy constant reading.
+ ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+ &active_class_);
// Obtain `dart:_internal::ExternalName.name`.
EnsureExternalClassIsLookedUp();
@@ -653,70 +632,89 @@
Instance& constant = Instance::Handle(Z);
String& uri_path = String::Handle(Z);
Library& library = Library::Handle(Z);
-#if !defined(DART_PRECOMPILER)
- Object& result = Object::Handle(Z);
-#endif
+ const intptr_t length = potential_extension_libraries.Length();
for (intptr_t i = 0; i < length; ++i) {
- library ^= potential_extension_libraries_.At(i);
- ASSERT(!library.is_declared_in_bytecode());
- helper_.SetOffset(library.kernel_offset());
+ library ^= potential_extension_libraries.At(i);
- LibraryHelper library_helper(&helper_);
- library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
-
- const intptr_t annotation_count = helper_.ReadListLength();
- for (intptr_t j = 0; j < annotation_count; ++j) {
- uri_path = String::null();
-
- const intptr_t tag = helper_.PeekTag();
- if (tag == kConstantExpression || tag == kDeprecated_ConstantExpression) {
- helper_.ReadByte(); // Skip the tag.
-
- if (tag == kConstantExpression) {
- helper_.ReadPosition(); // Skip fileOffset.
- helper_.SkipDartType(); // Skip type.
+ if (library.is_declared_in_bytecode()) {
+ const auto& imports = Array::Handle(Z, library.imports());
+ auto& ns = Namespace::Handle(Z);
+ auto& importee = Library::Handle(Z);
+ for (intptr_t j = 0; j < imports.Length(); ++j) {
+ ns ^= imports.At(j);
+ if (ns.IsNull()) continue;
+ importee = ns.library();
+ uri_path = importee.url();
+ if (uri_path.StartsWith(Symbols::DartExtensionScheme())) {
+ LoadNativeExtension(library, uri_path);
}
- const intptr_t constant_table_index = helper_.ReadUInt();
- constant ^= constant_table.GetOrDie(constant_table_index);
- if (constant.clazz() == external_name_class_.raw()) {
- uri_path ^= constant.GetField(external_name_field_);
+ }
+ } else {
+ helper_.SetOffset(library.kernel_offset());
+
+ LibraryHelper library_helper(&helper_);
+ library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
+
+ const intptr_t annotation_count = helper_.ReadListLength();
+ for (intptr_t j = 0; j < annotation_count; ++j) {
+ uri_path = String::null();
+
+ const intptr_t tag = helper_.PeekTag();
+ if (tag == kConstantExpression ||
+ tag == kDeprecated_ConstantExpression) {
+ helper_.ReadByte(); // Skip the tag.
+
+ if (tag == kConstantExpression) {
+ helper_.ReadPosition(); // Skip fileOffset.
+ helper_.SkipDartType(); // Skip type.
+ }
+ const intptr_t constant_table_offset = helper_.ReadUInt();
+ constant = constant_evaluator.EvaluateConstantExpression(
+ constant_table_offset);
+ if (constant.clazz() == external_name_class_.raw()) {
+ uri_path ^= constant.GetField(external_name_field_);
+ }
+ } else if (tag == kConstructorInvocation ||
+ tag == kConstConstructorInvocation) {
+ uri_path = DetectExternalNameCtor();
+ } else {
+ helper_.SkipExpression();
}
- } else if (tag == kConstructorInvocation ||
- tag == kConstConstructorInvocation) {
- uri_path = DetectExternalNameCtor();
- } else {
- helper_.SkipExpression();
+
+ if (uri_path.IsNull()) continue;
+
+ LoadNativeExtension(library, uri_path);
+
+ // Create a dummy library and add it as an import to the current
+ // library. This allows later to discover and reload this native
+ // extension, e.g. when running from an app-jit snapshot.
+ // See Loader::ReloadNativeExtensions(...) which relies on
+ // Dart_GetImportsOfScheme('dart-ext').
+ const auto& native_library = Library::Handle(Library::New(uri_path));
+ library.AddImport(Namespace::Handle(Namespace::New(
+ native_library, Array::null_array(), Array::null_array())));
}
-
- if (uri_path.IsNull()) continue;
-
-#if !defined(DART_PRECOMPILER)
- if (!I->HasTagHandler()) {
- H.ReportError("no library handler registered.");
- }
-
- I->BlockClassFinalization();
- result = I->CallTagHandler(Dart_kImportExtensionTag, library, uri_path);
- I->UnblockClassFinalization();
-
- if (result.IsError()) {
- H.ReportError(Error::Cast(result), "library handler failed");
- }
-#endif
-
- // Create a dummy library and add it as an import to the current library.
- // This allows later to discover and reload this native extension, e.g.
- // when running from an app-jit snapshot.
- // See Loader::ReloadNativeExtensions(...) which relies on
- // Dart_GetImportsOfScheme('dart-ext').
- const auto& native_library = Library::Handle(Library::New(uri_path));
- library.AddImport(Namespace::Handle(Namespace::New(
- native_library, Array::null_array(), Array::null_array())));
}
}
- potential_extension_libraries_ = GrowableObjectArray::null();
- ASSERT(constant_table.Release().raw() == constant_table_array.raw());
+}
+
+void KernelLoader::LoadNativeExtension(const Library& library,
+ const String& uri_path) {
+#if !defined(DART_PRECOMPILER)
+ if (!I->HasTagHandler()) {
+ H.ReportError("no library handler registered.");
+ }
+
+ I->BlockClassFinalization();
+ const auto& result = Object::Handle(
+ Z, I->CallTagHandler(Dart_kImportExtensionTag, library, uri_path));
+ I->UnblockClassFinalization();
+
+ if (result.IsError()) {
+ H.ReportError(Error::Cast(result), "library handler failed");
+ }
+#endif
}
RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
@@ -743,6 +741,7 @@
}
}
+ // Finalize still pending classes if requested.
if (process_pending_classes) {
if (!ClassFinalizer::ProcessPendingClasses()) {
// Class finalization failed -> sticky error would be set.
@@ -750,44 +749,17 @@
}
}
- // Set pending fields array to flag constant table loading.
- ASSERT(I->object_store()->pending_unevaluated_const_fields() ==
- GrowableObjectArray::null());
- GrowableObjectArray& pending_unevaluated_const_fields =
- GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
- I->object_store()->set_pending_unevaluated_const_fields(
- pending_unevaluated_const_fields);
-
- // All classes were successfully loaded, so let's:
- // a) load & canonicalize the constant table
- const Array& constants = ReadConstantTable();
-
- // b) set the native names for native functions which have been created
- // so far (the rest will be directly set during LoadProcedure)
- AnnotateNativeProcedures(constants);
- LoadNativeExtensionLibraries(constants);
-
- // c) update all scripts with the constants array
- ASSERT(kernel_program_info_.constants() == Array::null());
- kernel_program_info_.set_constants(constants);
- kernel_program_info_.set_constants_table(ExternalTypedData::Handle(Z));
-
- // d) evaluate pending field initializers
- Error& error = Error::Handle(Z);
- Field& field = Field::Handle(Z);
- for (intptr_t i = 0, n = pending_unevaluated_const_fields.Length(); i < n;
- i++) {
- field ^= pending_unevaluated_const_fields.At(i);
- error = field.Initialize();
- if (!error.IsNull()) {
- H.ReportError(error, "postponed field initializer");
- }
- }
- pending_unevaluated_const_fields = GrowableObjectArray::null();
- I->object_store()->set_pending_unevaluated_const_fields(
- pending_unevaluated_const_fields);
-
- // e) evaluate pragmas that were delayed
+ // Sets the constants array to an empty hash and leaves the constant
+ // table's raw bytes in place for lazy reading. We can fix up all
+ // "pending" processing now, and must ensure we don't create new
+ // ones from this point on.
+ ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
+ const Array& array =
+ Array::Handle(Z, HashTables::New<KernelConstantsMap>(16, Heap::kOld));
+ kernel_program_info_.set_constants(array);
+ H.SetConstants(array); // for caching
+ AnnotateNativeProcedures();
+ LoadNativeExtensionLibraries();
EvaluateDelayedPragmas();
NameIndex main = program_->main_method();
@@ -920,12 +892,11 @@
reader.set_raw_buffer(program->kernel_data() + subprogram_start);
reader.set_size(subprogram_end - subprogram_start);
reader.set_offset(0);
- Program* subprogram = Program::ReadFrom(&reader);
+ std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
ASSERT(subprogram->is_single_program());
- KernelLoader loader(subprogram, /*uri_to_source_table=*/nullptr);
+ KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
loader.walk_incremental_kernel(modified_libs, is_empty_program,
p_num_classes, p_num_procedures);
- delete subprogram;
}
}
}
@@ -1067,8 +1038,9 @@
helper_.ReaderOffset() - correction_offset_;
intptr_t annotation_count = helper_.ReadListLength(); // read list length.
if (annotation_count > 0) {
- EnsurePotentialExtensionLibraries();
- potential_extension_libraries_.Add(library);
+ // This must wait until we can evaluate constants.
+ // So put on the "pending" list.
+ H.AddPotentialExtensionLibrary(library);
}
for (intptr_t i = 0; i < annotation_count; ++i) {
helper_.SkipExpression(); // read ith annotation.
@@ -1148,7 +1120,6 @@
if (toplevel_class.is_loaded()) {
return;
}
-
TIMELINE_DURATION(Thread::Current(), Isolate, "FinishTopLevelClassLoading");
ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
@@ -1190,7 +1161,7 @@
{
String& native_name_unused = String::Handle();
bool is_potential_native_unused;
- ReadVMAnnotations(annotation_count, &native_name_unused,
+ ReadVMAnnotations(library, annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1436,8 +1407,9 @@
out_class->set_script(script);
}
if (out_class->token_pos() == TokenPosition::kNoSource) {
- class_helper.ReadUntilIncluding(ClassHelper::kStartPosition);
+ class_helper.ReadUntilIncluding(ClassHelper::kEndPosition);
out_class->set_token_pos(class_helper.start_position_);
+ out_class->set_end_token_pos(class_helper.end_position_);
}
class_helper.ReadUntilIncluding(ClassHelper::kFlags);
@@ -1451,7 +1423,7 @@
{
String& native_name_unused = String::Handle(Z);
bool is_potential_native_unused = false;
- ReadVMAnnotations(annotation_count, &native_name_unused,
+ ReadVMAnnotations(library, annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
if (has_pragma_annotation) {
@@ -1545,7 +1517,7 @@
{
String& native_name_unused = String::Handle();
bool is_potential_native_unused;
- ReadVMAnnotations(annotation_count, &native_name_unused,
+ ReadVMAnnotations(library, annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1618,7 +1590,7 @@
{
String& native_name_unused = String::Handle();
bool is_potential_native_unused;
- ReadVMAnnotations(annotation_count, &native_name_unused,
+ ReadVMAnnotations(library, annotation_count, &native_name_unused,
&is_potential_native_unused, &has_pragma_annotation);
}
constructor_helper.SetJustRead(ConstructorHelper::kAnnotations);
@@ -1678,7 +1650,11 @@
}
}
- ASSERT(!klass.is_loaded());
+ // Due to ReadVMAnnotations(), the klass may have been loaded at this point
+ // (loading the class while evaluating annotations).
+ if (klass.is_loaded()) {
+ return;
+ }
// Everything up til the procedures are skipped implicitly, and class_helper
// is no longer used.
@@ -1760,12 +1736,14 @@
// `has_pragma_annotation`: non-null if @pragma(...) was found (no information
// is given on the kind of pragma directive).
//
-void KernelLoader::ReadVMAnnotations(intptr_t annotation_count,
+void KernelLoader::ReadVMAnnotations(const Library& library,
+ intptr_t annotation_count,
String* native_name,
bool* is_potential_native,
bool* has_pragma_annotation) {
*is_potential_native = false;
*has_pragma_annotation = false;
+ Instance& constant = Instance::Handle(Z);
String& detected_name = String::Handle(Z);
for (intptr_t i = 0; i < annotation_count; ++i) {
const intptr_t tag = helper_.PeekTag();
@@ -1828,7 +1806,13 @@
Symbols::DartCore(), Symbols::Pragma());
}
} else {
- KernelConstantsMap constant_table(constant_table_array.raw());
+ // Prepare lazy constant reading.
+ const dart::Class& toplevel_class =
+ Class::Handle(Z, library.toplevel_class());
+ ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
+ ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+ &active_class_);
+
helper_.ReadByte(); // Skip the tag.
// Obtain `dart:_internal::ExternalName.name`.
@@ -1841,18 +1825,27 @@
helper_.ReadPosition(); // Skip fileOffset.
helper_.SkipDartType(); // Skip type.
}
- const intptr_t constant_table_index = helper_.ReadUInt();
- const Object& constant =
- Object::Handle(constant_table.GetOrDie(constant_table_index));
- if (constant.clazz() == external_name_class_.raw()) {
- const Instance& instance =
- Instance::Handle(Instance::RawCast(constant.raw()));
- *native_name =
- String::RawCast(instance.GetField(external_name_field_));
- } else if (constant.clazz() == pragma_class_.raw()) {
- *has_pragma_annotation = true;
+ const intptr_t constant_table_offset = helper_.ReadUInt();
+ // A cycle in evaluating the same library instance occurs when we are
+ // trying to finalize a class while evaluation the constant. We break
+ // this cycle by ignoring the second evaluation, since the first
+ // evaluation will take care of inspecting the result.
+ // TODO(ajcbik): avoid cycle detection completely by peeking
+ // into the constants and proceed only for @pragma
+ // or @ExternalName
+ if (EnqueueLibraryForEvaluation(library)) {
+ constant = constant_evaluator.EvaluateConstantExpression(
+ constant_table_offset);
+ DequeueLibraryForEvaluation(library);
+ if (constant.clazz() == external_name_class_.raw()) {
+ const Instance& instance =
+ Instance::Handle(Instance::RawCast(constant.raw()));
+ *native_name =
+ String::RawCast(instance.GetField(external_name_field_));
+ } else if (constant.clazz() == pragma_class_.raw()) {
+ *has_pragma_annotation = true;
+ }
}
- ASSERT(constant_table.Release().raw() == constant_table_array.raw());
}
} else {
helper_.SkipExpression();
@@ -1881,8 +1874,8 @@
bool is_potential_native;
bool has_pragma_annotation;
const intptr_t annotation_count = helper_.ReadListLength();
- ReadVMAnnotations(annotation_count, &native_name, &is_potential_native,
- &has_pragma_annotation);
+ ReadVMAnnotations(library, annotation_count, &native_name,
+ &is_potential_native, &has_pragma_annotation);
// If this is a potential native, we'll unset is_external in
// AnnotateNativeProcedures instead.
is_external = is_external && native_name.IsNull();
@@ -1959,6 +1952,7 @@
function.set_native_name(native_name);
}
if (is_potential_native) {
+ // Cannot be processed right now, so put on "pending" list.
EnsurePotentialNatives();
potential_natives_.Add(function);
}
@@ -1979,6 +1973,8 @@
if (has_pragma_annotation) {
if (kernel_program_info_.constants() == Array::null()) {
+ // Any potential pragma function before point at which
+ // constant table could be loaded goes to "pending".
EnsurePotentialPragmaFunctions();
potential_pragma_functions_.Add(function);
} else {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index f6d7665..a6bd55d 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -230,8 +230,6 @@
void ReadObfuscationProhibitions();
- const Array& ReadConstantTable();
-
// Check for the presence of a (possibly const) constructor for the
// 'ExternalName' class. If found, returns the name parameter to the
// constructor.
@@ -243,11 +241,13 @@
bool IsClassName(NameIndex name, const String& library, const String& klass);
- void AnnotateNativeProcedures(const Array& constant_table);
- void LoadNativeExtensionLibraries(const Array& constant_table);
+ void AnnotateNativeProcedures();
+ void LoadNativeExtensionLibraries();
+ void LoadNativeExtension(const Library& library, const String& uri_path);
void EvaluateDelayedPragmas();
- void ReadVMAnnotations(intptr_t annotation_count,
+ void ReadVMAnnotations(const Library& library,
+ intptr_t annotation_count,
String* native_name,
bool* is_potential_native,
bool* has_pragma_annotation);
@@ -390,9 +390,34 @@
translation_helper_.EnsurePotentialPragmaFunctions();
}
- void EnsurePotentialExtensionLibraries() {
- if (potential_extension_libraries_.IsNull()) {
- potential_extension_libraries_ = GrowableObjectArray::New();
+ // Returns `true` if the [library] was newly enqueued or `false`
+ // if it was already enqueued. Allocates storage on first enqueue.
+ bool EnqueueLibraryForEvaluation(const Library& library) {
+ evaluating_ = kernel_program_info_.evaluating();
+ if (evaluating_.IsNull()) {
+ evaluating_ = GrowableObjectArray::New();
+ kernel_program_info_.set_evaluating(evaluating_);
+ ASSERT(!evaluating_.IsNull());
+ } else {
+ for (intptr_t i = 0, n = evaluating_.Length(); i < n; i++) {
+ if (library.raw() == evaluating_.At(i)) {
+ return false;
+ }
+ }
+ }
+ evaluating_.Add(library);
+ return true;
+ }
+
+ // Dequeues most recent libary. Releases storage when empty.
+ void DequeueLibraryForEvaluation(const Library& library) {
+ ASSERT(!evaluating_.IsNull());
+ RawObject* object = evaluating_.RemoveLast();
+ ASSERT(library.raw() == object);
+ if (evaluating_.Length() == 0) {
+ evaluating_ = GrowableObjectArray::null();
+ kernel_program_info_.set_evaluating(evaluating_);
+ ASSERT(evaluating_.IsNull());
}
}
@@ -423,9 +448,9 @@
Class& external_name_class_;
Field& external_name_field_;
+ GrowableObjectArray& evaluating_;
GrowableObjectArray& potential_natives_;
GrowableObjectArray& potential_pragma_functions_;
- GrowableObjectArray& potential_extension_libraries_;
Class& pragma_class_;
diff --git a/runtime/vm/libfuzzer/dart_libfuzzer.cc b/runtime/vm/libfuzzer/dart_libfuzzer.cc
index 5c870ab..a1cb53f 100644
--- a/runtime/vm/libfuzzer/dart_libfuzzer.cc
+++ b/runtime/vm/libfuzzer/dart_libfuzzer.cc
@@ -31,7 +31,7 @@
}
// Target function that stresses various utilities.
-// Found: http:/dartbug.com/36818
+// Found: http://dartbug.com/36818
static int TestUtilities(const uint8_t* Data, size_t Size) {
dart::Utils::StringHash(reinterpret_cast<const char*>(Data), Size);
dart::bin::DartUtils::SniffForMagicNumber(Data, Size);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 19ceac8..9ad6cd4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4,6 +4,8 @@
#include "vm/object.h"
+#include <memory>
+
#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/unicode.h"
@@ -2274,6 +2276,7 @@
}
RawAbstractType* Class::RareType() const {
+ ASSERT(is_declaration_loaded());
const Type& type = Type::Handle(Type::New(
*this, Object::null_type_arguments(), TokenPosition::kNoSource));
return ClassFinalizer::FinalizeType(*this, type);
@@ -2292,6 +2295,7 @@
FakeObject fake;
result.set_handle_vtable(fake.vtable());
result.set_token_pos(TokenPosition::kNoSource);
+ result.set_end_token_pos(TokenPosition::kNoSource);
result.set_instance_size(FakeObject::InstanceSize());
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
result.set_next_field_offset(FakeObject::NextFieldOffset());
@@ -3382,10 +3386,7 @@
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
- const Error& error = Error::Handle(zone, EnsureIsFinalized(thread));
- if (!error.IsNull()) {
- return error.raw();
- }
+ CHECK_ERROR(EnsureIsFinalized(thread));
// Check for real fields and user-defined setters.
const Field& field = Field::Handle(zone, LookupStaticField(setter_name));
@@ -3542,6 +3543,21 @@
arguments, type_arguments);
}
+void Class::EnsureDeclarationLoaded() const {
+ if (!is_declaration_loaded()) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ UNREACHABLE();
+#else
+ // Loading of class declaration can be postponed until needed
+ // if class comes from bytecode.
+ ASSERT(is_declared_in_bytecode());
+ kernel::BytecodeReader::LoadClassDeclaration(*this);
+ ASSERT(is_declaration_loaded());
+ ASSERT(is_type_finalized());
+#endif
+ }
+}
+
// Ensure that top level parsing of the class has been done.
RawError* Class::EnsureIsFinalized(Thread* thread) const {
// Finalized classes have already been parsed.
@@ -3660,6 +3676,7 @@
ASSERT(fake.IsInstance());
result.set_handle_vtable(fake.vtable());
result.set_token_pos(TokenPosition::kNoSource);
+ result.set_end_token_pos(TokenPosition::kNoSource);
result.set_instance_size(FakeInstance::InstanceSize());
result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
result.set_next_field_offset(FakeInstance::NextFieldOffset());
@@ -3975,69 +3992,16 @@
StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
}
-TokenPosition Class::ComputeEndTokenPos() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return TokenPosition::kNoSource;
-#else
- // Return the begin token for synthetic classes.
- if (is_synthesized_class() || IsTopLevel()) {
- return token_pos();
- }
-
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- const Script& scr = Script::Handle(zone, script());
- ASSERT(!scr.IsNull());
-
- if (scr.kind() == RawScript::kKernelTag) {
- if (is_declared_in_bytecode()) {
- // TODO(alexmarkov): keep end_token_pos in Class?
- UNIMPLEMENTED();
- return token_pos();
- }
- ASSERT(kernel_offset() > 0);
- const Library& lib = Library::Handle(zone, library());
- const ExternalTypedData& kernel_data =
- ExternalTypedData::Handle(zone, lib.kernel_data());
- ASSERT(!kernel_data.IsNull());
- const intptr_t library_kernel_offset = lib.kernel_offset();
- ASSERT(library_kernel_offset > 0);
- const intptr_t class_offset = kernel_offset();
-
- kernel::TranslationHelper translation_helper(thread);
- translation_helper.InitFromScript(scr);
-
- kernel::KernelReaderHelper kernel_reader_helper(zone, &translation_helper,
- scr, kernel_data, 0);
- kernel_reader_helper.SetOffset(class_offset);
- kernel::ClassHelper class_helper(&kernel_reader_helper);
- class_helper.ReadUntilIncluding(kernel::ClassHelper::kEndPosition);
- if (class_helper.end_position_.IsReal()) return class_helper.end_position_;
-
- TokenPosition largest_seen = token_pos();
-
- // Walk through all functions and get their end_tokens to find the classes
- // "end token".
- // TODO(jensj): Should probably walk though all fields as well.
- Function& function = Function::Handle(zone);
- const Array& arr = Array::Handle(functions());
- for (int i = 0; i < arr.Length(); i++) {
- function ^= arr.At(i);
- if (function.script() == script()) {
- if (largest_seen < function.end_token_pos()) {
- largest_seen = function.end_token_pos();
- }
- }
- }
- return TokenPosition(largest_seen);
- }
-
- UNREACHABLE();
-#endif
+void Class::set_end_token_pos(TokenPosition token_pos) const {
+ ASSERT(!token_pos.IsClassifying());
+ StoreNonPointer(&raw_ptr()->end_token_pos_, token_pos);
}
int32_t Class::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint(
*this);
#else
@@ -4186,6 +4150,7 @@
}
RawType* Class::DeclarationType() const {
+ ASSERT(is_declaration_loaded());
if (declaration_type() != Type::null()) {
return declaration_type();
}
@@ -5747,6 +5712,7 @@
}
void Function::EnsureHasCompiledUnoptimizedCode() const {
+ ASSERT(!ForceOptimize());
Thread* thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
DEBUG_ASSERT(thread->TopErrorHandlerIsExitFrame());
@@ -6075,6 +6041,20 @@
FfiTrampolineData::Cast(obj).set_callback_target(target);
}
+RawInstance* Function::FfiCallbackExceptionalReturn() const {
+ ASSERT(IsFfiTrampoline());
+ const Object& obj = Object::Handle(raw_ptr()->data_);
+ ASSERT(!obj.IsNull());
+ return FfiTrampolineData::Cast(obj).callback_exceptional_return();
+}
+
+void Function::SetFfiCallbackExceptionalReturn(const Instance& value) const {
+ ASSERT(IsFfiTrampoline());
+ const Object& obj = Object::Handle(raw_ptr()->data_);
+ ASSERT(!obj.IsNull());
+ FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
+}
+
RawType* Function::SignatureType() const {
Type& type = Type::Handle(ExistingSignatureType());
if (type.IsNull()) {
@@ -7797,7 +7777,8 @@
intptr_t Function::KernelDataProgramOffset() const {
ASSERT(!is_declared_in_bytecode());
- if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
+ if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher() ||
+ IsFfiTrampoline()) {
return 0;
}
Object& data = Object::Handle(raw_ptr()->data_);
@@ -7942,6 +7923,9 @@
// arguments.
int32_t Function::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
*this);
#else
@@ -8095,7 +8079,7 @@
}
// Compiling in unoptimized mode should never fail if there are no errors.
ASSERT(HasCode());
- ASSERT(unoptimized_code() == result.raw());
+ ASSERT(ForceOptimize() || unoptimized_code() == result.raw());
return CurrentCode();
}
@@ -8288,6 +8272,11 @@
StoreNonPointer(&raw_ptr()->callback_id_, callback_id);
}
+void FfiTrampolineData::set_callback_exceptional_return(
+ const Instance& value) const {
+ StorePointer(&raw_ptr()->callback_exceptional_return_, value.raw());
+}
+
RawFfiTrampolineData* FfiTrampolineData::New() {
ASSERT(Object::ffi_trampoline_data_class() != Class::null());
RawObject* raw =
@@ -8587,6 +8576,9 @@
int32_t Field::SourceFingerprint() const {
#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (is_declared_in_bytecode()) {
+ return 0; // TODO(37353): Implement or remove.
+ }
return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint(
*this);
#else
@@ -11334,7 +11326,7 @@
String::New("Expression evaluation not available in precompiled mode."));
return ApiError::New(error_str);
#else
- kernel::Program* kernel_pgm =
+ std::unique_ptr<kernel::Program> kernel_pgm =
kernel::Program::ReadFromBuffer(kernel_bytes, kernel_length);
if (kernel_pgm == NULL) {
@@ -11342,12 +11334,11 @@
String::New("Kernel isolate returned ill-formed kernel.")));
}
- kernel::KernelLoader loader(kernel_pgm, /*uri_to_source_table=*/nullptr);
+ kernel::KernelLoader loader(kernel_pgm.get(),
+ /*uri_to_source_table=*/nullptr);
const Object& result = Object::Handle(
loader.LoadExpressionEvaluationFunction(library_url, klass));
-
- delete kernel_pgm;
- kernel_pgm = NULL;
+ kernel_pgm.reset();
if (result.IsError()) return result.raw();
@@ -12149,6 +12140,11 @@
StorePointer(&raw_ptr()->constants_table_, value.raw());
}
+void KernelProgramInfo::set_evaluating(
+ const GrowableObjectArray& evaluating) const {
+ StorePointer(&raw_ptr()->evaluating_, evaluating.raw());
+}
+
void KernelProgramInfo::set_potential_natives(
const GrowableObjectArray& candidates) const {
StorePointer(&raw_ptr()->potential_natives_, candidates.raw());
@@ -14476,6 +14472,10 @@
set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_));
}
+void Code::set_is_force_optimized(bool value) const {
+ set_state_bits(ForceOptimizedBit::update(value, raw_ptr()->state_bits_));
+}
+
void Code::set_is_alive(bool value) const {
set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_));
}
@@ -14749,6 +14749,7 @@
result ^= raw;
result.set_pointer_offsets_length(pointer_offsets_length);
result.set_is_optimized(false);
+ result.set_is_force_optimized(false);
result.set_is_alive(false);
NOT_IN_PRODUCT(result.set_comments(Comments::New(0)));
NOT_IN_PRODUCT(result.set_compile_timestamp(0));
@@ -14938,6 +14939,20 @@
return code.raw();
}
+void Code::NotifyCodeObservers(const Code& code, bool optimized) {
+#if !defined(PRODUCT)
+ ASSERT(!Thread::Current()->IsAtSafepoint());
+ if (CodeObservers::AreActive()) {
+ const Object& owner = Object::Handle(code.owner());
+ if (owner.IsFunction()) {
+ NotifyCodeObservers(Function::Cast(owner), code, optimized);
+ } else {
+ NotifyCodeObservers(code.Name(), code, optimized);
+ }
+ }
+#endif
+}
+
void Code::NotifyCodeObservers(const Function& function,
const Code& code,
bool optimized) {
@@ -15296,21 +15311,21 @@
return info.metadata_payloads();
}
-TokenPosition Bytecode::GetTokenIndexOfPC(uword pc) const {
+TokenPosition Bytecode::GetTokenIndexOfPC(uword return_address) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
if (!HasSourcePositions()) {
return TokenPosition::kNoSource;
}
- uword pc_offset = pc - PayloadStart();
+ uword pc_offset = return_address - PayloadStart();
// PC could equal to bytecode size if the last instruction is Throw.
ASSERT(pc_offset <= static_cast<uword>(Size()));
kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(),
*this);
TokenPosition token_pos = TokenPosition::kNoSource;
while (iter.MoveNext()) {
- if (pc_offset < iter.PcOffset()) {
+ if (pc_offset <= iter.PcOffset()) {
break;
}
token_pos = iter.TokenPos();
@@ -16152,9 +16167,11 @@
RawObject* Instance::InvokeGetter(const String& getter_name,
bool respect_reflectable,
bool check_is_entrypoint) const {
- Zone* zone = Thread::Current()->zone();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
Class& klass = Class::Handle(zone, clazz());
+ CHECK_ERROR(klass.EnsureIsFinalized(thread));
TypeArguments& type_args = TypeArguments::Handle(zone);
if (klass.NumTypeArguments() > 0) {
type_args = GetTypeArguments();
@@ -16210,9 +16227,11 @@
const Instance& value,
bool respect_reflectable,
bool check_is_entrypoint) const {
- Zone* zone = Thread::Current()->zone();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
const Class& klass = Class::Handle(zone, clazz());
+ CHECK_ERROR(klass.EnsureIsFinalized(thread));
TypeArguments& type_args = TypeArguments::Handle(zone);
if (klass.NumTypeArguments() > 0) {
type_args = GetTypeArguments();
@@ -16255,8 +16274,10 @@
const Array& arg_names,
bool respect_reflectable,
bool check_is_entrypoint) const {
- Zone* zone = Thread::Current()->zone();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
Class& klass = Class::Handle(zone, clazz());
+ CHECK_ERROR(klass.EnsureIsFinalized(thread));
Function& function = Function::Handle(
zone, Resolver::ResolveDynamicAnyArgs(zone, klass, function_name));
@@ -16382,7 +16403,7 @@
NoSafepointScope no_safepoint;
const intptr_t instance_size = SizeFromClass();
ASSERT(instance_size != 0);
- uint32_t hash = instance_size;
+ uint32_t hash = instance_size / kWordSize;
uword this_addr = reinterpret_cast<uword>(this->raw_ptr());
Instance& member = Instance::Handle();
for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
@@ -16455,6 +16476,10 @@
return true;
}
+RawInstance* Instance::CopyShallowToOldSpace(Thread* thread) const {
+ return Instance::RawCast(Object::Clone(*this, Heap::kOld));
+}
+
RawInstance* Instance::CheckAndCanonicalize(Thread* thread,
const char** error_str) const {
ASSERT(error_str != NULL);
@@ -16506,6 +16531,12 @@
return Type::NullType();
}
const Class& cls = Class::Handle(clazz());
+ if (!cls.is_finalized()) {
+ // Various predefined classes can be instantiated by the VM or
+ // Dart_NewString/Integer/TypedData/... before the class is finalized.
+ ASSERT(cls.is_prefinalized());
+ cls.EnsureDeclarationLoaded();
+ }
if (cls.IsClosureClass()) {
Function& signature =
Function::Handle(Closure::Cast(*this).GetInstantiatedSignature(
@@ -17242,6 +17273,10 @@
return !IsFunctionType() && (type_class_id() == kClosureCid);
}
+bool AbstractType::IsFfiPointerType() const {
+ return HasTypeClass() && type_class_id() == kFfiPointerCid;
+}
+
bool AbstractType::IsSubtypeOf(const AbstractType& other,
Heap::Space space) const {
ASSERT(IsFinalized());
@@ -17712,14 +17747,7 @@
for (intptr_t i = 0; i < from_index; i++) {
type_arg = type_args.TypeAt(i);
other_type_arg = other_type_args.TypeAt(i);
- // Type arguments may not match if they are TypeRefs without
- // underlying type (which will be set later).
- ASSERT(
- type_arg.IsEquivalent(other_type_arg, trail) ||
- (type_arg.IsTypeRef() &&
- TypeRef::Cast(type_arg).type() == AbstractType::null()) ||
- (other_type_arg.IsTypeRef() &&
- TypeRef::Cast(other_type_arg).type() == AbstractType::null()));
+ ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
}
}
#endif
@@ -18178,10 +18206,9 @@
// TODO(regis): Try to reduce the number of nodes required to represent the
// referenced recursive type.
AbstractType& ref_type = AbstractType::Handle(type());
- if (!ref_type.IsNull()) {
- ref_type = ref_type.Canonicalize(trail);
- set_type(ref_type);
- }
+ ASSERT(!ref_type.IsNull());
+ ref_type = ref_type.Canonicalize(trail);
+ set_type(ref_type);
return raw();
}
@@ -18207,11 +18234,15 @@
}
intptr_t TypeRef::Hash() const {
- // Do not calculate the hash of the referenced type to avoid divergence.
- // TypeRef can participate in type canonicalization even before referenced
- // type is set, so its hash should not rely on referenced type.
- const intptr_t kTypeRefHash = 37;
- return kTypeRefHash;
+ // Do not use hash of the referenced type because
+ // - we could be in process of calculating it (as TypeRef is used to
+ // represent recursive references to types).
+ // - referenced type might be incomplete (e.g. not all its
+ // type arguments are set).
+ const AbstractType& ref_type = AbstractType::Handle(type());
+ ASSERT(!ref_type.IsNull());
+ const uint32_t result = Class::Handle(ref_type.type_class()).id();
+ return FinalizeHash(result, kHashBits);
}
RawTypeRef* TypeRef::New() {
@@ -21366,24 +21397,24 @@
}
RawPointer* Pointer::New(const AbstractType& type_arg,
- const Integer& c_memory_address,
- intptr_t cid,
+ size_t native_address,
Heap::Space space) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
+
TypeArguments& type_args = TypeArguments::Handle(zone);
type_args = TypeArguments::New(1);
type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
type_args = type_args.Canonicalize();
- const Class& cls = Class::Handle(Isolate::Current()->class_table()->At(cid));
+ const Class& cls =
+ Class::Handle(Isolate::Current()->class_table()->At(kFfiPointerCid));
cls.EnsureIsFinalized(Thread::Current());
Pointer& result = Pointer::Handle(zone);
- result ^= Object::Allocate(cid, Pointer::InstanceSize(), space);
- NoSafepointScope no_safepoint;
+ result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
result.SetTypeArguments(type_args);
- result.SetCMemoryAddress(c_memory_address);
+ result.SetNativeAddress(native_address);
return result.raw();
}
@@ -21392,9 +21423,7 @@
TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
String& type_args_name = String::Handle(type_args.UserVisibleName());
return OS::SCreate(Thread::Current()->zone(), "Pointer%s: address=0x%" Px,
- type_args_name.ToCString(),
- static_cast<intptr_t>(
- Integer::Handle(GetCMemoryAddress()).AsInt64Value()));
+ type_args_name.ToCString(), NativeAddress());
}
RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {
@@ -21408,23 +21437,7 @@
bool Pointer::IsPointer(const Instance& obj) {
ASSERT(!obj.IsNull());
-
- // fast path for predefined classes
- intptr_t cid = obj.raw()->GetClassId();
- if (RawObject::IsFfiPointerClassId(cid)) {
- return true;
- }
-
- // slow check for subtyping
- const Class& pointer_class = Class::ZoneHandle(
- Isolate::Current()->object_store()->ffi_pointer_class());
- AbstractType& pointer_type =
- AbstractType::Handle(pointer_class.DeclarationType());
- pointer_type = pointer_type.InstantiateFrom(Object::null_type_arguments(),
- Object::null_type_arguments(),
- kNoneFree, NULL, Heap::kNew);
- AbstractType& type = AbstractType::Handle(obj.GetType(Heap::kNew));
- return type.IsSubtypeOf(pointer_type, Heap::kNew);
+ return RawObject::IsFfiPointerClassId(obj.raw()->GetClassId());
}
bool Instance::IsPointer() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 58eacf7..2411db7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -866,8 +866,11 @@
TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
void set_token_pos(TokenPosition value) const;
-
- TokenPosition ComputeEndTokenPos() const;
+ TokenPosition end_token_pos() const {
+ ASSERT(is_declaration_loaded());
+ return raw_ptr()->end_token_pos_;
+ }
+ void set_end_token_pos(TokenPosition value) const;
int32_t SourceFingerprint() const;
@@ -1306,6 +1309,10 @@
const Array& param_values,
const TypeArguments& type_param_values) const;
+ // Load class declaration (super type, interfaces, type parameters and
+ // number of type arguments) if it is not loaded yet.
+ void EnsureDeclarationLoaded() const;
+
RawError* EnsureIsFinalized(Thread* thread) const;
// Allocate a class used for VM internal objects.
@@ -2118,6 +2125,13 @@
// Can only be called on FFI trampolines.
void SetFfiCallbackTarget(const Function& target) const;
+ // Can only be called on FFI trampolines.
+ // Null for Dart -> native calls.
+ RawInstance* FfiCallbackExceptionalReturn() const;
+
+ // Can only be called on FFI trampolines.
+ void SetFfiCallbackExceptionalReturn(const Instance& value) const;
+
// Return a new function with instantiated result and parameter types.
RawFunction* InstantiateSignatureFrom(
const TypeArguments& instantiator_type_arguments,
@@ -3257,6 +3271,11 @@
RawFunction* callback_target() const { return raw_ptr()->callback_target_; }
void set_callback_target(const Function& value) const;
+ RawInstance* callback_exceptional_return() const {
+ return raw_ptr()->callback_exceptional_return_;
+ }
+ void set_callback_exceptional_return(const Instance& value) const;
+
int32_t callback_id() const { return raw_ptr()->callback_id_; }
void set_callback_id(int32_t value) const;
@@ -4402,6 +4421,10 @@
RawArray* constants() const { return raw_ptr()->constants_; }
void set_constants(const Array& constants) const;
+ // Records libraries under evaluation to break evaluation cycles.
+ RawGrowableObjectArray* evaluating() const { return raw_ptr()->evaluating_; }
+ void set_evaluating(const GrowableObjectArray& evaluating) const;
+
// If we load a kernel blob with evaluated constants, then we delay setting
// the native names of [Function] objects until we've read the constant table
// (since native names are encoded as constants).
@@ -4555,7 +4578,8 @@
// Returns the pool index from the offset relative to a tagged RawObjectPool*,
// adjusting for the tag-bit.
static intptr_t IndexFromOffset(intptr_t offset) {
- ASSERT(Utils::IsAligned(offset + kHeapObjectTag, kWordSize));
+ ASSERT(
+ Utils::IsAligned(offset + kHeapObjectTag, compiler::target::kWordSize));
return (offset + kHeapObjectTag - data_offset()) /
sizeof(RawObjectPool::Entry);
}
@@ -4712,7 +4736,9 @@
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;
}
@@ -5193,6 +5219,14 @@
return Code::OptimizedBit::decode(code->ptr()->state_bits_);
}
+ bool is_force_optimized() const {
+ return ForceOptimizedBit::decode(raw_ptr()->state_bits_);
+ }
+ void set_is_force_optimized(bool value) const;
+ static bool IsForceOptimized(RawCode* code) {
+ return Code::ForceOptimizedBit::decode(code->ptr()->state_bits_);
+ }
+
bool is_alive() const { return AliveBit::decode(raw_ptr()->state_bits_); }
void set_is_alive(bool value) const;
@@ -5424,6 +5458,9 @@
StorePointer(&raw_ptr()->exception_handlers_, handlers.raw());
}
+ // WARNING: function() returns the owner which is not guaranteed to be
+ // a Function. It is up to the caller to guarantee it isn't a stub, class,
+ // or something else.
// TODO(turnidge): Consider dropping this function and making
// everybody use owner(). Currently this function is misused - even
// while generating the snapshot.
@@ -5470,6 +5507,7 @@
CodeStatistics* stats);
// Notifies all active [CodeObserver]s.
+ static void NotifyCodeObservers(const Code& code, bool optimized);
static void NotifyCodeObservers(const Function& function,
const Code& code,
bool optimized);
@@ -5546,12 +5584,19 @@
friend class RawCode;
enum {
kOptimizedBit = 0,
- kAliveBit = 1,
- kPtrOffBit = 2,
- kPtrOffSize = 30,
+ kForceOptimizedBit = 1,
+ kAliveBit = 2,
+ kPtrOffBit = 3,
+ kPtrOffSize = 29,
};
class OptimizedBit : public BitField<int32_t, bool, kOptimizedBit, 1> {};
+
+ // Force-optimized is true if the Code was generated for a function with
+ // Function::ForceOptimize().
+ class ForceOptimizedBit
+ : public BitField<int32_t, bool, kForceOptimizedBit, 1> {};
+
class AliveBit : public BitField<int32_t, bool, kAliveBit, 1> {};
class PtrOffBits
: public BitField<int32_t, intptr_t, kPtrOffBit, kPtrOffSize> {};
@@ -5681,7 +5726,7 @@
RawExternalTypedData* GetBinary(Zone* zone) const;
- TokenPosition GetTokenIndexOfPC(uword pc) const;
+ TokenPosition GetTokenIndexOfPC(uword return_address) const;
intptr_t GetTryIndexAtPc(uword return_address) const;
intptr_t instructions_binary_offset() const {
@@ -6225,6 +6270,8 @@
virtual bool CheckAndCanonicalizeFields(Thread* thread,
const char** error_str) const;
+ RawInstance* CopyShallowToOldSpace(Thread* thread) const;
+
#if defined(DEBUG)
// Check if instance is canonical.
virtual bool CheckIsCanonical(Thread* thread) const;
@@ -6795,6 +6842,9 @@
// Check if this type represents the Dart '_Closure' type.
bool IsDartClosureType() const;
+ // Check if this type represents the 'Pointer' type from "dart:ffi".
+ bool IsFfiPointerType() const;
+
// Check the subtype relationship.
bool IsSubtypeOf(const AbstractType& other, Heap::Space space) const;
@@ -7282,9 +7332,7 @@
return reinterpret_cast<intptr_t>(New(value));
}
- static bool IsValid(int64_t value) {
- return (value >= kMinValue) && (value <= kMaxValue);
- }
+ static bool IsValid(int64_t value) { return compiler::target::IsSmi(value); }
void operator=(RawSmi* value) {
raw_ = value;
@@ -9040,8 +9088,7 @@
class Pointer : public Instance {
public:
static RawPointer* New(const AbstractType& type_arg,
- const Integer& c_memory_address,
- intptr_t class_id = kFfiPointerCid,
+ uword native_address,
Heap::Space space = Heap::kNew);
static intptr_t InstanceSize() {
@@ -9050,10 +9097,12 @@
static bool IsPointer(const Instance& obj);
- RawInteger* GetCMemoryAddress() const { return raw_ptr()->c_memory_address_; }
+ size_t NativeAddress() const {
+ return Integer::Handle(raw_ptr()->c_memory_address_).AsInt64Value();
+ }
- void SetCMemoryAddress(const Integer& value) const {
- StorePointer(&raw_ptr()->c_memory_address_, value.raw());
+ void SetNativeAddress(size_t address) const {
+ StorePointer(&raw_ptr()->c_memory_address_, Integer::New(address));
}
static intptr_t type_arguments_offset() {
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 0dba671..51d3365 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -102,9 +102,18 @@
if (!owner.IsFunction()) {
return; // No switchable calls in stub code.
}
+ const Function& function = Function::Cast(owner);
- const Array& ic_data_array =
- Array::Handle(zone, Function::Cast(owner).ic_data_array());
+ if (function.kind() == RawFunction::kIrregexpFunction) {
+ // Regex matchers do not support breakpoints or stepping, and they only call
+ // core library functions that cannot change due to reload. As a performance
+ // optimization, avoid this matching of ICData to PCs for these functions'
+ // large number of instance calls.
+ ASSERT(!function.is_debuggable());
+ return;
+ }
+
+ const Array& ic_data_array = Array::Handle(zone, function.ic_data_array());
if (ic_data_array.IsNull()) {
// The megamorphic miss stub and some recognized function doesn't populate
// their ic_data_array. Check this only happens for functions without IC
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3786d8e..2ba49c8 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -116,7 +116,7 @@
jsobj.AddProperty("library", Object::Handle(library()));
const Script& script = Script::Handle(this->script());
if (!script.IsNull()) {
- jsobj.AddLocation(script, token_pos(), ComputeEndTokenPos());
+ jsobj.AddLocation(script, token_pos(), end_token_pos());
}
{
JSONArray interfaces_array(&jsobj, "interfaces");
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 47c461e..8294709 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -140,7 +140,7 @@
set_linked_hash_set_class(cls);
#ifdef DART_PRECOMPILED_RUNTIME
- // These objects are only needed for code generation.
+ // The rest of these objects are only needed for code generation.
return;
#else
Isolate* isolate = thread->isolate();
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index d3277a4..f0ded97 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -143,6 +143,8 @@
RW(GrowableObjectArray, changed_in_last_reload) \
RW(Class, ffi_pointer_class) \
RW(Class, ffi_native_type_class) \
+ RW(Class, ffi_struct_class) \
+ RW(Object, ffi_as_function_internal) \
// Please remember the last entry must be referred in the 'to' function below.
// The object store is a per isolate instance which stores references to
@@ -235,7 +237,7 @@
DECLARE_OBJECT_STORE_FIELD)
#undef DECLARE_OBJECT_STORE_FIELD
RawObject** to() {
- return reinterpret_cast<RawObject**>(&ffi_pointer_class_);
+ return reinterpret_cast<RawObject**>(&ffi_as_function_internal_);
}
RawObject** to_snapshot(Snapshot::Kind kind) {
switch (kind) {
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 0921cc8..8e66ed7 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -168,7 +168,7 @@
EXPECT_EQ(type_arguments1.raw(), type_arguments3.raw());
}
-TEST_CASE(Class_ComputeEndTokenPos) {
+TEST_CASE(Class_EndTokenPos) {
const char* kScript =
"\n"
"class A {\n"
@@ -178,7 +178,6 @@
" foo(a) { return '''\"}'''; }\n"
" // }\n"
" var bar = '\\'}';\n"
- " var baz = \"${foo('}')}\";\n"
"}\n";
Dart_Handle lib_h = TestCase::LoadTestScript(kScript, NULL);
EXPECT_VALID(lib_h);
@@ -189,12 +188,15 @@
const Class& cls =
Class::Handle(lib.LookupClass(String::Handle(String::New("A"))));
EXPECT(!cls.IsNull());
- const TokenPosition end_token_pos = cls.ComputeEndTokenPos();
+ const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
+ EXPECT(error.IsNull());
+ const TokenPosition end_token_pos = cls.end_token_pos();
const Script& scr = Script::Handle(cls.script());
intptr_t line;
intptr_t col;
scr.GetTokenLocation(end_token_pos, &line, &col);
- EXPECT(line == 10 && col == 1);
+ EXPECT_EQ(9, line);
+ EXPECT_EQ(1, col);
}
ISOLATE_UNIT_TEST_CASE(InstanceClass) {
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 517f3c4..efde807 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -90,7 +90,7 @@
int OS::GetLocalTimeZoneAdjustmentInSeconds() {
int32_t local_offset, dst_offset;
zx_time_t now = 0;
- zx_clock_get_new(ZX_CLOCK_UTC, &now);
+ zx_clock_get(ZX_CLOCK_UTC, &now);
zx_status_t status = GetLocalAndDstOffsetInSeconds(
now / ZX_SEC(1), &local_offset, &dst_offset);
return status == ZX_OK ? local_offset : 0;
@@ -102,7 +102,7 @@
int64_t OS::GetCurrentTimeMicros() {
zx_time_t now = 0;
- zx_clock_get_new(ZX_CLOCK_UTC, &now);
+ zx_clock_get(ZX_CLOCK_UTC, &now);
return now / kNanosecondsPerMicrosecond;
}
@@ -122,7 +122,7 @@
int64_t OS::GetCurrentThreadCPUMicros() {
zx_time_t now = 0;
- zx_clock_get_new(ZX_CLOCK_THREAD, &now);
+ zx_clock_get(ZX_CLOCK_THREAD, &now);
return now / kNanosecondsPerMicrosecond;
}
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 4ad4340..0b580dd 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -4,6 +4,8 @@
#include "vm/port.h"
+#include <utility>
+
#include "platform/utils.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
@@ -82,14 +84,20 @@
}
Dart_Port PortMap::AllocatePort() {
- const Dart_Port kMASK = 0x3fffffff;
- Dart_Port result = prng_->NextUInt32() & kMASK;
+ Dart_Port result;
// Keep getting new values while we have an illegal port number or the port
// number is already in use.
- while ((result == 0) || (FindPort(result) >= 0)) {
- result = prng_->NextUInt32() & kMASK;
- }
+ do {
+ // Ensure port ids are representable in JavaScript for the benefit of
+ // vm-service clients such as Observatory.
+ const Dart_Port kMask1 = 0xFFFFFFFFFFFFF;
+ // Ensure port ids are never valid object pointers so that reinterpreting
+ // an object pointer as a port id never produces a used port id.
+ const Dart_Port kMask2 = 0x3;
+ result = (prng_->NextUInt64() & kMask1) | kMask2;
+ ASSERT(!reinterpret_cast<RawObject*>(result)->IsWellFormed());
+ } while (FindPort(result) >= 0);
ASSERT(result != 0);
ASSERT(FindPort(result) < 0);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 97153de..d3a1450 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1615,16 +1615,13 @@
ASSERT(function != NULL);
const intptr_t code_index = profile_code->code_table_index();
ASSERT(profile_code != NULL);
- Code& code = Code::ZoneHandle();
- if (profile_code->code().IsCode()) {
- code ^= profile_code->code().raw();
- } else {
- // No inlining in bytecode.
- }
+
GrowableArray<const Function*>* inlined_functions = NULL;
GrowableArray<TokenPosition>* inlined_token_positions = NULL;
TokenPosition token_position = TokenPosition::kNoSource;
- if (!code.IsNull()) {
+ Code& code = Code::ZoneHandle();
+ if (profile_code->code().IsCode()) {
+ code ^= profile_code->code().raw();
inlined_functions_cache_.Get(pc, code, sample, frame_index,
&inlined_functions, &inlined_token_positions,
&token_position);
@@ -1637,6 +1634,11 @@
(*inlined_token_positions)[i].ToCString());
}
}
+ } else if (profile_code->code().IsBytecode()) {
+ // No inlining in bytecode.
+ const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(),
+ profile_code->code().raw());
+ token_position = bc.GetTokenIndexOfPC(pc);
}
if (code.IsNull() || (inlined_functions == NULL) ||
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 1cb8236..25ae272 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -280,23 +280,37 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
// Inclusive code: main -> B.boo.
walker.Reset(Profile::kInclusiveCode);
// Move down from the root.
EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
@@ -306,8 +320,10 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT(walker.Down());
EXPECT_STREQ("main", walker.CurrentName());
@@ -321,8 +337,10 @@
EXPECT(walker.Down());
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
}
@@ -616,23 +634,37 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
// Inclusive code: main -> B.boo.
walker.Reset(Profile::kInclusiveCode);
// Move down from the root.
EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
@@ -642,8 +674,10 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT(walker.Down());
EXPECT_STREQ("main", walker.CurrentName());
@@ -657,8 +691,10 @@
EXPECT(walker.Down());
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
}
@@ -744,35 +780,59 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentNodeTickCount());
- EXPECT_EQ(3, walker.CurrentInclusiveTicks());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentNodeTickCount());
- EXPECT_EQ(3, walker.CurrentInclusiveTicks());
- EXPECT_EQ(0, walker.CurrentExclusiveTicks());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+ EXPECT(!walker.Down());
+ }
// Inclusive code: main -> B.boo.
walker.Reset(Profile::kInclusiveCode);
// Move down from the root.
EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentNodeTickCount());
- EXPECT_EQ(3, walker.CurrentInclusiveTicks());
- EXPECT_EQ(0, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentNodeTickCount());
- EXPECT_EQ(3, walker.CurrentInclusiveTicks());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT(walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentNodeTickCount());
+ EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
}
@@ -841,9 +901,11 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT_EQ(3, walker.CurrentNodeTickCount());
EXPECT_EQ(3, walker.CurrentInclusiveTicks());
@@ -867,9 +929,11 @@
EXPECT_EQ(3, walker.CurrentNodeTickCount());
EXPECT_EQ(3, walker.CurrentInclusiveTicks());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(3, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
+ }
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(!walker.Down());
}
@@ -921,14 +985,21 @@
walker.Reset(Profile::kExclusiveCode);
EXPECT(walker.Down());
- EXPECT_STREQ("Double_add", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] _Double._add", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] _Double.+", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("Double_add", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] _Double._add", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] _Double.+", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
double_class.SetTraceAllocation(false);
@@ -988,12 +1059,19 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] new _List", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
array_class.SetTraceAllocation(false);
@@ -1078,10 +1156,15 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateContext", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
context_class.SetTraceAllocation(false);
@@ -1142,8 +1225,10 @@
EXPECT(walker.Down());
EXPECT_SUBSTRING("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
+ EXPECT(walker.Down());
+ }
EXPECT_SUBSTRING("foo", walker.CurrentName());
EXPECT(!walker.Down());
}
@@ -1212,10 +1297,17 @@
EXPECT(walker.Down());
EXPECT_STREQ("TypedData_Float32Array_new", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] new Float32List", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
float32_list_class.SetTraceAllocation(false);
@@ -1293,12 +1385,17 @@
EXPECT(walker.Down());
EXPECT_STREQ("String_concat", walker.CurrentName());
EXPECT(walker.Down());
-#if 1
- EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName());
- EXPECT(walker.Down());
-#endif
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] _StringBase.+", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
one_byte_string_class.SetTraceAllocation(false);
@@ -1376,17 +1473,29 @@
EXPECT(walker.Down());
EXPECT_STREQ("OneByteString_allocate", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] _OneByteString._allocate",
- walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] _OneByteString._concatAll",
- walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] _StringBase._interpolate",
- walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] _OneByteString._allocate", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] _OneByteString._concatAll",
+ walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] _StringBase._interpolate", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Unoptimized] _OneByteString._allocate",
+ walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] _OneByteString._concatAll",
+ walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] _StringBase._interpolate",
+ walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
one_byte_string_class.SetTraceAllocation(false);
@@ -1421,6 +1530,7 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
+ SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
const char* kScript =
"class A {\n"
@@ -1706,6 +1816,7 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
+ SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
const char* kScript =
"class A {\n"
@@ -1890,48 +2001,91 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] init", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] go", walker.CurrentName());
- EXPECT(walker.Down());
- EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
- EXPECT(!walker.Down());
+ if (FLAG_enable_interpreter) {
+ EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] orange", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] napkin", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] mayo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] lemon", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] kindle", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] jeep", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] ice", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] haystack", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] granola", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] fred", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] elephant", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] dog", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] cantaloupe", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] banana", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] apple", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] secondInit", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] init", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] go", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ } else {
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] init", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] go", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
}
}
@@ -1988,9 +2142,11 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(1, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ 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.CurrentNodeTickCount());
EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2013,6 +2169,7 @@
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
"const NeverInline = 'NeverInline';\n"
@@ -2159,9 +2316,11 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(1, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ 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.CurrentNodeTickCount());
EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2202,6 +2361,7 @@
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
@@ -2382,9 +2542,11 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(1, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ 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.CurrentNodeTickCount());
EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2431,6 +2593,7 @@
SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
// Optimize quickly.
SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
const char* kScript =
"const AlwaysInline = 'AlwaysInline';\n"
@@ -2511,9 +2674,11 @@
EXPECT(walker.Down());
EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
EXPECT(walker.Down());
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(1, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
+ if (!FLAG_enable_interpreter) {
+ 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.CurrentNodeTickCount());
EXPECT_EQ(1, walker.CurrentInclusiveTicks());
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index e63d22b..029f91a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -174,15 +174,11 @@
: public BitField<uint32_t, intptr_t, kSizeTagPos, kSizeTagSize> {};
static intptr_t SizeToTagValue(intptr_t size) {
- ASSERT(Utils::IsAligned(
- size, compiler::target::ObjectAlignment::kObjectAlignment));
- return (size > kMaxSizeTag)
- ? 0
- : (size >>
- compiler::target::ObjectAlignment::kObjectAlignmentLog2);
+ ASSERT(Utils::IsAligned(size, kObjectAlignment));
+ return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2);
}
static intptr_t TagValueToSize(intptr_t value) {
- return value << compiler::target::ObjectAlignment::kObjectAlignmentLog2;
+ return value << kObjectAlignmentLog2;
}
};
@@ -490,6 +486,10 @@
#if defined(HASH_IN_OBJECT_HEADER)
// On 64 bit there is a hash field in the header for the identity hash.
uint32_t hash_;
+#elif defined(IS_SIMARM_X64)
+ // On simarm_x64 the hash isn't used, but we need the padding anyway so that
+ // the object layout fits assumptions made about X64.
+ uint32_t padding_;
#endif
// TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
@@ -800,6 +800,7 @@
cpp_vtable handle_vtable_;
TokenPosition token_pos_;
+ TokenPosition end_token_pos_;
int32_t instance_size_in_words_; // Size if fixed len or 0 if variable len.
int32_t type_arguments_field_offset_in_words_; // Offset of type args fld.
int32_t next_field_offset_in_words_; // Offset of the next instance field.
@@ -1038,7 +1039,10 @@
// Target Dart method for callbacks, otherwise null.
RawFunction* callback_target_;
- VISIT_TO(RawObject*, callback_target_);
+ // For callbacks, value to return if Dart target throws an exception.
+ RawInstance* callback_exceptional_return_;
+
+ VISIT_TO(RawObject*, callback_exceptional_return_);
RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
// Callback id for callbacks.
@@ -1258,13 +1262,14 @@
RawArray* bytecode_component_;
RawGrowableObjectArray* potential_natives_;
RawGrowableObjectArray* potential_pragma_functions_;
+ RawGrowableObjectArray* evaluating_; // detects cycles
RawExternalTypedData* constants_table_;
RawArray* libraries_cache_;
RawArray* classes_cache_;
VISIT_TO(RawObject*, classes_cache_);
RawObject** to_snapshot(Snapshot::Kind kind) {
- return reinterpret_cast<RawObject**>(&ptr()->potential_natives_);
+ return reinterpret_cast<RawObject**>(&ptr()->constants_table_);
}
};
@@ -1457,6 +1462,7 @@
friend class Function;
friend class ImageReader;
friend class ImageWriter;
+ friend class BlobImageWriter;
};
class RawPcDescriptors : public RawObject {
@@ -1518,6 +1524,7 @@
const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
friend class Object;
+ friend class ImageWriter;
};
// CodeSourceMap encodes a mapping from code PC ranges to source token
@@ -1536,6 +1543,7 @@
const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
friend class Object;
+ friend class ImageWriter;
};
// StackMap is an immutable representation of the layout of the stack at a
@@ -1559,6 +1567,8 @@
// Variable length data follows here (bitmap of the stack layout).
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
+
+ friend class ImageWriter;
};
class RawLocalVarDescriptors : public RawObject {
@@ -2088,6 +2098,7 @@
friend class OneByteStringDeserializationCluster;
friend class TwoByteStringDeserializationCluster;
friend class RODataSerializationCluster;
+ friend class ImageWriter;
};
class RawOneByteString : public RawString {
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 35d4fdc..e9113d9 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -93,6 +93,7 @@
F(KernelProgramInfo, bytecode_component_) \
F(KernelProgramInfo, potential_natives_) \
F(KernelProgramInfo, potential_pragma_functions_) \
+ F(KernelProgramInfo, evaluating_) \
F(KernelProgramInfo, constants_table_) \
F(KernelProgramInfo, libraries_cache_) \
F(KernelProgramInfo, classes_cache_) \
@@ -199,6 +200,7 @@
F(FfiTrampolineData, signature_type_) \
F(FfiTrampolineData, c_signature_) \
F(FfiTrampolineData, callback_target_) \
+ F(FfiTrampolineData, callback_exceptional_return_) \
F(TypedDataBase, data_) \
F(TypedDataBase, length_) \
F(TypedDataView, typed_data_) \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index c886658..2b5d9cf2 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2132,7 +2132,7 @@
for (intptr_t i = 0; i < num_frames; i++) {
ActivationFrame* frame = stack->FrameAt(i);
#ifndef DART_PRECOMPILED_RUNTIME
- if (!frame->IsInterpreted()) {
+ if (!frame->IsInterpreted() && !frame->function().ForceOptimize()) {
// Ensure that we have unoptimized code.
frame->function().EnsureHasCompiledUnoptimizedCode();
}
@@ -2219,6 +2219,13 @@
DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
#if defined(USING_SIMULATOR)
uword stack_pos = Simulator::Current()->get_sp();
+ // If simulator was never called (for example, in pure
+ // interpreted mode) it may return 0 as a value of SPREG.
+ if (stack_pos == 0) {
+ // Use any reasonable value which would not be treated
+ // as stack overflow.
+ stack_pos = thread->saved_stack_limit();
+ }
#else
uword stack_pos = OSThread::GetCurrentStackPointer();
#endif
@@ -2296,7 +2303,8 @@
// If running with interpreter, do the unoptimized compilation first.
const bool optimizing_compilation = function.ShouldCompilerOptimize();
ASSERT(FLAG_enable_interpreter || optimizing_compilation);
- ASSERT((!optimizing_compilation) || function.HasCode());
+ ASSERT((!optimizing_compilation) || function.HasCode() ||
+ function.ForceOptimize());
#if defined(PRODUCT)
if (!optimizing_compilation ||
@@ -2510,6 +2518,11 @@
void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
ASSERT(optimized_code.is_optimized());
+
+ // Force-optimized code is optimized code which cannot deoptimize and doesn't
+ // have unoptimized code to fall back to.
+ ASSERT(!optimized_code.is_force_optimized());
+
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Function& function = Function::Handle(zone, optimized_code.function());
@@ -2590,7 +2603,8 @@
while (frame != NULL) {
if (!frame->is_interpreted()) {
optimized_code = frame->LookupDartCode();
- if (optimized_code.is_optimized()) {
+ if (optimized_code.is_optimized() &&
+ !optimized_code.is_force_optimized()) {
DeoptimizeAt(optimized_code, frame);
}
}
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index a5f12e0..b39fa23 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3628,6 +3628,17 @@
#endif
}
+static const MethodParameter* get_vm_timeline_micros_params[] = {
+ NO_ISOLATE_PARAMETER, NULL,
+};
+
+static bool GetVMTimelineMicros(Thread* thread, JSONStream* js) {
+ JSONObject obj(js);
+ obj.AddProperty("type", "Timestamp");
+ obj.AddPropertyTimeMicros("timestamp", OS::GetCurrentMonotonicMicros());
+ return true;
+}
+
static const MethodParameter* clear_vm_timeline_params[] = {
NO_ISOLATE_PARAMETER, NULL,
};
@@ -4976,6 +4987,8 @@
get_vm_timeline_params },
{ "getVMTimelineFlags", GetVMTimelineFlags,
get_vm_timeline_flags_params },
+ { "getVMTimelineMicros", GetVMTimelineMicros,
+ get_vm_timeline_micros_params },
{ "invoke", Invoke, invoke_params },
{ "kill", Kill, kill_params },
{ "pause", Pause,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 15d30ff..835282f 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 20
+#define SERVICE_PROTOCOL_MINOR_VERSION 21
class Array;
class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 2c5731c..2dfda77 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.20
+# Dart VM Service Protocol 3.21
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.20_ of the Dart VM Service Protocol. This
+This document describes of _version 3.21_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
- [getVM](#getvm)
- [getVMTimeline](#getvmtimeline)
- [getVMTimelineFlags](#getvmtimelineflags)
+ - [getVMTimelineMicros](#getvmtimelinemicros)
- [invoke](#invoke)
- [pause](#pause)
- [kill](#kill)
@@ -107,6 +108,7 @@
- [Timeline](#timeline)
- [TimelineEvent](#timelineevent)
- [TimelineFlags](#timelineflags)
+ - [Timestamp](#timestamp)
- [TypeArguments](#typearguments)
- [UresolvedSourceLocation](#unresolvedsourcelocation)
- [Version](#version)
@@ -490,7 +492,7 @@
### clearVMTimeline
-```
+```
Success clearVMTimeline()
```
@@ -615,8 +617,8 @@
```
AllocationProfile getAllocationProfile(string isolateId,
- boolean reset [optional],
- boolean gc [optional])
+ bool reset [optional],
+ bool gc [optional])
```
The _getAllocationProfile_ RPC is used to retrieve allocation information for a
@@ -643,7 +645,8 @@
### getInstances
```
-InstanceSet getInstances(string objectId,
+InstanceSet getInstances(string isolateId,
+ string objectId,
int limit)
```
@@ -806,8 +809,8 @@
### getVMTimeline
```
-Timeline getVMTimeline(int timeOriginMicros,
- int timeExtentMicros)
+Timeline getVMTimeline(int timeOriginMicros [optional],
+ int timeExtentMicros [optional])
```
The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
@@ -815,7 +818,8 @@
The _timeOriginMicros_ parameter is the beginning of the time range used to filter
timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
The _timeExtentMicros_ parameter specifies how large the time range used to filter
timeline events should be.
@@ -839,6 +843,17 @@
See [TimelineFlags](#timelineflags).
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
### pause
```
@@ -2318,7 +2333,7 @@
int totalCount;
// An array of instances of the requested type.
- @Instance[] instances;
+ @Object[] instances;
}
```
@@ -2897,7 +2912,7 @@
class TimelineFlags extends Response {
// The name of the recorder currently in use. Recorder types include, but are
// not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
- // Set to "null" if no recorder is currently set.
+ // Set to "null" if no recorder is currently set.
string recorderName;
// The list of all available timeline streams.
@@ -2908,6 +2923,15 @@
}
```
+### Timestamp
+
+```
+class Timestamp extends Response {
+ // A timestamp in microseconds since epoch.
+ int timestamp;
+}
+```
+
### TypeArguments
```
@@ -3056,5 +3080,6 @@
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 14293eb..04fd1e9 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.21-dev
+# Dart VM Service Protocol 3.22-dev
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.21-dev_ of the Dart VM Service Protocol. This
+This document describes of _version 3.22-dev_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
- [getVM](#getvm)
- [getVMTimeline](#getvmtimeline)
- [getVMTimelineFlags](#getvmtimelineflags)
+ - [getVMTimelineMicros](#getvmtimelinemicros)
- [invoke](#invoke)
- [pause](#pause)
- [kill](#kill)
@@ -107,6 +108,7 @@
- [Timeline](#timeline)
- [TimelineEvent](#timelineevent)
- [TimelineFlags](#timelineflags)
+ - [Timestamp](#timestamp)
- [TypeArguments](#typearguments)
- [UresolvedSourceLocation](#unresolvedsourcelocation)
- [Version](#version)
@@ -490,7 +492,7 @@
### clearVMTimeline
-```
+```
Success clearVMTimeline()
```
@@ -615,8 +617,8 @@
```
AllocationProfile getAllocationProfile(string isolateId,
- boolean reset [optional],
- boolean gc [optional])
+ bool reset [optional],
+ bool gc [optional])
```
The _getAllocationProfile_ RPC is used to retrieve allocation information for a
@@ -643,7 +645,8 @@
### getInstances
```
-InstanceSet getInstances(string objectId,
+InstanceSet getInstances(string isolateId,
+ string objectId,
int limit)
```
@@ -806,8 +809,8 @@
### getVMTimeline
```
-Timeline getVMTimeline(int timeOriginMicros,
- int timeExtentMicros)
+Timeline getVMTimeline(int timeOriginMicros [optional],
+ int timeExtentMicros [optional])
```
The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
@@ -815,7 +818,8 @@
The _timeOriginMicros_ parameter is the beginning of the time range used to filter
timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
The _timeExtentMicros_ parameter specifies how large the time range used to filter
timeline events should be.
@@ -839,6 +843,17 @@
See [TimelineFlags](#timelineflags).
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
### pause
```
@@ -2318,7 +2333,7 @@
int totalCount;
// An array of instances of the requested type.
- @Instance[] instances;
+ @Object[] instances;
}
```
@@ -2897,7 +2912,7 @@
class TimelineFlags extends Response {
// The name of the recorder currently in use. Recorder types include, but are
// not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
- // Set to "null" if no recorder is currently set.
+ // Set to "null" if no recorder is currently set.
string recorderName;
// The list of all available timeline streams.
@@ -2908,6 +2923,15 @@
}
```
+### Timestamp
+
+```
+class Timestamp extends Response {
+ // A timestamp in microseconds since epoch.
+ int timestamp;
+}
+```
+
### TypeArguments
```
@@ -3056,5 +3080,6 @@
3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 2cd0745..24197fe 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -829,10 +829,12 @@
// Get the active Simulator for the current isolate.
Simulator* Simulator::Current() {
- Simulator* simulator = Isolate::Current()->simulator();
+ Isolate* isolate = Isolate::Current();
+ Simulator* simulator = isolate->simulator();
if (simulator == NULL) {
+ NoSafepointScope no_safepoint;
simulator = new Simulator();
- Isolate::Current()->set_simulator(simulator);
+ isolate->set_simulator(simulator);
}
return simulator;
}
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index c835793..8eb8dd5 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -869,10 +869,12 @@
// Get the active Simulator for the current isolate.
Simulator* Simulator::Current() {
- Simulator* simulator = Isolate::Current()->simulator();
+ Isolate* isolate = Isolate::Current();
+ Simulator* simulator = isolate->simulator();
if (simulator == NULL) {
+ NoSafepointScope no_safepoint;
simulator = new Simulator();
- Isolate::Current()->set_simulator(simulator);
+ isolate->set_simulator(simulator);
}
return simulator;
}
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 99726ee..2a7176d 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -584,10 +584,12 @@
// Get the active Simulator for the current isolate.
Simulator* Simulator::Current() {
- Simulator* simulator = Isolate::Current()->simulator();
+ Isolate* isolate = Isolate::Current();
+ Simulator* simulator = isolate->simulator();
if (simulator == NULL) {
+ NoSafepointScope no_safepoint;
simulator = new Simulator();
- Isolate::Current()->set_simulator(simulator);
+ isolate->set_simulator(simulator);
}
return simulator;
}
@@ -702,45 +704,12 @@
DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs,
intptr_t rhs,
intptr_t* out) {
- intptr_t res = 1;
-#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
- asm volatile(
- "imul %2, %1\n"
- "jo 1f;\n"
- "xor %0, %0\n"
- "mov %1, 0(%3)\n"
- "1: "
- : "+r"(res), "+r"(lhs)
- : "r"(rhs), "r"(out)
- : "cc");
-#elif defined(HOST_ARCH_ARM)
- asm volatile(
- "smull %1, ip, %1, %2;\n"
- "cmp ip, %1, ASR #31;\n"
- "bne 1f;\n"
- "mov %0, $0;\n"
- "str %1, [%3, #0]\n"
- "1:"
- : "+r"(res), "+r"(lhs)
- : "r"(rhs), "r"(out)
- : "cc", "r12");
-#elif defined(HOST_ARCH_ARM64)
- int64_t prod_lo = 0;
- asm volatile(
- "mul %1, %2, %3\n"
- "smulh %2, %2, %3\n"
- "cmp %2, %1, ASR #63;\n"
- "bne 1f;\n"
- "mov %0, #0;\n"
- "str %1, [%4, #0]\n"
- "1:"
- : "=r"(res), "+r"(prod_lo), "+r"(lhs)
- : "r"(rhs), "r"(out)
- : "cc");
-#else
-#error "Unsupported platform"
-#endif
- return (res != 0);
+ const intptr_t kMaxBits = (sizeof(intptr_t) * 8) - 2;
+ if ((Utils::HighestBit(lhs) + Utils::HighestBit(rhs)) < kMaxBits) {
+ *out = lhs * rhs;
+ return false;
+ }
+ return true;
}
DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index febc594..0a79bd9 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -88,6 +88,9 @@
}
}
+ // These don't have unoptimized code and are only used for synthetic stubs.
+ if (func.ForceOptimize()) return true;
+
switch (func.kind()) {
case RawFunction::kRegularFunction:
case RawFunction::kClosureFunction:
@@ -559,19 +562,20 @@
script = cls.script();
range.AddProperty("scriptIndex", GetScriptIndex(script));
range.AddProperty("startPos", cls.token_pos());
- range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("endPos", cls.end_token_pos());
range.AddProperty("compiled", false);
range.AddProperty("error", err);
continue;
}
ASSERT(cls.is_finalized());
} else {
+ cls.EnsureDeclarationLoaded();
// Emit one range for the whole uncompiled class.
JSONObject range(jsarr);
script = cls.script();
range.AddProperty("scriptIndex", GetScriptIndex(script));
range.AddProperty("startPos", cls.token_pos());
- range.AddProperty("endPos", cls.ComputeEndTokenPos());
+ range.AddProperty("endPos", cls.end_token_pos());
range.AddProperty("compiled", false);
continue;
}
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index fa77c7d..76a31f8 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -48,7 +48,7 @@
if (!expected.OperatorEquals(actual)) {
OS::PrintErr("expected: '%s' actual: '%s'\n", expected.ToCString(),
actual.ToCString());
- FATAL("Expect_equals fails.\n");
+ EXPECT(false);
}
}
@@ -112,9 +112,7 @@
ASSERT(!lib.IsNull());
const char* lib_name = String::Handle(zone, lib.url()).ToCString();
char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name);
- if (strcmp(full_name, name) != 0) {
- FATAL("StackFrame_validateFrame fails, incorrect frame.\n");
- }
+ EXPECT_STREQ(full_name, name);
return;
}
count += 1; // Count the dart frames.
@@ -251,7 +249,45 @@
// The true stack depends on which strategy we are using for noSuchMethod. The
// stacktrace as seen by Dart is the same either way because dispatcher
// methods are marked invisible.
- if (FLAG_lazy_dispatchers) {
+ if (FLAG_enable_interpreter) {
+ kScriptChars =
+ "class StackFrame {"
+ " static equals(var obj1, var obj2) native \"StackFrame_equals\";"
+ " static int frameCount() native \"StackFrame_frameCount\";"
+ " static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
+ " static validateFrame(int index,"
+ " String name) native "
+ "\"StackFrame_validateFrame\";"
+ "} "
+ "class StackFrame2Test {"
+ " StackFrame2Test() {}"
+ " noSuchMethod(Invocation im) {"
+ " /* We should have 8 general frames and 4 dart frames as follows:"
+ " * exit frame"
+ " * dart frame corresponding to StackFrame.frameCount"
+ " * dart frame corresponding to StackFrame2Test.noSuchMethod"
+ " * entry frame"
+ " * exit frame"
+ " * dart frame for noSuchMethod dispatcher"
+ " * dart frame corresponding to StackFrame2Test.testMain"
+ " * entry frame"
+ " */"
+ " StackFrame.equals(8, StackFrame.frameCount());"
+ " StackFrame.equals(4, StackFrame.dartFrameCount());"
+ " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
+ " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
+ " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");"
+ " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");"
+ " return 5;"
+ " }"
+ " static testMain() {"
+ " /* Declare |obj| dynamic so that noSuchMethod can be"
+ " * called in strong mode. */"
+ " dynamic obj = new StackFrame2Test();"
+ " StackFrame.equals(5, obj.foo(101, 202));"
+ " }"
+ "}";
+ } else if (FLAG_lazy_dispatchers) {
kScriptChars =
"class StackFrame {"
" static equals(var obj1, var obj2) native \"StackFrame_equals\";"
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index fb281f7..559fc77 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -25,6 +25,7 @@
V(ApiError, "ApiError") \
V(ArgDescVar, ":arg_desc") \
V(ArgumentError, "ArgumentError") \
+ V(AsFunctionInternal, "_asFunctionInternal") \
V(AssertionError, "_AssertionError") \
V(AssignIndexToken, "[]=") \
V(AsyncCompleter, ":async_completer") \
@@ -235,6 +236,7 @@
V(SetterPrefix, "set:") \
V(SignatureData, "SignatureData") \
V(SingleTargetCache, "SingleTargetCache") \
+ V(SizeOfStructField, "#sizeOf") \
V(SpaceExtendsSpace, " extends ") \
V(SpaceIsFromSpace, " is from ") \
V(SpaceOfSpace, " of ") \
@@ -247,6 +249,8 @@
V(StreamIterator, "StreamIterator") \
V(StreamIteratorConstructor, "StreamIterator.") \
V(StringBase, "_StringBase") \
+ V(Struct, "Struct") \
+ V(StructFromPointer, "#fromPointer") \
V(SubtypeTestCache, "SubtypeTestCache") \
V(SwitchExpr, ":switch_expr") \
V(Symbol, "Symbol") \
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 68d85c2..6582016 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -919,8 +919,7 @@
};
#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
-// A recorder that sends events to Fuchsia's tracing app. See:
-// https://fuchsia.googlesource.com/garnet/+/master/docs/tracing_usage_guide.md
+// A recorder that sends events to Fuchsia's tracing app.
class TimelineEventFuchsiaRecorder : public TimelineEventPlatformRecorder {
public:
TimelineEventFuchsiaRecorder() {}
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index b75e93b..d7a6e3c 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -676,7 +676,7 @@
String::Handle(lib.url()).ToCString(), /* klass=*/nullptr,
/* is_static= */ false);
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
- return Dart_NewApiError(compilation_result.error);
+ return Api::NewError("%s", compilation_result.error);
}
const uint8_t* kernel_bytes = compilation_result.kernel;
diff --git a/runtime/vm/verified_memory_test.cc b/runtime/vm/verified_memory_test.cc
deleted file mode 100644
index a78fe5d..0000000
--- a/runtime/vm/verified_memory_test.cc
+++ /dev/null
@@ -1,114 +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.
-
-#include "vm/verified_memory.h"
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-void Init() {
-#if defined(DEBUG)
- FLAG_verified_mem = true;
-#endif
-}
-
-void Shutdown() {
-#if defined(DEBUG)
- // We must reset this to false to avoid checking some assumptions in
- // VM shutdown that are left violated by these tests.
- FLAG_verified_mem = false;
-#endif
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryReserve) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- delete vm;
- Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryCommit) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- vm->Commit(false);
- delete vm;
- Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryBasic) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- vm->Commit(false);
- double* addr = reinterpret_cast<double*>(vm->address());
- VerifiedMemory::Write(&addr[0], 0.5);
- EXPECT_EQ(0.5, addr[0]);
- VerifiedMemory::Write(&addr[1], 1.5);
- VerifiedMemory::Write(&addr[2], 2.5);
- VerifiedMemory::Write(&addr[0], 0.25);
- static const double kNaN = NAN;
- VerifiedMemory::Write(&addr[0], kNaN); // Bitwise comparison should be used.
- VerifiedMemory::Write(&addr[0], 0.5);
- int64_t* unverified = reinterpret_cast<int64_t*>(&addr[3]);
- *unverified = 123;
- VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
- delete vm;
- Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryAccept) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- vm->Commit(false);
- double* addr = reinterpret_cast<double*>(vm->address());
- VerifiedMemory::Write(&addr[0], 0.5);
- VerifiedMemory::Write(&addr[1], 1.5);
- VerifiedMemory::Write(&addr[2], 2.5);
- VerifiedMemory::Write(&addr[0], 0.25);
- // Unverified write followed by Accept ("I know what I'm doing").
- memset(addr, 0xf3, 2 * sizeof(double));
- VerifiedMemory::Accept(reinterpret_cast<uword>(addr), 2 * sizeof(double));
- VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
- delete vm;
- Shutdown();
-}
-
-// Negative tests below.
-
-VM_UNIT_TEST_CASE(VerifyImplicit_Crash) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- vm->Commit(false);
- double* addr = reinterpret_cast<double*>(vm->address());
- addr[0] = 0.5; // Forget to use Write.
- VerifiedMemory::Write(&addr[0], 1.5);
- Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifyExplicit_Crash) {
- Init();
- const intptr_t kReservationSize = 64 * KB;
- VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
- EXPECT_EQ(kReservationSize, vm->size());
- vm->Commit(false);
- double* addr = reinterpret_cast<double*>(vm->address());
- VerifiedMemory::Write(&addr[0], 0.5);
- VerifiedMemory::Write(&addr[1], 1.5);
- addr[1] = 3.5; // Forget to use Write.
- VerifiedMemory::Write(&addr[2], 2.5);
- VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
- Shutdown();
-}
-
-} // namespace dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/Uri.dart b/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
index 28e05b5..d04d0c5 100644
--- a/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
+++ b/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
@@ -6,7 +6,7 @@
/**
* A parsed URI, inspired by:
- * http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
+ * https://github.com/google/closure-library/blob/master/closure/goog/uri/uri.js
*/
class SwarmUri {
/**
diff --git a/samples/ffi/sqlite/docs/sqlite-tutorial.md b/samples/ffi/sqlite/docs/sqlite-tutorial.md
index c38170c..f9db349 100644
--- a/samples/ffi/sqlite/docs/sqlite-tutorial.md
+++ b/samples/ffi/sqlite/docs/sqlite-tutorial.md
@@ -118,7 +118,7 @@
queryC.free();
```
-Browse the code: [CString class](../lib/src/ffi/cstring.dart), [code calling sqlite3_prepare_v2](../lib/src/database.dart#57), and [dart:ffi pointer interface](../../../../sdk/lib/ffi/ffi.dart).
+Browse the code: [CString class](../lib/src/ffi/utf8.dart), [code calling sqlite3_prepare_v2](../lib/src/database.dart#57), and [dart:ffi pointer interface](../../../../sdk/lib/ffi/ffi.dart).
## Dart API
@@ -152,7 +152,7 @@
"This row is not the current row, reading data from the non-current"
" row is not supported by sqlite.");
}
- // ...
+ // ...
}
}
```
@@ -231,4 +231,4 @@
For example we could catch C++ exceptions in a C++ layer, and rethrow them in Dart.
The architecture diagram would change to the following in that case.
-![architecture2](lib/scenario-full.svg)
\ No newline at end of file
+![architecture2](lib/scenario-full.svg)
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
index 613dbad..a248716 100644
--- a/samples/ffi/sqlite/lib/src/bindings/bindings.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -4,7 +4,7 @@
import "dart:ffi";
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
import "../ffi/dylib_utils.dart";
import "signatures.dart";
@@ -27,10 +27,10 @@
/// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
/// an English language description of the error following a failure of any
/// of the sqlite3_open() routines.
- int Function(CString filename, Pointer<DatabasePointer> databaseOut,
- int flags, CString vfs) sqlite3_open_v2;
+ int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
+ int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
- int Function(DatabasePointer database) sqlite3_close_v2;
+ int Function(Pointer<Database> database) sqlite3_close_v2;
/// Compiling An SQL Statement
///
@@ -80,11 +80,11 @@
/// original SQL text. This causes the [sqlite3_step] interface to
/// behave differently in three ways:
int Function(
- DatabasePointer database,
- CString query,
+ Pointer<Database> database,
+ Pointer<Utf8> query,
int nbytes,
- Pointer<StatementPointer> statementOut,
- Pointer<CString> tail) sqlite3_prepare_v2;
+ Pointer<Pointer<Statement>> statementOut,
+ Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
/// Evaluate An SQL Statement
///
@@ -162,7 +162,7 @@
/// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
/// then the more specific [error codes] are returned directly
/// by sqlite3_step(). The use of the "v2" interface is recommended.
- int Function(StatementPointer statement) sqlite3_step;
+ int Function(Pointer<Statement> statement) sqlite3_step;
/// CAPI3REF: Reset A Prepared Statement Object
///
@@ -185,7 +185,7 @@
/// [sqlite3_reset] returns an appropriate [Errors].
///
/// ^The [sqlite3_reset] interface does not change the values
- int Function(StatementPointer statement) sqlite3_reset;
+ int Function(Pointer<Statement> statement) sqlite3_reset;
/// Destroy A Prepared Statement Object
///
@@ -210,14 +210,14 @@
/// a prepared statement after it has been finalized. Any use of a prepared
/// statement after it has been finalized can result in undefined and
/// undesirable behavior such as segfaults and heap corruption.
- int Function(StatementPointer statement) sqlite3_finalize;
+ int Function(Pointer<Statement> statement) sqlite3_finalize;
/// Number Of Columns In A Result Set
///
/// ^Return the number of columns in the result set returned by the
/// prepared statement. ^This routine returns 0 if pStmt is an SQL
/// statement that does not return data (for example an [UPDATE]).
- int Function(StatementPointer statement) sqlite3_column_count;
+ int Function(Pointer<Statement> statement) sqlite3_column_count;
/// Column Names In A Result Set
///
@@ -242,7 +242,7 @@
/// ^The name of a result column is the value of the "AS" clause for
/// that column, if there is an AS clause. If there is no AS clause
/// then the name of the column is unspecified and may change from
- CString Function(StatementPointer statement, int columnIndex)
+ Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_name;
/// CAPI3REF: Declared Datatype Of A Query Result
@@ -272,26 +272,28 @@
/// strongly typed, but the typing is dynamic not static. ^Type
/// is associated with individual values, not with the containers
/// used to hold those values.
- CString Function(StatementPointer statement, int columnIndex)
+ Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_decltype;
- int Function(StatementPointer statement, int columnIndex) sqlite3_column_type;
+ int Function(Pointer<Statement> statement, int columnIndex)
+ sqlite3_column_type;
- ValuePointer Function(StatementPointer statement, int columnIndex)
+ Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_value;
- double Function(StatementPointer statement, int columnIndex)
+ double Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_double;
- int Function(StatementPointer statement, int columnIndex) sqlite3_column_int;
+ int Function(Pointer<Statement> statement, int columnIndex)
+ sqlite3_column_int;
- CString Function(StatementPointer statement, int columnIndex)
+ Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
sqlite3_column_text;
/// The sqlite3_errstr() interface returns the English-language text that
/// describes the result code, as UTF-8. Memory to hold the error message
/// string is managed internally and must not be freed by the application.
- CString Function(int code) sqlite3_errstr;
+ Pointer<Utf8> Function(int code) sqlite3_errstr;
/// Error Codes And Messages
///
@@ -324,7 +326,7 @@
/// If an interface fails with SQLITE_MISUSE, that means the interface
/// was invoked incorrectly by the application. In that case, the
/// error code and message may or may not be set.
- CString Function(DatabasePointer database) sqlite3_errmsg;
+ Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
_SQLiteBindings() {
sqlite = dlopenPlatformSpecific("sqlite3");
diff --git a/samples/ffi/sqlite/lib/src/bindings/signatures.dart b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
index bb1b1e9..8994577 100644
--- a/samples/ffi/sqlite/lib/src/bindings/signatures.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
@@ -4,52 +4,54 @@
import "dart:ffi";
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
import "types.dart";
-typedef sqlite3_open_v2_native_t = Int32 Function(
- CString filename, Pointer<DatabasePointer> ppDb, Int32 flags, CString vfs);
+typedef sqlite3_open_v2_native_t = Int32 Function(Pointer<Utf8> filename,
+ Pointer<Pointer<Database>> ppDb, Int32 flags, Pointer<Utf8> vfs);
-typedef sqlite3_close_v2_native_t = Int32 Function(DatabasePointer database);
+typedef sqlite3_close_v2_native_t = Int32 Function(Pointer<Database> database);
typedef sqlite3_prepare_v2_native_t = Int32 Function(
- DatabasePointer database,
- CString query,
+ Pointer<Database> database,
+ Pointer<Utf8> query,
Int32 nbytes,
- Pointer<StatementPointer> statementOut,
- Pointer<CString> tail);
+ Pointer<Pointer<Statement>> statementOut,
+ Pointer<Pointer<Utf8>> tail);
-typedef sqlite3_step_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_step_native_t = Int32 Function(Pointer<Statement> statement);
-typedef sqlite3_reset_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_reset_native_t = Int32 Function(Pointer<Statement> statement);
-typedef sqlite3_finalize_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_finalize_native_t = Int32 Function(
+ Pointer<Statement> statement);
-typedef sqlite3_errstr_native_t = CString Function(Int32 error);
+typedef sqlite3_errstr_native_t = Pointer<Utf8> Function(Int32 error);
-typedef sqlite3_errmsg_native_t = CString Function(DatabasePointer database);
+typedef sqlite3_errmsg_native_t = Pointer<Utf8> Function(
+ Pointer<Database> database);
typedef sqlite3_column_count_native_t = Int32 Function(
- StatementPointer statement);
+ Pointer<Statement> statement);
-typedef sqlite3_column_name_native_t = CString Function(
- StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_name_native_t = Pointer<Utf8> Function(
+ Pointer<Statement> statement, Int32 columnIndex);
-typedef sqlite3_column_decltype_native_t = CString Function(
- StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_decltype_native_t = Pointer<Utf8> Function(
+ Pointer<Statement> statement, Int32 columnIndex);
typedef sqlite3_column_type_native_t = Int32 Function(
- StatementPointer statement, Int32 columnIndex);
+ Pointer<Statement> statement, Int32 columnIndex);
-typedef sqlite3_column_value_native_t = ValuePointer Function(
- StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_value_native_t = Pointer<Value> Function(
+ Pointer<Statement> statement, Int32 columnIndex);
typedef sqlite3_column_double_native_t = Double Function(
- StatementPointer statement, Int32 columnIndex);
+ Pointer<Statement> statement, Int32 columnIndex);
typedef sqlite3_column_int_native_t = Int32 Function(
- StatementPointer statement, Int32 columnIndex);
+ Pointer<Statement> statement, Int32 columnIndex);
-typedef sqlite3_column_text_native_t = CString Function(
- StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_text_native_t = Pointer<Utf8> Function(
+ Pointer<Statement> statement, Int32 columnIndex);
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
index b843d74..f536b91 100644
--- a/samples/ffi/sqlite/lib/src/bindings/types.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/types.dart
@@ -4,7 +4,7 @@
import "dart:ffi";
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
/// Database Connection Handle
///
@@ -15,7 +15,7 @@
/// is its destructor. There are many other interfaces (such as
/// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
/// [sqlite3_busy_timeout()] to name but three) that are methods on an
-class DatabasePointer extends Pointer<Void> {}
+class Database extends Struct<Database> {}
/// SQL Statement Object
///
@@ -38,7 +38,7 @@
///
/// Refer to documentation on individual methods above for additional
/// information.
-class StatementPointer extends Pointer<Void> {}
+class Statement extends Struct<Statement> {}
/// Dynamically Typed Value Object
///
@@ -74,4 +74,4 @@
/// [sqlite3_result_value()] and [sqlite3_bind_value()].
/// The [sqlite3_value_blob | sqlite3_value_type()] family of
/// interfaces require protected sqlite3_value objects.
-class ValuePointer extends Pointer<Void> {}
+class Value extends Struct<Value> {}
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index a20b7fc..2cd4316 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -6,10 +6,13 @@
import "dart:ffi";
import "bindings/bindings.dart";
-import "bindings/types.dart";
+
+import "bindings/types.dart" as types;
+import "bindings/types.dart" hide Database;
+
import "bindings/constants.dart";
import "collections/closable_iterator.dart";
-import "ffi/cstring.dart";
+import "ffi/utf8.dart";
/// [Database] represents an open connection to a SQLite database.
///
@@ -17,16 +20,16 @@
///
/// This database interacts with SQLite synchonously.
class Database {
- DatabasePointer _database;
+ Pointer<types.Database> _database;
bool _open = false;
/// Open a database located at the file [path].
Database(String path,
[int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
- Pointer<DatabasePointer> dbOut = allocate();
- CString pathC = CString.allocate(path);
+ Pointer<Pointer<types.Database>> dbOut = Pointer.allocate();
+ final pathC = Utf8.allocate(path);
final int resultCode =
- bindings.sqlite3_open_v2(pathC, dbOut, flags, fromAddress(0));
+ bindings.sqlite3_open_v2(pathC, dbOut, flags, Pointer.fromAddress(0));
_database = dbOut.load();
dbOut.free();
pathC.free();
@@ -59,11 +62,11 @@
/// Execute a query, discarding any returned rows.
void execute(String query) {
- Pointer<StatementPointer> statementOut = allocate();
- CString queryC = CString.allocate(query);
+ Pointer<Pointer<Statement>> statementOut = Pointer.allocate();
+ Pointer<Utf8> queryC = Utf8.allocate(query);
int resultCode = bindings.sqlite3_prepare_v2(
- _database, queryC, -1, statementOut, fromAddress(0));
- StatementPointer statement = statementOut.load();
+ _database, queryC, -1, statementOut, Pointer.fromAddress(0));
+ Pointer<Statement> statement = statementOut.load();
statementOut.free();
queryC.free();
@@ -78,11 +81,11 @@
/// Evaluate a query and return the resulting rows as an iterable.
Result query(String query) {
- Pointer<StatementPointer> statementOut = allocate();
- CString queryC = CString.allocate(query);
+ Pointer<Pointer<Statement>> statementOut = Pointer.allocate();
+ Pointer<Utf8> queryC = Utf8.allocate(query);
int resultCode = bindings.sqlite3_prepare_v2(
- _database, queryC, -1, statementOut, fromAddress(0));
- StatementPointer statement = statementOut.load();
+ _database, queryC, -1, statementOut, Pointer.fromAddress(0));
+ Pointer<Statement> statement = statementOut.load();
statementOut.free();
queryC.free();
@@ -95,7 +98,7 @@
int columnCount = bindings.sqlite3_column_count(statement);
for (int i = 0; i < columnCount; i++) {
String columnName =
- CString.fromUtf8(bindings.sqlite3_column_name(statement, i));
+ bindings.sqlite3_column_name(statement, i).load<Utf8>().toString();
columnIndices[columnName] = i;
}
@@ -103,12 +106,13 @@
}
SQLiteException _loadError([int errorCode]) {
- String errorMessage = CString.fromUtf8(bindings.sqlite3_errmsg(_database));
+ String errorMessage =
+ bindings.sqlite3_errmsg(_database).load<Utf8>().toString();
if (errorCode == null) {
return SQLiteException(errorMessage);
}
String errorCodeExplanation =
- CString.fromUtf8(bindings.sqlite3_errstr(errorCode));
+ bindings.sqlite3_errstr(errorCode).load<Utf8>().toString();
return SQLiteException(
"$errorMessage (Code $errorCode: $errorCodeExplanation)");
}
@@ -122,7 +126,7 @@
class Result extends IterableBase<Row> implements ClosableIterable<Row> {
final Database _database;
final ClosableIterator<Row> _iterator;
- final StatementPointer _statement;
+ final Pointer<Statement> _statement;
final Map<String, int> _columnIndices;
Row _currentRow = null;
@@ -139,7 +143,7 @@
}
class _ResultIterator implements ClosableIterator<Row> {
- final StatementPointer _statement;
+ final Pointer<Statement> _statement;
final Map<String, int> _columnIndices;
Row _currentRow = null;
@@ -177,7 +181,7 @@
}
class Row {
- final StatementPointer _statement;
+ final Pointer<Statement> _statement;
final Map<String, int> _columnIndices;
bool _isCurrentRow = true;
@@ -208,8 +212,10 @@
dynamicType =
_typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
} else {
- dynamicType = _typeFromText(CString.fromUtf8(
- bindings.sqlite3_column_decltype(_statement, columnIndex)));
+ dynamicType = _typeFromText(bindings
+ .sqlite3_column_decltype(_statement, columnIndex)
+ .load<Utf8>()
+ .toString());
}
switch (dynamicType) {
@@ -245,8 +251,10 @@
/// Reads column [columnIndex] and converts to [Type.Text] if not text.
String readColumnByIndexAsText(int columnIndex) {
_checkIsCurrentRow();
- return CString.fromUtf8(
- bindings.sqlite3_column_text(_statement, columnIndex));
+ return bindings
+ .sqlite3_column_text(_statement, columnIndex)
+ .load<Utf8>()
+ .toString();
}
void _checkIsCurrentRow() {
diff --git a/samples/ffi/sqlite/lib/src/ffi/cstring.dart b/samples/ffi/sqlite/lib/src/ffi/utf8.dart
similarity index 61%
rename from samples/ffi/sqlite/lib/src/ffi/cstring.dart
rename to samples/ffi/sqlite/lib/src/ffi/utf8.dart
index da095e4..b7da3c5 100644
--- a/samples/ffi/sqlite/lib/src/ffi/cstring.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/utf8.dart
@@ -8,36 +8,41 @@
import "arena.dart";
/// Represents a String in C memory, managed by an [Arena].
-class CString extends Pointer<Uint8> {
+class Utf8 extends Struct<Utf8> {
+ @Int8()
+ int char;
+
/// Allocates a [CString] in the current [Arena] and populates it with
/// [dartStr].
- factory CString(String dartStr) => CString.inArena(Arena.current(), dartStr);
+ static Pointer<Utf8> fromString(String dartStr) =>
+ Utf8.fromStringArena(Arena.current(), dartStr);
/// Allocates a [CString] in [arena] and populates it with [dartStr].
- factory CString.inArena(Arena arena, String dartStr) =>
- arena.scoped(CString.allocate(dartStr));
+ static Pointer<Utf8> fromStringArena(Arena arena, String dartStr) =>
+ arena.scoped(allocate(dartStr));
/// Allocate a [CString] not managed in and populates it with [dartStr].
///
/// This [CString] is not managed by an [Arena]. Please ensure to [free] the
/// memory manually!
- factory CString.allocate(String dartStr) {
+ static Pointer<Utf8> allocate(String dartStr) {
List<int> units = Utf8Encoder().convert(dartStr);
- Pointer<Uint8> str = allocate(count: units.length + 1);
+ Pointer<Utf8> str = Pointer.allocate(count: units.length + 1);
for (int i = 0; i < units.length; ++i) {
- str.elementAt(i).store(units[i]);
+ str.elementAt(i).load<Utf8>().char = units[i];
}
- str.elementAt(units.length).store(0);
+ str.elementAt(units.length).load<Utf8>().char = 0;
return str.cast();
}
/// Read the string for C memory into Dart.
- static String fromUtf8(CString str) {
- if (str == null) return null;
+ String toString() {
+ final str = addressOf;
+ if (str == nullptr) return null;
int len = 0;
- while (str.elementAt(++len).load<int>() != 0);
+ while (str.elementAt(++len).load<Utf8>().char != 0);
List<int> units = List(len);
- for (int i = 0; i < len; ++i) units[i] = str.elementAt(i).load();
+ for (int i = 0; i < len; ++i) units[i] = str.elementAt(i).load<Utf8>().char;
return Utf8Decoder().convert(units);
}
}
diff --git a/samples/samples.status b/samples/samples.status
index f72f9e5..b5f2b33 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -8,9 +8,6 @@
[ $builder_tag == optimization_counter_threshold ]
sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign # This test is too slow for testing with low optimization counter threshold.
-[ $compiler == precompiler ]
-sample_extension/test/*: Skip # These tests attempt to spawn another script using the precompiled runtime.
-
[ $compiler == dart2js && $runtime == none ]
*: Fail, Pass # TODO(ahe): Triage these tests.
@@ -26,7 +23,7 @@
[ $arch != x64 || $compiler != dartk || $system != linux || $hot_reload || $hot_reload_rollback ]
ffi/sqlite/test/sqlite_test: Skip # FFI not supported or libsqlite3.so not available.
-[ $compiler == app_jitk || $compiler == dartkb || $compiler == dartkp ]
+[ $compiler == app_jitk || $compiler == dartkp ]
sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign
sample_extension/test/sample_extension_test: SkipByDesign
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index a759348..5d2bbb6 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -1051,7 +1051,7 @@
* res.close();
* }
*/
-abstract class HttpRequest implements Stream<List<int>> {
+abstract class HttpRequest implements Stream<Uint8List> {
/**
* The content length of the request body.
*
@@ -1947,7 +1947,7 @@
* });
* });
*/
-abstract class HttpClientResponse implements Stream<List<int>> {
+abstract class HttpClientResponse implements Stream<Uint8List> {
/**
* Returns the status code.
*
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 5c39ad4..c3325a4 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -125,10 +125,10 @@
typedef void _BytesConsumer(List<int> bytes);
-class _HttpIncoming extends Stream<List<int>> {
+class _HttpIncoming extends Stream<Uint8List> {
final int _transferLength;
final Completer _dataCompleter = new Completer();
- Stream<List<int>> _stream;
+ Stream<Uint8List> _stream;
bool fullBodyRead = false;
@@ -154,7 +154,7 @@
_HttpIncoming(this.headers, this._transferLength, this._stream);
- StreamSubscription<List<int>> listen(void onData(List<int> event),
+ StreamSubscription<Uint8List> listen(void onData(Uint8List event),
{Function onError, void onDone(), bool cancelOnError}) {
hasSubscriber = true;
return _stream.handleError((error) {
@@ -173,7 +173,7 @@
}
}
-abstract class _HttpInboundMessage extends Stream<List<int>> {
+abstract class _HttpInboundMessage extends Stream<Uint8List> {
final _HttpIncoming _incoming;
List<Cookie> _cookies;
@@ -225,7 +225,7 @@
}
}
- StreamSubscription<List<int>> listen(void onData(List<int> event),
+ StreamSubscription<Uint8List> listen(void onData(Uint8List event),
{Function onError, void onDone(), bool cancelOnError}) {
return _incoming.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
@@ -382,18 +382,21 @@
});
}
- StreamSubscription<List<int>> listen(void onData(List<int> event),
+ StreamSubscription<Uint8List> listen(void onData(Uint8List event),
{Function onError, void onDone(), bool cancelOnError}) {
if (_incoming.upgraded) {
// If upgraded, the connection is already 'removed' form the client.
// Since listening to upgraded data is 'bogus', simply close and
// return empty stream subscription.
_httpRequest._httpClientConnection.destroy();
- return new Stream<List<int>>.empty().listen(null, onDone: onDone);
+ return new Stream<Uint8List>.empty().listen(null, onDone: onDone);
}
- Stream<List<int>> stream = _incoming;
+ Stream<Uint8List> stream = _incoming;
if (compressionState == HttpClientResponseCompressionState.decompressed) {
- stream = stream.transform(gzip.decoder);
+ stream = stream
+ .cast<List<int>>()
+ .transform(gzip.decoder)
+ .transform(const _ToUint8List());
}
return stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
@@ -534,6 +537,30 @@
}
}
+class _ToUint8List extends Converter<List<int>, Uint8List> {
+ const _ToUint8List();
+
+ Uint8List convert(List<int> input) => Uint8List.fromList(input);
+
+ Sink<List<int>> startChunkedConversion(Sink<Uint8List> sink) {
+ return _Uint8ListConversionSink(sink);
+ }
+}
+
+class _Uint8ListConversionSink implements Sink<List<int>> {
+ const _Uint8ListConversionSink(this._target);
+
+ final Sink<Uint8List> _target;
+
+ void add(List<int> data) {
+ _target.add(Uint8List.fromList(data));
+ }
+
+ void close() {
+ _target.close();
+ }
+}
+
class _StreamSinkImpl<T> implements StreamSink<T> {
final StreamConsumer<T> _target;
final Completer _doneCompleter = new Completer();
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index eb7663b..089006f 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -265,7 +265,7 @@
bool _paused = true;
bool _bodyPaused = false;
StreamController<_HttpIncoming> _controller;
- StreamController<List<int>> _bodyController;
+ StreamController<Uint8List> _bodyController;
factory _HttpParser.requestParser() {
return new _HttpParser._(true);
@@ -762,7 +762,7 @@
// Always present the data as a view. This way we can handle all
// cases like this, and the user will not experience different data
// typed (which could lead to polymorphic user code).
- List<int> data = new Uint8List.view(
+ Uint8List data = new Uint8List.view(
_buffer.buffer, _buffer.offsetInBytes + _index, dataAvailable);
_bodyController.add(data);
if (_remainingContent != -1) {
@@ -993,7 +993,7 @@
assert(_bodyController == null);
assert(!_bodyPaused);
var incoming;
- _bodyController = new StreamController<List<int>>(
+ _bodyController = new StreamController<Uint8List>(
sync: true,
onListen: () {
if (incoming != _incoming) return;
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 1525959..1c62090 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -425,7 +425,7 @@
cast(obj, type, @notNull bool isImplicit) {
if (obj == null) return obj;
var actual = getReifiedType(obj);
- if (_isSubtypeOrLegacySubtype(actual, type) == true) {
+ if (isSubtypeOf(actual, type)) {
return obj;
}
return castError(obj, type, isImplicit);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 3c9852c..3265b7f 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -472,7 +472,7 @@
var actual = JS('', '#[#]', obj, _runtimeType);
// If there's no actual type, it's a JS function.
// Allow them to subtype all Dart function types.
- if (actual == null || _isSubtypeOrLegacySubtype(actual, this) == true) {
+ if (actual == null || isSubtypeOf(actual, this)) {
return obj;
}
}
@@ -753,13 +753,7 @@
})()''');
/// Returns true if [ft1] <: [ft2].
-/// Returns false if [ft1] </: [ft2] in both spec and strong mode
-/// Returns null if [ft1] </: [ft2] in strong mode, but spec mode
-/// may differ
-/// If [isCovariant] is true, then we are checking subtyping in a covariant
-/// position, and hence the direction of the check for function types
-/// corresponds to the direction of the check according to the Dart spec.
-_isFunctionSubtype(ft1, ft2, isCovariant) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2) => JS('', '''(() => {
let ret1 = $ft1.returnType;
let ret2 = $ft2.returnType;
@@ -767,16 +761,12 @@
let args2 = $ft2.args;
if (args1.length > args2.length) {
- // If we're in a covariant position, then Dart's arity rules
- // agree with strong mode, otherwise we can't be sure.
- return ($isCovariant) ? false : null;
+ return false;
}
for (let i = 0; i < args1.length; ++i) {
- if (!$_isSubtype(args2[i], args1[i], !$isCovariant)) {
- // Even if isSubtypeOf returns false, assignability
- // means that we can't be definitive
- return null;
+ if (!$_isSubtype(args2[i], args1[i])) {
+ return false;
}
}
@@ -784,19 +774,19 @@
let optionals2 = $ft2.optionals;
if (args1.length + optionals1.length < args2.length + optionals2.length) {
- return ($isCovariant) ? false : null;
+ return false;
}
let j = 0;
for (let i = args1.length; i < args2.length; ++i, ++j) {
- if (!$_isSubtype(args2[i], optionals1[j], !$isCovariant)) {
- return null;
+ if (!$_isSubtype(args2[i], optionals1[j])) {
+ return false;
}
}
for (let i = 0; i < optionals2.length; ++i, ++j) {
- if (!$_isSubtype(optionals2[i], optionals1[j], !$isCovariant)) {
- return null;
+ if (!$_isSubtype(optionals2[i], optionals1[j])) {
+ return false;
}
}
@@ -809,36 +799,21 @@
let n1 = named1[name];
let n2 = named2[name];
if (n1 === void 0) {
- return ($isCovariant) ? false : null;
+ return false;
}
- if (!$_isSubtype(n2, n1, !$isCovariant)) {
- return null;
+ if (!$_isSubtype(n2, n1)) {
+ return false;
}
}
- // Check return type last, so that arity mismatched functions can be
- // definitively rejected.
-
- // For `void` we will give the same answer as the VM, so don't return null.
- if (ret1 === $void_) return $_isTop(ret2);
-
- if (!$_isSubtype(ret1, ret2, $isCovariant)) return null;
- return true;
+ return $_isSubtype(ret1, ret2);
})()''');
-/// Whether [t1] <: [t2].
+/// Returns true if [t1] <: [t2].
@notNull
bool isSubtypeOf(Object t1, Object t2) {
// TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
// dispatched on the type. Can we optimize the subtype relation too?
- return JS('!', '!!#', _isSubtypeOrLegacySubtype(t1, t2));
-}
-
-/// Returns true if [t1] <: [t2].
-/// Returns false if [t1] </: [t2] and we should not ignore this cast failure.
-/// Returns null if [t1] </: [t2] and we should ignore this cast failure when
-/// the appropriate flags are set.
-bool _isSubtypeOrLegacySubtype(Object t1, Object t2) {
Object map;
if (JS('!', '!#.hasOwnProperty(#)', t1, _subtypeCache)) {
JS('', '#[#] = # = new Map()', t1, _subtypeCache, map);
@@ -848,7 +823,7 @@
bool result = JS('', '#.get(#)', map, t2);
if (JS('!', '# !== void 0', result)) return result;
}
- var result = _isSubtype(t1, t2, true);
+ var result = _isSubtype(t1, t2);
JS('', '#.set(#, #)', map, t2, result);
return result;
}
@@ -871,8 +846,10 @@
bool _isFutureOr(type) =>
identical(getGenericClass(type), getGenericClass(FutureOr));
-bool _isSubtype(t1, t2, isCovariant) => JS('', '''(() => {
- if ($t1 === $t2) return true;
+bool _isSubtype(t1, t2) => JS('', '''(() => {
+ if ($t1 === $t2) {
+ return true;
+ }
// Trivially true.
if (${_isTop(t2)} || ${_isBottom(t1)}) {
@@ -880,9 +857,7 @@
}
// Trivially false.
- if (${_isBottom(t2)}) return null;
- if (${_isTop(t1)}) {
- if ($t1 === $dynamic) return null;
+ if (${_isTop(t1)} || ${_isBottom(t2)}) {
return false;
}
@@ -892,14 +867,13 @@
if (${_isFutureOr(t2)}) {
let t2TypeArg = ${getGenericArgs(t2)}[0];
// FutureOr<A> <: FutureOr<B> iff A <: B
- return $_isSubtype(t1TypeArg, t2TypeArg, $isCovariant);
+ return $_isSubtype(t1TypeArg, t2TypeArg);
}
// given t1 is Future<A> | A, then:
// (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
let t1Future = ${getGenericClass(Future)}(t1TypeArg);
- return $_isSubtype(t1Future, $t2, $isCovariant) &&
- $_isSubtype(t1TypeArg, $t2, $isCovariant);
+ return $_isSubtype(t1Future, $t2) && $_isSubtype(t1TypeArg, $t2);
}
if ($_isFutureOr($t2)) {
@@ -907,11 +881,9 @@
// t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
let t2TypeArg = ${getGenericArgs(t2)}[0];
let t2Future = ${getGenericClass(Future)}(t2TypeArg);
- let s1 = $_isSubtype($t1, t2Future, $isCovariant);
- let s2 = $_isSubtype($t1, t2TypeArg, $isCovariant);
- if (s1 === true || s2 === true) return true;
- if (s1 === null || s2 === null) return null;
- return false;
+ let s1 = $_isSubtype($t1, t2Future);
+ let s2 = $_isSubtype($t1, t2TypeArg);
+ return s1 || s2;
}
// "Traditional" name-based subtype check. Avoid passing
@@ -930,15 +902,19 @@
if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) return true;
// Compare two interface types:
- return ${_isInterfaceSubtype(t1, t2, isCovariant)};
+ return ${_isInterfaceSubtype(t1, t2)};
}
// Function subtyping.
- if (!($t1 instanceof $AbstractFunctionType)) return false;
+ if (!($t1 instanceof $AbstractFunctionType)) {
+ return false;
+ }
// Handle generic functions.
if ($t1 instanceof $GenericFunctionType) {
- if (!($t2 instanceof $GenericFunctionType)) return false;
+ if (!($t2 instanceof $GenericFunctionType)) {
+ return false;
+ }
// Given generic functions g1 and g2, g1 <: g2 iff:
//
@@ -947,7 +923,9 @@
// where TFresh is a list of fresh type variables that both g1 and g2 will
// be instantiated with.
let formalCount = $t1.formalCount;
- if (formalCount !== $t2.formalCount) return false;
+ if (formalCount !== $t2.formalCount) {
+ return false;
+ }
// Using either function's type formals will work as long as they're both
// instantiated with the same ones. The instantiate operation is guaranteed
@@ -968,7 +946,7 @@
let t2Bounds = $t2.instantiateTypeBounds(fresh);
// TODO(jmesserly): we could optimize for the common case of no bounds.
for (let i = 0; i < formalCount; i++) {
- if (!$_isSubtype(t2Bounds[i], t1Bounds[i], !$isCovariant)) {
+ if (!$_isSubtype(t2Bounds[i], t1Bounds[i])) {
return false;
}
}
@@ -980,29 +958,31 @@
}
// Handle non-generic functions.
- return ${_isFunctionSubtype(t1, t2, isCovariant)};
+ return ${_isFunctionSubtype(t1, t2)};
})()''');
-bool _isInterfaceSubtype(t1, t2, isCovariant) => JS('', '''(() => {
- // We support Dart's covariant generics with the caveat that we do not
- // substitute bottom for dynamic in subtyping rules.
- // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
- // - S !<: S<T1, ..., Tn>
- // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn>
-
+bool _isInterfaceSubtype(t1, t2) => JS('', '''(() => {
// If we have lazy JS types, unwrap them. This will effectively
// reduce to a prototype check below.
if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
- if ($t1 === $t2) return true;
- if ($t1 === $Object) return false;
+ if ($t1 === $t2) {
+ return true;
+ }
+ if ($t1 === $Object) {
+ return false;
+ }
// Classes cannot subtype `Function` or vice versa.
- if ($t1 === $Function || $t2 === $Function) return false;
+ if ($t1 === $Function || $t2 === $Function) {
+ return false;
+ }
// If t1 is a JS Object, we may not hit core.Object.
- if ($t1 == null) return $t2 == $Object || $t2 == $dynamic;
+ if ($t1 == null) {
+ return $t2 == $Object || $t2 == $dynamic;
+ }
// Check if t1 and t2 have the same raw type. If so, check covariance on
// type parameters.
@@ -1017,13 +997,14 @@
return true;
} else if (length == 0) {
// t1 is raw, but t2 is not
- if (typeArguments2.every($_isTop)) return true;
- return null;
+ if (typeArguments2.every($_isTop)) {
+ return true;
+ }
+ return false;
}
if (length != typeArguments2.length) $assertFailed();
for (let i = 0; i < length; ++i) {
- let result =
- $_isSubtype(typeArguments1[i], typeArguments2[i], $isCovariant);
+ let result = $_isSubtype(typeArguments1[i], typeArguments2[i]);
if (!result) {
return result;
}
@@ -1031,37 +1012,25 @@
return true;
}
- let indefinite = false;
- function definitive(t1, t2) {
- let result = $_isInterfaceSubtype(t1, t2, $isCovariant);
- if (result == null) {
- indefinite = true;
- return false;
- }
- return result;
+ if ($_isInterfaceSubtype(t1.__proto__, $t2)) {
+ return true;
}
- if (definitive($t1.__proto__, $t2)) return true;
-
// Check mixin.
let m1 = $getMixin($t1);
- if (m1 != null) {
- if (definitive(m1, $t2)) return true;
+ if (m1 != null && $_isInterfaceSubtype(m1, $t2)) {
+ return true;
}
// Check interfaces.
let getInterfaces = $getImplements($t1);
if (getInterfaces) {
for (let i1 of getInterfaces()) {
- if (definitive(i1, $t2)) return true;
+ if ($_isInterfaceSubtype(i1, $t2)) {
+ return true;
+ }
}
}
-
- // We found no definite supertypes, and at least one indefinite supertype
- // so the answer is indefinite.
- if (indefinite) return null;
- // We found no definite supertypes and no indefinite supertypes, so we
- // can return false.
return false;
})()''');
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 87fab54..4b63f9e 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -58,7 +58,6 @@
storedCallback = callback;
// Because of a broken shadow-dom polyfill we have to change the
// children instead a cheap property.
- // See https://github.com/Polymer/ShadowDOM/issues/468
JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', div, div,
span, div, span);
};
diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
index 5377630..0cecf96 100644
--- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -207,6 +207,11 @@
/// Calls are replaced with the [HInterceptor] SSA instruction.
external getInterceptor(object);
+/// Returns the Rti object for the type for JavaScript arrays via JS-interop.
+///
+/// Calls are replaced with a [HLoadType] SSA instruction.
+external Object getJSArrayInteropRti();
+
/// Returns the object corresponding to Namer.staticStateHolder.
external JS_GET_STATIC_STATE();
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index beee35b..654019c 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -59,7 +59,7 @@
unmangleGlobalNameIfPreservedAnyways,
unmangleAllIdentifiersIfPreservedAnyways;
-import 'dart:_rti' as newRti show getRuntimeType;
+import 'dart:_rti' as newRti show createRuntimeType, getRuntimeType;
part 'annotations.dart';
part 'constant_map.dart';
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index b53dcc8..d0bd80f 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -6,10 +6,18 @@
library rti;
import 'dart:_foreign_helper'
- show JS, JS_EMBEDDED_GLOBAL, RAW_DART_FUNCTION_REF;
+ show
+ getInterceptor,
+ getJSArrayInteropRti,
+ JS,
+ JS_BUILTIN,
+ JS_EMBEDDED_GLOBAL,
+ JS_GET_NAME,
+ RAW_DART_FUNCTION_REF;
import 'dart:_interceptors' show JSArray, JSUnmodifiableArray;
-import 'dart:_js_embedded_names' show RtiUniverseFieldNames, RTI_UNIVERSE;
+import 'dart:_js_embedded_names'
+ show JsBuiltin, JsGetName, RtiUniverseFieldNames, RTI_UNIVERSE;
import 'dart:_recipe_syntax';
@@ -56,15 +64,15 @@
/// Method called from generated code to evaluate a type environment recipe in
/// `this` type environment.
- Rti _eval(String recipe) {
+ Rti _eval(recipe) {
// TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here.
- return _rtiEval(this, recipe);
+ return _rtiEval(this, _Utils.asString(recipe));
}
/// Method called from generated code to extend `this` type environment (an
/// interface or binding Rti) with function type arguments (a singleton
/// argument or tuple of arguments).
- Rti _bind(Rti typeOrTuple) => _rtiBind(this, typeOrTuple);
+ Rti _bind(typeOrTuple) => _rtiBind(this, _castToRti(typeOrTuple));
/// Method called from generated code to extend `this` type (as a singleton
/// type environment) with function type arguments (a singleton argument or
@@ -80,7 +88,12 @@
dynamic _precomputed4;
// The Type object corresponding to this Rti.
- Type _typeCache;
+ Object _cachedRuntimeType;
+ static _Type _getCachedRuntimeType(Rti rti) =>
+ JS('_Type|Null', '#', rti._cachedRuntimeType);
+ static void _setCachedRuntimeType(Rti rti, _Type type) {
+ rti._cachedRuntimeType = type;
+ }
/// The kind of Rti `this` is, one of the kindXXX constants below.
///
@@ -88,9 +101,9 @@
///
/// The zero initializer ensures dart2js type analysis considers [_kind] is
/// non-nullable.
- int _kind = 0;
+ Object /*int*/ _kind = 0;
- static int _getKind(Rti rti) => rti._kind;
+ static int _getKind(Rti rti) => _Utils.asInt(rti._kind);
static void _setKind(Rti rti, int kind) {
rti._kind = kind;
}
@@ -143,7 +156,7 @@
return _Utils.asString(_getPrimary(rti));
}
- static JSArray _getInterfaceTypeArguments(rti) {
+ static JSArray _getInterfaceTypeArguments(Rti rti) {
// The array is a plain JavaScript Array, otherwise we would need the type
// `JSArray<Rti>` to exist before we could create the type `JSArray<Rti>`.
assert(_getKind(rti) == kindInterface);
@@ -155,7 +168,7 @@
return _castToRti(_getPrimary(rti));
}
- static JSArray _getBindingArguments(rti) {
+ static JSArray _getBindingArguments(Rti rti) {
assert(_getKind(rti) == kindBinding);
return JS('JSUnmodifiableArray', '#', _getRest(rti));
}
@@ -192,16 +205,16 @@
/// (2)using `env._eval("@<0>")._bind(args)` in place of `env._bind1(args)`).
Object _bindCache;
- static Object _getBindCache(Rti rti) => rti._evalCache;
+ static Object _getBindCache(Rti rti) => rti._bindCache;
static void _setBindCache(Rti rti, value) {
- rti._evalCache = value;
+ rti._bindCache = value;
}
static Rti allocate() {
return new Rti();
}
- String _canonicalRecipe;
+ Object _canonicalRecipe;
static String _getCanonicalRecipe(Rti rti) {
var s = rti._canonicalRecipe;
@@ -231,11 +244,84 @@
/// Evaluate a ground-term type.
/// Called from generated code.
Rti findType(String recipe) {
- _Universe.eval(_theUniverse(), recipe);
+ return _Universe.eval(_theUniverse(), recipe);
+}
+
+/// Returns the Rti type of [object].
+/// Called from generated code.
+Rti instanceType(object) {
+ // TODO(sra): Add specializations of this method. One possible way is to
+ // arrange that the interceptor has a _getType method that is injected into
+ // DartObject, Interceptor and JSArray. Then this method can be replaced-by
+ // `getInterceptor(o)._getType(o)`, allowing interceptor optimizations to
+ // select the specialization.
+
+ if (_Utils.instanceOf(
+ object,
+ JS_BUILTIN(
+ 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
+ var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+ if (rti != null) return _castToRti(rti);
+ return _instanceTypeFromConstructor(JS('', '#.constructor', object));
+ }
+
+ if (_Utils.isArray(object)) {
+ var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+ // TODO(sra): Do we need to protect against an Array passed between two Dart
+ // programs loaded into the same JavaScript isolate (e.g. via JS-interop).
+ // FWIW, the legacy rti has this problem too. Perhaps JSArrays should use a
+ // program-local `symbol` for the type field.
+ if (rti != null) return _castToRti(rti);
+ return _castToRti(getJSArrayInteropRti());
+ }
+
+ var interceptor = getInterceptor(object);
+ return _instanceTypeFromConstructor(JS('', '#.constructor', interceptor));
+}
+
+Rti _instanceTypeFromConstructor(constructor) {
+ // TODO(sra): Cache Rti on constructor.
+ return findType(JS('String', '#.name', constructor));
}
Type getRuntimeType(object) {
- throw UnimplementedError('getRuntimeType');
+ Rti rti = instanceType(object);
+ return _createRuntimeType(rti);
+}
+
+/// Called from generated code.
+Type _createRuntimeType(Rti rti) {
+ _Type type = Rti._getCachedRuntimeType(rti);
+ if (type != null) return type;
+ // TODO(https://github.com/dart-lang/language/issues/428) For NNBD transition,
+ // canonicalization may be needed. It might be possible to generate a
+ // star-free recipe from the canonical recipe and evaluate that.
+ type = _Type(rti);
+ Rti._setCachedRuntimeType(rti, type);
+ return type;
+}
+
+/// Called from generated code in the constant pool.
+Type typeLiteral(String recipe) {
+ return _createRuntimeType(findType(recipe));
+}
+
+/// Implementation of [Type] based on Rti.
+class _Type implements Type {
+ final Rti _rti;
+ int _hashCode;
+
+ _Type(this._rti);
+
+ int get hashCode => _hashCode ??= Rti._getCanonicalRecipe(_rti).hashCode;
+
+ @pragma('dart2js:noInline')
+ bool operator ==(other) {
+ return (other is _Type) && identical(_rti, other._rti);
+ }
+
+ @override
+ String toString() => _rtiToString(_rti, null);
}
/// Called from generated code.
@@ -243,27 +329,61 @@
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- throw UnimplementedError(
- '${Error.safeToString(object)} is ${_rtiToString(testRti, null)}');
+ Rti objectRti = instanceType(object);
+ return isSubtype(_theUniverse(), objectRti, testRti);
}
/// Called from generated code.
_generalAsCheckImplementation(object) {
+ if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- throw UnimplementedError(
- '${Error.safeToString(object)} as ${_rtiToString(testRti, null)}');
+ Rti objectRti = instanceType(object);
+ if (isSubtype(_theUniverse(), objectRti, testRti)) return object;
+ var message = "${Error.safeToString(object)}:"
+ " type '${_rtiToString(objectRti, null)}'"
+ " is not a subtype of type '${_rtiToString(testRti, null)}'";
+ throw new _CastError.fromMessage('CastError: $message');
}
/// Called from generated code.
_generalTypeCheckImplementation(object) {
+ if (object == null) return object;
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
- throw UnimplementedError(
- '${Error.safeToString(object)} as ${_rtiToString(testRti, null)}'
- ' (TypeError)');
+ Rti objectRti = instanceType(object);
+ if (isSubtype(_theUniverse(), objectRti, testRti)) return object;
+ var message = "${Error.safeToString(object)}:"
+ " type '${_rtiToString(objectRti, null)}'"
+ " is not a subtype of type '${_rtiToString(testRti, null)}'";
+ throw new _TypeError.fromMessage('TypeError: $message');
+}
+
+/// Called from generated code.
+checkTypeBound(Rti type, Rti bound, variable) {
+ if (isSubtype(_theUniverse(), type, bound)) return type;
+ var message = "Type '${_rtiToString(type, null)}'"
+ " is not a subtype of type '${_rtiToString(bound, null)}'"
+ " of '${_Utils.asString(variable)}'";
+ throw _TypeError.fromMessage('TypeError: $message');
+}
+
+class _CastError extends Error implements CastError {
+ final String message;
+ _CastError.fromMessage(this.message);
+
+ @override
+ String toString() => message;
+}
+
+class _TypeError extends Error implements TypeError {
+ final String message;
+ _TypeError.fromMessage(this.message);
+
+ @override
+ String toString() => message;
}
String _rtiToString(Rti rti, List<String> genericContext) {
@@ -359,12 +479,14 @@
static evalCache(universe) =>
JS('', '#.#', universe, RtiUniverseFieldNames.evalCache);
- static findRule(universe, String targetType) =>
- JS('', '#.#.#', universe, RtiUniverseFieldNames.typeRules, targetType);
+ static Object typeRules(universe) =>
+ JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
- static void addRule(universe, String targetType, rule) {
- JS('', '#.#.# = #', universe, RtiUniverseFieldNames.typeRules, targetType,
- rule);
+ static Object findRule(universe, String targetType) =>
+ JS('', '#.#', typeRules(universe), targetType);
+
+ static void addRules(universe, rules) {
+ JS('', 'Object.assign(#, #)', typeRules(universe), rules);
}
static Object sharedEmptyArray(universe) =>
@@ -407,8 +529,7 @@
if (Rti._getKind(argumentsRti) == Rti.kindBinding) {
argumentsArray = Rti._getBindingArguments(argumentsRti);
} else {
- argumentsArray = JS('', '[]');
- _Utils.arrayPush(argumentsArray, argumentsRti);
+ argumentsArray = JS('', '[#]', argumentsRti);
}
var rti = _lookupBindingRti(universe, environment, argumentsArray);
_cacheSet(cache, argumentsRecipe, rti);
@@ -460,10 +581,15 @@
// for the proposed type.
// * `createXXX` to create the type if it does not exist.
- static String _canonicalRecipeOfDynamic() => '@';
- static String _canonicalRecipeOfVoid() => '~';
- static String _canonicalRecipeOfNever() => '0&';
- static String _canonicalRecipeOfAny() => '1&';
+ static String _canonicalRecipeOfDynamic() => Recipe.pushDynamicString;
+ static String _canonicalRecipeOfVoid() => Recipe.pushVoidString;
+ static String _canonicalRecipeOfNever() =>
+ Recipe.pushNeverExtensionString + Recipe.extensionOpString;
+ static String _canonicalRecipeOfAny() =>
+ Recipe.pushAnyExtensionString + Recipe.extensionOpString;
+
+ static String _canonicalRecipeOfFutureOr(Rti baseType) =>
+ Rti._getCanonicalRecipe(baseType) + Recipe.wrapFutureOrString;
static Rti _lookupDynamicRti(universe) {
return _lookupTerminalRti(
@@ -497,6 +623,23 @@
return _finishRti(universe, rti);
}
+ static Rti _lookupFutureOrRti(universe, Rti baseType) {
+ String canonicalRecipe = _canonicalRecipeOfFutureOr(baseType);
+ var cache = evalCache(universe);
+ var probe = _cacheGet(cache, canonicalRecipe);
+ if (probe != null) return _castToRti(probe);
+ return _createFutureOrRti(universe, baseType, canonicalRecipe);
+ }
+
+ static Rti _createFutureOrRti(
+ universe, Rti baseType, String canonicalRecipe) {
+ var rti = Rti.allocate();
+ Rti._setKind(rti, Rti.kindFutureOr);
+ Rti._setPrimary(rti, baseType);
+ Rti._setCanonicalRecipe(rti, canonicalRecipe);
+ return _finishRti(universe, rti);
+ }
+
static String _canonicalRecipeJoin(Object arguments) {
String s = '', sep = '';
int length = _Utils.arrayLength(arguments);
@@ -504,7 +647,7 @@
Rti argument = _castToRti(_Utils.arrayAt(arguments, i));
String subrecipe = Rti._getCanonicalRecipe(argument);
s += sep + subrecipe;
- sep = ',';
+ sep = Recipe.separatorString;
}
return s;
}
@@ -514,7 +657,9 @@
String s = _Utils.asString(name);
int length = _Utils.arrayLength(arguments);
if (length != 0) {
- s += '<' + _canonicalRecipeJoin(arguments) + '>';
+ s += Recipe.startTypeArgumentsString +
+ _canonicalRecipeJoin(arguments) +
+ Recipe.endTypeArgumentsString;
}
return s;
}
@@ -540,14 +685,17 @@
static String _canonicalRecipeOfBinding(Rti base, Object arguments) {
String s = Rti._getCanonicalRecipe(base);
- s += ';'; // TODO(sra): Omit when base encoding is Rti without ToType.
- s += '<' + _canonicalRecipeJoin(arguments) + '>';
+ s += Recipe
+ .toTypeString; // TODO(sra): Omit when base encoding is Rti without ToType.
+ s += Recipe.startTypeArgumentsString +
+ _canonicalRecipeJoin(arguments) +
+ Recipe.endTypeArgumentsString;
return s;
}
/// [arguments] becomes owned by the created Rti.
static Rti _lookupBindingRti(Object universe, Rti base, Object arguments) {
- var newBase = base;
+ Rti newBase = base;
var newArguments = arguments;
if (Rti._getKind(base) == Rti.kindBinding) {
newBase = Rti._getBindingBase(base);
@@ -708,11 +856,11 @@
}
// Field accessors for the parser.
- static Object universe(Object parser) => JS('String', '#.u', parser);
+ static Object universe(Object parser) => JS('', '#.u', parser);
static Rti environment(Object parser) => JS('Rti', '#.e', parser);
static String recipe(Object parser) => JS('String', '#.r', parser);
static Object stack(Object parser) => JS('', '#.s', parser);
- static Object position(Object parser) => JS('int', '#.p', parser);
+ static int position(Object parser) => JS('int', '#.p', parser);
static void setPosition(Object parser, int p) {
JS('', '#.p = #', parser, p);
}
@@ -739,7 +887,7 @@
} else {
i++;
switch (ch) {
- case Recipe.noOp:
+ case Recipe.separator:
break;
case Recipe.toType:
@@ -768,6 +916,14 @@
handleExtendedOperations(parser, stack);
break;
+ case Recipe.wrapFutureOr:
+ var u = universe(parser);
+ push(
+ stack,
+ _Universe._lookupFutureOrRti(
+ u, toType(u, environment(parser), pop(stack))));
+ break;
+
default:
JS('', 'throw "Bad character " + #', ch);
}
@@ -909,37 +1065,33 @@
throw UnimplementedError("TypeRule is static methods only.");
}
- // TODO(fishythefish): Create whole rule at once rather than adding individual
- // supertypes/type variables.
-
- @pragma('dart2js:noInline')
- static Object create() {
- return JS('=Object', '{}');
- }
-
- static void addTypeVariable(rule, String typeVariable, String binding) {
- JS('', '#.# = #', rule, typeVariable, binding);
- }
-
static String lookupTypeVariable(rule, String typeVariable) =>
- JS('String|Null', '#.#', rule, typeVariable);
-
- static void addSupertype(rule, String supertype, Object supertypeArgs) {
- JS('', '#.# = #', rule, supertype, supertypeArgs);
- }
+ JS('', '#.#', rule, typeVariable);
static JSArray lookupSupertype(rule, String supertype) =>
- JS('JSArray|Null', '#.#', rule, supertype);
+ JS('', '#.#', rule, supertype);
}
// -------- Subtype tests ------------------------------------------------------
// Future entry point from compiled code.
bool isSubtype(universe, Rti s, Rti t) {
+ // TODO(sra): When more tests are working, remove this rediculous hack.
+ // Temporary 'metering' of isSubtype calls to force tests that endlessly loop
+ // to fail.
+ int next = JS('int', '(#||0) + 1', _ticks);
+ _ticks = next;
+ if (next > 10 * 1000 * 1000) {
+ throw StateError('Too many isSubtype calls'
+ ' ${_rtiToString(s, null)} <: ${_rtiToString(t, null)}');
+ }
+
return _isSubtype(universe, s, null, t, null);
}
-bool _isSubtype(universe, Rti s, var sEnv, Rti t, var tEnv) {
+int _ticks = 0;
+
+bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
// TODO(fishythefish): Update for NNBD. See
// https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules
@@ -969,14 +1121,13 @@
if (isNullType(s)) return true;
- if (isFunctionType(t)) {
+ if (isFunctionKind(t)) {
// TODO(fishythefish): Check if s is a function subtype of t.
- throw UnimplementedError("isFunctionType(t)");
+ throw UnimplementedError("isFunctionKind(t)");
}
- if (isFunctionType(s)) {
- // TODO(fishythefish): Check if t is Function.
- throw UnimplementedError("isFunctionType(s)");
+ if (isFunctionKind(s)) {
+ return isFunctionType(t);
}
if (isFutureOrType(t)) {
@@ -990,28 +1141,50 @@
// `true` because [s] <: T.
return true;
} else {
- // TODO(fishythefish): Check [s] <: Future<T>.
+ // Check [s] <: Future<T>.
+ String futureClass = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+ var argumentsArray = JS('', '[#]', tTypeArgument);
+ return _isSubtypeOfInterface(
+ universe, s, sEnv, futureClass, argumentsArray, tEnv);
}
}
- assert(Rti._getKind(s) == Rti.kindInterface);
assert(Rti._getKind(t) == Rti.kindInterface);
- String sName = Rti._getInterfaceName(s);
String tName = Rti._getInterfaceName(t);
- // TODO(fishythefish): Handle identical names.
+ var tArgs = Rti._getInterfaceTypeArguments(t);
+ return _isSubtypeOfInterface(universe, s, sEnv, tName, tArgs, tEnv);
+}
+
+bool _isSubtypeOfInterface(
+ universe, Rti s, sEnv, String tName, Object tArgs, tEnv) {
+ assert(Rti._getKind(s) == Rti.kindInterface);
+ String sName = Rti._getInterfaceName(s);
+
+ if (sName == tName) {
+ var sArgs = Rti._getInterfaceTypeArguments(s);
+ int length = _Utils.arrayLength(sArgs);
+ assert(length == _Utils.arrayLength(tArgs));
+ for (int i = 0; i < length; i++) {
+ Rti sArg = _castToRti(_Utils.arrayAt(sArgs, i));
+ Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+ if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) return false;
+ }
+ return true;
+ }
+
+ // TODO(fishythefish): Should we recursively attempt to find supertypes?
var rule = _Universe.findRule(universe, sName);
if (rule == null) return false;
var supertypeArgs = TypeRule.lookupSupertype(rule, tName);
if (supertypeArgs == null) return false;
- var tArgs = Rti._getInterfaceTypeArguments(t);
int length = _Utils.arrayLength(supertypeArgs);
assert(length == _Utils.arrayLength(tArgs));
for (int i = 0; i < length; i++) {
String recipe = _Utils.arrayAt(supertypeArgs, i);
Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe);
Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
- if (!isSubtype(universe, supertypeArg, tArg)) return false;
+ if (!_isSubtype(universe, supertypeArg, sEnv, tArg, tEnv)) return false;
}
return true;
@@ -1024,19 +1197,23 @@
bool isVoidType(Rti t) => Rti._getKind(t) == Rti.kindVoid;
bool isJsInteropType(Rti t) => Rti._getKind(t) == Rti.kindAny;
bool isFutureOrType(Rti t) => Rti._getKind(t) == Rti.kindFutureOr;
-bool isFunctionType(Rti t) => Rti._getKind(t) == Rti.kindFunction;
+bool isFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindFunction;
bool isGenericFunctionTypeParameter(Rti t) =>
Rti._getKind(t) == Rti.kindGenericFunctionParameter;
-bool isObjectType(Rti t) {
- // TODO(fishythefish): Look up Object in universe and compare.
- return false;
-}
+bool isObjectType(Rti t) =>
+ Rti._getKind(t) == Rti.kindInterface &&
+ Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
-bool isNullType(Rti t) {
- // TODO(fishythefish): Look up Null in universe and compare.
- return false;
-}
+// TODO(fishythefish): Which representation should we use for NNBD?
+// Do we also need to check for `Never?`, etc.?
+bool isNullType(Rti t) =>
+ Rti._getKind(t) == Rti.kindInterface &&
+ Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+bool isFunctionType(Rti t) =>
+ Rti._getKind(t) == Rti.kindInterface &&
+ Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME);
/// Unchecked cast to Rti.
Rti _castToRti(s) => JS('Rti', '#', s);
@@ -1049,8 +1226,13 @@
static bool isString(Object o) => JS('bool', 'typeof # == "string"', o);
static bool isNum(Object o) => JS('bool', 'typeof # == "number"', o);
+ static bool instanceOf(Object o, Object constructor) =>
+ JS('bool', '# instanceof #', o, constructor);
+
static bool isIdentical(s, t) => JS('bool', '# === #', s, t);
+ static bool isArray(Object o) => JS('bool', 'Array.isArray(#)', o);
+
static int arrayLength(Object array) => JS('int', '#.length', array);
static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i);
@@ -1080,6 +1262,10 @@
}
// -------- Entry points for testing -------------------------------------------
+String testingCanonicalRecipe(rti) {
+ return Rti._getCanonicalRecipe(rti);
+}
+
String testingRtiToString(rti) {
return _rtiToString(_castToRti(rti), null);
}
@@ -1092,20 +1278,8 @@
return _Universe.create();
}
-Object testingCreateRule() {
- return TypeRule.create();
-}
-
-void testingAddTypeVariable(rule, String typeVariable, String binding) {
- TypeRule.addTypeVariable(rule, typeVariable, binding);
-}
-
-void testingAddSupertype(rule, String supertype, Object supertypeArgs) {
- TypeRule.addSupertype(rule, supertype, supertypeArgs);
-}
-
-void testingAddRule(universe, String targetType, rule) {
- _Universe.addRule(universe, targetType, rule);
+void testingAddRules(universe, rules) {
+ _Universe.addRules(universe, rules);
}
bool testingIsSubtype(universe, rti1, rti2) {
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index 78d0975..7666379 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -12,18 +12,54 @@
// Operators.
- static const int noOp = _comma;
+ static const int separator = _comma;
+ static const String separatorString = _commaString;
static const int toType = _semicolon;
+ static const String toTypeString = _semicolonString;
static const int pushDynamic = _at;
+ static const String pushDynamicString = _atString;
static const int pushVoid = _tilde;
- static const int wrapFutureOr = _formfeed;
+ static const String pushVoidString = _tildeString;
+
+ static const int wrapStar = _asterisk;
+ static const String wrapStarString = _asteriskString;
+ static const int wrapQuestion = _question;
+ static const String wrapQuestionString = _questionString;
+ static const int wrapFutureOr = _slash;
+ static const String wrapFutureOrString = _slashString;
static const int startTypeArguments = _lessThan;
+ static const String startTypeArgumentsString = _lessThanString;
static const int endTypeArguments = _greaterThan;
+ static const String endTypeArgumentsString = _greaterThanString;
+
+ static const int startFunctionArguments = _leftParen;
+ static const String startFunctionArgumentsString = _leftParenString;
+ static const int endFunctionArguments = _rightParen;
+ static const String endFunctionArgumentsString = _rightParenString;
+ static const int startOptionalGroup = _leftBracket;
+ static const String startOptionalGroupString = _leftBracketString;
+ static const int endOptionalGroup = _rightBracket;
+ static const String endOptionalGroupString = _rightBracketString;
+ static const int startNamedGroup = _leftBrace;
+ static const String startNamedGroupString = _leftBraceString;
+ static const int endNamedGroup = _rightBrace;
+ static const String endNamedGroupString = _rightBraceString;
+ static const int nameSeparator = _colon;
+ static const String nameSeparatorString = _colonString;
+
+ static const int genericFunctionTypeParameterIndex = _circumflex;
+ static const String genericFunctionTypeParameterIndexString =
+ _circumflexString;
static const int extensionOp = _ampersand;
+ static const String extensionOpString = _ampersandString;
+ static const int pushNeverExtension = 0;
+ static const String pushNeverExtensionString = '$pushNeverExtension';
+ static const int pushAnyExtension = 1;
+ static const String pushAnyExtensionString = '$pushAnyExtension';
// Number and name components.
@@ -39,29 +75,156 @@
// Private names.
- static const int _formfeed = 0x0C; // '\f' in string literal.
+ static const int _formfeed = 0x0C;
+ static const String _formfeedString = '\f';
+ static const int _space = 0x20;
+ static const String _spaceString = ' ';
+ static const int _exclamation = 0x21;
+ static const String _exclamationString = '!';
+ static const int _hash = 0x23;
+ static const String _hashString = '#';
static const int _dollar = 0x24;
+ static const String _dollarString = r'$';
+ static const int _percent = 0x25;
+ static const String _percentString = '%';
static const int _ampersand = 0x26;
+ static const String _ampersandString = '&';
+ static const int _apostrophe = 0x27;
+ static const String _apostropheString = "'";
+ static const int _leftParen = 0x28;
+ static const String _leftParenString = '(';
+ static const int _rightParen = 0x29;
+ static const String _rightParenString = ')';
+ static const int _asterisk = 0x2A;
+ static const String _asteriskString = '*';
static const int _plus = 0x2B;
+ static const String _plusString = '+';
static const int _comma = 0x2C;
+ static const String _commaString = ',';
+ static const int _minus = 0x2D;
+ static const String _minusString = '-';
static const int _period = 0x2E;
+ static const String _periodString = '.';
+ static const int _slash = 0x2F;
+ static const String _slashString = '/';
+
static const int _digit0 = 0x30;
static const int _digit9 = 0x39;
+
+ static const int _colon = 0x3A;
+ static const String _colonString = ':';
static const int _semicolon = 0x3B;
+ static const String _semicolonString = ';';
static const int _lessThan = 0x3C;
+ static const String _lessThanString = '<';
+ static const int _equals = 0x3D;
+ static const String _equalsString = '=';
static const int _greaterThan = 0x3E;
- static const int _question = 0x3f;
+ static const String _greaterThanString = '>';
+ static const int _question = 0x3F;
+ static const String _questionString = '?';
static const int _at = 0x40;
+ static const String _atString = '@';
- static const int _underscore = 0x5F;
- static const int _lowercaseA = 0x61;
- static const int _tilde = 0x7E;
+ static const int _uppercaseA = 0x41;
+ static const int _uppercaseZ = 0x5A;
- static const int _leftParen = 0x28;
- static const int _rightParen = 0x29;
static const int _leftBracket = 0x5B;
+ static const String _leftBracketString = '[';
+ static const int _backslash = 0x5C;
+ static const String _backslashString = r'\';
static const int _rightBracket = 0x5D;
+ static const String _rightBracketString = ']';
+ static const int _circumflex = 0x5E;
+ static const String _circumflexString = '^';
+ static const int _underscore = 0x5F;
+ static const String _underscoreString = '_';
+ static const int _backtick = 0x60;
+ static const String _backtickString = '`';
+
+ static const int _lowercaseA = 0x61;
+ static const int _lowercaseZ = 0x7A;
+
static const int _leftBrace = 0x7B;
+ static const String _leftBraceString = '{';
+ static const int _vertical = 0x7C;
+ static const String _verticalString = '|';
static const int _rightBrace = 0x7D;
+ static const String _rightBraceString = '}';
+ static const int _tilde = 0x7E;
+ static const String _tildeString = '~';
+
+ static void testEquivalence() {
+ void test(String label, int charCode, String str) {
+ if (String.fromCharCode(charCode) != str) {
+ throw StateError("$label: String.fromCharCode($charCode) != $str");
+ }
+ }
+
+ void testExtension(String label, int op, String str) {
+ if ('$op' != str) {
+ throw StateError("$label: $op.toString() != $str");
+ }
+ }
+
+ test("separator", separator, separatorString);
+ test("toType", toType, toTypeString);
+ test("pushDynamic", pushDynamic, pushDynamicString);
+ test("pushVoid", pushVoid, pushVoidString);
+ test("wrapStar", wrapStar, wrapStarString);
+ test("wrapQuestion", wrapQuestion, wrapQuestionString);
+ test("wrapFutureOr", wrapFutureOr, wrapFutureOrString);
+ test("startTypeArguments", startTypeArguments, startTypeArgumentsString);
+ test("endTypeArguments", endTypeArguments, endTypeArgumentsString);
+ test("startFunctionArguments", startFunctionArguments,
+ startFunctionArgumentsString);
+ test("endFunctionArguments", endFunctionArguments,
+ endFunctionArgumentsString);
+ test("startOptionalGroup", startOptionalGroup, startOptionalGroupString);
+ test("endOptionalGroup", endOptionalGroup, endOptionalGroupString);
+ test("startNamedGroup", startNamedGroup, startNamedGroupString);
+ test("endNamedGroup", endNamedGroup, endNamedGroupString);
+ test("nameSeparator", nameSeparator, nameSeparatorString);
+ test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
+ genericFunctionTypeParameterIndexString);
+ test("extensionOp", extensionOp, extensionOpString);
+ testExtension(
+ "pushNeverExtension", pushNeverExtension, pushNeverExtensionString);
+ testExtension("pushAnyExtension", pushAnyExtension, pushAnyExtensionString);
+
+ test("_formfeed", _formfeed, _formfeedString);
+ test("_space", _space, _spaceString);
+ test("_exclamation", _exclamation, _exclamationString);
+ test("_hash", _hash, _hashString);
+ test("_dollar", _dollar, _dollarString);
+ test("_percent", _percent, _percentString);
+ test("_ampersand", _ampersand, _ampersandString);
+ test("_apostrophe", _apostrophe, _apostropheString);
+ test("_leftParen", _leftParen, _leftParenString);
+ test("_rightParen", _rightParen, _rightParenString);
+ test("_asterisk", _asterisk, _asteriskString);
+ test("_plus", _plus, _plusString);
+ test("_comma", _comma, _commaString);
+ test("_minus", _minus, _minusString);
+ test("_period", _period, _periodString);
+ test("_slash", _slash, _slashString);
+ test("_colon", _colon, _colonString);
+ test("_semicolon", _semicolon, _semicolonString);
+ test("_lessThan", _lessThan, _lessThanString);
+ test("_equals", _equals, _equalsString);
+ test("_greaterThan", _greaterThan, _greaterThanString);
+ test("_question", _question, _questionString);
+ test("_at", _at, _atString);
+ test("_leftBracket", _leftBracket, _leftBracketString);
+ test("_backslash", _backslash, _backslashString);
+ test("_rightBracket", _rightBracket, _rightBracketString);
+ test("_circumflex", _circumflex, _circumflexString);
+ test("_underscore", _underscore, _underscoreString);
+ test("_backtick", _backtick, _backtickString);
+ test("_leftBrace", _leftBrace, _leftBraceString);
+ test("_vertical", _vertical, _verticalString);
+ test("_rightBrace", _rightBrace, _rightBraceString);
+ test("_tilde", _tilde, _tildeString);
+ }
}
diff --git a/sdk/lib/convert/encoding.dart b/sdk/lib/convert/encoding.dart
index 7441e0a..7ce8ec3 100644
--- a/sdk/lib/convert/encoding.dart
+++ b/sdk/lib/convert/encoding.dart
@@ -19,8 +19,8 @@
Converter<List<int>, String> get decoder;
Future<String> decodeStream(Stream<List<int>> byteStream) {
- return byteStream
- .transform<String>(decoder)
+ return decoder
+ .bind(byteStream)
.fold(StringBuffer(),
(StringBuffer buffer, String string) => buffer..write(string))
.then((StringBuffer buffer) => buffer.toString());
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index fff3d7a..a0f67ac 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -464,8 +464,8 @@
* This increases the length of the list by one and shifts all objects
* at or after the index towards the end of the list.
*
- * An error occurs if the [index] is less than 0 or greater than length.
- * An [UnsupportedError] occurs if the list is fixed-length.
+ * The list must be growable.
+ * The [index] value must be non-negative and no greater than [length].
*/
void insert(int index, E element);
@@ -475,8 +475,8 @@
* This increases the length of the list by the length of [iterable] and
* shifts all later objects towards the end of the list.
*
- * An error occurs if the [index] is less than 0 or greater than length.
- * An [UnsupportedError] occurs if the list is fixed-length.
+ * The list must be growable.
+ * The [index] value must be non-negative and no greater than [length].
*/
void insertAll(int index, Iterable<E> iterable);
@@ -537,6 +537,8 @@
/**
* Pops and returns the last object in this list.
*
+ * The list must not be empty.
+ *
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
E removeLast();
@@ -674,6 +676,14 @@
* A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
* `len` is this list's `length`. The range starts at `start` and has length
* `end - start`. An empty range (with `end == start`) is valid.
+ *
+ * Example:
+ * ```dart
+ * List<int> list = new List(3);
+ * list.fillRange(0, 2, 1);
+ * print(list); // [1, 1, null]
+ * ```
+ *
*/
void fillRange(int start, int end, [E fillValue]);
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 748933d..b3046cc 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -12,7 +12,7 @@
*
* Dart regular expressions have the same syntax and semantics as
* JavaScript regular expressions. See
- * <http://ecma-international.org/ecma-262/5.1/#sec-15.10>
+ * <https://ecma-international.org/ecma-262/9.0/#sec-regexp-regular-expression-objects>
* for the specification of JavaScript regular expressions.
*
* [firstMatch] is the main implementation method that applies a regular
diff --git a/sdk/lib/ffi/annotations.dart b/sdk/lib/ffi/annotations.dart
index 24401e6..d246b56 100644
--- a/sdk/lib/ffi/annotations.dart
+++ b/sdk/lib/ffi/annotations.dart
@@ -4,19 +4,6 @@
part of dart.ffi;
-class Struct {
- const Struct();
-}
-
-/// This Dart class represents a C struct.
-///
-/// Fields in this struct, annotated with a subtype of [NativeType], are
-/// automatically transformed into wrappers to access the fields of the struct
-/// in C memory.
-///
-/// Fields without a [NativeType] annotation are not supported.
-const struct = const Struct();
-
class DartRepresentationOf {
/// Represents the Dart type corresponding to a [NativeType].
///
@@ -32,9 +19,9 @@
/// [Double] -> [double]
/// [Float] -> [double]
/// [Pointer]<T> -> [Pointer]<T>
- /// T extends [Pointer] -> T
/// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
/// where DartRepresentationOf(Tn) -> Sn
+ /// T extends Struct<T> -> T
const DartRepresentationOf(String nativeType);
}
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index 98aa64a..46d660e 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -20,13 +20,15 @@
external Pointer<T> lookup<T extends NativeType>(String symbolName);
/// Helper that combines lookup and cast to a Dart function.
- F lookupFunction<T extends Function, F extends Function>(String symbolName) {
- return lookup<NativeFunction<T>>(symbolName)?.asFunction<F>();
- }
+ external F lookupFunction<T extends Function, F extends Function>(
+ String symbolName);
/// Dynamic libraries are equal if they load the same library.
external bool operator ==(other);
/// The hash code for a DynamicLibrary only depends on the loaded library
external int get hashCode;
+
+ /// The handle to the dynamic library.
+ external Pointer<Void> get handle;
}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 5176ebb..4b9a50f 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -9,81 +9,83 @@
part "native_type.dart";
part "annotations.dart";
part "dynamic_library.dart";
+part "struct.dart";
-/// Allocate [count] elements of type [T] on the C heap with malloc() and return
-/// a pointer to the newly allocated memory.
+/// Number of bytes used by native type T.
///
-/// Note that the memory are uninitialized.
-///
-/// TODO(dacoharkes): change signature to T allocate<T extends Pointer>() ?
-/// This would enable us to allocate structs. However how do we know the size of
-/// structs? https://github.com/dart-lang/sdk/issues/35782
-external Pointer<T> allocate<T extends NativeType>({int count: 1});
-
-/// Construction from raw value
-external T fromAddress<T extends Pointer>(int ptr);
-
-/// number of bytes used by native type T
+/// Includes padding and alignment of structs.
external int sizeOf<T extends NativeType>();
-/// Convert Dart function to a C function pointer, automatically marshalling
-/// the arguments and return value
-///
-/// Note: this is not implemented, always returns Pointer with address 0.
-///
-/// TODO(dacoharkes): Implement this feature.
-/// https://github.com/dart-lang/sdk/issues/35761
-external Pointer<NativeFunction<T>> fromFunction<T extends Function>(
- @DartRepresentationOf("T") Function f);
-
-/*
-/// TODO(dacoharkes): Implement this feature.
-/// https://github.com/dart-lang/sdk/issues/35770
-/// Return a pointer object that has a finalizer attached to it. When this
-/// pointer object is collected by GC the given finalizer is invoked.
-///
-/// Note: the pointer object passed to the finalizer is not the same as
-/// the pointer object that is returned from [finalizable] - it points
-/// to the same memory region but has different identity.
-external Pointer<T> finalizable<T extends NativeType>(
- Pointer<T> p, void finalizer(Pointer<T> ptr));
-*/
-
/// Represents a pointer into the native C memory.
+final Pointer<Void> nullptr = Pointer.fromAddress(0);
+
+/// Represents a pointer into the native C memory. Cannot be extended.
+@pragma("vm:entry-point")
class Pointer<T extends NativeType> extends NativeType {
const Pointer();
+ /// Allocate [count] elements of type [T] on the native heap via malloc() and
+ /// return a pointer to the newly allocated memory.
+ ///
+ /// Note that the memory is uninitialized.
+ external factory Pointer.allocate({int count: 1});
+
+ /// Construction from raw integer.
+ external factory Pointer.fromAddress(int ptr);
+
+ /// Convert Dart function to a C function pointer, automatically marshalling
+ /// the arguments and return value
+ ///
+ /// If an exception is thrown while calling `f()`, the native function will
+ /// return `exceptionalReturn`, which must be assignable to return type of `f`.
+ ///
+ /// The returned function address can only be invoked on the mutator (main)
+ /// thread of the current isolate. It will abort the process if invoked on any
+ /// other thread.
+ ///
+ /// The pointer returned will remain alive for the duration of the current
+ /// isolate's lifetime. After the isolate it was created in is terminated,
+ /// invoking it from native code will cause undefined behavior.
+ ///
+ /// Does not accept dynamic invocations -- where the type of the receiver is
+ /// [dynamic].
+ external static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+ @DartRepresentationOf("T") Function f, Object exceptionalReturn);
+
/// Store a Dart value into this location.
///
- /// The [value] is automatically marshalled into its C representation.
+ /// The [value] is automatically marshalled into its native representation.
/// Note that ints which do not fit in [T] are truncated and sign extended,
/// and doubles stored into Pointer<[Float]> lose precision.
external void store(@DartRepresentationOf("T") Object value);
/// Load a Dart value from this location.
///
- /// The value is automatically unmarshalled from its C representation.
+ /// The value is automatically unmarshalled from its native representation.
+ /// Loading a [Struct] reference returns a reference backed by native memory
+ /// (the same pointer as it's loaded from).
external R load<@DartRepresentationOf("T") R>();
/// Access to the raw pointer value.
+ /// On 32-bit systems, the upper 32-bits of the result are 0.
external int get address;
/// Pointer arithmetic (takes element size into account).
external Pointer<T> elementAt(int index);
/// Pointer arithmetic (byte offset).
- ///
- /// TODO(dacoharkes): remove this?
- /// https://github.com/dart-lang/sdk/issues/35883
+ // TODO(dacoharkes): remove this?
+ // https://github.com/dart-lang/sdk/issues/35883
external Pointer<T> offsetBy(int offsetInBytes);
- /// Cast Pointer<T> to a (subtype of) Pointer<V>.
- external U cast<U extends Pointer>();
+ /// Cast Pointer<T> to a Pointer<V>.
+ external Pointer<U> cast<U extends NativeType>();
/// Convert to Dart function, automatically marshalling the arguments
/// and return value.
///
- /// Can only be called on [Pointer]<[NativeFunction]>.
+ /// Can only be called on [Pointer]<[NativeFunction]>. Does not accept dynamic
+ /// invocations -- where the type of the receiver is [dynamic].
external R asFunction<@DartRepresentationOf("T") R extends Function>();
/// Free memory on the C heap pointed to by this pointer with free().
diff --git a/sdk/lib/ffi/ffi_sources.gni b/sdk/lib/ffi/ffi_sources.gni
index d67b267..d2bb279 100644
--- a/sdk/lib/ffi/ffi_sources.gni
+++ b/sdk/lib/ffi/ffi_sources.gni
@@ -8,5 +8,6 @@
# The above file needs to be first as it lists the parts below.
"annotations.dart",
"dynamic_library.dart",
- "native_type.dart"
+ "native_type.dart",
+ "struct.dart"
]
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
new file mode 100644
index 0000000..23124eb
--- /dev/null
+++ b/sdk/lib/ffi/struct.dart
@@ -0,0 +1,26 @@
+// 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.
+
+part of dart.ffi;
+
+/// This class is extended to define structs.
+///
+/// Fields in a struct, annotated with a subtype of [NativeType], are
+/// automatically transformed into wrappers to access the fields of the struct
+/// in native memory.
+///
+/// All fields in a struct must either have a type which extends [NativeType] or
+/// else have an annotation indicating the corresponding native type (e.g.
+/// "@Int32()" for "int").
+///
+/// Instances of a subclass of [Struct] have reference semantics and are backed
+/// by native memory. The may allocated via [Pointer.allocate] or loaded from a
+/// [Pointer], but not by a generative constructor.
+abstract class Struct<S extends NativeType> extends NativeType {
+ /// Returns the address backing the reference.
+ final Pointer<S> addressOf;
+
+ Struct() : addressOf = null;
+ Struct.fromPointer(this.addressOf);
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index eb75be5..e9c8707 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -18416,7 +18416,7 @@
// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
-// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.
+// https://w3c.github.io/html/sec-forms.html#the-input-element.
/**
* Exposes the functionality common between all InputElement types.
@@ -36425,7 +36425,7 @@
abstract class KeyCode {
// These constant names were borrowed from Closure's Keycode enumeration
// class.
- // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
+ // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
static const int WIN_KEY_FF_LINUX = 0;
static const int MAC_ENTER = 3;
static const int BACKSPACE = 8;
@@ -37285,7 +37285,7 @@
*/
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
// This code inspired by Closure's KeyHandling library.
- // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+ // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js
/**
* The set of keys that have been pressed down without seeing their
@@ -37310,7 +37310,7 @@
/**
* An enumeration of key identifiers currently part of the W3C draft for DOM3
* and their mappings to keyCodes.
- * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/keyset.html#KeySet-Set
*/
static const Map<String, int> _keyIdentifier = const {
'Up': KeyCode.UP,
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 861ce47..768ba51 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -483,7 +483,7 @@
* must be read to completion or the subscription on the stream must
* be cancelled.
*/
- Stream<List<int>> openRead([int start, int end]);
+ Stream<Uint8List> openRead([int start, int end]);
/**
* Creates a new independent [IOSink] for the file. The
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 68d8b1b..66a4134 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -7,9 +7,9 @@
// Read the file in blocks of size 64k.
const int _blockSize = 64 * 1024;
-class _FileStream extends Stream<List<int>> {
+class _FileStream extends Stream<Uint8List> {
// Stream controller.
- StreamController<List<int>> _controller;
+ StreamController<Uint8List> _controller;
// Information about the underlying file.
String _path;
@@ -33,7 +33,7 @@
_FileStream.forStdin() : _position = 0;
- StreamSubscription<List<int>> listen(void onData(List<int> event),
+ StreamSubscription<Uint8List> listen(void onData(Uint8List event),
{Function onError, void onDone(), bool cancelOnError}) {
_setupController();
return _controller.stream.listen(onData,
@@ -41,7 +41,7 @@
}
void _setupController() {
- _controller = new StreamController<List<int>>(
+ _controller = new StreamController<Uint8List>(
sync: true,
onListen: _start,
onResume: _readBlock,
@@ -498,7 +498,7 @@
return new _RandomAccessFile(id, "");
}
- Stream<List<int>> openRead([int start, int end]) {
+ Stream<Uint8List> openRead([int start, int end]) {
return new _FileStream(path, start, end);
}
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 63b32b3..8d76549 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -825,12 +825,12 @@
}
/**
- * Datagram package. Data send to and received from datagram sockets
+ * Datagram package. Data sent to and received from datagram sockets
* contains the internet address and port of the destination or source
* togeter with the data.
*/
class Datagram {
- List<int> data;
+ Uint8List data;
InternetAddress address;
int port;
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 5321ddf..b51c141 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -10,6 +10,16 @@
LibTest/html/*: SkipByDesign # d8 is not a browser
WebPlatformTest/*: SkipByDesign # d8 is not a browser
+[ $compiler == dart2js && $runtime == d8 && $host_checked ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: Slow
+LibTest/core/List/List_class_A01_t05: Slow
+LibTest/core/List/List_class_A01_t06: Slow
+
[ $compiler == dart2js && $runtime == ie11 ]
LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # slow babeljs transformation
LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # slow babeljs transformation
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 48b24cc..e74c130 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -50,8 +50,6 @@
LibTest/io/exit/exit_A01_t01: RuntimeError
LibTest/io/exit/exit_A02_t01: RuntimeError
LibTest/io/exitCode/exitCode_A01_t01: RuntimeError
-LibTest/isolate/Isolate/spawnUri_A01_t02: RuntimeError
-LibTest/isolate/Isolate/spawnUri_A05_t05: RuntimeError
LibTest/isolate/ReceivePort/lastWhere_A01_t01: RuntimeError
[ $compiler == fasta ]
@@ -1432,3 +1430,10 @@
LibTest/math/MutableRectangle/width_A03_t02: RuntimeError
LibTest/math/Rectangle/Rectangle_A03_t04: RuntimeError
Utils/tests/Expect/throws_A01_t04: RuntimeError
+
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/compiler/dart2js/closure/data/captured_variable.dart b/tests/compiler/dart2js/closure/data/captured_variable.dart
index e5dc4b2..409184d 100644
--- a/tests/compiler/dart2js/closure/data/captured_variable.dart
+++ b/tests/compiler/dart2js/closure/data/captured_variable.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.
-/*element: boxedLoopVariableExample:*/
+/*member: boxedLoopVariableExample:*/
boxedLoopVariableExample() {
var input = [1, 2, 3];
var fs = [];
@@ -15,25 +15,25 @@
return fs;
}
-/*element: readParameterInAnonymousClosure:*/
+/*member: readParameterInAnonymousClosure:*/
readParameterInAnonymousClosure(/**/ parameter) {
return /*fields=[parameter],free=[parameter]*/ () => parameter;
}
-/*element: readParameterInClosure:*/
+/*member: readParameterInClosure:*/
readParameterInClosure(/**/ parameter) {
/*fields=[parameter],free=[parameter]*/ func() => parameter;
return func;
}
-/*element: writeParameterInAnonymousClosure:box=(box0 which holds [parameter])*/
+/*member: writeParameterInAnonymousClosure:box=(box0 which holds [parameter])*/
writeParameterInAnonymousClosure(/*boxed*/ parameter) {
return /*fields=[box0],free=[box0,parameter]*/ () {
parameter = 42;
};
}
-/*element: writeParameterInClosure:box=(box0 which holds [parameter])*/
+/*member: writeParameterInClosure:box=(box0 which holds [parameter])*/
writeParameterInClosure(/*boxed*/ parameter) {
/*fields=[box0],free=[box0,parameter]*/ func() {
parameter = 43;
@@ -42,20 +42,20 @@
return func;
}
-/*element: readLocalInAnonymousClosure:*/
+/*member: readLocalInAnonymousClosure:*/
readLocalInAnonymousClosure(/**/ parameter) {
var /**/ local = parameter;
return /*fields=[local],free=[local]*/ () => local;
}
-/*element: readLocalInClosure:*/
+/*member: readLocalInClosure:*/
readLocalInClosure(/**/ parameter) {
var /**/ local = parameter;
/*fields=[local],free=[local]*/ func() => local;
return func;
}
-/*element: writeLocalInAnonymousClosure:box=(box0 which holds [local])*/
+/*member: writeLocalInAnonymousClosure:box=(box0 which holds [local])*/
writeLocalInAnonymousClosure(/**/ parameter) {
// ignore: UNUSED_LOCAL_VARIABLE
var /*boxed*/ local = parameter;
@@ -64,7 +64,7 @@
};
}
-/*element: writeLocalInClosure:box=(box0 which holds [local])*/
+/*member: writeLocalInClosure:box=(box0 which holds [local])*/
writeLocalInClosure(/**/ parameter) {
// ignore: UNUSED_LOCAL_VARIABLE
var /*boxed*/ local = parameter;
@@ -75,25 +75,25 @@
return func;
}
-/*element: Foo.:hasThis*/
+/*member: Foo.:hasThis*/
class Foo {
- int /*element: Foo.bar:hasThis*/ bar = 4;
+ int /*member: Foo.bar:hasThis*/ bar = 4;
- /*element: Foo.baz:hasThis*/ baz() {
+ /*member: Foo.baz:hasThis*/ baz() {
/*fields=[this],free=[this],hasThis*/ func() => bar;
return func;
}
}
-/*element: Repro.:hasThis*/
+/*member: Repro.:hasThis*/
class Repro {
- /*element: Repro.qux:hasThis*/ qux() {
+ /*member: Repro.qux:hasThis*/ qux() {
/*fields=[this],free=[this],hasThis*/ threeNested(foo) =>
/*fields=[this],free=[this],hasThis*/ (bar) => someFunction();
return threeNested;
}
- /*element: Repro.someFunction:hasThis*/ someFunction() => 3;
+ /*member: Repro.someFunction:hasThis*/ someFunction() => 3;
}
main() {
diff --git a/tests/compiler/dart2js/closure/data/generic.dart b/tests/compiler/dart2js/closure/data/generic.dart
index 8823cb6..c1a3f5d 100644
--- a/tests/compiler/dart2js/closure/data/generic.dart
+++ b/tests/compiler/dart2js/closure/data/generic.dart
@@ -3,44 +3,44 @@
// BSD-style license that can be found in the LICENSE file.
class Class1<T> {
- /*element: Class1.field:hasThis*/
+ /*member: Class1.field:hasThis*/
var field = /*fields=[T],free=[T],hasThis*/ () => T;
- /*element: Class1.funcField:hasThis*/
+ /*member: Class1.funcField:hasThis*/
Function funcField;
- /*element: Class1.:hasThis*/
+ /*member: Class1.:hasThis*/
Class1() {
field = /*fields=[T],free=[T],hasThis*/ () => T;
}
- /*element: Class1.setFunc:hasThis*/
+ /*member: Class1.setFunc:hasThis*/
Class1.setFunc(this.funcField);
- /*element: Class1.fact:*/
+ /*member: Class1.fact:*/
factory Class1.fact() => new Class1<T>();
- /*element: Class1.fact2:*/
+ /*member: Class1.fact2:*/
factory Class1.fact2() =>
new Class1.setFunc(/*fields=[T],free=[T]*/ () => new Set<T>());
- /*element: Class1.method1:hasThis*/
+ /*member: Class1.method1:hasThis*/
method1() => T;
- /*element: Class1.method2:hasThis*/
+ /*member: Class1.method2:hasThis*/
method2() {
return /*fields=[this],free=[this],hasThis*/ () => T;
}
- /*element: Class1.method3:hasThis*/
+ /*member: Class1.method3:hasThis*/
method3<S>() => S;
- /*element: Class1.method4:hasThis*/
+ /*member: Class1.method4:hasThis*/
method4<S>() {
return /*fields=[S],free=[S],hasThis*/ () => S;
}
- /*element: Class1.method5:hasThis*/
+ /*member: Class1.method5:hasThis*/
method5() {
/*hasThis*/ local<S>() {
return /*fields=[S],free=[S],hasThis*/ () => S;
@@ -49,7 +49,7 @@
return local<double>();
}
- /*element: Class1.method6:hasThis*/
+ /*member: Class1.method6:hasThis*/
method6<S>() {
/*fields=[S],free=[S],hasThis*/ local<U>() {
return /*fields=[S,U],free=[S,U],hasThis*/ () => '$S$U';
@@ -67,15 +67,15 @@
return local2(local<double>());
}
- /*element: Class1.staticMethod1:*/
+ /*member: Class1.staticMethod1:*/
static staticMethod1<S>() => S;
- /*element: Class1.staticMethod2:*/
+ /*member: Class1.staticMethod2:*/
static staticMethod2<S>() {
return /*fields=[S],free=[S]*/ () => S;
}
- /*element: Class1.staticMethod3:*/
+ /*member: Class1.staticMethod3:*/
static staticMethod3() {
local<S>() {
return /*fields=[S],free=[S]*/ () => S;
@@ -84,7 +84,7 @@
return local<double>();
}
- /*element: Class1.staticMethod4:*/
+ /*member: Class1.staticMethod4:*/
static staticMethod4<S>() {
/*fields=[S],free=[S]*/ local<U>() {
return /*fields=[S,U],free=[S,U]*/ () => '$S$U';
@@ -97,15 +97,15 @@
}
}
-/*element: topLevelMethod1:*/
+/*member: topLevelMethod1:*/
topLevelMethod1<S>() => S;
-/*element: topLevelMethod2:*/
+/*member: topLevelMethod2:*/
topLevelMethod2<S>() {
return /*fields=[S],free=[S]*/ () => S;
}
-/*element: topLevelMethod3:*/
+/*member: topLevelMethod3:*/
topLevelMethod3() {
local<S>() {
return /*fields=[S],free=[S]*/ () => S;
@@ -114,7 +114,7 @@
return local<double>();
}
-/*element: topLevelMethod4:*/
+/*member: topLevelMethod4:*/
topLevelMethod4<S>() {
/*fields=[S],free=[S]*/ local<U>() {
return /*fields=[S,U],free=[S,U]*/ () => '$S$U';
@@ -126,7 +126,7 @@
return local2(local<double>());
}
-/*element: main:*/
+/*member: main:*/
main() {
new Class1<int>().method1();
new Class1<int>.fact().method2();
diff --git a/tests/compiler/dart2js/closure/data/instantiation1.dart b/tests/compiler/dart2js/closure/data/instantiation1.dart
index 22e5276..e8ba217 100644
--- a/tests/compiler/dart2js/closure/data/instantiation1.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation1.dart
@@ -6,9 +6,9 @@
typedef int F<R>(R a);
-/*element: B.:hasThis*/
+/*member: B.:hasThis*/
class B<S> {
- /*element: B.method:hasThis*/
+ /*member: B.method:hasThis*/
method() {
return
/*strong.fields=[this],free=[this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/instantiation2.dart b/tests/compiler/dart2js/closure/data/instantiation2.dart
index c1f6335..d3a616f 100644
--- a/tests/compiler/dart2js/closure/data/instantiation2.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation2.dart
@@ -6,9 +6,9 @@
typedef bool F<R>(R a);
-/*element: B.:hasThis*/
+/*member: B.:hasThis*/
class B<S> {
- /*element: B.method:hasThis*/
+ /*member: B.method:hasThis*/
method() {
return
/*strong.fields=[this],free=[this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/list_literal_class.dart b/tests/compiler/dart2js/closure/data/list_literal_class.dart
index 4384e6b..080bb77 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_class.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
class A<T> {
- /*element: A.method:hasThis*/
+ /*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
/*fields=[this],free=[this],hasThis*/ dynamic local() => <T>[];
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
index 997fd78..a20f0b8 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
class A<T> {
- /*element: A.method:hasThis*/
+ /*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
/*omit.hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/map_literal_class.dart b/tests/compiler/dart2js/closure/data/map_literal_class.dart
index 975b5ee..f6f1f0c 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_class.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
class A<T> {
- /*element: A.method:hasThis*/
+ /*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
/*fields=[this],free=[this],hasThis*/ dynamic local() => <T, int>{};
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
index 7161fd6..da671a3 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
@@ -4,9 +4,9 @@
import 'package:expect/expect.dart';
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
class A<T> {
- /*element: A.method:hasThis*/
+ /*member: A.method:hasThis*/
@pragma('dart2js:noInline')
method() {
/*omit.hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/mixed.dart b/tests/compiler/dart2js/closure/data/mixed.dart
index 2cec1c4..20fdcbe 100644
--- a/tests/compiler/dart2js/closure/data/mixed.dart
+++ b/tests/compiler/dart2js/closure/data/mixed.dart
@@ -5,7 +5,7 @@
// Test that free variables aren't mixed between capturing and non-capturing
// closures.
-/*element: mutateInClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInClosure:box=(box0 which holds [localVar])*/
mutateInClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -17,7 +17,7 @@
return localVar;
}
-/*element: mutateOutsideClosure:box=(box0 which holds [localVar])*/
+/*member: mutateOutsideClosure:box=(box0 which holds [localVar])*/
mutateOutsideClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -30,7 +30,7 @@
return localVar;
}
-/*element: mutateInOtherClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInOtherClosure:box=(box0 which holds [localVar])*/
mutateInOtherClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -45,7 +45,7 @@
return localVar;
}
-/*element: mutateInNestedClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInNestedClosure:box=(box0 which holds [localVar])*/
mutateInNestedClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
diff --git a/tests/compiler/dart2js/closure/data/mutations.dart b/tests/compiler/dart2js/closure/data/mutations.dart
index e0524d2..8516ba3 100644
--- a/tests/compiler/dart2js/closure/data/mutations.dart
+++ b/tests/compiler/dart2js/closure/data/mutations.dart
@@ -4,7 +4,7 @@
// Test that captured variables are boxed regardless of where they are mutated.
-/*element: mutateUnused:*/
+/*member: mutateUnused:*/
mutateUnused() {
var localVar;
/**/ () {
@@ -14,7 +14,7 @@
return localVar;
}
-/*element: mutateInClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInClosure:box=(box0 which holds [localVar])*/
mutateInClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -23,7 +23,7 @@
return localVar;
}
-/*element: mutateOutsideClosure:box=(box0 which holds [localVar])*/
+/*member: mutateOutsideClosure:box=(box0 which holds [localVar])*/
mutateOutsideClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -33,7 +33,7 @@
return localVar;
}
-/*element: mutateInOtherClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInOtherClosure:box=(box0 which holds [localVar])*/
mutateInOtherClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
@@ -45,7 +45,7 @@
return localVar;
}
-/*element: mutateInNestedClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInNestedClosure:box=(box0 which holds [localVar])*/
mutateInNestedClosure() {
var /*boxed*/ localVar;
/*fields=[box0],free=[box0,localVar]*/ () {
diff --git a/tests/compiler/dart2js/closure/data/nested_closures.dart b/tests/compiler/dart2js/closure/data/nested_closures.dart
index 1dad607..2f2cb12 100644
--- a/tests/compiler/dart2js/closure/data/nested_closures.dart
+++ b/tests/compiler/dart2js/closure/data/nested_closures.dart
@@ -4,7 +4,7 @@
/// Test boxing/captures for nested closures.
-/*element: useOne:box=(box0 which holds [b1])*/ useOne(/*boxed*/ b1) {
+/*member: useOne:box=(box0 which holds [b1])*/ useOne(/*boxed*/ b1) {
/*box=(box1 which holds [b2]),fields=[box0],free=[b1,box0]*/ () {
var /*boxed*/ b2 = (b1 = 1);
@@ -17,7 +17,7 @@
return b1;
}
-/*element: useBoth:box=(box0 which holds [b1])*/ useBoth(/*boxed*/ b1) {
+/*member: useBoth:box=(box0 which holds [b1])*/ useBoth(/*boxed*/ b1) {
/*box=(box1 which holds [b2]),fields=[box0],free=[b1,box0]*/ () {
var /*boxed*/ b2 = (b1 = 1);
@@ -30,7 +30,7 @@
return b1;
}
-/*element: useMany:box=(box0 which holds [b1,b2,b3])*/
+/*member: useMany:box=(box0 which holds [b1,b2,b3])*/
useMany(c1, /*boxed*/ b1) {
var /*boxed*/ b2 = 2;
var /*boxed*/ b3 = 3;
diff --git a/tests/compiler/dart2js/closure/data/test_type_class.dart b/tests/compiler/dart2js/closure/data/test_type_class.dart
index afa2f5b..222ca14 100644
--- a/tests/compiler/dart2js/closure/data/test_type_class.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_class.dart
@@ -6,9 +6,9 @@
/// Explicit is-test is always required.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:hasThis*/
+/*member: Class1.:hasThis*/
class Class1<T> {
- /*element: Class1.method1:hasThis*/
+ /*member: Class1.method1:hasThis*/
method1(dynamic o) {
/*fields=[o,this],free=[o,this],hasThis*/
dynamic local() => o is T;
@@ -20,9 +20,9 @@
/// Explicit as-cast is always required.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:hasThis*/
+/*member: Class2.:hasThis*/
class Class2<T> {
- /*element: Class2.method2:hasThis*/
+ /*member: Class2.method2:hasThis*/
method2(dynamic o) {
/*fields=[o,this],free=[o,this],hasThis*/
dynamic local() => o as T;
@@ -34,9 +34,9 @@
/// Implicit as-cast is only required in strong mode.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:hasThis*/
+/*member: Class3.:hasThis*/
class Class3<T> {
- /*element: Class3.method3:hasThis*/
+ /*member: Class3.method3:hasThis*/
method3(dynamic o) {
/*omit.fields=[o],free=[o],hasThis*/
/*strong.fields=[o,this],free=[o,this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/test_type_method.dart b/tests/compiler/dart2js/closure/data/test_type_method.dart
index cb8f88d..bab82c3 100644
--- a/tests/compiler/dart2js/closure/data/test_type_method.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_method.dart
@@ -6,7 +6,7 @@
/// Explicit is-test is always required.
////////////////////////////////////////////////////////////////////////////////
-/*element: method1:*/
+/*member: method1:*/
method1<T>(dynamic o) {
/*fields=[T,o],free=[T,o]*/
dynamic local() => o is T;
@@ -17,7 +17,7 @@
/// Explicit as-cast is always required.
////////////////////////////////////////////////////////////////////////////////
-/*element: method2:*/
+/*member: method2:*/
method2<T>(dynamic o) {
/*fields=[T,o],free=[T,o]*/
dynamic local() => o as T;
@@ -28,7 +28,7 @@
/// Implicit as-cast is only required in strong mode.
////////////////////////////////////////////////////////////////////////////////
-/*element: method3:*/
+/*member: method3:*/
method3<T>(dynamic o) {
/*strong.fields=[T,o],free=[T,o]*/
/*omit.fields=[o],free=[o]*/
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_class.dart b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
index 84a8a53..853ffd6 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
@@ -7,9 +7,9 @@
/// variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:hasThis*/
+/*member: Class1.:hasThis*/
class Class1<T> {
- /*element: Class1.method1:hasThis*/
+ /*member: Class1.method1:hasThis*/
method1(T o) {
/*fields=[o],free=[o],hasThis*/
dynamic local() {
@@ -25,9 +25,9 @@
/// A sound assignment to a local variable doesn't capture the type variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
class Class1b<T> {
- /*element: Class1b.method1b:hasThis*/
+ /*member: Class1b.method1b:hasThis*/
method1b(T o) {
/*fields=[o],free=[o],hasThis*/
dynamic local() {
@@ -44,9 +44,9 @@
/// A local function parameter type is only captured in strong mode.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:hasThis*/
+/*member: Class2.:hasThis*/
class Class2<T> {
- /*element: Class2.method2:hasThis*/
+ /*member: Class2.method2:hasThis*/
method2() {
/*omit.hasThis*/
/*strong.fields=[this],free=[this],hasThis*/
@@ -59,9 +59,9 @@
/// A local function return type is only captured in strong mode.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:hasThis*/
+/*member: Class3.:hasThis*/
class Class3<T> {
- /*element: Class3.method3:hasThis*/
+ /*member: Class3.method3:hasThis*/
method3(dynamic o) {
/*omit.fields=[o],free=[o],hasThis*/
/*strong.fields=[o,this],free=[o,this],hasThis*/
@@ -74,9 +74,9 @@
/// A member parameter type is not captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:hasThis*/
+/*member: Class4.:hasThis*/
class Class4<T> {
- /*element: Class4.method4:hasThis*/
+ /*member: Class4.method4:hasThis*/
method4(T o) {
/*fields=[o],free=[o],hasThis*/
dynamic local() => o;
@@ -88,9 +88,9 @@
/// A member return type is not captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:hasThis*/
+/*member: Class5.:hasThis*/
class Class5<T> {
- /*element: Class5.method5:hasThis*/
+ /*member: Class5.method5:hasThis*/
T method5(dynamic o) {
/*fields=[o],free=[o],hasThis*/
dynamic local() => o;
@@ -102,9 +102,9 @@
/// A local function parameter type is not captured by an inner local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class6.:hasThis*/
+/*member: Class6.:hasThis*/
class Class6<T> {
- /*element: Class6.method6:hasThis*/
+ /*member: Class6.method6:hasThis*/
method6() {
/*omit.hasThis*/
/*strong.fields=[this],free=[this],hasThis*/
@@ -122,9 +122,9 @@
/// A local function return type is not captured by an inner local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class7.:hasThis*/
+/*member: Class7.:hasThis*/
class Class7<T> {
- /*element: Class7.method7:hasThis*/
+ /*member: Class7.method7:hasThis*/
method7(dynamic o) {
/*omit.fields=[o],free=[o],hasThis*/
/*strong.fields=[o,this],free=[o,this],hasThis*/
@@ -142,9 +142,9 @@
/// A field type is not captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class8.:hasThis*/
+/*member: Class8.:hasThis*/
class Class8<T> {
- /*element: Class8.field8:hasThis*/
+ /*member: Class8.field8:hasThis*/
T field8 = /*hasThis*/ () {
return null;
}();
diff --git a/tests/compiler/dart2js/closure/data/type_arguments_class.dart b/tests/compiler/dart2js/closure/data/type_arguments_class.dart
index 8061663..2340013 100644
--- a/tests/compiler/dart2js/closure/data/type_arguments_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_arguments_class.dart
@@ -7,12 +7,12 @@
/// type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1a.:hasThis*/
+/*member: Class1a.:hasThis*/
class Class1a<T> {}
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
class Class1b<T> {
- /*element: Class1b.method1:hasThis*/
+ /*member: Class1b.method1:hasThis*/
method1() {
/*fields=[this],free=[this],hasThis*/
dynamic local() => new Class1a<T>();
@@ -25,12 +25,12 @@
/// _not_ capture the type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2a.:hasThis*/
+/*member: Class2a.:hasThis*/
class Class2a<T> {}
-/*element: Class2b.:hasThis*/
+/*member: Class2b.:hasThis*/
class Class2b<T> {
- /*element: Class2b.method2:hasThis*/
+ /*member: Class2b.method2:hasThis*/
method2() {
/*hasThis*/
dynamic local() => new Class2a<T>();
diff --git a/tests/compiler/dart2js/closure/data/type_arguments_method.dart b/tests/compiler/dart2js/closure/data/type_arguments_method.dart
index 99733a8..ad35ada 100644
--- a/tests/compiler/dart2js/closure/data/type_arguments_method.dart
+++ b/tests/compiler/dart2js/closure/data/type_arguments_method.dart
@@ -7,12 +7,12 @@
/// type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1a.:hasThis*/
+/*member: Class1a.:hasThis*/
class Class1a<T> {}
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
class Class1b<T> {
- /*element: Class1b.method1:hasThis*/
+ /*member: Class1b.method1:hasThis*/
method1() {
/*fields=[this],free=[this],hasThis*/
dynamic local() => new Class1a<T>();
@@ -25,12 +25,12 @@
/// does _not_ capture the type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2a.:hasThis*/
+/*member: Class2a.:hasThis*/
class Class2a<T> {}
-/*element: Class2b.:hasThis*/
+/*member: Class2b.:hasThis*/
class Class2b<T> {
- /*element: Class2b.method2:hasThis*/
+ /*member: Class2b.method2:hasThis*/
method2() {
/*hasThis*/
dynamic local() => new Class2a<T>();
@@ -69,9 +69,9 @@
/// the type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5a.:hasThis*/
+/*member: Class5a.:hasThis*/
class Class5a {
- /*element: Class5a.method5a:hasThis*/
+ /*member: Class5a.method5a:hasThis*/
method5a<T>(o) => o is T;
}
@@ -86,9 +86,9 @@
/// arguments does _not_ capture the type variables.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class6a.:hasThis*/
+/*member: Class6a.:hasThis*/
class Class6a {
- /*element: Class6a.method6a:hasThis*/
+ /*member: Class6a.method6a:hasThis*/
method6a<T>(o) => o;
}
diff --git a/tests/compiler/dart2js/closure/data/type_variables.dart b/tests/compiler/dart2js/closure/data/type_variables.dart
index 7180c2b..1521b3a 100644
--- a/tests/compiler/dart2js/closure/data/type_variables.dart
+++ b/tests/compiler/dart2js/closure/data/type_variables.dart
@@ -3,37 +3,37 @@
// BSD-style license that can be found in the LICENSE file.
class Class1<T> {
- /*element: Class1.field:hasThis*/
+ /*member: Class1.field:hasThis*/
var field = /*fields=[T],free=[T],hasThis*/ () => T;
- /*element: Class1.funcField:hasThis*/
+ /*member: Class1.funcField:hasThis*/
Function funcField;
- /*element: Class1.:hasThis*/
+ /*member: Class1.:hasThis*/
Class1() {
field = /*fields=[T],free=[T],hasThis*/ () => T;
}
- /*element: Class1.setFunc:hasThis*/
+ /*member: Class1.setFunc:hasThis*/
Class1.setFunc(this.funcField);
- /*element: Class1.fact:*/
+ /*member: Class1.fact:*/
factory Class1.fact() => new Class1<T>();
- /*element: Class1.fact2:*/
+ /*member: Class1.fact2:*/
factory Class1.fact2() =>
new Class1.setFunc(/*fields=[T],free=[T]*/ () => new Set<T>());
- /*element: Class1.method1:hasThis*/
+ /*member: Class1.method1:hasThis*/
method1() => T;
- /*element: Class1.method2:hasThis*/
+ /*member: Class1.method2:hasThis*/
method2() {
return /*fields=[this],free=[this],hasThis*/ () => T;
}
}
-/*element: main:*/
+/*member: main:*/
main() {
new Class1<int>().method1();
new Class1<int>.fact().method2();
diff --git a/tests/compiler/dart2js/codegen/model_data/capture.dart b/tests/compiler/dart2js/codegen/model_data/capture.dart
index 5e44fb0..251c751 100644
--- a/tests/compiler/dart2js/codegen/model_data/capture.dart
+++ b/tests/compiler/dart2js/codegen/model_data/capture.dart
@@ -2,22 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method1:params=0*/
+/*member: method1:params=0*/
@pragma('dart2js:noInline')
method1([a]) => /*access=[a],params=0*/ () => a;
class Class {
- /*element: Class.f:emitted*/
+ /*member: Class.f:emitted*/
@pragma('dart2js:noElision')
var f;
- /*element: Class.capture:params=0*/
+ /*member: Class.capture:params=0*/
@pragma('dart2js:noInline')
Class.capture([a]) : f = (/*access=[a],params=0*/ () => a);
// TODO(johnniwinther): Remove the redundant assignment of elided boxed
// parameters.
- /*element: Class.box:assign=[a,a],params=0*/
+ /*member: Class.box:assign=[a,a],params=0*/
@pragma('dart2js:noInline')
Class.box([a])
: f = (/*access=[_box_0],assign=[a],params=0*/ () {
@@ -28,11 +28,11 @@
}
class Subclass extends Class {
- /*element: Subclass.capture:params=0*/
+ /*member: Subclass.capture:params=0*/
@pragma('dart2js:noInline')
Subclass.capture([a]) : super.internal(/*access=[a],params=0*/ () => a);
- /*element: Subclass.box:assign=[a,a],params=0*/
+ /*member: Subclass.box:assign=[a,a],params=0*/
@pragma('dart2js:noInline')
Subclass.box([a])
: super.internal(/*access=[_box_0],assign=[a],params=0*/ () {
@@ -40,7 +40,7 @@
});
}
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
method1();
new Class.capture();
diff --git a/tests/compiler/dart2js/codegen/model_data/constant_folding.dart b/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
index 6ca83c8..ce74ab7 100644
--- a/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
+++ b/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
@@ -6,7 +6,7 @@
import "package:expect/expect.dart";
-/*element: main:calls=[checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1)],params=0*/
+/*member: main:calls=[checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1)],params=0*/
void main() {
const BitNot(42, 4294967253).check();
const BitNot(4294967253, 42).check();
@@ -17,7 +17,7 @@
const BitNot(0x12121212121212, 0xEDEDEDED).check();
}
-/*element: jsEquals:calls=[Expect_equals(3),Expect_equals(3),get$isNegative(1),get$isNegative(1),toString$0(1),toString$0(1)],params=3*/
+/*member: jsEquals:calls=[Expect_equals(3),Expect_equals(3),get$isNegative(1),get$isNegative(1),toString$0(1),toString$0(1)],params=3*/
void jsEquals(expected, actual, [String reason = null]) {
if (expected is num && actual is num) {
if (expected.isNaN && actual.isNaN) return;
@@ -42,7 +42,7 @@
const TestOp(this.expected, this.result);
- /*element: TestOp.checkAll:access=[arg,expected,result],calls=[jsEquals(3),jsEquals(3),jsEquals(3)],params=1*/
+ /*member: TestOp.checkAll:access=[arg,expected,result],calls=[jsEquals(3),jsEquals(3),jsEquals(3)],params=1*/
@pragma('dart2js:noInline')
checkAll(evalResult) {
jsEquals(expected, result,
@@ -56,7 +56,7 @@
}
class BitNot extends TestOp {
- /*element: BitNot.arg:emitted*/
+ /*member: BitNot.arg:emitted*/
final arg;
const BitNot(this.arg, expected) : super(expected, ~arg);
diff --git a/tests/compiler/dart2js/codegen/model_data/constructors.dart b/tests/compiler/dart2js/codegen/model_data/constructors.dart
index e7c0d8c..6d25ce6 100644
--- a/tests/compiler/dart2js/codegen/model_data/constructors.dart
+++ b/tests/compiler/dart2js/codegen/model_data/constructors.dart
@@ -3,94 +3,94 @@
// BSD-style license that can be found in the LICENSE file.
class Class {
- /*element: Class.constructor1:params=0*/
+ /*member: Class.constructor1:params=0*/
@pragma('dart2js:noInline')
Class.constructor1() {}
- /*element: Class.constructor2a:params=0*/
+ /*member: Class.constructor2a:params=0*/
@pragma('dart2js:noInline')
Class.constructor2a([a]) {}
- /*element: Class.constructor2b:params=1*/
+ /*member: Class.constructor2b:params=1*/
@pragma('dart2js:noInline')
Class.constructor2b([a]) {}
- /*element: Class.constructor2c:params=1*/
+ /*member: Class.constructor2c:params=1*/
@pragma('dart2js:noInline')
Class.constructor2c([a]) {}
- /*element: Class.constructor3a:params=0*/
+ /*member: Class.constructor3a:params=0*/
@pragma('dart2js:noInline')
Class.constructor3a([a, b]) {}
- /*element: Class.constructor3b:params=1*/
+ /*member: Class.constructor3b:params=1*/
@pragma('dart2js:noInline')
Class.constructor3b([a, b]) {}
- /*element: Class.constructor3c:params=2*/
+ /*member: Class.constructor3c:params=2*/
@pragma('dart2js:noInline')
Class.constructor3c([a, b]) {}
- /*element: Class.constructor4a:params=0*/
+ /*member: Class.constructor4a:params=0*/
@pragma('dart2js:noInline')
Class.constructor4a({a}) {}
- /*element: Class.constructor4b:params=1*/
+ /*member: Class.constructor4b:params=1*/
@pragma('dart2js:noInline')
Class.constructor4b({a}) {}
- /*element: Class.constructor4c:params=1*/
+ /*member: Class.constructor4c:params=1*/
@pragma('dart2js:noInline')
Class.constructor4c({a}) {}
- /*element: Class.constructor5a:params=0*/
+ /*member: Class.constructor5a:params=0*/
@pragma('dart2js:noInline')
Class.constructor5a({a, b}) {}
- /*element: Class.constructor5b:params=1*/
+ /*member: Class.constructor5b:params=1*/
@pragma('dart2js:noInline')
Class.constructor5b({a, b}) {}
- /*element: Class.constructor5c:params=1*/
+ /*member: Class.constructor5c:params=1*/
@pragma('dart2js:noInline')
Class.constructor5c({a, b}) {}
- /*element: Class.constructor6a:params=1*/
+ /*member: Class.constructor6a:params=1*/
@pragma('dart2js:noInline')
Class.constructor6a(a, [b, c]) {}
- /*element: Class.constructor6b:params=2*/
+ /*member: Class.constructor6b:params=2*/
@pragma('dart2js:noInline')
Class.constructor6b(a, [b, c]) {}
- /*element: Class.constructor6c:params=3*/
+ /*member: Class.constructor6c:params=3*/
@pragma('dart2js:noInline')
Class.constructor6c(a, [b, c]) {}
- /*element: Class.constructor7a:params=1*/
+ /*member: Class.constructor7a:params=1*/
@pragma('dart2js:noInline')
Class.constructor7a(a, {b, c}) {}
- /*element: Class.constructor7b:params=2*/
+ /*member: Class.constructor7b:params=2*/
@pragma('dart2js:noInline')
Class.constructor7b(a, {b, c}) {}
- /*element: Class.constructor7c:params=2*/
+ /*member: Class.constructor7c:params=2*/
@pragma('dart2js:noInline')
Class.constructor7c(a, {b, c}) {}
- /*element: Class.constructor8a:params=2*/
+ /*member: Class.constructor8a:params=2*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
Class.constructor8a([a, b]) {}
- /*element: Class.constructor8b:params=2*/
+ /*member: Class.constructor8b:params=2*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
Class.constructor8b({a, b}) {}
}
-/*element: main:
+/*member: main:
calls=[
Class$constructor1(0),
Class$constructor2a(0),
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
index e7f67fb..427eb7a 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_get.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.
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
method1(new Class1a());
method2(new Class2a<int>());
@@ -13,61 +13,61 @@
}
class Class1a {
- /*element: Class1a.field1:emitted*/
+ /*member: Class1a.field1:emitted*/
@pragma('dart2js:noElision')
int field1;
}
-/*element: method1:access=[field1],params=1*/
+/*member: method1:access=[field1],params=1*/
@pragma('dart2js:noInline')
method1(dynamic c) {
return c.field1;
}
class Class2a<T> {
- /*element: Class2a.field2:emitted*/
+ /*member: Class2a.field2:emitted*/
@pragma('dart2js:noElision')
T field2;
}
-/*element: method2:access=[field2],params=1*/
+/*member: method2:access=[field2],params=1*/
@pragma('dart2js:noInline')
method2(dynamic c) {
return c.field2;
}
class Class3a {
- /*element: Class3a.field3:emitted,get=simple*/
+ /*member: Class3a.field3:emitted,get=simple*/
@pragma('dart2js:noElision')
int field3;
}
class Class3b {
- /*element: Class3b.field3:emitted,get=simple*/
+ /*member: Class3b.field3:emitted,get=simple*/
@pragma('dart2js:noElision')
int field3;
}
-/*element: method3:calls=[get$field3(0)],params=1*/
+/*member: method3:calls=[get$field3(0)],params=1*/
@pragma('dart2js:noInline')
method3(dynamic c) {
return c.field3;
}
class Class4a {
- /*element: Class4a.field4:emitted,get=simple*/
+ /*member: Class4a.field4:emitted,get=simple*/
@pragma('dart2js:noElision')
int field4;
}
class Class4b implements Class4a {
- /*element: Class4b.field4:emitted,get=simple*/
+ /*member: Class4b.field4:emitted,get=simple*/
@pragma('dart2js:noElision')
@override
int field4;
}
-/*element: method4:calls=[get$field4(0)],params=1*/
+/*member: method4:calls=[get$field4(0)],params=1*/
@pragma('dart2js:noInline')
method4(Class4a c) {
return c.field4;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index 7694ba4..ed3aa49 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.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.
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
method1(new Class1a()..field1);
method2(new Class2a<int>()..field2);
@@ -13,73 +13,73 @@
}
class Class1a {
- /*element: Class1a.field1:emitted*/
+ /*member: Class1a.field1:emitted*/
int field1;
}
-/*element: method1:assign=[field1],params=1*/
+/*member: method1:assign=[field1],params=1*/
@pragma('dart2js:noInline')
method1(dynamic c) {
c.field1 = 42;
}
class Class2a<T> {
- /*strong.element: Class2a.field2:checked,emitted*/
- /*omit.element: Class2a.field2:emitted*/
- /*strongConst.element: Class2a.field2:checked,emitted*/
- /*omitConst.element: Class2a.field2:emitted*/
+ /*strong.member: Class2a.field2:checked,emitted*/
+ /*omit.member: Class2a.field2:emitted*/
+ /*strongConst.member: Class2a.field2:checked,emitted*/
+ /*omitConst.member: Class2a.field2:emitted*/
T field2;
}
-/*strong.element: method2:calls=[set$field2(1)],params=1*/
-/*omit.element: method2:assign=[field2],params=1*/
-/*strongConst.element: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.element: method2:assign=[field2],params=1*/
+/*strong.member: method2:calls=[set$field2(1)],params=1*/
+/*omit.member: method2:assign=[field2],params=1*/
+/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
+/*omitConst.member: method2:assign=[field2],params=1*/
@pragma('dart2js:noInline')
method2(dynamic c) {
c.field2 = 42;
}
class Class3a {
- /*strong.element: Class3a.field3:checked,emitted*/
- /*omit.element: Class3a.field3:emitted,set=simple*/
- /*strongConst.element: Class3a.field3:checked,emitted*/
- /*omitConst.element: Class3a.field3:emitted,set=simple*/
+ /*strong.member: Class3a.field3:checked,emitted*/
+ /*omit.member: Class3a.field3:emitted,set=simple*/
+ /*strongConst.member: Class3a.field3:checked,emitted*/
+ /*omitConst.member: Class3a.field3:emitted,set=simple*/
int field3;
}
class Class3b {
- /*strong.element: Class3b.field3:checked,emitted*/
- /*omit.element: Class3b.field3:emitted,set=simple*/
- /*strongConst.element: Class3b.field3:checked,emitted*/
- /*omitConst.element: Class3b.field3:emitted,set=simple*/
+ /*strong.member: Class3b.field3:checked,emitted*/
+ /*omit.member: Class3b.field3:emitted,set=simple*/
+ /*strongConst.member: Class3b.field3:checked,emitted*/
+ /*omitConst.member: Class3b.field3:emitted,set=simple*/
int field3;
}
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
@pragma('dart2js:noInline')
method3(dynamic c) {
c.field3 = 42;
}
class Class4a {
- /*strong.element: Class4a.field4:checked,emitted*/
- /*omit.element: Class4a.field4:emitted,set=simple*/
- /*strongConst.element: Class4a.field4:checked,emitted*/
- /*omitConst.element: Class4a.field4:emitted,set=simple*/
+ /*strong.member: Class4a.field4:checked,emitted*/
+ /*omit.member: Class4a.field4:emitted,set=simple*/
+ /*strongConst.member: Class4a.field4:checked,emitted*/
+ /*omitConst.member: Class4a.field4:emitted,set=simple*/
int field4;
}
class Class4b implements Class4a {
- /*strong.element: Class4b.field4:checked,emitted*/
- /*omit.element: Class4b.field4:emitted,set=simple*/
- /*strongConst.element: Class4b.field4:checked,emitted*/
- /*omitConst.element: Class4b.field4:emitted,set=simple*/
+ /*strong.member: Class4b.field4:checked,emitted*/
+ /*omit.member: Class4b.field4:emitted,set=simple*/
+ /*strongConst.member: Class4b.field4:checked,emitted*/
+ /*omitConst.member: Class4b.field4:emitted,set=simple*/
@override
int field4;
}
-/*element: method4:calls=[set$field4(1)],params=1*/
+/*member: method4:calls=[set$field4(1)],params=1*/
@pragma('dart2js:noInline')
method4(Class4a c) {
c.field4 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
index 84e646c..fcaa994 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.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.
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
method1(new Class1a());
method2(new Class2a<int>());
@@ -13,73 +13,73 @@
}
class Class1a {
- /*element: Class1a.field1:elided*/
+ /*member: Class1a.field1:elided*/
int field1;
}
-/*element: method1:params=1*/
+/*member: method1:params=1*/
@pragma('dart2js:noInline')
method1(dynamic c) {
c.field1 = 42;
}
class Class2a<T> {
- /*strong.element: Class2a.field2:checked,elided*/
- /*omit.element: Class2a.field2:elided*/
- /*strongConst.element: Class2a.field2:checked,elided*/
- /*omitConst.element: Class2a.field2:elided*/
+ /*strong.member: Class2a.field2:checked,elided*/
+ /*omit.member: Class2a.field2:elided*/
+ /*strongConst.member: Class2a.field2:checked,elided*/
+ /*omitConst.member: Class2a.field2:elided*/
T field2;
}
-/*strong.element: method2:calls=[set$field2(1)],params=1*/
-/*omit.element: method2:params=1*/
-/*strongConst.element: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.element: method2:params=1*/
+/*strong.member: method2:calls=[set$field2(1)],params=1*/
+/*omit.member: method2:params=1*/
+/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
+/*omitConst.member: method2:params=1*/
@pragma('dart2js:noInline')
method2(dynamic c) {
c.field2 = 42;
}
class Class3a {
- /*strong.element: Class3a.field3:checked,elided*/
- /*omit.element: Class3a.field3:elided,set=simple*/
- /*strongConst.element: Class3a.field3:checked,elided*/
- /*omitConst.element: Class3a.field3:elided,set=simple*/
+ /*strong.member: Class3a.field3:checked,elided*/
+ /*omit.member: Class3a.field3:elided,set=simple*/
+ /*strongConst.member: Class3a.field3:checked,elided*/
+ /*omitConst.member: Class3a.field3:elided,set=simple*/
int field3;
}
class Class3b {
- /*strong.element: Class3b.field3:checked,elided*/
- /*omit.element: Class3b.field3:elided,set=simple*/
- /*strongConst.element: Class3b.field3:checked,elided*/
- /*omitConst.element: Class3b.field3:elided,set=simple*/
+ /*strong.member: Class3b.field3:checked,elided*/
+ /*omit.member: Class3b.field3:elided,set=simple*/
+ /*strongConst.member: Class3b.field3:checked,elided*/
+ /*omitConst.member: Class3b.field3:elided,set=simple*/
int field3;
}
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
@pragma('dart2js:noInline')
method3(dynamic c) {
c.field3 = 42;
}
class Class4a {
- /*strong.element: Class4a.field4:checked,elided*/
- /*omit.element: Class4a.field4:elided,set=simple*/
- /*strongConst.element: Class4a.field4:checked,elided*/
- /*omitConst.element: Class4a.field4:elided,set=simple*/
+ /*strong.member: Class4a.field4:checked,elided*/
+ /*omit.member: Class4a.field4:elided,set=simple*/
+ /*strongConst.member: Class4a.field4:checked,elided*/
+ /*omitConst.member: Class4a.field4:elided,set=simple*/
int field4;
}
class Class4b implements Class4a {
- /*strong.element: Class4b.field4:checked,elided*/
- /*omit.element: Class4b.field4:elided,set=simple*/
- /*strongConst.element: Class4b.field4:checked,elided*/
- /*omitConst.element: Class4b.field4:elided,set=simple*/
+ /*strong.member: Class4b.field4:checked,elided*/
+ /*omit.member: Class4b.field4:elided,set=simple*/
+ /*strongConst.member: Class4b.field4:checked,elided*/
+ /*omitConst.member: Class4b.field4:elided,set=simple*/
@override
int field4;
}
-/*element: method4:calls=[set$field4(1)],params=1*/
+/*member: method4:calls=[set$field4(1)],params=1*/
@pragma('dart2js:noInline')
method4(Class4a c) {
c.field4 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart b/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
index f1e788e..39e6f1e 100644
--- a/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
+++ b/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
@@ -4,49 +4,49 @@
import 'package:expect/expect.dart';
-/*element: _field4:params=0*/
+/*member: _field4:params=0*/
_field4() => 4;
class Class1 {
- /*element: Class1.field1:elided*/
+ /*member: Class1.field1:elided*/
var field1 = 0;
- /*element: Class1.field2:emitted*/
+ /*member: Class1.field2:emitted*/
@pragma('dart2js:noElision')
var field2 = 1;
- /*element: Class1.field3:elided,get=simple*/
+ /*member: Class1.field3:elided,get=simple*/
var field3 = 2;
- /*element: Class1.field4:elided*/
+ /*member: Class1.field4:elided*/
var field4 = _field4;
}
-/*element: method1:params=1*/
+/*member: method1:params=1*/
@pragma('dart2js:noInline')
method1(Class1 c) {
return c.field1;
}
-/*element: method2:access=[field2],params=1*/
+/*member: method2:access=[field2],params=1*/
@pragma('dart2js:noInline')
method2(Class1 c) {
return c.field2;
}
class Class2 {
- /*element: Class2.field3:elided,get=simple*/
+ /*member: Class2.field3:elided,get=simple*/
final field3 = 3;
}
-/*element: method3:calls=[get$field3(0)],params=1*/
+/*member: method3:calls=[get$field3(0)],params=1*/
@pragma('dart2js:noInline')
method3(c) {
return c.field3;
}
class Class3 extends Class1 {
- /*element: Class3.method4:params=0*/
+ /*member: Class3.method4:params=0*/
@pragma('dart2js:noInline')
method4() {
return super.field1;
@@ -54,20 +54,20 @@
}
class Class4 extends Class1 {
- /*element: Class4.method5:calls=[_field4(0)],params=0*/
+ /*member: Class4.method5:calls=[_field4(0)],params=0*/
@pragma('dart2js:noInline')
method5() {
return super.field4();
}
}
-/*element: method6:access=[toString],params=1*/
+/*member: method6:access=[toString],params=1*/
@pragma('dart2js:noInline')
method6(Class1 c) {
return c.field1;
}
-/*element: method7:access=[toString],calls=[_field4(0)],params=1*/
+/*member: method7:access=[toString],calls=[_field4(0)],params=1*/
@pragma('dart2js:noInline')
method7(Class1 c) {
return c.field4();
@@ -75,24 +75,24 @@
var field8;
-/*element: method8:!access,params=0*/
+/*member: method8:!access,params=0*/
@pragma('dart2js:noInline')
method8() => field8;
var field9 = 10;
-/*element: method9:!access,params=0*/
+/*member: method9:!access,params=0*/
@pragma('dart2js:noInline')
method9() => field9;
-/*element: field10:emitted,lazy*/
+/*member: field10:emitted,lazy*/
var field10 = method9() + 10;
-/*element: method10:calls=[$get$field10(0)],params=0*/
+/*member: method10:calls=[$get$field10(0)],params=0*/
@pragma('dart2js:noInline')
method10() => field10;
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
Expect.equals(0, method1(new Class1()));
Expect.equals(1, method2(new Class1()));
diff --git a/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart b/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
index fc33c4b..ec053ae 100644
--- a/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
@@ -8,28 +8,28 @@
c,
}
-/*element: tester1:params=0*/
+/*member: tester1:params=0*/
@pragma('dart2js:noInline')
tester1() {}
-/*element: tester2:params=0*/
+/*member: tester2:params=0*/
@pragma('dart2js:noInline')
tester2() {}
-/*element: tester3:params=0*/
+/*member: tester3:params=0*/
@pragma('dart2js:noInline')
tester3() {}
class Class {
- /*element: Class.state1:elided*/
+ /*member: Class.state1:elided*/
final int state1;
- /*element: Class.state2:elided*/
+ /*member: Class.state2:elided*/
final Enum state2;
Class({this.state1: 1, this.state2: Enum.c});
- /*element: Class.method1a:calls=[tester2(0)],params=0*/
+ /*member: Class.method1a:calls=[tester2(0)],params=0*/
@pragma('dart2js:noInline')
method1a() {
if (state1 == 0) {
@@ -42,7 +42,7 @@
}
// TODO(johnniwinther): Inline switch cases with constant expressions.
- /*element: Class.method1b:calls=[tester2(0)],params=0,switch*/
+ /*member: Class.method1b:calls=[tester2(0)],params=0,switch*/
@pragma('dart2js:noInline')
method1b() {
switch (state1) {
@@ -55,7 +55,7 @@
}
}
- /*element: Class.method2a:calls=[tester3(0)],params=0*/
+ /*member: Class.method2a:calls=[tester3(0)],params=0*/
@pragma('dart2js:noInline')
method2a() {
if (state2 == Enum.a) {
@@ -67,7 +67,7 @@
}
}
- /*element: Class.method2b:calls=[tester1(0),tester2(0),tester3(0)],params=0,switch*/
+ /*member: Class.method2b:calls=[tester1(0),tester2(0),tester3(0)],params=0,switch*/
@pragma('dart2js:noInline')
method2b() {
// TODO(johnniwinther): Eliminate dead code in enum switch.
@@ -82,7 +82,7 @@
}
}
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
var c = new Class();
c.method1a();
diff --git a/tests/compiler/dart2js/codegen/model_data/field_set.dart b/tests/compiler/dart2js/codegen/model_data/field_set.dart
index 2c68409..1bc4366 100644
--- a/tests/compiler/dart2js/codegen/model_data/field_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/field_set.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.
-/*element: main:access=*,calls=*,params=0*/
+/*member: main:access=*,calls=*,params=0*/
main() {
method1(new Class1a());
method2(new Class2a());
@@ -23,58 +23,58 @@
}
class Class1a {
- /*element: Class1a.field1:emitted*/
+ /*member: Class1a.field1:emitted*/
@pragma('dart2js:noElision')
int field1;
}
-/*element: method1:assign=[field1],params=1*/
+/*member: method1:assign=[field1],params=1*/
@pragma('dart2js:noInline')
method1(Class1a c) {
c.field1 = 42;
}
class Class2a {
- /*element: Class2a.field2:emitted*/
+ /*member: Class2a.field2:emitted*/
@pragma('dart2js:noElision')
int field2 = 42;
}
class Class2b extends Class2a {}
-/*element: method2:assign=[field2],params=1*/
+/*member: method2:assign=[field2],params=1*/
@pragma('dart2js:noInline')
method2(Class2a c) {
c.field2 = 42;
}
class Class3a {
- /*element: Class3a.field3:elided,set=simple*/
+ /*member: Class3a.field3:elided,set=simple*/
var field3;
}
class Class3b implements Class3a {
- /*element: Class3b.field3:emitted,set=simple*/
+ /*member: Class3b.field3:emitted,set=simple*/
var field3;
}
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
@pragma('dart2js:noInline')
method3(Class3a a) => a.field3 = 42;
class Class5a {
- /*element: Class5a.field5:elided*/
+ /*member: Class5a.field5:elided*/
int field5;
}
-/*element: method5:params=1*/
+/*member: method5:params=1*/
@pragma('dart2js:noInline')
method5(Class5a c) {
c.field5 = 42;
}
class Class6a {
- /*element: Class6a.field6:elided*/
+ /*member: Class6a.field6:elided*/
int field6 = 42;
}
@@ -82,15 +82,15 @@
@pragma('dart2js:noInline')
method6(Class6a c) {
- /*element: method6:params=1*/
+ /*member: method6:params=1*/
c.field6 = 42;
}
-/*element: field7:emitted*/
+/*member: field7:emitted*/
@pragma('dart2js:noElision')
int field7;
-/*element: method7:assign=[field7],params=0*/
+/*member: method7:assign=[field7],params=0*/
@pragma('dart2js:noInline')
method7() {
field7 = 42;
@@ -98,17 +98,17 @@
int field8;
-/*element: method8:params=0*/
+/*member: method8:params=0*/
@pragma('dart2js:noInline')
method8() {
field8 = 42;
}
-/*element: field9:emitted,lazy*/
+/*member: field9:emitted,lazy*/
@pragma('dart2js:noElision')
int field9 = throw 'field9';
-/*element: method9:assign=[field9],params=0*/
+/*member: method9:assign=[field9],params=0*/
@pragma('dart2js:noInline')
method9() {
field9 = 42;
@@ -116,7 +116,7 @@
int field10 = throw 'field9';
-/*element: method10:params=0*/
+/*member: method10:params=0*/
@pragma('dart2js:noInline')
method10() {
field10 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/fields.dart b/tests/compiler/dart2js/codegen/model_data/fields.dart
index 7815fbe..5f08845 100644
--- a/tests/compiler/dart2js/codegen/model_data/fields.dart
+++ b/tests/compiler/dart2js/codegen/model_data/fields.dart
@@ -8,7 +8,7 @@
var field1c;
-/*element: field2a:params=0*/
+/*member: field2a:params=0*/
@pragma('dart2js:noInline')
get field2a => 42;
@@ -18,30 +18,30 @@
@pragma('dart2js:noInline')
get field2b => 42;
-/*element: field2b=:params=1*/
+/*member: field2b=:params=1*/
@pragma('dart2js:noInline')
set field2b(_) {}
-/*element: field2c:params=0*/
+/*member: field2c:params=0*/
@pragma('dart2js:noInline')
get field2c => 42;
-/*element: field2c=:params=1*/
+/*member: field2c=:params=1*/
@pragma('dart2js:noInline')
set field2c(_) {}
class Class {
- /*element: Class.field1a:emitted*/
+ /*member: Class.field1a:emitted*/
@pragma('dart2js:noElision')
var field1a;
- /*element: Class.field1b:elided*/
+ /*member: Class.field1b:elided*/
var field1b;
- /*element: Class.field1c:emitted*/
+ /*member: Class.field1c:emitted*/
var field1c;
- /*element: Class.field2a:params=0*/
+ /*member: Class.field2a:params=0*/
@pragma('dart2js:noInline')
get field2a => 42;
@@ -51,27 +51,27 @@
@pragma('dart2js:noInline')
get field2b => 42;
- /*element: Class.field2b=:params=1*/
+ /*member: Class.field2b=:params=1*/
@pragma('dart2js:noInline')
set field2b(_) {}
- /*element: Class.field2c:params=0*/
+ /*member: Class.field2c:params=0*/
@pragma('dart2js:noInline')
get field2c => 42;
set field2c(_) {}
- /*element: Class.field3a:elided*/
+ /*member: Class.field3a:elided*/
var field3a = 0;
- /*element: Class.field3b:elided*/
+ /*member: Class.field3b:elided*/
var field3b;
- /*element: Class.:params=0*/
+ /*member: Class.:params=0*/
@pragma('dart2js:noInline')
Class([this.field3b]);
- /*element: Class.test:calls=[get$field2a(0),get$field2c(0),set$field2b(1)],params=0*/
+ /*member: Class.test:calls=[get$field2a(0),get$field2c(0),set$field2b(1)],params=0*/
@pragma('dart2js:noInline')
test() {
field1a;
@@ -84,7 +84,7 @@
}
}
-/*element: main:calls=[Class$(0),field2a(0),field2b(1),field2c(0),field2c0(1),test$0(0)],params=0*/
+/*member: main:calls=[Class$(0),field2a(0),field2b(1),field2c(0),field2c0(1),test$0(0)],params=0*/
main() {
field1a;
field1b = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
index aced524..4834159 100644
--- a/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
@@ -3,97 +3,97 @@
// BSD-style license that can be found in the LICENSE file.
class Class {
- /*element: Class.method1:params=0*/
+ /*member: Class.method1:params=0*/
@pragma('dart2js:noInline')
method1() {}
- /*element: Class.method2a:params=0*/
+ /*member: Class.method2a:params=0*/
@pragma('dart2js:noInline')
method2a([a]) {}
- /*element: Class.method2b:params=1*/
+ /*member: Class.method2b:params=1*/
@pragma('dart2js:noInline')
method2b([a]) {}
- /*element: Class.method2c:params=1,stubs=[method2c$0:method2c$1(1)]*/
+ /*member: Class.method2c:params=1,stubs=[method2c$0:method2c$1(1)]*/
@pragma('dart2js:noInline')
method2c([a]) {}
- /*element: Class.method3a:params=0*/
+ /*member: Class.method3a:params=0*/
@pragma('dart2js:noInline')
method3a([a, b]) {}
- /*element: Class.method3b:params=1,stubs=[method3b$0:method3b$1(1)]*/
+ /*member: Class.method3b:params=1,stubs=[method3b$0:method3b$1(1)]*/
@pragma('dart2js:noInline')
method3b([a, b]) {}
- /*element: Class.method3c:params=2*/
+ /*member: Class.method3c:params=2*/
@pragma('dart2js:noInline')
method3c([a, b]) {}
- /*element: Class.method4a:params=0*/
+ /*member: Class.method4a:params=0*/
@pragma('dart2js:noInline')
method4a({a}) {}
- /*element: Class.method4b:params=1*/
+ /*member: Class.method4b:params=1*/
@pragma('dart2js:noInline')
method4b({a}) {}
- /*element: Class.method4c:params=1,stubs=[method4c$0:method4c$1$a(1)]*/
+ /*member: Class.method4c:params=1,stubs=[method4c$0:method4c$1$a(1)]*/
@pragma('dart2js:noInline')
method4c({a}) {}
- /*element: Class.method5a:params=0*/
+ /*member: Class.method5a:params=0*/
@pragma('dart2js:noInline')
method5a({a, b}) {}
- /*element: Class.method5b:params=1*/
+ /*member: Class.method5b:params=1*/
@pragma('dart2js:noInline')
method5b({a, b}) {}
- /*element: Class.method5c:params=1*/
+ /*member: Class.method5c:params=1*/
@pragma('dart2js:noInline')
method5c({a, b}) {}
- /*element: Class.method6a:params=0,stubs=[method6a$0:method6a$1$0(1)]*/
+ /*member: Class.method6a:params=0,stubs=[method6a$0:method6a$1$0(1)]*/
@pragma('dart2js:noInline')
method6a<T>() {}
- /*element: Class.method7a:params=1*/
+ /*member: Class.method7a:params=1*/
@pragma('dart2js:noInline')
method7a(a, [b, c]) {}
- /*element: Class.method7b:params=2,stubs=[method7b$1:method7b$2(2)]*/
+ /*member: Class.method7b:params=2,stubs=[method7b$1:method7b$2(2)]*/
@pragma('dart2js:noInline')
method7b(a, [b, c]) {}
- /*element: Class.method7c:params=3*/
+ /*member: Class.method7c:params=3*/
@pragma('dart2js:noInline')
method7c(a, [b, c]) {}
- /*element: Class.method8a:params=1*/
+ /*member: Class.method8a:params=1*/
@pragma('dart2js:noInline')
method8a(a, {b, c}) {}
- /*element: Class.method8b:params=2*/
+ /*member: Class.method8b:params=2*/
@pragma('dart2js:noInline')
method8b(a, {b, c}) {}
- /*element: Class.method8c:params=2*/
+ /*member: Class.method8c:params=2*/
@pragma('dart2js:noInline')
method8c(a, {b, c}) {}
- /*element: Class.method9a:params=2,stubs=[method9a$0:method9a$2(2)]*/
+ /*member: Class.method9a:params=2,stubs=[method9a$0:method9a$2(2)]*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
method9a([a, b]) {}
- /*element: Class.method9b:params=2,stubs=[method9b$0:method9b$2$a$b(2)]*/
+ /*member: Class.method9b:params=2,stubs=[method9b$0:method9b$2$a$b(2)]*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
method9b({a, b}) {}
- /*element: Class.test:calls=*,params=0*/
+ /*member: Class.test:calls=*,params=0*/
@pragma('dart2js:noInline')
test() {
method1();
@@ -133,7 +133,7 @@
}
}
-/*element: main:calls=[test$0(0)],params=0*/
+/*member: main:calls=[test$0(0)],params=0*/
main() {
new Class().test();
}
diff --git a/tests/compiler/dart2js/codegen/model_data/native.dart b/tests/compiler/dart2js/codegen/model_data/native.dart
index 23dcd6e..02cae6f 100644
--- a/tests/compiler/dart2js/codegen/model_data/native.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native.dart
@@ -16,7 +16,7 @@
int field2;
- /*element: Class.method1:
+ /*member: Class.method1:
calls=[method1(a,b,c)],
params=4,
stubs=[
@@ -28,7 +28,7 @@
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
- /*element: Class.method2:
+ /*member: Class.method2:
calls=[method2(a,b,c)],
params=4,
stubs=[
@@ -44,7 +44,7 @@
// TODO(johnniwinther): Control the order of the named arguments. Currently
// we sort them lexicographically but that doesn't match the target
// expectations.
- /*element: Class.method3:
+ /*member: Class.method3:
calls=[method3(a,c,b)],
params=4,
stubs=[
@@ -60,7 +60,7 @@
// TODO(johnniwinther): Control the order of the named arguments. Currently
// we sort them lexicographically but that doesn't match the target
// expectations.
- /*element: Class.method4:
+ /*member: Class.method4:
calls=[method4(a,c,d,b)],
params=5,
stubs=[
@@ -77,18 +77,18 @@
native;
}
-/*element: makeClass:params=0*/
+/*member: makeClass:params=0*/
@Creates('Class')
makeClass()
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
-/*element: main:calls=[test(1),*],params=0*/
+/*member: main:calls=[test(1),*],params=0*/
main() {
test(makeClass());
}
-/*element: test:
+/*member: test:
assign=[field1,field2],
calls=[
method1$1(2),
diff --git a/tests/compiler/dart2js/codegen/model_data/native_inlined.dart b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
index 7e99271..63d5cd6 100644
--- a/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
@@ -15,7 +15,7 @@
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
- /*element: Class.method2:
+ /*member: Class.method2:
calls=[method2(a,b,c)],
params=4,
stubs=[
@@ -30,7 +30,7 @@
// TODO(johnniwinther): Control the order of the named arguments. Currently
// we sort them lexicographically but that doesn't match the target
// expectations.
- /*element: Class.method3:
+ /*member: Class.method3:
calls=[method3(a,c,b)],
params=4,
stubs=[
@@ -45,7 +45,7 @@
// TODO(johnniwinther): Control the order of the named arguments. Currently
// we sort them lexicographically but that doesn't match the target
// expectations.
- /*element: Class.method4:
+ /*member: Class.method4:
calls=[method4(a,c,d,b)],
params=5,
stubs=[
@@ -61,18 +61,18 @@
native;
}
-/*element: makeClass:params=0*/
+/*member: makeClass:params=0*/
@Creates('Class')
makeClass()
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
-/*element: main:calls=[test(1),*],params=0*/
+/*member: main:calls=[test(1),*],params=0*/
main() {
test(makeClass());
}
-/*element: test:
+/*member: test:
calls=[
method1(0),
method1(0,1),
diff --git a/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
index 9317686..33e8453 100644
--- a/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
@@ -5,28 +5,28 @@
// ignore: import_internal_library
import 'dart:_js_helper';
-/*element: Class.:access=[toString],params=1*/
+/*member: Class.:access=[toString],params=1*/
@Native('Class')
class Class {
- /*element: Class.method1:calls=[method1()],params=1*/
+ /*member: Class.method1:calls=[method1()],params=1*/
@pragma('dart2js:noInline')
method1([a, b])
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method2:calls=[method2(a)],params=2*/
+ /*member: Class.method2:calls=[method2(a)],params=2*/
@pragma('dart2js:noInline')
method2([a, b])
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method3:calls=[method3(a,b)],params=3*/
+ /*member: Class.method3:calls=[method3(a,b)],params=3*/
@pragma('dart2js:noInline')
method3([a, b])
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method4:
+ /*member: Class.method4:
calls=[method4(a,b)],
params=3,
stubs=[method4$0:method4()]
@@ -36,7 +36,7 @@
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method5:
+ /*member: Class.method5:
calls=[method5(a,b)],
params=3,
stubs=[method5$1:method5(a)]
@@ -46,7 +46,7 @@
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method6:
+ /*member: Class.method6:
calls=[method6(a,b,c)],
params=4,
stubs=[method6$1:method6(a)]
@@ -56,7 +56,7 @@
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method7:
+ /*member: Class.method7:
calls=[method7(a,b,c)],
params=4,
stubs=[method7$2$b:method7(a,b)]
@@ -66,7 +66,7 @@
// ignore: native_function_body_in_non_sdk_code
native;
- /*element: Class.method8:
+ /*member: Class.method8:
calls=[method8(a,b,c)],
params=4,
stubs=[
@@ -79,7 +79,7 @@
native;
}
-/*element: test:
+/*member: test:
calls=[
method1$0(1),
method2$1(2),
@@ -113,7 +113,7 @@
c.method8(null, c: null);
}
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
main() {
test(new Class());
}
diff --git a/tests/compiler/dart2js/codegen/model_data/regress_36222.dart b/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
index 8ab6ea3..6b2143d 100644
--- a/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
+++ b/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
@@ -7,21 +7,21 @@
class A {
const A({this.foo = A.defaultFoo});
- /*element: A.defaultFoo:params=2*/
+ /*member: A.defaultFoo:params=2*/
static int defaultFoo(int x, int y) {
return x + y;
}
- /*element: A.foo:elided,stubCalls=[foo$2:call$2(arg0,arg1),foo$2:main_A_defaultFoo$closure(0)]*/
+ /*member: A.foo:elided,stubCalls=[foo$2:call$2(arg0,arg1),foo$2:main_A_defaultFoo$closure(0)]*/
final BinaryFunc foo;
}
-/*element: test:calls=[foo$2(2)],params=1*/
+/*member: test:calls=[foo$2(2)],params=1*/
@pragma('dart2js:assumeDynamic')
@pragma('dart2js:noInline')
test(dynamic a) => a.foo(1, 2);
-/*element: main:calls=[test(1)],params=0*/
+/*member: main:calls=[test(1)],params=0*/
main() {
test(new A());
}
diff --git a/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
index b95aa11..31b2433 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
@@ -2,97 +2,97 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method1:params=0*/
+/*member: method1:params=0*/
@pragma('dart2js:noInline')
method1() {}
-/*element: method2a:params=0*/
+/*member: method2a:params=0*/
@pragma('dart2js:noInline')
method2a([a]) {}
-/*element: method2b:params=1*/
+/*member: method2b:params=1*/
@pragma('dart2js:noInline')
method2b([a]) {}
-/*element: method2c:params=1*/
+/*member: method2c:params=1*/
@pragma('dart2js:noInline')
method2c([a]) {}
-/*element: method3a:params=0*/
+/*member: method3a:params=0*/
@pragma('dart2js:noInline')
method3a([a, b]) {}
-/*element: method3b:params=1*/
+/*member: method3b:params=1*/
@pragma('dart2js:noInline')
method3b([a, b]) {}
-/*element: method3c:params=2*/
+/*member: method3c:params=2*/
@pragma('dart2js:noInline')
method3c([a, b]) {}
-/*element: method4a:params=0*/
+/*member: method4a:params=0*/
@pragma('dart2js:noInline')
method4a({a}) {}
-/*element: method4b:params=1*/
+/*member: method4b:params=1*/
@pragma('dart2js:noInline')
method4b({a}) {}
-/*element: method4c:params=1*/
+/*member: method4c:params=1*/
@pragma('dart2js:noInline')
method4c({a}) {}
-/*element: method5a:params=0*/
+/*member: method5a:params=0*/
@pragma('dart2js:noInline')
method5a({a, b}) {}
-/*element: method5b:params=1*/
+/*member: method5b:params=1*/
@pragma('dart2js:noInline')
method5b({a, b}) {}
-/*element: method5c:params=1*/
+/*member: method5c:params=1*/
@pragma('dart2js:noInline')
method5c({a, b}) {}
-/*element: method6a:params=0*/
+/*member: method6a:params=0*/
@pragma('dart2js:noInline')
method6a<T>() {}
-/*element: method7a:params=1*/
+/*member: method7a:params=1*/
@pragma('dart2js:noInline')
method7a(a, [b, c]) {}
-/*element: method7b:params=2*/
+/*member: method7b:params=2*/
@pragma('dart2js:noInline')
method7b(a, [b, c]) {}
-/*element: method7c:params=3*/
+/*member: method7c:params=3*/
@pragma('dart2js:noInline')
method7c(a, [b, c]) {}
-/*element: method8a:params=1*/
+/*member: method8a:params=1*/
@pragma('dart2js:noInline')
method8a(a, {b, c}) {}
-/*element: method8b:params=2*/
+/*member: method8b:params=2*/
@pragma('dart2js:noInline')
method8b(a, {b, c}) {}
-/*element: method8c:params=2*/
+/*member: method8c:params=2*/
@pragma('dart2js:noInline')
method8c(a, {b, c}) {}
-/*element: method9a:params=2*/
+/*member: method9a:params=2*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
method9a([a, b]) {}
-/*element: method9b:params=2*/
+/*member: method9b:params=2*/
@pragma('dart2js:noInline')
@pragma('dart2js:noElision')
method9b({a, b}) {}
-/*element: main:
+/*member: main:
calls=[
method1(0),
method2a(0),
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
index 75fa653..524b200 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -10,18 +10,18 @@
class B implements I1, I2 {}
-/*element: foo:params=1*/
+/*member: foo:params=1*/
@pragma('dart2js:noInline')
void foo(I1 x) {}
-/*element: bar:params=1*/
+/*member: bar:params=1*/
@pragma('dart2js:noInline')
void bar(I2 x) {}
-/*strong.element: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*omit.element: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*strongConst.element: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
-/*omitConst.element: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*strong.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
+/*omit.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
+/*strongConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*omitConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
main() {
dynamic f = bar;
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
index c10e7bd..c8e9b8e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
@@ -4,8 +4,8 @@
import '../libs/basic_deferred_lib.dart' deferred as lib;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[FunctionConstant(funky)=OutputUnit(1, {lib})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
index b688215..6bd1661 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
@@ -4,7 +4,7 @@
import '../libs/deferred_class_library.dart' deferred as lib;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() {
lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
return new lib.MyClass().foo(87);
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
index ccada1f..1ed34b3 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
@@ -5,8 +5,8 @@
import '../libs/deferred_constant1_lib1.dart';
import '../libs/deferred_constant1_lib2.dart' deferred as lib2;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(C(value=ConstructedConstant(C(value=IntConstant(7)))))=OutputUnit(1, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
index 5a08d48..8306e71 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
@@ -6,8 +6,8 @@
import '../libs/deferred_constant2_lib.dart' deferred as lib;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(Constant(value=IntConstant(499)))=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
index 27c1129..17a05a9 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
@@ -5,11 +5,11 @@
import '../libs/deferred_constant3_shared.dart';
import '../libs/deferred_constant3_lib1.dart' deferred as l1;
-/*strong.element: c1:OutputUnit(main, {})*/
+/*strong.member: c1:OutputUnit(main, {})*/
const c1 = /*strong.OutputUnit(main, {})*/ const C(1);
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
index 80b59bf..cd5ae14 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
@@ -9,7 +9,7 @@
import "package:async_helper/async_helper.dart";
import "dart:js" as js;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() {
// We patch document.body.appendChild to change the script src on first
// invocation.
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
index 89cedc8..47ecc4e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
@@ -7,8 +7,8 @@
import '../libs/deferred_function_lib.dart' deferred as lib;
-/*strong.element: readFoo:OutputUnit(main, {})*/
-/*strongConst.element: readFoo:
+/*strong.member: readFoo:OutputUnit(main, {})*/
+/*strongConst.member: readFoo:
OutputUnit(main, {}),
constants=[FunctionConstant(foo)=OutputUnit(1, {lib})]
*/
@@ -16,7 +16,7 @@
return lib.foo;
}
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() {
lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
lib.foo('b');
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
index 754ee48..7919162 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
@@ -6,7 +6,7 @@
import "../libs/deferred_overlapping_lib2.dart" deferred as lib2;
// lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk.
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
void main() {
lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
new lib1.C1();
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
index 2aca8d8..deed5a1 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
@@ -4,8 +4,8 @@
import '../libs/deferred_typed_map_lib1.dart' deferred as lib;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
MapConstant(<int, dynamic Function({M b})>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
index 90343e4..23578ec 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
@@ -4,8 +4,8 @@
import '../libs/deferred_typedef_lib1.dart' deferred as lib1;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(C(a=TypeConstant(void Function()),b=FunctionConstant(topLevelMethod)))=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
index 3e42dd2..8dab5c6 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
@@ -4,7 +4,7 @@
import '../libs/dont_inline_deferred_global_lib.dart' deferred as lib;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
void main() {
lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
print(lib.finalVar);
diff --git a/tests/compiler/dart2js/deferred_loading/data/future_or.dart b/tests/compiler/dart2js/deferred_loading/data/future_or.dart
index 5927f8b..a31156a 100644
--- a/tests/compiler/dart2js/deferred_loading/data/future_or.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/future_or.dart
@@ -6,8 +6,8 @@
import '../libs/future_or_lib1.dart' deferred as lib1;
import '../libs/future_or_lib2.dart' as lib2;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[ConstructedConstant(A())=OutputUnit(1, {lib1})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
index 0e41e0c..8e008fc 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
@@ -9,7 +9,7 @@
import '../libs/instantiation0_strong_lib1.dart' deferred as b;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
print(b.m(3));
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
index feaa5cd..174bc54c 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
@@ -12,7 +12,7 @@
import '../libs/instantiation1_strong_lib1.dart' deferred as b;
import '../libs/instantiation1_strong_lib2.dart' deferred as c;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
index 198ec06..bd99ede 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
@@ -11,7 +11,7 @@
import '../libs/instantiation2_strong_lib1.dart' deferred as b;
import '../libs/instantiation2_strong_lib2.dart' deferred as c;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
index 578710e..dcc3b55 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
@@ -7,11 +7,11 @@
/*class: global#Instantiation:OutputUnit(1, {b})*/
/*class: global#Instantiation1:OutputUnit(1, {b})*/
-/*element: global#instantiate1:OutputUnit(1, {b})*/
+/*member: global#instantiate1:OutputUnit(1, {b})*/
import '../libs/instantiation3_strong_lib1.dart' deferred as b;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
print(b.m(3));
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
index b7ed01a..4fe43c2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
@@ -9,13 +9,13 @@
/*class: global#Instantiation1:OutputUnit(1, {b})*/
/*class: global#Instantiation2:OutputUnit(3, {c})*/
-/*element: global#instantiate1:OutputUnit(1, {b})*/
-/*element: global#instantiate2:OutputUnit(3, {c})*/
+/*member: global#instantiate1:OutputUnit(1, {b})*/
+/*member: global#instantiate2:OutputUnit(3, {c})*/
import '../libs/instantiation4_strong_lib1.dart' deferred as b;
import '../libs/instantiation4_strong_lib2.dart' deferred as c;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
index 785b6bf..6397d89 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
@@ -8,12 +8,12 @@
/*class: global#Instantiation:OutputUnit(1, {b, c})*/
/*class: global#Instantiation1:OutputUnit(1, {b, c})*/
-/*element: global#instantiate1:OutputUnit(1, {b, c})*/
+/*member: global#instantiate1:OutputUnit(1, {b, c})*/
import '../libs/instantiation5_strong_lib1.dart' deferred as b;
import '../libs/instantiation5_strong_lib2.dart' deferred as c;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await b.loadLibrary();
await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
index a1bccc0..c082a4d 100644
--- a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
@@ -11,7 +11,7 @@
import '../libs/shared_constant_a.dart';
import '../libs/shared_constant_b.dart';
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
(await doA()).method();
await doB();
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
index 1f5a958..22404aa 100644
--- a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
@@ -12,7 +12,7 @@
import "../libs/static_separate_lib1.dart" deferred as lib1;
import "../libs/static_separate_lib2.dart" deferred as lib2;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
void main() {
asyncStart();
Expect.throws(/*OutputUnit(main, {})*/ () {
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
index 80026e3..b64e30e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
@@ -5,7 +5,7 @@
import '../libs/type_argument_dependency_lib1.dart';
import '../libs/type_argument_dependency_lib2.dart' deferred as c;
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
main() async {
await c.loadLibrary();
c.createA();
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
index 14f63696..a39b055 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
@@ -6,8 +6,8 @@
import '../libs/type_arguments_lib2.dart' as lib2;
import '../libs/type_arguments_lib3.dart' deferred as lib3;
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(A<B>())=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index b23c178..880c642 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -216,6 +216,7 @@
Expect.fail("Duplicate id $id.");
}
if (value != null) {
- actualMap[id] = new ActualData<T>(id, value, sourceSpan, object);
+ actualMap[id] =
+ new ActualData<T>(id, value, sourceSpan.uri, sourceSpan.begin, object);
}
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
index 0091deb..25d4ccd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
@@ -2,11 +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.
-/*element: defaultArg:OutputUnit(1, {lib})*/
+/*member: defaultArg:OutputUnit(1, {lib})*/
defaultArg() => "";
-/*strong.element: funky:OutputUnit(1, {lib})*/
-/*strongConst.element: funky:
+/*strong.member: funky:OutputUnit(1, {lib})*/
+/*strongConst.member: funky:
OutputUnit(1, {lib}),
constants=[FunctionConstant(defaultArg)=OutputUnit(1, {lib})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
index 3e359eb..4910c2a 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
@@ -8,10 +8,10 @@
/*class: MyClass:OutputUnit(1, {lib})*/
class MyClass {
- /*element: MyClass.:OutputUnit(1, {lib})*/
+ /*member: MyClass.:OutputUnit(1, {lib})*/
const MyClass();
- /*element: MyClass.foo:OutputUnit(1, {lib})*/
+ /*member: MyClass.foo:OutputUnit(1, {lib})*/
foo(x) {
print('MyClass.foo($x)');
return (x - 3) ~/ 2;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
index c304f13..afd84b4 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
@@ -6,9 +6,9 @@
/*class: C:OutputUnit(main, {})*/
class C {
- /*element: C.value:OutputUnit(main, {})*/
+ /*member: C.value:OutputUnit(main, {})*/
final value;
- /*strong.element: C.:OutputUnit(main, {})*/
+ /*strong.member: C.:OutputUnit(main, {})*/
const C(this.value);
}
@@ -16,14 +16,14 @@
/// Constant used from main: not deferred.
/// ---------------------------------------------------------------------------
-/*strong.element: C1:OutputUnit(main, {})*/
+/*strong.member: C1:OutputUnit(main, {})*/
const C1 = /*strong.OutputUnit(main, {})*/ const C(1);
/// ---------------------------------------------------------------------------
/// Constant completely deferred.
/// ---------------------------------------------------------------------------
-/*strong.element: C2:OutputUnit(1, {lib2})*/
+/*strong.member: C2:OutputUnit(1, {lib2})*/
const C2 = /*strong.OutputUnit(1, {lib2})*/ const C(2);
/// ---------------------------------------------------------------------------
@@ -31,25 +31,25 @@
/// and the constants are in different output units.
/// ---------------------------------------------------------------------------
-/*strong.element: C3:OutputUnit(1, {lib2})*/
+/*strong.member: C3:OutputUnit(1, {lib2})*/
const C3 = /*strong.OutputUnit(main, {})*/ const C(1);
-/*strong.element: C4:OutputUnit(1, {lib2})*/
+/*strong.member: C4:OutputUnit(1, {lib2})*/
const C4 = /*strong.OutputUnit(main, {})*/ const C(4);
/// ---------------------------------------------------------------------------
/// Constant value used form a closure within main.
/// ---------------------------------------------------------------------------
-/*strong.element: C5:OutputUnit(1, {lib2})*/
+/*strong.member: C5:OutputUnit(1, {lib2})*/
const C5 = /*strong.OutputUnit(main, {})*/ const C(5);
/// ---------------------------------------------------------------------------
/// Deferred constants, used after a deferred load.
/// ---------------------------------------------------------------------------
-/*strong.element: C6:OutputUnit(1, {lib2})*/
+/*strong.member: C6:OutputUnit(1, {lib2})*/
const C6 = "string6";
-/*strong.element: C7:OutputUnit(1, {lib2})*/
+/*strong.member: C7:OutputUnit(1, {lib2})*/
const C7 = /*strong.OutputUnit(1, {lib2})*/ const C(const C(7));
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
index 12221777..dc1516d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
@@ -6,16 +6,16 @@
/*class: Constant:OutputUnit(1, {lib})*/
class Constant {
- /*element: Constant.value:OutputUnit(1, {lib})*/
+ /*member: Constant.value:OutputUnit(1, {lib})*/
final value;
- /*strong.element: Constant.:OutputUnit(1, {lib})*/
+ /*strong.member: Constant.:OutputUnit(1, {lib})*/
const Constant(this.value);
- /*element: Constant.==:OutputUnit(1, {lib})*/
+ /*member: Constant.==:OutputUnit(1, {lib})*/
operator ==(other) => other is Constant && value == other.value;
- /*element: Constant.hashCode:OutputUnit(1, {lib})*/
+ /*member: Constant.hashCode:OutputUnit(1, {lib})*/
get hashCode => 0;
}
-/*strong.element: C1:OutputUnit(1, {lib})*/
+/*strong.member: C1:OutputUnit(1, {lib})*/
const C1 = /*strong.OutputUnit(1, {lib})*/ const Constant(499);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
index ad37207..2edad58 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
@@ -5,14 +5,14 @@
import 'deferred_constant3_shared.dart';
import 'deferred_constant3_lib2.dart' deferred as l2;
-/*strong.element: c2:OutputUnit(1, {l1})*/
+/*strong.member: c2:OutputUnit(1, {l1})*/
const c2 = /*strong.OutputUnit(1, {l1})*/ const C(2);
-/*strong.element: c3:OutputUnit(1, {l1})*/
+/*strong.member: c3:OutputUnit(1, {l1})*/
const c3 = /*strong.OutputUnit(1, {l1})*/ const C(3);
-/*strong.element: m1:OutputUnit(1, {l1})*/
-/*strongConst.element: m1:
+/*strong.member: m1:OutputUnit(1, {l1})*/
+/*strongConst.member: m1:
OutputUnit(1, {l1}),
constants=[
ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
index b834b48..7dbbe8b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
@@ -4,17 +4,17 @@
import 'deferred_constant3_shared.dart';
-/*strong.element: c3:OutputUnit(2, {l2})*/
+/*strong.member: c3:OutputUnit(2, {l2})*/
const c3 = /*strong.OutputUnit(main, {})*/ const C(1);
-/*strong.element: c4:OutputUnit(2, {l2})*/
+/*strong.member: c4:OutputUnit(2, {l2})*/
const c4 = /*strong.OutputUnit(2, {l2})*/ const C(4);
-/*strong.element: c5:OutputUnit(2, {l2})*/
+/*strong.member: c5:OutputUnit(2, {l2})*/
const c5 = /*strong.OutputUnit(2, {l2})*/ const C(5);
-/*strong.element: m2:OutputUnit(2, {l2})*/
-/*strongConst.element: m2:
+/*strong.member: m2:OutputUnit(2, {l2})*/
+/*strongConst.member: m2:
OutputUnit(2, {l2}),
constants=[
ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
index d4480d1..f2a7bdd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
@@ -4,9 +4,9 @@
/*class: C:OutputUnit(main, {})*/
class C {
- /*strong.element: C.:OutputUnit(main, {})*/
+ /*strong.member: C.:OutputUnit(main, {})*/
const C(this.x);
- /*element: C.x:OutputUnit(main, {})*/
+ /*member: C.x:OutputUnit(main, {})*/
final x;
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
index ed22832..e2bccb3 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.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.
-/*element: foo:OutputUnit(1, {lib})*/
+/*member: foo:OutputUnit(1, {lib})*/
foo() {
return "loaded";
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
index 5d40356..1424c6a 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
@@ -6,7 +6,7 @@
library deferred_function_library;
-/*element: foo:OutputUnit(1, {lib})*/
+/*member: foo:OutputUnit(1, {lib})*/
foo(x) {
print('foo($x)');
return 42;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
index 194e27d..47d7393 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
@@ -5,5 +5,5 @@
import "deferred_overlapping_lib3.dart";
/*class: C1:OutputUnit(2, {lib1})*/
-/*element: C1.:OutputUnit(2, {lib1})*/
+/*member: C1.:OutputUnit(2, {lib1})*/
class C1 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
index 3e49d22..10073a0 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
@@ -5,5 +5,5 @@
import "deferred_overlapping_lib3.dart";
/*class: C2:OutputUnit(3, {lib2})*/
-/*element: C2.:OutputUnit(3, {lib2})*/
+/*member: C2.:OutputUnit(3, {lib2})*/
class C2 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
index 5167cc6..43a1071 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
@@ -3,5 +3,5 @@
// BSD-style license that can be found in the LICENSE file.
/*class: C3:OutputUnit(1, {lib1, lib2})*/
-/*element: C3.:OutputUnit(1, {lib1, lib2})*/
+/*member: C3.:OutputUnit(1, {lib1, lib2})*/
class C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
index cec8198..b435e6d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
@@ -7,13 +7,13 @@
typedef dynamic FF({M b});
-/*strong.element: table:OutputUnit(1, {lib})*/
+/*strong.member: table:OutputUnit(1, {lib})*/
const table =
/*strong.OutputUnit(1, {lib})*/
const <int, FF>{1: f1, 2: f2};
-/*element: f1:OutputUnit(1, {lib})*/
+/*member: f1:OutputUnit(1, {lib})*/
dynamic f1({M b}) => null;
-/*element: f2:OutputUnit(1, {lib})*/
+/*member: f2:OutputUnit(1, {lib})*/
dynamic f2({M b}) => null;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
index e8b71f2..4cdfe95 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
@@ -6,13 +6,13 @@
/*class: C:OutputUnit(1, {lib1})*/
class C {
- /*element: C.a:OutputUnit(1, {lib1})*/
+ /*member: C.a:OutputUnit(1, {lib1})*/
final a;
- /*element: C.b:OutputUnit(1, {lib1})*/
+ /*member: C.b:OutputUnit(1, {lib1})*/
final b;
- /*strong.element: C.:OutputUnit(1, {lib1})*/
+ /*strong.member: C.:OutputUnit(1, {lib1})*/
const C(this.a, this.b);
}
@@ -20,11 +20,11 @@
typedef void MyF2();
-/*element: topLevelMethod:OutputUnit(1, {lib1})*/
+/*member: topLevelMethod:OutputUnit(1, {lib1})*/
topLevelMethod() {}
-/*strong.element: cA:OutputUnit(1, {lib1})*/
+/*strong.member: cA:OutputUnit(1, {lib1})*/
const cA = /*strong.OutputUnit(1, {lib1})*/ const C(MyF1, topLevelMethod);
-/*strong.element: cB:OutputUnit(1, {lib1})*/
+/*strong.member: cB:OutputUnit(1, {lib1})*/
const cB = /*strong.OutputUnit(1, {lib1})*/ MyF2;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
index a207e12..837d58c 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
@@ -5,37 +5,37 @@
import "dont_inline_deferred_constants_main.dart" show C;
import "dont_inline_deferred_constants_main.dart" as main;
-/*strong.element: C1:OutputUnit(1, {lib1})*/
+/*strong.member: C1:OutputUnit(1, {lib1})*/
const C1 = "string1";
-/*strong.element: C1b:OutputUnit(1, {lib1})*/
+/*strong.member: C1b:OutputUnit(1, {lib1})*/
const C1b = /*strong.OutputUnit(1, {lib1})*/ const C("string1");
-/*strong.element: C2:OutputUnit(1, {lib1})*/
+/*strong.member: C2:OutputUnit(1, {lib1})*/
const C2 = 1010;
-/*strong.element: C2b:OutputUnit(1, {lib1})*/
+/*strong.member: C2b:OutputUnit(1, {lib1})*/
const C2b = /*strong.OutputUnit(1, {lib1})*/ const C(1010);
/*class: D:null*/
class D {
- /*strong.element: D.C3:OutputUnit(1, {lib1})*/
+ /*strong.member: D.C3:OutputUnit(1, {lib1})*/
static const C3 = "string2";
- /*strong.element: D.C3b:OutputUnit(1, {lib1})*/
+ /*strong.member: D.C3b:OutputUnit(1, {lib1})*/
static const C3b = /*strong.OutputUnit(1, {lib1})*/ const C("string2");
}
-/*strong.element: C4:OutputUnit(1, {lib1})*/
+/*strong.member: C4:OutputUnit(1, {lib1})*/
const C4 = "string4";
-/*strong.element: C5:OutputUnit(1, {lib1})*/
+/*strong.member: C5:OutputUnit(1, {lib1})*/
const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
-/*strong.element: C6:OutputUnit(1, {lib1})*/
+/*strong.member: C6:OutputUnit(1, {lib1})*/
const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
-/*element: foo:OutputUnit(1, {lib1})*/
+/*member: foo:OutputUnit(1, {lib1})*/
foo() {
print("lib1");
main.foo();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
index 79948c6..f475d99 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
@@ -5,16 +5,16 @@
import "dont_inline_deferred_constants_main.dart" show C;
import "dont_inline_deferred_constants_main.dart" as main;
-/*strong.element: C4:OutputUnit(3, {lib2})*/
+/*strong.member: C4:OutputUnit(3, {lib2})*/
const C4 = "string4";
-/*strong.element: C5:OutputUnit(3, {lib2})*/
+/*strong.member: C5:OutputUnit(3, {lib2})*/
const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
-/*strong.element: C6:OutputUnit(3, {lib2})*/
+/*strong.member: C6:OutputUnit(3, {lib2})*/
const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
-/*element: foo:OutputUnit(3, {lib2})*/
+/*member: foo:OutputUnit(3, {lib2})*/
foo() {
print("lib2");
main.foo();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
index ae08f33..552be6b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
@@ -5,23 +5,23 @@
import 'dont_inline_deferred_constants_lib1.dart' deferred as lib1;
import 'dont_inline_deferred_constants_lib2.dart' deferred as lib2;
-/*strong.element: c:OutputUnit(main, {})*/
+/*strong.member: c:OutputUnit(main, {})*/
const c = "string3";
/*class: C:OutputUnit(main, {})*/
class C {
- /*element: C.p:OutputUnit(main, {})*/
+ /*member: C.p:OutputUnit(main, {})*/
final p;
- /*strong.element: C.:OutputUnit(main, {})*/
+ /*strong.member: C.:OutputUnit(main, {})*/
const C(this.p);
}
-/*element: foo:OutputUnit(2, {lib1, lib2})*/
+/*member: foo:OutputUnit(2, {lib1, lib2})*/
foo() => print("main");
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
OutputUnit(main, {}),
constants=[
ConstructedConstant(C(p=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
index 626b672..262c084 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
@@ -2,8 +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.
-/*element: finalVar:OutputUnit(1, {lib})*/
+/*member: finalVar:OutputUnit(1, {lib})*/
final finalVar = "string1";
-/*element: globalVar:OutputUnit(1, {lib})*/
+/*member: globalVar:OutputUnit(1, {lib})*/
var globalVar = "string2";
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
index a5bf524..c11d4b8 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
@@ -4,5 +4,5 @@
import 'future_or_lib2.dart';
-/*strong.element: field:OutputUnit(1, {lib1})*/
+/*strong.member: field:OutputUnit(1, {lib1})*/
const dynamic field = /*strong.OutputUnit(1, {lib1})*/ const A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
index 3c7fcbc..634a6b4 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
@@ -4,9 +4,9 @@
/*class: A:OutputUnit(main, {})*/
class A {
- /*strong.element: A.:OutputUnit(1, {lib1})*/
+ /*strong.member: A.:OutputUnit(1, {lib1})*/
const A();
- /*element: A.method:OutputUnit(main, {})*/
+ /*member: A.method:OutputUnit(main, {})*/
method() {}
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
index 67ababf..533595e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
OutputUnit(1, {b}),
constants=[InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
index 0124514..03ca1d9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
OutputUnit(1, {b}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
index 4f60650..eaf6318 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
T getFoo<T, S>(T v, S w) => v;
typedef dynamic G<T, S>(T v, S w);
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
OutputUnit(3, {c}),
constants=[
InstantiationConstant([int, int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
index 4a7f401..a5b2423 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(2, {b})*/
+/*member: getFoo:OutputUnit(2, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(2, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(2, {b})*/
+/*strongConst.member: m:
OutputUnit(2, {b}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(2, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
index 6b47d58..7e50462 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
OutputUnit(3, {c}),
constants=[
InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
index 89af87b..74a68cb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
OutputUnit(1, {b}),
constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
index 89af87b..74a68cb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
OutputUnit(1, {b}),
constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
index 3d0891b..d1ac5bc 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
T getFoo<T, S>(T v, S w) => v;
typedef dynamic G<T, S>(T v, S w);
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
OutputUnit(3, {c}),
constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
index dd75082..18813d7 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(2, {b})*/
+/*member: getFoo:OutputUnit(2, {b})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(2, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(2, {b})*/
+/*strongConst.member: m:
OutputUnit(2, {b}),
constants=[FunctionConstant(getFoo)=OutputUnit(2, {b})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
index 17a6fdc..ddc4f0e9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
@@ -2,13 +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.
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
T getFoo<T>(T v) => v;
typedef dynamic G<T>(T v);
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
OutputUnit(3, {c}),
constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
index dc47eae..7a5817c 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
@@ -4,8 +4,8 @@
import 'shared_constant_shared.dart' deferred as s1;
-/*strong.element: doA:OutputUnit(main, {})*/
-/*strongConst.element: doA:
+/*strong.member: doA:OutputUnit(main, {})*/
+/*strongConst.member: doA:
OutputUnit(main, {}),
constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
index 8ec4363..e4cd5e7 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
@@ -4,8 +4,8 @@
import 'shared_constant_shared.dart' deferred as s2;
-/*strong.element: doB:OutputUnit(main, {})*/
-/*strongConst.element: doB:
+/*strong.member: doB:OutputUnit(main, {})*/
+/*strongConst.member: doB:
OutputUnit(main, {}),
constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
*/
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
index 5c7759a..8d1d346 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
@@ -4,9 +4,9 @@
/*class: C:OutputUnit(1, {s1, s2})*/
class C {
- /*strong.element: C.:OutputUnit(1, {s1, s2})*/
+ /*strong.member: C.:OutputUnit(1, {s1, s2})*/
const C();
- /*element: C.method:OutputUnit(1, {s1, s2})*/
+ /*member: C.method:OutputUnit(1, {s1, s2})*/
method() => print("1");
}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
index b29aeba..d11cc9e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
@@ -4,6 +4,6 @@
import 'shared_constant_c.dart';
-/*strong.element: constant:OutputUnit(1, {s1, s2})*/
+/*strong.member: constant:OutputUnit(1, {s1, s2})*/
const constant =
/*strong.OutputUnit(1, {s1, s2})*/ const C();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
index 4707d65..f61fbe9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
@@ -6,15 +6,15 @@
/*class: ConstClass:OutputUnit(2, {lib1, lib2})*/
class ConstClass {
- /*element: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
+ /*member: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
final x;
- /*strong.element: ConstClass.:OutputUnit(2, {lib1, lib2})*/
+ /*strong.member: ConstClass.:OutputUnit(2, {lib1, lib2})*/
const ConstClass(this.x);
}
-/*strong.element: x:OutputUnit(2, {lib1, lib2})*/
-/*strongConst.element: x:
+/*strong.member: x:OutputUnit(2, {lib1, lib2})*/
+/*strongConst.member: x:
OutputUnit(2, {lib1, lib2}),
constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
*/
@@ -22,16 +22,16 @@
/*class: C:OutputUnit(1, {lib1})*/
class C {
- /*element: C.foo:OutputUnit(3, {lib2})*/
+ /*member: C.foo:OutputUnit(3, {lib2})*/
static foo() {
/*OutputUnit(3, {lib2})*/ () {}(); // Hack to avoid inlining.
return 1;
}
- /*element: C.:OutputUnit(1, {lib1})*/
+ /*member: C.:OutputUnit(1, {lib1})*/
C();
- /*element: C.bar:OutputUnit(1, {lib1})*/
+ /*member: C.bar:OutputUnit(1, {lib1})*/
bar() {
/*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
return 1;
@@ -40,8 +40,8 @@
/*class: C1:null*/
class C1 {
- /*strong.element: C1.foo:OutputUnit(3, {lib2})*/
- /*strongConst.element: C1.foo:
+ /*strong.member: C1.foo:OutputUnit(3, {lib2})*/
+ /*strongConst.member: C1.foo:
OutputUnit(3, {lib2}),
constants=[MapConstant({})=OutputUnit(3, {lib2})]
*/
@@ -51,59 +51,59 @@
/*class: C2:OutputUnit(1, {lib1})*/
class C2 {
- /*element: C2.foo:OutputUnit(3, {lib2})*/
+ /*member: C2.foo:OutputUnit(3, {lib2})*/
static var foo = new Map<int, int>.from({1: 2});
- /*element: C2.bar:OutputUnit(1, {lib1})*/
+ /*member: C2.bar:OutputUnit(1, {lib1})*/
var bar = new Map<int, int>.from({1: 2});
- /*element: C2.:OutputUnit(1, {lib1})*/
+ /*member: C2.:OutputUnit(1, {lib1})*/
C2();
}
/*class: C3:OutputUnit(1, {lib1})*/
class C3 {
- /*strong.element: C3.foo:OutputUnit(3, {lib2})*/
- /*strongConst.element: C3.foo:
+ /*strong.member: C3.foo:OutputUnit(3, {lib2})*/
+ /*strongConst.member: C3.foo:
OutputUnit(3, {lib2}),
constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
*/
static final foo = const ConstClass(const ConstClass(1));
- /*strong.element: C3.bar:OutputUnit(1, {lib1})*/
- /*strongConst.element: C3.bar:
+ /*strong.member: C3.bar:OutputUnit(1, {lib1})*/
+ /*strongConst.member: C3.bar:
OutputUnit(1, {lib1}),
constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
*/
final bar = const ConstClass(const ConstClass(1));
- /*element: C3.:OutputUnit(1, {lib1})*/
+ /*member: C3.:OutputUnit(1, {lib1})*/
C3();
}
/*class: C4:OutputUnit(1, {lib1})*/
class C4 {
- /*element: C4.foo:OutputUnit(3, {lib2})*/
+ /*member: C4.foo:OutputUnit(3, {lib2})*/
static final foo = new Map<ConstClass, ConstClass>.from({x: x});
- /*element: C4.bar:OutputUnit(1, {lib1})*/
+ /*member: C4.bar:OutputUnit(1, {lib1})*/
final bar = new Map<ConstClass, ConstClass>.from({x: x});
- /*element: C4.:OutputUnit(1, {lib1})*/
+ /*member: C4.:OutputUnit(1, {lib1})*/
C4();
}
/*class: C5:OutputUnit(1, {lib1})*/
class C5 {
- /*strong.element: C5.foo:OutputUnit(3, {lib2})*/
+ /*strong.member: C5.foo:OutputUnit(3, {lib2})*/
static const foo = /*strong.OutputUnit(3, {lib2})*/ const [
const {1: 3}
];
- /*element: C5.:OutputUnit(1, {lib1})*/
+ /*member: C5.:OutputUnit(1, {lib1})*/
C5();
- /*element: C5.bar:OutputUnit(1, {lib1})*/
+ /*member: C5.bar:OutputUnit(1, {lib1})*/
bar() {
/*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
return 1;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
index bb0ca27..e0bf128 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
@@ -7,8 +7,8 @@
import "package:expect/expect.dart";
import "static_separate_lib1.dart";
-/*strong.element: foo:OutputUnit(3, {lib2})*/
-/*strongConst.element: foo:
+/*strong.member: foo:OutputUnit(3, {lib2})*/
+/*strongConst.member: foo:
OutputUnit(3, {lib2}),
constants=[
ListConstant(<Map<int,int>>[MapConstant(<int, int>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
index d785ac6..c89d690 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
@@ -4,5 +4,5 @@
import 'type_argument_dependency_lib2.dart';
-/*element: doCast:OutputUnit(main, {})*/
+/*member: doCast:OutputUnit(main, {})*/
doCast(List<dynamic> l) => l.cast<B>().map(/*OutputUnit(main, {})*/ (x) => 1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
index 4ed198d..452d66e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
@@ -4,12 +4,12 @@
/*class: A:OutputUnit(main, {})*/
class A {
- /*element: A.:OutputUnit(1, {c})*/
+ /*member: A.:OutputUnit(1, {c})*/
A();
}
/*class: B:OutputUnit(main, {})*/
class B extends A {}
-/*element: createA:OutputUnit(1, {c})*/
+/*member: createA:OutputUnit(1, {c})*/
createA() => new A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
index b66d8d2..7d907f9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
@@ -6,15 +6,15 @@
/*class: A:OutputUnit(1, {lib1})*/
class A<T> {
- /*strong.element: A.:OutputUnit(1, {lib1})*/
+ /*strong.member: A.:OutputUnit(1, {lib1})*/
const A();
}
/*class: B:OutputUnit(1, {lib1})*/
class B {}
-/*strong.element: field1:OutputUnit(1, {lib1})*/
+/*strong.member: field1:OutputUnit(1, {lib1})*/
const dynamic field1 = /*strong.OutputUnit(1, {lib1})*/ const A<B>();
-/*strong.element: field2:OutputUnit(1, {lib1})*/
+/*strong.member: field2:OutputUnit(1, {lib1})*/
const dynamic field2 = /*strong.OutputUnit(1, {lib1})*/ const A<F>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
index 12b8c62..571959b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
@@ -4,12 +4,12 @@
/*class: C:OutputUnit(main, {})*/
class C<T> {
- /*strong.element: C.:OutputUnit(main, {})*/
+ /*strong.member: C.:OutputUnit(main, {})*/
const C();
}
/*class: D:OutputUnit(main, {})*/
class D {}
-/*strong.element: field:OutputUnit(main, {})*/
+/*strong.member: field:OutputUnit(main, {})*/
const dynamic field = /*strong.OutputUnit(main, {})*/ const C<D>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
index c280a53..2ef8be5 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
@@ -4,12 +4,12 @@
/*class: E:OutputUnit(3, {lib3})*/
class E<T> {
- /*strong.element: E.:OutputUnit(3, {lib3})*/
+ /*strong.member: E.:OutputUnit(3, {lib3})*/
const E();
}
/*class: F:OutputUnit(2, {lib1, lib3})*/
class F {}
-/*strong.element: field:OutputUnit(3, {lib3})*/
+/*strong.member: field:OutputUnit(3, {lib3})*/
const dynamic field = /*strong.OutputUnit(3, {lib3})*/ const E<F>();
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart
index c6beb4da..762af65 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -7,493 +7,42 @@
import 'package:compiler/src/js_model/locals.dart';
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;
+import 'package:front_end/src/testing/id.dart';
+import 'package:front_end/src/testing/id_extractor.dart';
-enum IdKind {
- element,
- cls,
- node,
- invoke,
- update,
- iterator,
- current,
- moveNext,
+export 'package:front_end/src/testing/id.dart';
+export 'package:front_end/src/testing/id_extractor.dart';
+
+SourceSpan computeSourceSpanFromUriOffset(Uri uri, int offset) {
+ return uri != null ? new SourceSpan(uri, offset, offset + 1) : null;
}
-/// Id for a code point or element with type inference information.
-abstract class Id {
- IdKind get kind;
- bool get isGlobal;
-
- /// Display name for this id.
- String get descriptor;
-}
-
-class IdValue {
- final Id id;
- final String value;
-
- const IdValue(this.id, this.value);
-
- @override
- int get hashCode => id.hashCode * 13 + value.hashCode * 17;
-
- @override
- bool operator ==(other) {
- if (identical(this, other)) return true;
- if (other is! IdValue) return false;
- return id == other.id && value == other.value;
- }
-
- @override
- String toString() => idToString(id, value);
-
- static String idToString(Id id, String value) {
- switch (id.kind) {
- case IdKind.element:
- ElementId elementId = id;
- return '$elementPrefix${elementId.name}:$value';
- case IdKind.cls:
- ClassId classId = id;
- return '$classPrefix${classId.name}:$value';
- case IdKind.node:
- return value;
- case IdKind.invoke:
- return '$invokePrefix$value';
- case IdKind.update:
- return '$updatePrefix$value';
- case IdKind.iterator:
- return '$iteratorPrefix$value';
- case IdKind.current:
- return '$currentPrefix$value';
- case IdKind.moveNext:
- return '$moveNextPrefix$value';
- }
- throw new UnsupportedError("Unexpected id kind: ${id.kind}");
- }
-
- static const String globalPrefix = "global#";
- static const String elementPrefix = "element: ";
- static const String classPrefix = "class: ";
- static const String invokePrefix = "invoke: ";
- static const String updatePrefix = "update: ";
- static const String iteratorPrefix = "iterator: ";
- static const String currentPrefix = "current: ";
- static const String moveNextPrefix = "moveNext: ";
-
- static IdValue decode(int offset, String text) {
- Id id;
- String expected;
- if (text.startsWith(elementPrefix)) {
- text = text.substring(elementPrefix.length);
- int colonPos = text.indexOf(':');
- if (colonPos == -1) throw "Invalid element id: '$text'";
- String name = text.substring(0, colonPos);
- bool isGlobal = name.startsWith(globalPrefix);
- if (isGlobal) {
- name = name.substring(globalPrefix.length);
- }
- id = new ElementId(name, isGlobal: isGlobal);
- expected = text.substring(colonPos + 1);
- } else if (text.startsWith(classPrefix)) {
- text = text.substring(classPrefix.length);
- int colonPos = text.indexOf(':');
- if (colonPos == -1) throw "Invalid class id: '$text'";
- String name = text.substring(0, colonPos);
- bool isGlobal = name.startsWith(globalPrefix);
- if (isGlobal) {
- name = name.substring(globalPrefix.length);
- }
- id = new ClassId(name, isGlobal: isGlobal);
- expected = text.substring(colonPos + 1);
- } else if (text.startsWith(invokePrefix)) {
- id = new NodeId(offset, IdKind.invoke);
- expected = text.substring(invokePrefix.length);
- } else if (text.startsWith(updatePrefix)) {
- id = new NodeId(offset, IdKind.update);
- expected = text.substring(updatePrefix.length);
- } else if (text.startsWith(iteratorPrefix)) {
- id = new NodeId(offset, IdKind.iterator);
- expected = text.substring(iteratorPrefix.length);
- } else if (text.startsWith(currentPrefix)) {
- id = new NodeId(offset, IdKind.current);
- expected = text.substring(currentPrefix.length);
- } else if (text.startsWith(moveNextPrefix)) {
- id = new NodeId(offset, IdKind.moveNext);
- expected = text.substring(moveNextPrefix.length);
- } else {
- id = new NodeId(offset, IdKind.node);
- expected = text;
- }
- // Remove newlines.
- expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
- return new IdValue(id, expected);
- }
-}
-
-/// Id for an member element.
-class ElementId implements Id {
- final String className;
- final String memberName;
- @override
- final bool isGlobal;
-
- factory ElementId(String text, {bool isGlobal: false}) {
- int dotPos = text.indexOf('.');
- if (dotPos != -1) {
- return new ElementId.internal(text.substring(dotPos + 1),
- className: text.substring(0, dotPos), isGlobal: isGlobal);
- } else {
- return new ElementId.internal(text, isGlobal: isGlobal);
- }
- }
-
- ElementId.internal(this.memberName, {this.className, this.isGlobal: false});
-
- @override
- int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
-
- @override
- bool operator ==(other) {
- if (identical(this, other)) return true;
- if (other is! ElementId) return false;
- return className == other.className && memberName == other.memberName;
- }
-
- @override
- IdKind get kind => IdKind.element;
-
- String get name => className != null ? '$className.$memberName' : memberName;
-
- @override
- String get descriptor => 'member $name';
-
- @override
- String toString() => 'element:$name';
-}
-
-/// Id for a class.
-class ClassId implements Id {
- final String className;
- @override
- final bool isGlobal;
-
- ClassId(this.className, {this.isGlobal: false});
-
- @override
- int get hashCode => className.hashCode * 13;
-
- @override
- bool operator ==(other) {
- if (identical(this, other)) return true;
- if (other is! ClassId) return false;
- return className == other.className;
- }
-
- @override
- IdKind get kind => IdKind.cls;
-
- String get name => className;
-
- @override
- String get descriptor => 'class $name';
-
- @override
- String toString() => 'class:$name';
-}
-
-/// Id for a code point with type inference information.
-// TODO(johnniwinther): Create an [NodeId]-based equivalence with the kernel IR.
-class NodeId implements Id {
- final int value;
- @override
- final IdKind kind;
-
- const NodeId(this.value, this.kind);
-
- @override
- bool get isGlobal => false;
-
- @override
- int get hashCode => value.hashCode * 13 + kind.hashCode * 17;
-
- @override
- bool operator ==(other) {
- if (identical(this, other)) return true;
- if (other is! NodeId) return false;
- return value == other.value && kind == other.kind;
- }
-
- @override
- String get descriptor => 'offset $value ($kind)';
-
- @override
- String toString() => '$kind:$value';
-}
-
-class ActualData<T> {
- final Id id;
- final T value;
- final SourceSpan sourceSpan;
- final Object object;
-
- ActualData(this.id, this.value, this.sourceSpan, this.object);
-
- int get offset {
- if (id is NodeId) {
- NodeId nodeId = id;
- return nodeId.value;
- } else {
- return sourceSpan.begin;
- }
- }
-
- String get objectText {
- return 'object `${'$object'.replaceAll('\n', '')}` (${object.runtimeType})';
- }
-
- @override
- String toString() =>
- 'ActualData(id=$id,value=$value,sourceSpan=$sourceSpan,object=$objectText)';
-}
-
-abstract class DataRegistry<T> {
+abstract class IrDataRegistryMixin<T> implements DataRegistry<T> {
DiagnosticReporter get reporter;
- Map<Id, ActualData<T>> get actualMap;
- void registerValue(SourceSpan sourceSpan, Id id, T value, Object object) {
- if (actualMap.containsKey(id)) {
- ActualData<T> existingData = actualMap[id];
- reportHere(reporter, sourceSpan,
- "Duplicate id ${id}, value=$value, object=$object");
- reportHere(
- reporter,
- sourceSpan,
- "Duplicate id ${id}, value=${existingData.value}, "
- "object=${existingData.object}");
- Expect.fail("Duplicate id $id.");
- }
- if (value != null) {
- actualMap[id] = new ActualData<T>(id, value, sourceSpan, object);
- }
+ @override
+ void report(Uri uri, int offset, String message) {
+ reportHere(reporter, computeSourceSpanFromUriOffset(uri, offset), message);
+ }
+
+ @override
+ void fail(String message) {
+ Expect.fail(message);
}
}
-/// Compute a canonical [Id] for kernel-based nodes.
-Id computeEntityId(ir.Member node) {
- String className;
- if (node.enclosingClass != null) {
- className = node.enclosingClass.name;
- }
- String memberName = node.name.name;
- if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
- memberName += '=';
- }
- return new ElementId.internal(memberName, className: className);
-}
-
-/// Abstract IR visitor for computing data corresponding to a node or element,
-/// and record it with a generic [Id]
-abstract class IrDataExtractor<T> extends ir.Visitor with DataRegistry<T> {
+abstract class IrDataExtractor<T> extends DataExtractor<T>
+ with IrDataRegistryMixin<T> {
@override
final DiagnosticReporter reporter;
- @override
- final Map<Id, ActualData<T>> actualMap;
- /// Implement this to compute the data corresponding to [member].
- ///
- /// If `null` is returned, [member] has no associated data.
- T computeMemberValue(Id id, ir.Member member);
-
- /// Implement this to compute the data corresponding to [node].
- ///
- /// If `null` is returned, [node] has no associated data.
- T computeNodeValue(Id id, ir.TreeNode node);
-
- IrDataExtractor(this.reporter, this.actualMap);
-
- void computeForMember(ir.Member member) {
- ElementId id = computeEntityId(member);
- if (id == null) return;
- T value = computeMemberValue(id, member);
- registerValue(computeSourceSpan(member), id, value, member);
- }
-
- void computeForNode(ir.TreeNode node, NodeId id) {
- if (id == null) return;
- T value = computeNodeValue(id, node);
- registerValue(computeSourceSpan(node), id, value, node);
- }
+ IrDataExtractor(this.reporter, Map<Id, ActualData<T>> actualMap)
+ : super(actualMap);
SourceSpan computeSourceSpan(ir.TreeNode node) {
return computeSourceSpanFromTreeNode(node);
}
- NodeId computeDefaultNodeId(ir.TreeNode node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on $node (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.node);
- }
-
- NodeId createInvokeId(ir.TreeNode node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on ${node} (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.invoke);
- }
-
- NodeId createUpdateId(ir.TreeNode node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on ${node} (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.update);
- }
-
- NodeId createIteratorId(ir.ForInStatement node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on ${node} (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.iterator);
- }
-
- NodeId createCurrentId(ir.ForInStatement node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on ${node} (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.current);
- }
-
- NodeId createMoveNextId(ir.ForInStatement node) {
- assert(node.fileOffset != ir.TreeNode.noOffset,
- "No fileOffset on ${node} (${node.runtimeType})");
- return new NodeId(node.fileOffset, IdKind.moveNext);
- }
-
- NodeId createLabeledStatementId(ir.LabeledStatement node) =>
- computeDefaultNodeId(node.body);
- NodeId createLoopId(ir.TreeNode node) => computeDefaultNodeId(node);
- NodeId createGotoId(ir.TreeNode node) => computeDefaultNodeId(node);
- NodeId createSwitchId(ir.SwitchStatement node) => computeDefaultNodeId(node);
- NodeId createSwitchCaseId(ir.SwitchCase node) =>
- new NodeId(node.expressionOffsets.first, IdKind.node);
-
- void run(ir.Node root) {
- root.accept(this);
- }
-
- @override
- defaultNode(ir.Node node) {
- node.visitChildren(this);
- }
-
- @override
- defaultMember(ir.Member node) {
- super.defaultMember(node);
- computeForMember(node);
- }
-
- @override
- visitMethodInvocation(ir.MethodInvocation node) {
- ir.TreeNode receiver = node.receiver;
- if (receiver is ir.VariableGet &&
- receiver.variable.parent is ir.FunctionDeclaration) {
- // This is an invocation of a named local function.
- computeForNode(node, createInvokeId(node.receiver));
- node.arguments.accept(this);
- } else if (node.name.name == '==' &&
- receiver is ir.VariableGet &&
- receiver.variable.name == null) {
- // This is a desugared `?.`.
- } else if (node.name.name == '[]') {
- computeForNode(node, computeDefaultNodeId(node));
- super.visitMethodInvocation(node);
- } else if (node.name.name == '[]=') {
- computeForNode(node, createUpdateId(node));
- super.visitMethodInvocation(node);
- } else {
- computeForNode(node, createInvokeId(node));
- super.visitMethodInvocation(node);
- }
- }
-
- @override
- visitLoadLibrary(ir.LoadLibrary node) {
- computeForNode(node, createInvokeId(node));
- }
-
- @override
- visitPropertyGet(ir.PropertyGet node) {
- computeForNode(node, computeDefaultNodeId(node));
- super.visitPropertyGet(node);
- }
-
- @override
- visitVariableDeclaration(ir.VariableDeclaration node) {
- if (node.name != null && node.parent is! ir.FunctionDeclaration) {
- // Skip synthetic variables and function declaration variables.
- computeForNode(node, computeDefaultNodeId(node));
- }
- super.visitVariableDeclaration(node);
- }
-
- @override
- visitFunctionDeclaration(ir.FunctionDeclaration node) {
- computeForNode(node, computeDefaultNodeId(node));
- super.visitFunctionDeclaration(node);
- }
-
- @override
- visitFunctionExpression(ir.FunctionExpression node) {
- computeForNode(node, computeDefaultNodeId(node));
- super.visitFunctionExpression(node);
- }
-
- @override
- visitVariableGet(ir.VariableGet node) {
- if (node.variable.name != null && !node.variable.isFieldFormal) {
- // Skip use of synthetic variables.
- computeForNode(node, computeDefaultNodeId(node));
- }
- super.visitVariableGet(node);
- }
-
- @override
- visitPropertySet(ir.PropertySet node) {
- computeForNode(node, createUpdateId(node));
- super.visitPropertySet(node);
- }
-
- @override
- visitVariableSet(ir.VariableSet node) {
- if (node.variable.name != null) {
- // Skip use of synthetic variables.
- computeForNode(node, createUpdateId(node));
- }
- super.visitVariableSet(node);
- }
-
- @override
- visitDoStatement(ir.DoStatement node) {
- computeForNode(node, createLoopId(node));
- super.visitDoStatement(node);
- }
-
- @override
- visitForStatement(ir.ForStatement node) {
- computeForNode(node, createLoopId(node));
- super.visitForStatement(node);
- }
-
- @override
- visitForInStatement(ir.ForInStatement node) {
- computeForNode(node, createLoopId(node));
- computeForNode(node, createIteratorId(node));
- computeForNode(node, createCurrentId(node));
- computeForNode(node, createMoveNextId(node));
- super.visitForInStatement(node);
- }
-
- @override
- visitWhileStatement(ir.WhileStatement node) {
- computeForNode(node, createLoopId(node));
- super.visitWhileStatement(node);
- }
-
@override
visitLabeledStatement(ir.LabeledStatement node) {
if (!JumpVisitor.canBeBreakTarget(node.body) &&
@@ -502,30 +51,4 @@
}
super.visitLabeledStatement(node);
}
-
- @override
- visitBreakStatement(ir.BreakStatement node) {
- computeForNode(node, createGotoId(node));
- super.visitBreakStatement(node);
- }
-
- @override
- visitSwitchStatement(ir.SwitchStatement node) {
- computeForNode(node, createSwitchId(node));
- super.visitSwitchStatement(node);
- }
-
- @override
- visitSwitchCase(ir.SwitchCase node) {
- if (node.expressionOffsets.isNotEmpty) {
- computeForNode(node, createSwitchCaseId(node));
- }
- super.visitSwitchCase(node);
- }
-
- @override
- visitContinueSwitchStatement(ir.ContinueSwitchStatement node) {
- computeForNode(node, createGotoId(node));
- super.visitContinueSwitchStatement(node);
- }
}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 799be65..548568d 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -14,7 +14,7 @@
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/util/features.dart';
import 'package:expect/expect.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import '../helpers/memory_compiler.dart';
import '../equivalence/id_equivalence.dart';
@@ -280,7 +280,7 @@
}
for (Id id in globalIds) {
- if (id is ElementId) {
+ if (id is MemberId) {
MemberEntity member;
if (id.className != null) {
ClassEntity cls = getGlobalClass(id.className);
@@ -403,9 +403,7 @@
String actualCode(Uri uri) {
Map<int, List<String>> annotations = <int, List<String>>{};
actualMaps[uri].forEach((Id id, ActualData<T> data) {
- annotations
- .putIfAbsent(data.sourceSpan.begin, () => [])
- .add('${data.value}');
+ annotations.putIfAbsent(data.offset, () => []).add('${data.value}');
});
return withAnnotations(code[uri].sourceCode, annotations);
}
@@ -863,7 +861,7 @@
if (!dataValidator.isEmpty(actual)) {
reportError(
data.compiler.reporter,
- actualData.sourceSpan,
+ computeSourceSpanFromUriOffset(actualData.uri, actualData.offset),
'EXTRA $mode DATA for ${id.descriptor}:\n '
'object : ${actualData.objectText}\n '
'actual : ${colorizeActual('${IdValue.idToString(id, actualText)}')}\n '
@@ -879,7 +877,7 @@
if (unexpectedMessage != null) {
reportError(
data.compiler.reporter,
- actualData.sourceSpan,
+ computeSourceSpanFromUriOffset(actualData.uri, actualData.offset),
'UNEXPECTED $mode DATA for ${id.descriptor}:\n '
'detail : ${colorizeMessage(unexpectedMessage)}\n '
'object : ${actualData.objectText}\n '
@@ -951,7 +949,7 @@
ElementEnvironment elementEnvironment, Uri mainUri, Id id) {
if (id is NodeId) {
return new SourceSpan(mainUri, id.value, id.value + 1);
- } else if (id is ElementId) {
+ } else if (id is MemberId) {
String memberName = id.memberName;
bool isSetter = false;
if (memberName != '[]=' && memberName != '==' && memberName.endsWith('=')) {
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
index d85a4a0..e5874e3 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -10,14 +10,14 @@
}
class Class1 {
- /*element: Class1.field1:constant=BoolConstant(false)*/
+ /*member: Class1.field1:constant=BoolConstant(false)*/
final bool field1;
const Class1({this.field1: false});
}
class Class2 {
- /*strongConst.element: Class2.field2:constant=BoolConstant(true)*/
+ /*strongConst.member: Class2.field2:constant=BoolConstant(true)*/
final bool field2;
const Class2({this.field2: false});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
index b228203..fad3d3b 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
@@ -12,7 +12,7 @@
}
class Class1a {
- /*element: Class1a.field1:elided*/
+ /*member: Class1a.field1:elided*/
int field1;
}
@@ -22,7 +22,7 @@
}
class Class2a<T> {
- /*element: Class2a.field2:elided*/
+ /*member: Class2a.field2:elided*/
T field2;
}
@@ -32,12 +32,12 @@
}
class Class3a {
- /*element: Class3a.field3:elided*/
+ /*member: Class3a.field3:elided*/
int field3;
}
class Class3b {
- /*element: Class3b.field3:elided*/
+ /*member: Class3b.field3:elided*/
int field3;
}
@@ -47,12 +47,12 @@
}
class Class4a {
- /*element: Class4a.field4:elided*/
+ /*member: Class4a.field4:elided*/
int field4;
}
class Class4b implements Class4a {
- /*element: Class4b.field4:elided*/
+ /*member: Class4b.field4:elided*/
@override
int field4;
}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
index 27a4a61..a5a0fbf 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
@@ -3,13 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
enum Enum {
- /*strong.element: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
+ /*strong.member: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
a,
- /*strong.element: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
+ /*strong.member: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
b,
- /*strong.element: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
+ /*strong.member: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
c,
}
@@ -23,10 +23,10 @@
tester3() {}
class Class {
- /*element: Class.state1:constant=IntConstant(1)*/
+ /*member: Class.state1:constant=IntConstant(1)*/
final int state1;
- /*element: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
+ /*member: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
final Enum state2;
Class({this.state1: 1, this.state2: Enum.c});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
index d6120a4..f56c73f 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
@@ -23,22 +23,22 @@
var field1 = 0;
var field2;
- /*element: Class1.field3a:allocator,initial=IntConstant(3)*/
+ /*member: Class1.field3a:allocator,initial=IntConstant(3)*/
var field3a;
- /*element: Class1.field3b:constant=IntConstant(3)*/
+ /*member: Class1.field3b:constant=IntConstant(3)*/
var field3b;
- /*element: Class1.field4a:allocator,initial=IntConstant(4)*/
+ /*member: Class1.field4a:allocator,initial=IntConstant(4)*/
var field4a = 4;
- /*element: Class1.field4b:constant=IntConstant(4)*/
+ /*member: Class1.field4b:constant=IntConstant(4)*/
var field4b = 4;
- /*element: Class1.field5a:allocator,initial=IntConstant(5)*/
+ /*member: Class1.field5a:allocator,initial=IntConstant(5)*/
var field5a = 5;
- /*element: Class1.field5b:constant=IntConstant(5)*/
+ /*member: Class1.field5b:constant=IntConstant(5)*/
var field5b = 5;
Class1.a()
diff --git a/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart b/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
index 715a521..3e0cbf5 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
@@ -35,52 +35,52 @@
}
class Class1a {
- /*element: Class1a.field1:*/
+ /*member: Class1a.field1:*/
var field1;
- /*element: Class1a.field2:*/
+ /*member: Class1a.field2:*/
var field2;
- /*element: Class1a.field3:allocator,initial=IntConstant(3)*/
+ /*member: Class1a.field3:allocator,initial=IntConstant(3)*/
var field3;
Class1a(this.field1, [this.field2 = 2, this.field3 = 3]);
}
class Class1b {
- /*element: Class1b.field1:*/
+ /*member: Class1b.field1:*/
var field1;
- /*element: Class1b.field2:*/
+ /*member: Class1b.field2:*/
var field2;
- /*element: Class1b.field3:constant=IntConstant(3)*/
+ /*member: Class1b.field3:constant=IntConstant(3)*/
var field3;
Class1b(this.field1, [this.field2 = 2, this.field3 = 3]);
}
class Class2a {
- /*element: Class2a.field1:*/
+ /*member: Class2a.field1:*/
var field1;
- /*element: Class2a.field2:*/
+ /*member: Class2a.field2:*/
var field2;
- /*element: Class2a.field3:allocator,initial=IntConstant(3)*/
+ /*member: Class2a.field3:allocator,initial=IntConstant(3)*/
var field3;
Class2a(this.field1, {this.field2 = 2, this.field3 = 3});
}
class Class2b {
- /*element: Class2b.field1:*/
+ /*member: Class2b.field1:*/
var field1;
- /*element: Class2b.field2:*/
+ /*member: Class2b.field2:*/
var field2;
- /*element: Class2b.field3:constant=IntConstant(3)*/
+ /*member: Class2b.field3:constant=IntConstant(3)*/
var field3;
Class2b(this.field1, {this.field2 = 2, this.field3 = 3});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart b/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
index d798780..a719c2e 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
@@ -11,7 +11,7 @@
return x + y;
}
- /*element: A.foo:constant=FunctionConstant(A.defaultFoo)*/
+ /*member: A.foo:constant=FunctionConstant(A.defaultFoo)*/
final BinaryFunc foo;
}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index a04f242..0958aad 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -113,196 +113,196 @@
use(c2.field13b);
}
-/*strong.element: const1:constant=BoolConstant(true)*/
+/*strong.member: const1:constant=BoolConstant(true)*/
const bool const1 = true;
class Class1 {
- /*element: Class1.field0a:allocator,initial=NullConstant*/
+ /*member: Class1.field0a:allocator,initial=NullConstant*/
var field0a;
- /*element: Class1.field0b:constant=NullConstant*/
+ /*member: Class1.field0b:constant=NullConstant*/
var field0b;
- /*element: Class1.field1a:allocator,initial=NullConstant*/
+ /*member: Class1.field1a:allocator,initial=NullConstant*/
var field1a = null;
- /*element: Class1.field1b:constant=NullConstant*/
+ /*member: Class1.field1b:constant=NullConstant*/
var field1b = null;
- /*element: Class1.field2a:allocator,initial=BoolConstant(true)*/
+ /*member: Class1.field2a:allocator,initial=BoolConstant(true)*/
var field2a = true;
- /*element: Class1.field2b:constant=BoolConstant(true)*/
+ /*member: Class1.field2b:constant=BoolConstant(true)*/
var field2b = true;
- /*element: Class1.field3a:allocator,initial=BoolConstant(false)*/
+ /*member: Class1.field3a:allocator,initial=BoolConstant(false)*/
var field3a = false;
- /*element: Class1.field3b:constant=BoolConstant(false)*/
+ /*member: Class1.field3b:constant=BoolConstant(false)*/
var field3b = false;
- /*element: Class1.field4a:allocator,initial=IntConstant(0)*/
+ /*member: Class1.field4a:allocator,initial=IntConstant(0)*/
var field4a = 0;
- /*element: Class1.field4b:constant=IntConstant(0)*/
+ /*member: Class1.field4b:constant=IntConstant(0)*/
var field4b = 0;
- /*element: Class1.field5a:allocator,initial=IntConstant(1)*/
+ /*member: Class1.field5a:allocator,initial=IntConstant(1)*/
var field5a = 1;
- /*element: Class1.field5b:constant=IntConstant(1)*/
+ /*member: Class1.field5b:constant=IntConstant(1)*/
var field5b = 1;
- /*element: Class1.field6a:allocator,initial=StringConstant("")*/
+ /*member: Class1.field6a:allocator,initial=StringConstant("")*/
var field6a = '';
- /*element: Class1.field6b:constant=StringConstant("")*/
+ /*member: Class1.field6b:constant=StringConstant("")*/
var field6b = '';
- /*element: Class1.field7a:allocator,initial=StringConstant("foo")*/
+ /*member: Class1.field7a:allocator,initial=StringConstant("foo")*/
var field7a = 'foo';
- /*element: Class1.field7b:constant=StringConstant("foo")*/
+ /*member: Class1.field7b:constant=StringConstant("foo")*/
var field7b = 'foo';
- /*element: Class1.field8a:initial=DoubleConstant(0.5)*/
+ /*member: Class1.field8a:initial=DoubleConstant(0.5)*/
var field8a = 0.5;
- /*element: Class1.field8b:constant=DoubleConstant(0.5)*/
+ /*member: Class1.field8b:constant=DoubleConstant(0.5)*/
var field8b = 0.5;
- /*element: Class1.field9a:initial=ListConstant([])*/
+ /*member: Class1.field9a:initial=ListConstant([])*/
var field9a = const [];
- /*element: Class1.field9b:constant=ListConstant([])*/
+ /*member: Class1.field9b:constant=ListConstant([])*/
var field9b = const [];
- /*element: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
var field9c = const [0, 1];
- /*element: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
var field9d = const [0, 1, 2];
- /*element: Class1.field10a:initial=MapConstant({})*/
+ /*member: Class1.field10a:initial=MapConstant({})*/
var field10a = const {};
- /*element: Class1.field10b:constant=MapConstant({})*/
+ /*member: Class1.field10b:constant=MapConstant({})*/
var field10b = const {};
- /*element: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
var field10c = const {0: 1, 2: 3};
- /*element: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
var field10d = const {0: 1, 2: 3, 4: 5};
- /*element: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+ /*member: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
var field11a = #foo;
- /*element: Class1.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+ /*member: Class1.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
var field11b = #foo;
- /*element: Class1.field12a:allocator,initial=IntConstant(5)*/
+ /*member: Class1.field12a:allocator,initial=IntConstant(5)*/
var field12a = 2 + 3;
- /*element: Class1.field12b:constant=IntConstant(5)*/
+ /*member: Class1.field12b:constant=IntConstant(5)*/
var field12b = 2 + 3;
- /*element: Class1.field13a:allocator,initial=BoolConstant(true)*/
+ /*member: Class1.field13a:allocator,initial=BoolConstant(true)*/
var field13a = const1;
- /*element: Class1.field13b:constant=BoolConstant(true)*/
+ /*member: Class1.field13b:constant=BoolConstant(true)*/
var field13b = const1;
}
class Class2 {
- /*element: Class2.field1a:allocator,initial=NullConstant*/
+ /*member: Class2.field1a:allocator,initial=NullConstant*/
var field1a;
- /*element: Class2.field1b:constant=NullConstant*/
+ /*member: Class2.field1b:constant=NullConstant*/
var field1b;
- /*element: Class2.field2a:allocator,initial=BoolConstant(true)*/
+ /*member: Class2.field2a:allocator,initial=BoolConstant(true)*/
var field2a;
- /*element: Class2.field2b:constant=BoolConstant(true)*/
+ /*member: Class2.field2b:constant=BoolConstant(true)*/
var field2b;
- /*element: Class2.field3a:allocator,initial=BoolConstant(false)*/
+ /*member: Class2.field3a:allocator,initial=BoolConstant(false)*/
var field3a;
- /*element: Class2.field3b:constant=BoolConstant(false)*/
+ /*member: Class2.field3b:constant=BoolConstant(false)*/
var field3b;
- /*element: Class2.field4a:allocator,initial=IntConstant(0)*/
+ /*member: Class2.field4a:allocator,initial=IntConstant(0)*/
var field4a;
- /*element: Class2.field4b:constant=IntConstant(0)*/
+ /*member: Class2.field4b:constant=IntConstant(0)*/
var field4b;
- /*element: Class2.field5a:allocator,initial=IntConstant(1)*/
+ /*member: Class2.field5a:allocator,initial=IntConstant(1)*/
var field5a;
- /*element: Class2.field5b:constant=IntConstant(1)*/
+ /*member: Class2.field5b:constant=IntConstant(1)*/
var field5b;
- /*element: Class2.field6a:allocator,initial=StringConstant("")*/
+ /*member: Class2.field6a:allocator,initial=StringConstant("")*/
var field6a;
- /*element: Class2.field6b:constant=StringConstant("")*/
+ /*member: Class2.field6b:constant=StringConstant("")*/
var field6b;
- /*element: Class2.field7a:allocator,initial=StringConstant("foo")*/
+ /*member: Class2.field7a:allocator,initial=StringConstant("foo")*/
var field7a;
- /*element: Class2.field7b:constant=StringConstant("foo")*/
+ /*member: Class2.field7b:constant=StringConstant("foo")*/
var field7b;
- /*element: Class2.field8a:initial=DoubleConstant(0.5)*/
+ /*member: Class2.field8a:initial=DoubleConstant(0.5)*/
var field8a;
- /*element: Class2.field8b:constant=DoubleConstant(0.5)*/
+ /*member: Class2.field8b:constant=DoubleConstant(0.5)*/
var field8b;
- /*element: Class2.field9a:initial=ListConstant([])*/
+ /*member: Class2.field9a:initial=ListConstant([])*/
var field9a;
- /*element: Class2.field9b:constant=ListConstant([])*/
+ /*member: Class2.field9b:constant=ListConstant([])*/
var field9b;
- /*element: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+ /*member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
var field9c;
- /*element: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+ /*member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
var field9d;
- /*element: Class2.field10a:initial=MapConstant({})*/
+ /*member: Class2.field10a:initial=MapConstant({})*/
var field10a;
- /*element: Class2.field10b:constant=MapConstant({})*/
+ /*member: Class2.field10b:constant=MapConstant({})*/
var field10b;
- /*element: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+ /*member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
var field10c;
- /*element: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+ /*member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
var field10d;
- /*element: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+ /*member: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
var field11a;
- /*element: Class2.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+ /*member: Class2.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
var field11b;
- /*element: Class2.field12a:allocator,initial=IntConstant(5)*/
+ /*member: Class2.field12a:allocator,initial=IntConstant(5)*/
var field12a;
- /*element: Class2.field12b:constant=IntConstant(5)*/
+ /*member: Class2.field12b:constant=IntConstant(5)*/
var field12b;
- /*element: Class2.field13a:allocator,initial=BoolConstant(true)*/
+ /*member: Class2.field13a:allocator,initial=BoolConstant(true)*/
var field13a;
- /*element: Class2.field13b:constant=BoolConstant(true)*/
+ /*member: Class2.field13b:constant=BoolConstant(true)*/
var field13b;
Class2()
diff --git a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
index deb273c..b6d316f 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
@@ -69,37 +69,37 @@
const factory Class.fact() = Class.generative;
}
-/*element: field1a:constant=IntConstant(0)*/
+/*member: field1a:constant=IntConstant(0)*/
final field1a = 0;
-/*element: field1b:constant=IntConstant(0)*/
+/*member: field1b:constant=IntConstant(0)*/
var field1b = 0;
-/*element: field1c:initial=IntConstant(0)*/
+/*member: field1c:initial=IntConstant(0)*/
var field1c = 0;
-/*element: field2a:constant=ListConstant([])*/
+/*member: field2a:constant=ListConstant([])*/
final field2a = const [];
-/*element: field2b:constant=ListConstant([])*/
+/*member: field2b:constant=ListConstant([])*/
var field2b = const [];
-/*element: field2c:initial=ListConstant([])*/
+/*member: field2c:initial=ListConstant([])*/
var field2c = const [];
-/*element: field3a:eager,final*/
+/*member: field3a:eager,final*/
final field3a = [];
-/*element: field3b:eager,final*/
+/*member: field3b:eager,final*/
var field3b = [];
-/*element: field3c:eager*/
+/*member: field3c:eager*/
var field3c = [];
-/*element: field3d:eager,final*/
+/*member: field3d:eager,final*/
var field3d = [1, 2, 3];
-/*element: field3e:eager,final*/
+/*member: field3e:eager,final*/
var field3e = [
1,
2,
@@ -110,7 +110,7 @@
]
];
-/*element: field3f:final,lazy*/
+/*member: field3f:final,lazy*/
var field3f = [
1,
2,
@@ -121,99 +121,99 @@
]
];
-/*element: field3g:final,lazy*/
+/*member: field3g:final,lazy*/
var field3g = [method()];
// TODO(johnniwinther): Recognize this as of eager complexity.
-/*element: field3h:final,lazy*/
+/*member: field3h:final,lazy*/
var field3h = [1 + 3];
-/*element: field4a:constant=IntConstant(5)*/
+/*member: field4a:constant=IntConstant(5)*/
final field4a = 2 + 3;
-/*element: field4b:constant=IntConstant(5)*/
+/*member: field4b:constant=IntConstant(5)*/
var field4b = 2 + 3;
-/*strong.element: field4c:constant=IntConstant(5)*/
+/*strong.member: field4c:constant=IntConstant(5)*/
const field4c = 2 + 3;
-/*element: field5a:constant=FunctionConstant(method)*/
+/*member: field5a:constant=FunctionConstant(method)*/
final field5a = method;
-/*element: field5b:constant=FunctionConstant(method)*/
+/*member: field5b:constant=FunctionConstant(method)*/
var field5b = method;
-/*strong.element: field5c:constant=FunctionConstant(method)*/
+/*strong.member: field5c:constant=FunctionConstant(method)*/
const field5c = method;
-/*element: field6a:constant=ConstructedConstant(Class())*/
+/*member: field6a:constant=ConstructedConstant(Class())*/
var field6a = const Class.generative();
-/*element: field6b:constant=ConstructedConstant(Class())*/
+/*member: field6b:constant=ConstructedConstant(Class())*/
var field6b = const Class.fact();
-/*element: field6c:final,lazy*/
+/*member: field6c:final,lazy*/
var field6c = method();
-/*element: field7a:eager,final*/
+/*member: field7a:eager,final*/
var field7a = {};
-/*element: field7b:eager,final*/
+/*member: field7b:eager,final*/
var field7b = {0: 1};
-/*element: field7c:eager,final*/
+/*member: field7c:eager,final*/
var field7c = {0: method};
-/*element: field7d:final,lazy*/
+/*member: field7d:final,lazy*/
var field7d = {0: method()};
-/*element: field7e:final,lazy*/
+/*member: field7e:final,lazy*/
var field7e = {method(): 0};
-/*element: field8a:eager,final*/
+/*member: field8a:eager,final*/
var field8a = {};
-/*element: field8b:eager,final*/
+/*member: field8b:eager,final*/
var field8b = {0};
-/*element: field8c:eager,final*/
+/*member: field8c:eager,final*/
var field8c = {method};
-/*element: field8d:final,lazy*/
+/*member: field8d:final,lazy*/
var field8d = {method()};
-/*element: field9g:eager=[field9d],final,index=1*/
+/*member: field9g:eager=[field9d],final,index=1*/
var field9g = field9d;
-/*element: field9a:eager,final*/
+/*member: field9a:eager,final*/
var field9a = [];
-/*element: field9c:eager=[field9b],final,index=3*/
+/*member: field9c:eager=[field9b],final,index=3*/
var field9c = [field9b];
-/*element: field9b:eager=[field9a],final,index=2*/
+/*member: field9b:eager=[field9a],final,index=2*/
var field9b = field9a;
// Because [field9g] is declared first and it depends upon [field9d], [field9d]
// must be created before [field9g] and thus has a lower index than, say,
// [field9b].
-/*element: field9d:eager=[field9a],final,index=0*/
+/*member: field9d:eager=[field9a],final,index=0*/
var field9d = [field9a];
-/*element: field9e:eager*/
+/*member: field9e:eager*/
var field9e = [];
-/*element: field9f:final,lazy*/
+/*member: field9f:final,lazy*/
var field9f = field9e;
-/*element: field9h:constant=ListConstant([])*/
+/*member: field9h:constant=ListConstant([])*/
var field9h = const [];
-/*element: field9i:eager,final*/
+/*member: field9i:eager,final*/
var field9i = [field9h];
-/*element: field10a:final,lazy*/
+/*member: field10a:final,lazy*/
int field10a = field10b;
-/*element: field10b:final,lazy*/
+/*member: field10b:final,lazy*/
int field10b = field10a;
diff --git a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
index 219c643..cc189f1 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class Class1 {
- /*element: Class1.field:constant=IntConstant(87)*/
+ /*member: Class1.field:constant=IntConstant(87)*/
final int field;
Class1.constructor1({this.field = 42});
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index a28477b..1a7ebe6 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -6,7 +6,6 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/js_backend/field_analysis.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:compiler/src/util/features.dart';
@@ -78,8 +77,9 @@
features.add(Tags.isEffectivelyFinal);
}
Id id = computeEntityId(node);
- actualMap[id] = new ActualData<Features>(
- id, features, computeSourceSpanFromTreeNode(node), member);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ actualMap[id] = new ActualData<Features>(id, features,
+ nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
}
}
diff --git a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
index df9b18b..a8fd083 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
@@ -10,21 +10,21 @@
}
class Class1 {
- /*element: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/
+ /*member: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/
final bool field1;
const Class1({this.field1: false});
}
class Class2 {
- /*element: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/
+ /*member: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/
final bool field2;
const Class2({this.field2: false});
}
class Class3 {
- /*element: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/
+ /*member: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/
final bool field3;
const Class3({this.field3: false});
diff --git a/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
index 0d7200d..e00b39c 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
@@ -8,30 +8,30 @@
}
class Class1 {
- /*element: Class1.field1:
+ /*member: Class1.field1:
Class1.a=IntConstant(1),
initial=IntConstant(0)
*/
var field1 = 0;
- /*element: Class1.field2:
+ /*member: Class1.field2:
Class1.a=IntConstant(1),
Class1.b=IntConstant(2),
initial=NullConstant
*/
var field2;
- /*element: Class1.field3:
+ /*member: Class1.field3:
Class1.a=IntConstant(3),
Class1.b=IntConstant(3),
initial=NullConstant
*/
var field3;
- /*element: Class1.field4:initial=IntConstant(4)*/
+ /*member: Class1.field4:initial=IntConstant(4)*/
var field4 = 4;
- /*element: Class1.field5:
+ /*member: Class1.field5:
Class1.a=IntConstant(5),
Class1.b=IntConstant(5),
initial=IntConstant(5)
diff --git a/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart b/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
index 1dbbde0..8a9d632 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
@@ -10,19 +10,19 @@
}
class Class1 {
- /*element: Class1.field1:
+ /*member: Class1.field1:
Class1.=?,
initial=NullConstant
*/
var field1;
- /*element: Class1.field2:
+ /*member: Class1.field2:
Class1.=1:IntConstant(2),
initial=NullConstant
*/
var field2;
- /*element: Class1.field3:
+ /*member: Class1.field3:
Class1.=2:IntConstant(3),
initial=NullConstant
*/
@@ -32,19 +32,19 @@
}
class Class2 {
- /*element: Class2.field1:
+ /*member: Class2.field1:
Class2.=?,
initial=NullConstant
*/
var field1;
- /*element: Class2.field2:
+ /*member: Class2.field2:
Class2.=field2:IntConstant(2),
initial=NullConstant
*/
var field2;
- /*element: Class2.field3:
+ /*member: Class2.field3:
Class2.=field3:IntConstant(3),
initial=NullConstant
*/
diff --git a/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart b/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
index 6794ac8..2641396 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
@@ -11,7 +11,7 @@
return x + y;
}
- /*element: A.foo:A.=foo:FunctionConstant(A.defaultFoo),initial=NullConstant*/
+ /*member: A.foo:A.=foo:FunctionConstant(A.defaultFoo),initial=NullConstant*/
final BinaryFunc foo;
}
diff --git a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
index f6bff5f..b2002b6 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
@@ -7,97 +7,97 @@
new Class2();
}
-/*strong.element: const1:complexity=constant,initial=BoolConstant(true)*/
+/*strong.member: const1:complexity=constant,initial=BoolConstant(true)*/
const bool const1 = true;
class Class1 {
- /*element: Class1.field0:initial=NullConstant*/
+ /*member: Class1.field0:initial=NullConstant*/
var field0;
- /*element: Class1.field1:initial=NullConstant*/
+ /*member: Class1.field1:initial=NullConstant*/
var field1 = null;
- /*element: Class1.field2:initial=BoolConstant(true)*/
+ /*member: Class1.field2:initial=BoolConstant(true)*/
var field2 = true;
- /*element: Class1.field3:initial=BoolConstant(false)*/
+ /*member: Class1.field3:initial=BoolConstant(false)*/
var field3 = false;
- /*element: Class1.field4:initial=IntConstant(0)*/
+ /*member: Class1.field4:initial=IntConstant(0)*/
var field4 = 0;
- /*element: Class1.field5:initial=IntConstant(1)*/
+ /*member: Class1.field5:initial=IntConstant(1)*/
var field5 = 1;
- /*element: Class1.field6:initial=StringConstant("")*/
+ /*member: Class1.field6:initial=StringConstant("")*/
var field6 = '';
- /*element: Class1.field7:initial=StringConstant("foo")*/
+ /*member: Class1.field7:initial=StringConstant("foo")*/
var field7 = 'foo';
- /*element: Class1.field8:initial=DoubleConstant(0.5)*/
+ /*member: Class1.field8:initial=DoubleConstant(0.5)*/
var field8 = 0.5;
- /*element: Class1.field9:initial=ListConstant([])*/
+ /*member: Class1.field9:initial=ListConstant([])*/
var field9 = const [];
- /*element: Class1.field10:initial=MapConstant({})*/
+ /*member: Class1.field10:initial=MapConstant({})*/
var field10 = const {};
- /*element: Class1.field11:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+ /*member: Class1.field11:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
var field11 = #foo;
- /*element: Class1.field12:initial=IntConstant(5)*/
+ /*member: Class1.field12:initial=IntConstant(5)*/
var field12 = 2 + 3;
- /*element: Class1.field13:initial=BoolConstant(true)*/
+ /*member: Class1.field13:initial=BoolConstant(true)*/
var field13 = const1;
- /*element: Class1.field14:*/
+ /*member: Class1.field14:*/
var field14 = const1 is int;
}
class Class2 {
- /*element: Class2.field1:Class2.=NullConstant,initial=NullConstant*/
+ /*member: Class2.field1:Class2.=NullConstant,initial=NullConstant*/
var field1;
- /*element: Class2.field2:Class2.=BoolConstant(true),initial=NullConstant*/
+ /*member: Class2.field2:Class2.=BoolConstant(true),initial=NullConstant*/
var field2;
- /*element: Class2.field3:Class2.=BoolConstant(false),initial=NullConstant*/
+ /*member: Class2.field3:Class2.=BoolConstant(false),initial=NullConstant*/
var field3;
- /*element: Class2.field4:Class2.=IntConstant(0),initial=NullConstant*/
+ /*member: Class2.field4:Class2.=IntConstant(0),initial=NullConstant*/
var field4;
- /*element: Class2.field5:Class2.=IntConstant(1),initial=NullConstant*/
+ /*member: Class2.field5:Class2.=IntConstant(1),initial=NullConstant*/
var field5;
- /*element: Class2.field6:Class2.=StringConstant(""),initial=NullConstant*/
+ /*member: Class2.field6:Class2.=StringConstant(""),initial=NullConstant*/
var field6;
- /*element: Class2.field7:Class2.=StringConstant("foo"),initial=NullConstant*/
+ /*member: Class2.field7:Class2.=StringConstant("foo"),initial=NullConstant*/
var field7;
- /*element: Class2.field8:Class2.=DoubleConstant(0.5),initial=NullConstant*/
+ /*member: Class2.field8:Class2.=DoubleConstant(0.5),initial=NullConstant*/
var field8;
- /*element: Class2.field9:Class2.=ListConstant([]),initial=NullConstant*/
+ /*member: Class2.field9:Class2.=ListConstant([]),initial=NullConstant*/
var field9;
- /*element: Class2.field10:Class2.=MapConstant({}),initial=NullConstant*/
+ /*member: Class2.field10:Class2.=MapConstant({}),initial=NullConstant*/
var field10;
- /*element: Class2.field11:Class2.=ConstructedConstant(Symbol(_name=StringConstant("foo"))),initial=NullConstant*/
+ /*member: Class2.field11:Class2.=ConstructedConstant(Symbol(_name=StringConstant("foo"))),initial=NullConstant*/
var field11;
- /*element: Class2.field12:Class2.=IntConstant(5),initial=NullConstant*/
+ /*member: Class2.field12:Class2.=IntConstant(5),initial=NullConstant*/
var field12;
- /*element: Class2.field13:Class2.=BoolConstant(true),initial=NullConstant*/
+ /*member: Class2.field13:Class2.=BoolConstant(true),initial=NullConstant*/
var field13;
- /*element: Class2.field14:Class2.=?,initial=NullConstant*/
+ /*member: Class2.field14:Class2.=?,initial=NullConstant*/
var field14;
Class2()
diff --git a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
index 4096f9e..b2c12c7 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
@@ -59,37 +59,37 @@
const factory Class.fact() = Class.generative;
}
-/*element: field1a:complexity=constant,initial=IntConstant(0)*/
+/*member: field1a:complexity=constant,initial=IntConstant(0)*/
final field1a = 0;
-/*element: field1b:complexity=constant,initial=IntConstant(0)*/
+/*member: field1b:complexity=constant,initial=IntConstant(0)*/
var field1b = 0;
-/*strong.element: field1c:complexity=constant,initial=IntConstant(0)*/
+/*strong.member: field1c:complexity=constant,initial=IntConstant(0)*/
const field1c = 0;
-/*element: field2a:complexity=constant,initial=ListConstant([])*/
+/*member: field2a:complexity=constant,initial=ListConstant([])*/
final field2a = const [];
-/*element: field2b:complexity=constant,initial=ListConstant([])*/
+/*member: field2b:complexity=constant,initial=ListConstant([])*/
var field2b = const [];
-/*strong.element: field2c:complexity=constant,initial=ListConstant([])*/
+/*strong.member: field2c:complexity=constant,initial=ListConstant([])*/
const field2c = const [];
-/*element: field3a:complexity=eager*/
+/*member: field3a:complexity=eager*/
final field3a = [];
-/*element: field3b:complexity=eager*/
+/*member: field3b:complexity=eager*/
var field3b = [];
-/*element: field3c:complexity=eager*/
+/*member: field3c:complexity=eager*/
var field3c = [];
-/*element: field3d:complexity=eager*/
+/*member: field3d:complexity=eager*/
var field3d = [1, 2, 3];
-/*element: field3e:complexity=eager*/
+/*member: field3e:complexity=eager*/
var field3e = [
1,
2,
@@ -100,7 +100,7 @@
]
];
-/*element: field3f:complexity=lazy*/
+/*member: field3f:complexity=lazy*/
var field3f = [
1,
2,
@@ -111,79 +111,79 @@
]
];
-/*element: field3g:complexity=lazy*/
+/*member: field3g:complexity=lazy*/
var field3g = [method()];
// TODO(johnniwinther): Recognize this as of eager complexity.
-/*element: field3h:complexity=lazy*/
+/*member: field3h:complexity=lazy*/
var field3h = [1 + 3];
// TODO(johnniwinther): Recognize `field4*` as of constant complexity.
-/*element: field4a:complexity=lazy,initial=IntConstant(5)*/
+/*member: field4a:complexity=lazy,initial=IntConstant(5)*/
final field4a = 2 + 3;
-/*element: field4b:complexity=lazy,initial=IntConstant(5)*/
+/*member: field4b:complexity=lazy,initial=IntConstant(5)*/
var field4b = 2 + 3;
-/*strong.element: field4c:complexity=lazy,initial=IntConstant(5)*/
+/*strong.member: field4c:complexity=lazy,initial=IntConstant(5)*/
const field4c = 2 + 3;
-/*element: field5a:complexity=constant,initial=FunctionConstant(method)*/
+/*member: field5a:complexity=constant,initial=FunctionConstant(method)*/
final field5a = method;
-/*element: field5b:complexity=constant,initial=FunctionConstant(method)*/
+/*member: field5b:complexity=constant,initial=FunctionConstant(method)*/
var field5b = method;
-/*strong.element: field5c:complexity=constant,initial=FunctionConstant(method)*/
+/*strong.member: field5c:complexity=constant,initial=FunctionConstant(method)*/
const field5c = method;
-/*element: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
+/*member: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
var field6a = const Class.generative();
-/*element: field6b:complexity=constant,initial=ConstructedConstant(Class())*/
+/*member: field6b:complexity=constant,initial=ConstructedConstant(Class())*/
var field6b = const Class.fact();
-/*element: field6c:complexity=lazy*/
+/*member: field6c:complexity=lazy*/
var field6c = method();
-/*element: field7a:complexity=eager*/
+/*member: field7a:complexity=eager*/
var field7a = {};
-/*element: field7b:complexity=eager*/
+/*member: field7b:complexity=eager*/
var field7b = {0: 1};
-/*element: field7c:complexity=eager*/
+/*member: field7c:complexity=eager*/
var field7c = {0: method};
-/*element: field7d:complexity=lazy*/
+/*member: field7d:complexity=lazy*/
var field7d = {0: method()};
-/*element: field7e:complexity=lazy*/
+/*member: field7e:complexity=lazy*/
var field7e = {method(): 0};
-/*element: field8a:complexity=eager*/
+/*member: field8a:complexity=eager*/
var field8a = {};
-/*element: field8b:complexity=eager*/
+/*member: field8b:complexity=eager*/
var field8b = {0};
-/*element: field8c:complexity=eager*/
+/*member: field8c:complexity=eager*/
var field8c = {method};
-/*element: field8d:complexity=lazy*/
+/*member: field8d:complexity=lazy*/
var field8d = {method()};
-/*element: field9a:complexity=eager*/
+/*member: field9a:complexity=eager*/
var field9a = [];
-/*element: field9b:complexity=eager&fields=[field9a]*/
+/*member: field9b:complexity=eager&fields=[field9a]*/
var field9b = field9a;
-/*element: field9c:complexity=eager&fields=[field9b]*/
+/*member: field9c:complexity=eager&fields=[field9b]*/
var field9c = [field9b];
-/*element: field10a:complexity=eager&fields=[field10b]*/
+/*member: field10a:complexity=eager&fields=[field10b]*/
int field10a = field10b;
-/*element: field10b:complexity=eager&fields=[field10a]*/
+/*member: field10b:complexity=eager&fields=[field10a]*/
int field10b = field10a;
diff --git a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
index 9fe7c7d..1f8c21a 100644
--- a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
@@ -6,7 +6,6 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/js_backend/field_analysis.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/util/features.dart';
@@ -62,8 +61,9 @@
features[Tags.complexity] = staticFieldData.complexity.shortText;
}
Id id = computeEntityId(node);
- actualMap[id] = new ActualData<Features>(
- id, features, computeSourceSpanFromTreeNode(node), member);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ actualMap[id] = new ActualData<Features>(id, features,
+ nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
}
}
diff --git a/tests/compiler/dart2js/impact/data/as.dart b/tests/compiler/dart2js/impact/data/as.dart
index b7b196a..fd2fe10 100644
--- a/tests/compiler/dart2js/impact/data/as.dart
+++ b/tests/compiler/dart2js/impact/data/as.dart
@@ -2,21 +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.
-/*element: main:static=[explicitAs(1),implicitAs(1),promoted(1)],type=[inst:JSNull]*/
+/*member: main:static=[explicitAs(1),implicitAs(1),promoted(1)],type=[inst:JSNull]*/
main() {
explicitAs(null);
implicitAs(null);
promoted(null);
}
-/*element: explicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
+/*member: explicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
explicitAs(String i) {
i.length;
// ignore: unnecessary_cast
return i as String;
}
-/*element: implicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
+/*member: implicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
String implicitAs(String i) {
dynamic j = i;
i.length;
@@ -24,7 +24,7 @@
return j;
}
-/*element: promoted:dynamic=[String.length],type=[inst:JSBool,inst:JSNull,is:String]*/
+/*member: promoted:dynamic=[String.length],type=[inst:JSBool,inst:JSNull,is:String]*/
String promoted(dynamic i) {
if (i is! String) return null;
i.length;
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index bde8eb7..0684ce7 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.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.
-/*element: main:
+/*member: main:
static=[
testAnonymousAsync(0),
testAnonymousAsyncStar(0),
@@ -31,7 +31,7 @@
testAsyncForInTyped(null);
}
-/*element: testSyncStar:
+/*member: testSyncStar:
static=[
_IterationMarker.endOfIteration(0),
_IterationMarker.uncaughtError(1),
@@ -40,7 +40,7 @@
*/
testSyncStar() sync* {}
-/*element: testAsync:
+/*member: testAsync:
static=[
StreamIterator.(1),
_asyncAwait(2),
@@ -52,7 +52,7 @@
*/
testAsync() async {}
-/*element: testAsyncStar:
+/*member: testAsyncStar:
static=[
StreamIterator.(1),
_IterationMarker.yieldSingle(1),
@@ -64,7 +64,7 @@
*/
testAsyncStar() async* {}
-/*element: testLocalSyncStar:
+/*member: testLocalSyncStar:
static=[
_IterationMarker.endOfIteration(0),
_IterationMarker.uncaughtError(1),
@@ -88,7 +88,7 @@
return local;
}
-/*element: testLocalAsync:
+/*member: testLocalAsync:
static=[
StreamIterator.(1),
_asyncAwait(2),
@@ -115,7 +115,7 @@
return local;
}
-/*element: testLocalAsyncStar:
+/*member: testLocalAsyncStar:
static=[
StreamIterator.(1),
_IterationMarker.yieldSingle(1),
@@ -142,7 +142,7 @@
return local;
}
-/*element: testAnonymousSyncStar:
+/*member: testAnonymousSyncStar:
static=[
_IterationMarker.endOfIteration(0),
_IterationMarker.uncaughtError(1),
@@ -165,7 +165,7 @@
return () sync* {};
}
-/*element: testAnonymousAsync:
+/*member: testAnonymousAsync:
static=[
StreamIterator.(1),
_asyncAwait(2),
@@ -191,7 +191,7 @@
return () async {};
}
-/*element: testAnonymousAsyncStar:
+/*member: testAnonymousAsyncStar:
static=[
StreamIterator.(1),
_IterationMarker.yieldSingle(1),
@@ -217,7 +217,7 @@
return () async* {};
}
-/*element: testAsyncForIn:
+/*member: testAsyncForIn:
dynamic=[
_StreamIterator.cancel(0),
_StreamIterator.current,
@@ -241,7 +241,7 @@
await for (var e in o) {}
}
-/*element: testAsyncForInTyped:
+/*member: testAsyncForInTyped:
dynamic=[
_StreamIterator.cancel(0),
_StreamIterator.current,
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index 5a067d6..d35718d 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.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.
-/*element: main:
+/*member: main:
static=[
testAbstractClassWithField(0),
testEnum(0),
@@ -40,104 +40,104 @@
testGenericNamedMixinInstantiation();
}
-/*element: Super1.:static=[Object.(0)]*/
+/*member: Super1.:static=[Object.(0)]*/
class Super1 {
- /*element: Super1.foo:*/
+ /*member: Super1.foo:*/
foo() {}
}
class Sub1 extends Super1 {
- /*element: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
+ /*member: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
Sub1() {
super.foo();
}
}
-/*element: testSuperCall:static=[Sub1.(0)]*/
+/*member: testSuperCall:static=[Sub1.(0)]*/
testSuperCall() => new Sub1();
-/*element: Super2.:static=[Object.(0)]*/
+/*member: Super2.:static=[Object.(0)]*/
class Super2 {
- /*element: Super2.foo:type=[inst:JSNull]*/
+ /*member: Super2.foo:type=[inst:JSNull]*/
var foo;
}
class Sub2 extends Super2 {
- /*element: Sub2.:static=[Super2.(0),Super2.foo]*/
+ /*member: Sub2.:static=[Super2.(0),Super2.foo]*/
Sub2() {
super.foo;
}
}
-/*element: testSuperGet:static=[Sub2.(0)]*/
+/*member: testSuperGet:static=[Sub2.(0)]*/
testSuperGet() => new Sub2();
-/*element: Super3.:static=[Object.(0)]*/
+/*member: Super3.:static=[Object.(0)]*/
class Super3 {
- /*element: Super3.foo:type=[inst:JSNull]*/
+ /*member: Super3.foo:type=[inst:JSNull]*/
var foo;
}
class Sub3 extends Super3 {
- /*element: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
+ /*member: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
Sub3() {
super.foo = true;
}
}
-/*element: testSuperFieldSet:static=[Sub3.(0)]*/
+/*member: testSuperFieldSet:static=[Sub3.(0)]*/
testSuperFieldSet() => new Sub3();
-/*element: Super4.:static=[Object.(0)]*/
+/*member: Super4.:static=[Object.(0)]*/
class Super4 {
- /*element: Super4.foo=:*/
+ /*member: Super4.foo=:*/
set foo(_) {}
}
class Sub4 extends Super4 {
- /*element: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
+ /*member: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
Sub4() {
super.foo = true;
}
}
-/*element: testSuperSetterSet:static=[Sub4.(0)]*/
+/*member: testSuperSetterSet:static=[Sub4.(0)]*/
testSuperSetterSet() => new Sub4();
-/*element: Super5.:static=[Object.(0)]*/
+/*member: Super5.:static=[Object.(0)]*/
class Super5 {
- /*element: Super5.foo:*/
+ /*member: Super5.foo:*/
foo() {}
}
-/*element: Sub5.:static=[Super5.(0),Super5.foo]*/
+/*member: Sub5.:static=[Super5.(0),Super5.foo]*/
class Sub5 extends Super5 {
Sub5() {
super.foo;
}
}
-/*element: testSuperClosurization:static=[Sub5.(0)]*/
+/*member: testSuperClosurization:static=[Sub5.(0)]*/
testSuperClosurization() => new Sub5();
class EmptyMixin {}
class ForwardingConstructorSuperClass {
- /*element: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
+ /*member: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
ForwardingConstructorSuperClass(arg);
}
class ForwardingConstructorClass = ForwardingConstructorSuperClass
with EmptyMixin;
-/*element: testForwardingConstructor:
+/*member: testForwardingConstructor:
static=[ForwardingConstructorClass.(1)],
type=[inst:JSNull]
*/
testForwardingConstructor() => new ForwardingConstructorClass(null);
class ForwardingConstructorTypedSuperClass {
- /*element: ForwardingConstructorTypedSuperClass.:
+ /*member: ForwardingConstructorTypedSuperClass.:
static=[Object.(0)],
type=[inst:JSBool,param:int]
*/
@@ -147,14 +147,14 @@
class ForwardingConstructorTypedClass = ForwardingConstructorTypedSuperClass
with EmptyMixin;
-/*element: testForwardingConstructorTyped:
+/*member: testForwardingConstructorTyped:
static=[ForwardingConstructorTypedClass.(1)],
type=[inst:JSNull]
*/
testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
class ForwardingConstructorGenericSuperClass<T> {
- /*element: ForwardingConstructorGenericSuperClass.:
+ /*member: ForwardingConstructorGenericSuperClass.:
static=[
Object.(0),
checkSubtype(4),
@@ -179,7 +179,7 @@
class ForwardingConstructorGenericClass<
S> = ForwardingConstructorGenericSuperClass<S> with EmptyMixin;
-/*element: testForwardingConstructorGeneric:
+/*member: testForwardingConstructorGeneric:
static=[
ForwardingConstructorGenericClass.(1),
assertIsSubtype(5),
@@ -191,7 +191,7 @@
}
enum Enum {
- /*strong.element: Enum.A:static=[Enum.(2)],
+ /*strong.member: Enum.A:static=[Enum.(2)],
type=[
inst:JSBool,
inst:JSDouble,
@@ -206,8 +206,8 @@
A
}
-/*strong.element: testEnum:static=[Enum.A]*/
-/*strongConst.element: testEnum:
+/*strong.member: testEnum:static=[Enum.A]*/
+/*strongConst.member: testEnum:
static=[
Enum._name=StringConstant("Enum.A"),
Enum.index=IntConstant(0)],
@@ -223,7 +223,7 @@
*/
testEnum() => Enum.A;
-/*element: staticGenericMethod:
+/*member: staticGenericMethod:
static=[
checkSubtype(4),
checkSubtypeOfRuntimeType(2),
@@ -245,7 +245,7 @@
*/
List<T> staticGenericMethod<T>(T arg) => [arg];
-/*element: testStaticGenericMethod:
+/*member: testStaticGenericMethod:
static=[staticGenericMethod<bool>(1)],
type=[inst:JSBool]
*/
@@ -253,7 +253,7 @@
staticGenericMethod<bool>(true);
}
-/*element: testInstanceGenericMethod:
+/*member: testInstanceGenericMethod:
dynamic=[exact:GenericClass.genericMethod<bool>(1)],
static=[
GenericClass.generative(0),
@@ -269,20 +269,20 @@
// ignore: UNUSED_FIELD
final _field;
- /*element: AbstractClass.:type=[inst:JSNull]*/
+ /*member: AbstractClass.:type=[inst:JSNull]*/
factory AbstractClass() => null;
}
-/*element: testAbstractClassWithField:static=[AbstractClass.(0)]*/
+/*member: testAbstractClassWithField:static=[AbstractClass.(0)]*/
testAbstractClassWithField() => new AbstractClass();
-/*element: testMixinInstantiation:static=[Sub.(0)]*/
+/*member: testMixinInstantiation:static=[Sub.(0)]*/
testMixinInstantiation() => new Sub();
-/*element: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
+/*member: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
testNamedMixinInstantiation() => new NamedMixin();
-/*element: testGenericMixinInstantiation:
+/*member: testGenericMixinInstantiation:
static=[
GenericSub.(0),
assertIsSubtype(5),
@@ -290,7 +290,7 @@
*/
testGenericMixinInstantiation() => new GenericSub<int, String>();
-/*element: testGenericNamedMixinInstantiation:
+/*member: testGenericNamedMixinInstantiation:
static=[
GenericNamedMixin.(0),
assertIsSubtype(5),
@@ -299,14 +299,14 @@
testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
class Class {
- /*element: GenericClass.generative:static=[Object.(0)]*/
+ /*member: GenericClass.generative:static=[Object.(0)]*/
const Class.generative();
}
class GenericClass<X, Y> {
const GenericClass.generative();
- /*element: GenericClass.genericMethod:
+ /*member: GenericClass.genericMethod:
static=[
checkSubtype(4),
checkSubtypeOfRuntimeType(2),
@@ -330,26 +330,26 @@
Map<X, T> genericMethod<T>(T arg) => {null: arg};
}
-/*element: Super.:static=[Object.(0)]*/
+/*member: Super.:static=[Object.(0)]*/
class Super {}
class Mixin1 {}
class Mixin2 {}
-/*element: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
+/*member: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
class Sub extends Super with Mixin1, Mixin2 {}
class NamedMixin = Super with Mixin1, Mixin2;
-/*element: GenericSuper.:static=[Object.(0)]*/
+/*member: GenericSuper.:static=[Object.(0)]*/
class GenericSuper<X1, Y1> {}
class GenericMixin1<X2, Y2> {}
class GenericMixin2<X3, Y3> {}
-/*element: GenericSub.:
+/*member: GenericSub.:
static=[_GenericSub&GenericSuper&GenericMixin1&GenericMixin2.(0)]
*/
class GenericSub<X4, Y4> extends GenericSuper<X4, Y4>
diff --git a/tests/compiler/dart2js/impact/data/constants.dart b/tests/compiler/dart2js/impact/data/constants.dart
index 12db520..9ad48e4 100644
--- a/tests/compiler/dart2js/impact/data/constants.dart
+++ b/tests/compiler/dart2js/impact/data/constants.dart
@@ -5,7 +5,7 @@
import '../libs/constants_lib.dart';
import '../libs/constants_lib.dart' deferred as defer;
-/*element: main:static=**/
+/*member: main:static=**/
main() {
nullLiteral();
boolLiteral();
@@ -56,209 +56,209 @@
staticTearOffDeferred();
}
-/*element: nullLiteral:type=[inst:JSNull]*/
+/*member: nullLiteral:type=[inst:JSNull]*/
nullLiteral() {
const dynamic local = null;
return local;
}
-/*element: boolLiteral:type=[inst:JSBool]*/
+/*member: boolLiteral:type=[inst:JSBool]*/
boolLiteral() {
const dynamic local = true;
return local;
}
-/*element: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
intLiteral() {
const dynamic local = 42;
return local;
}
-/*element: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
doubleLiteral() {
const dynamic local = 0.5;
return local;
}
-/*element: stringLiteral:type=[inst:JSString]*/
+/*member: stringLiteral:type=[inst:JSString]*/
stringLiteral() {
const dynamic local = "foo";
return local;
}
-/*element: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
symbolLiteral() => #foo;
-/*element: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
listLiteral() => const [true, false];
-/*element: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
mapLiteral() => const {true: false};
-/*element: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*member: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
stringMapLiteral() => const {'foo': false};
-/*element: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*member: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
setLiteral() => const {true, false};
-/*strong.element: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
-/*strongConst.element: instanceConstant:
+/*strong.member: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
+/*strongConst.member: instanceConstant:
static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
type=[const:Class,inst:JSBool]
*/
instanceConstant() => const Class(true, false);
-/*element: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+/*member: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
typeLiteral() {
const dynamic local = String;
return local;
}
-/*element: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*member: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
instantiation() {
const int Function(int) local = id;
return local;
}
-/*element: topLevelTearOff:static=[topLevelMethod]*/
+/*member: topLevelTearOff:static=[topLevelMethod]*/
topLevelTearOff() {
const dynamic local = topLevelMethod;
return local;
}
-/*element: staticTearOff:static=[Class.staticMethodField]*/
+/*member: staticTearOff:static=[Class.staticMethodField]*/
staticTearOff() {
const dynamic local = Class.staticMethodField;
return local;
}
-/*strong.element: nullLiteralRef:static=[nullLiteralField]*/
-/*strongConst.element: nullLiteralRef:type=[inst:JSNull]*/
+/*strong.member: nullLiteralRef:static=[nullLiteralField]*/
+/*strongConst.member: nullLiteralRef:type=[inst:JSNull]*/
nullLiteralRef() => nullLiteralField;
-/*strong.element: boolLiteralRef:static=[boolLiteralField]*/
-/*strongConst.element: boolLiteralRef:type=[inst:JSBool]*/
+/*strong.member: boolLiteralRef:static=[boolLiteralField]*/
+/*strongConst.member: boolLiteralRef:type=[inst:JSBool]*/
boolLiteralRef() => boolLiteralField;
-/*strong.element: intLiteralRef:static=[intLiteralField]*/
-/*strongConst.element: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralRef:static=[intLiteralField]*/
+/*strongConst.member: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
intLiteralRef() => intLiteralField;
-/*strong.element: doubleLiteralRef:static=[doubleLiteralField]*/
-/*strongConst.element: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralRef:static=[doubleLiteralField]*/
+/*strongConst.member: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
doubleLiteralRef() => doubleLiteralField;
-/*strong.element: stringLiteralRef:static=[stringLiteralField]*/
-/*strongConst.element: stringLiteralRef:type=[inst:JSString]*/
+/*strong.member: stringLiteralRef:static=[stringLiteralField]*/
+/*strongConst.member: stringLiteralRef:type=[inst:JSString]*/
stringLiteralRef() => stringLiteralField;
-/*strong.element: symbolLiteralRef:static=[symbolLiteralField]*/
-/*strongConst.element: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: symbolLiteralRef:static=[symbolLiteralField]*/
+/*strongConst.member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
symbolLiteralRef() => symbolLiteralField;
-/*strong.element: listLiteralRef:static=[listLiteralField]*/
-/*strongConst.element: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*strong.member: listLiteralRef:static=[listLiteralField]*/
+/*strongConst.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
listLiteralRef() => listLiteralField;
-/*strong.element: mapLiteralRef:static=[mapLiteralField]*/
-/*strongConst.element: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strong.member: mapLiteralRef:static=[mapLiteralField]*/
+/*strongConst.member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
mapLiteralRef() => mapLiteralField;
-/*strong.element: stringMapLiteralRef:static=[stringMapLiteralField]*/
-/*strongConst.element: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strong.member: stringMapLiteralRef:static=[stringMapLiteralField]*/
+/*strongConst.member: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
stringMapLiteralRef() => stringMapLiteralField;
-/*strong.element: setLiteralRef:static=[setLiteralField]*/
-/*strongConst.element: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strong.member: setLiteralRef:static=[setLiteralField]*/
+/*strongConst.member: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
setLiteralRef() => setLiteralField;
-/*strong.element: instanceConstantRef:static=[instanceConstantField]*/
-/*strongConst.element: instanceConstantRef:
+/*strong.member: instanceConstantRef:static=[instanceConstantField]*/
+/*strongConst.member: instanceConstantRef:
static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
type=[const:Class,inst:JSBool]
*/
instanceConstantRef() => instanceConstantField;
-/*strong.element: typeLiteralRef:static=[typeLiteralField]*/
-/*strongConst.element: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+/*strong.member: typeLiteralRef:static=[typeLiteralField]*/
+/*strongConst.member: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
typeLiteralRef() => typeLiteralField;
-/*strong.element: instantiationRef:static=[instantiationField]*/
-/*strongConst.element: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*strong.member: instantiationRef:static=[instantiationField]*/
+/*strongConst.member: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
instantiationRef() => instantiationField;
-/*strong.element: topLevelTearOffRef:static=[topLevelTearOffField]*/
-/*strongConst.element: topLevelTearOffRef:static=[topLevelMethod]*/
+/*strong.member: topLevelTearOffRef:static=[topLevelTearOffField]*/
+/*strongConst.member: topLevelTearOffRef:static=[topLevelMethod]*/
topLevelTearOffRef() => topLevelTearOffField;
-/*strong.element: staticTearOffRef:static=[staticTearOffField]*/
-/*strongConst.element: staticTearOffRef:static=[Class.staticMethodField]*/
+/*strong.member: staticTearOffRef:static=[staticTearOffField]*/
+/*strongConst.member: staticTearOffRef:static=[Class.staticMethodField]*/
staticTearOffRef() => staticTearOffField;
-/*strong.element: nullLiteralDeferred:static=[nullLiteralField{defer}]*/
-/*strongConst.element: nullLiteralDeferred:type=[inst:JSNull]*/
+/*strong.member: nullLiteralDeferred:static=[nullLiteralField{defer}]*/
+/*strongConst.member: nullLiteralDeferred:type=[inst:JSNull]*/
nullLiteralDeferred() => defer.nullLiteralField;
-/*strong.element: boolLiteralDeferred:static=[boolLiteralField{defer}]*/
-/*strongConst.element: boolLiteralDeferred:type=[inst:JSBool]*/
+/*strong.member: boolLiteralDeferred:static=[boolLiteralField{defer}]*/
+/*strongConst.member: boolLiteralDeferred:type=[inst:JSBool]*/
boolLiteralDeferred() => defer.boolLiteralField;
-/*strong.element: intLiteralDeferred:static=[intLiteralField{defer}]*/
-/*strongConst.element: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralDeferred:static=[intLiteralField{defer}]*/
+/*strongConst.member: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
intLiteralDeferred() => defer.intLiteralField;
-/*strong.element: doubleLiteralDeferred:static=[doubleLiteralField{defer}]*/
-/*strongConst.element: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralDeferred:static=[doubleLiteralField{defer}]*/
+/*strongConst.member: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
doubleLiteralDeferred() => defer.doubleLiteralField;
-/*strong.element: stringLiteralDeferred:static=[stringLiteralField{defer}]*/
-/*strongConst.element: stringLiteralDeferred:type=[inst:JSString]*/
+/*strong.member: stringLiteralDeferred:static=[stringLiteralField{defer}]*/
+/*strongConst.member: stringLiteralDeferred:type=[inst:JSString]*/
stringLiteralDeferred() => defer.stringLiteralField;
-/*strong.element: symbolLiteralDeferred:static=[symbolLiteralField{defer}]*/
+/*strong.member: symbolLiteralDeferred:static=[symbolLiteralField{defer}]*/
// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
symbolLiteralDeferred() => defer.symbolLiteralField;
-/*strong.element: listLiteralDeferred:static=[listLiteralField{defer}]*/
+/*strong.member: listLiteralDeferred:static=[listLiteralField{defer}]*/
// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*strongConst.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
listLiteralDeferred() => defer.listLiteralField;
-/*strong.element: mapLiteralDeferred:static=[mapLiteralField{defer}]*/
+/*strong.member: mapLiteralDeferred:static=[mapLiteralField{defer}]*/
// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strongConst.member: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
mapLiteralDeferred() => defer.mapLiteralField;
-/*strong.element: stringMapLiteralDeferred:static=[stringMapLiteralField{defer}]*/
+/*strong.member: stringMapLiteralDeferred:static=[stringMapLiteralField{defer}]*/
// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strongConst.member: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
stringMapLiteralDeferred() => defer.stringMapLiteralField;
-/*strong.element: setLiteralDeferred:static=[setLiteralField{defer}]*/
+/*strong.member: setLiteralDeferred:static=[setLiteralField{defer}]*/
// TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strongConst.member: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
setLiteralDeferred() => defer.setLiteralField;
-/*strong.element: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
-/*strongConst.element: instanceConstantDeferred:
+/*strong.member: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
+/*strongConst.member: instanceConstantDeferred:
static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
type=[const:Class{defer},inst:JSBool]
*/
instanceConstantDeferred() => defer.instanceConstantField;
-/*strong.element: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
-/*strongConst.element: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
+/*strong.member: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
+/*strongConst.member: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
typeLiteralDeferred() => defer.typeLiteralField;
-/*strong.element: instantiationDeferred:static=[instantiationField{defer}]*/
-/*strongConst.element: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*strong.member: instantiationDeferred:static=[instantiationField{defer}]*/
+/*strongConst.member: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
instantiationDeferred() => defer.instantiationField;
-/*strong.element: topLevelTearOffDeferred:static=[topLevelTearOffField{defer}]*/
-/*strongConst.element: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
+/*strong.member: topLevelTearOffDeferred:static=[topLevelTearOffField{defer}]*/
+/*strongConst.member: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
topLevelTearOffDeferred() => defer.topLevelTearOffField;
-/*strong.element: staticTearOffDeferred:static=[staticTearOffField{defer}]*/
-/*strongConst.element: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
+/*strong.member: staticTearOffDeferred:static=[staticTearOffField{defer}]*/
+/*strongConst.member: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
staticTearOffDeferred() => defer.staticTearOffField;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index 6f98595..a58c2da 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.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.
-/*element: main:
+/*member: main:
static=[
testConstRedirectingFactoryInvoke(0),
testConstRedirectingFactoryInvokeGeneric(0),
@@ -44,119 +44,119 @@
testFactoryConstructor();
}
-/*element: testConstructorInvoke:static=[Class.generative(0)]*/
+/*member: testConstructorInvoke:static=[Class.generative(0)]*/
testConstructorInvoke() {
new Class.generative();
}
-/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
testConstructorInvokeGeneric() {
new GenericClass<int, String>.generative();
}
-/*element: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*member: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
testConstructorInvokeGenericRaw() {
new GenericClass.generative();
}
-/*element: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*member: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
testConstructorInvokeGenericDynamic() {
new GenericClass<dynamic, dynamic>.generative();
}
-/*element: testFactoryInvoke:static=[Class.fact(0)]*/
+/*member: testFactoryInvoke:static=[Class.fact(0)]*/
testFactoryInvoke() {
new Class.fact();
}
-/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype(5),throwTypeError(1)]*/
testFactoryInvokeGeneric() {
new GenericClass<int, String>.fact();
}
-/*element: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
+/*member: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
testFactoryInvokeGenericRaw() {
new GenericClass.fact();
}
-/*element: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
+/*member: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
testFactoryInvokeGenericDynamic() {
new GenericClass<dynamic, dynamic>.fact();
}
-/*element: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*member: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
testRedirectingFactoryInvoke() {
new Class.redirect();
}
-/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
testRedirectingFactoryInvokeGeneric() {
new GenericClass<int, String>.redirect();
}
-/*element: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*member: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
testRedirectingFactoryInvokeGenericRaw() {
new GenericClass.redirect();
}
-/*element: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*member: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
testRedirectingFactoryInvokeGenericDynamic() {
new GenericClass<dynamic, dynamic>.redirect();
}
-/*strong.element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvoke:type=[const:Class]*/
+/*strong.member: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvoke:type=[const:Class]*/
testConstRedirectingFactoryInvoke() {
const Class.redirect();
}
-/*strong.element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
testConstRedirectingFactoryInvokeGeneric() {
const GenericClass<int, String>.redirect();
}
-/*strong.element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
testConstRedirectingFactoryInvokeGenericRaw() {
const GenericClass.redirect();
}
-/*strong.element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
testConstRedirectingFactoryInvokeGenericDynamic() {
const GenericClass<dynamic, dynamic>.redirect();
}
-/*element: ClassImplicitConstructor.:static=[Object.(0)]*/
+/*member: ClassImplicitConstructor.:static=[Object.(0)]*/
class ClassImplicitConstructor {}
-/*element: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
+/*member: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
testImplicitConstructor() => new ClassImplicitConstructor();
class ClassFactoryConstructor {
- /*element: ClassFactoryConstructor.:type=[inst:JSNull]*/
+ /*member: ClassFactoryConstructor.:type=[inst:JSNull]*/
factory ClassFactoryConstructor() => null;
}
-/*element: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
+/*member: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
testFactoryConstructor() => new ClassFactoryConstructor();
class Class {
- /*element: Class.generative:static=[Object.(0)]*/
+ /*member: Class.generative:static=[Object.(0)]*/
const Class.generative();
- /*element: Class.fact:type=[inst:JSNull]*/
+ /*member: Class.fact:type=[inst:JSNull]*/
factory Class.fact() => null;
const factory Class.redirect() = Class.generative;
}
class GenericClass<X, Y> {
- /*element: GenericClass.generative:static=[Object.(0)]*/
+ /*member: GenericClass.generative:static=[Object.(0)]*/
const GenericClass.generative();
- /*element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
+ /*member: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
factory GenericClass.fact() => null;
const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/effectively_final.dart b/tests/compiler/dart2js/impact/data/effectively_final.dart
index 305ca2b..9982845 100644
--- a/tests/compiler/dart2js/impact/data/effectively_final.dart
+++ b/tests/compiler/dart2js/impact/data/effectively_final.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.
-/*element: main:
+/*member: main:
static=[
effectivelyFinalList(0),
effectivelyFinalPromoted(0),
@@ -16,7 +16,7 @@
effectivelyFinalPromotedInvalid();
}
-/*element: effectivelyFinalList:
+/*member: effectivelyFinalList:
dynamic=[
List.add(1),
List.length,
@@ -39,7 +39,7 @@
c.length = 1;
}
-/*element: notEffectivelyFinalList:
+/*member: notEffectivelyFinalList:
dynamic=[
+,
add(1),
@@ -64,10 +64,10 @@
c = null;
}
-/*element: _method1:type=[inst:JSNull]*/
+/*member: _method1:type=[inst:JSNull]*/
num _method1() => null;
-/*element: effectivelyFinalPromoted:
+/*member: effectivelyFinalPromoted:
dynamic=[int.+,num.+],
static=[_method1(0)],
type=[
@@ -88,10 +88,10 @@
}
}
-/*element: _method2:type=[inst:JSNull]*/
+/*member: _method2:type=[inst:JSNull]*/
String _method2() => null;
-/*element: effectivelyFinalPromotedInvalid:
+/*member: effectivelyFinalPromotedInvalid:
dynamic=[String.+,int.+],
static=[_method2(0)],
type=[
diff --git a/tests/compiler/dart2js/impact/data/exact.dart b/tests/compiler/dart2js/impact/data/exact.dart
index 11a6d2d..1c6a6aa 100644
--- a/tests/compiler/dart2js/impact/data/exact.dart
+++ b/tests/compiler/dart2js/impact/data/exact.dart
@@ -2,28 +2,28 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: A.:static=[Object.(0)]*/
+/*member: A.:static=[Object.(0)]*/
class A {
method1() {}
method2() {}
method3() {}
}
-/*element: B.:static=[A.(0)]*/
+/*member: B.:static=[A.(0)]*/
class B extends A {
method1() {}
method2() {}
method3() {}
}
-/*element: C.:static=[B.(0)]*/
+/*member: C.:static=[B.(0)]*/
class C extends B {
method1() {}
method2() {}
method3() {}
}
-/*element: main:static=[callOnEffectivelyFinalB(0),callOnNewB(0),callOnNewC(0)]*/
+/*member: main:static=[callOnEffectivelyFinalB(0),callOnNewB(0),callOnNewC(0)]*/
main() {
callOnNewB();
callOnNewC();
@@ -31,17 +31,17 @@
callOnEffectivelyFinalB();
}
-/*element: callOnNewB:dynamic=[exact:B.method1(0)],static=[B.(0)]*/
+/*member: callOnNewB:dynamic=[exact:B.method1(0)],static=[B.(0)]*/
callOnNewB() {
new B().method1();
}
-/*element: callOnNewC:dynamic=[exact:C.method2(0)],static=[C.(0)]*/
+/*member: callOnNewC:dynamic=[exact:C.method2(0)],static=[C.(0)]*/
callOnNewC() {
new C().method2();
}
-/*element: callOnEffectivelyFinalB:dynamic=[exact:B.method3(0)],static=[B.(0)]*/
+/*member: callOnEffectivelyFinalB:dynamic=[exact:B.method3(0)],static=[B.(0)]*/
callOnEffectivelyFinalB() {
A a = new B();
a.method3();
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index ca8a80d..612c3ce 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.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.
-/*element: main:static=[
+/*member: main:static=[
testAs(1),
testAsGeneric(1),
testAsGenericDynamic(1),
@@ -68,47 +68,47 @@
testSetIfNull(null);
}
-/*element: testNot:type=[inst:JSBool]*/
+/*member: testNot:type=[inst:JSBool]*/
testNot() => !false;
-/*element: testUnaryMinus:
+/*member: testUnaryMinus:
dynamic=[int.unary-],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testUnaryMinus() => -1;
-/*element: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+/*member: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
// ignore: DEAD_CODE
testConditional() => true ? null : '';
-/*element: testPostInc:
+/*member: testPostInc:
dynamic=[+],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testPostInc(o) => o++;
-/*element: testPostDec:
+/*member: testPostDec:
dynamic=[-],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testPostDec(o) => o--;
-/*element: testPreInc:
+/*member: testPreInc:
dynamic=[+],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testPreInc(o) => ++o;
-/*element: testPreDec:
+/*member: testPreDec:
dynamic=[-],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testPreDec(o) => --o;
-/*element: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
testIs() => null is Class;
-/*element: testIsGeneric:
+/*member: testIsGeneric:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -128,20 +128,20 @@
*/
testIsGeneric() => null is GenericClass<int, String>;
-/*element: testIsGenericRaw:
+/*member: testIsGenericRaw:
type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
*/
testIsGenericRaw() => null is GenericClass;
-/*element: testIsGenericDynamic:
+/*member: testIsGenericDynamic:
type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
*/
testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
-/*element: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
testIsNot() => null is! Class;
-/*element: testIsNotGeneric:
+/*member: testIsNotGeneric:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -161,17 +161,17 @@
*/
testIsNotGeneric() => null is! GenericClass<int, String>;
-/*element: testIsNotGenericRaw:
+/*member: testIsNotGenericRaw:
type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
*/
testIsNotGenericRaw() => null is! GenericClass;
-/*element: testIsNotGenericDynamic:
+/*member: testIsNotGenericDynamic:
type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
*/
testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
-/*element: testIsTypedef:
+/*member: testIsTypedef:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -191,7 +191,7 @@
*/
testIsTypedef() => null is Typedef;
-/*element: testIsTypedefGeneric:
+/*member: testIsTypedefGeneric:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -210,7 +210,7 @@
is:int Function(String)]*/
testIsTypedefGeneric() => null is GenericTypedef<int, String>;
-/*element: testIsTypedefGenericRaw:
+/*member: testIsTypedefGenericRaw:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -229,7 +229,7 @@
is:dynamic Function(dynamic)]*/
testIsTypedefGenericRaw() => null is GenericTypedef;
-/*element: testIsTypedefGenericDynamic:
+/*member: testIsTypedefGenericDynamic:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -248,7 +248,7 @@
is:dynamic Function(dynamic)]*/
testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
-/*element: testIsTypedefDeep:
+/*member: testIsTypedefDeep:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -267,14 +267,14 @@
is:List<int Function(dynamic Function(dynamic))>]*/
testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
-/*element: testAs:
+/*member: testAs:
static=[throwRuntimeError(1)],
type=[as:Class,inst:JSBool]
*/
// ignore: UNNECESSARY_CAST
testAs(dynamic o) => o as Class;
-/*element: testAsGeneric:static=[checkSubtype(4),
+/*member: testAsGeneric:static=[checkSubtype(4),
getRuntimeTypeArgument(3),
getRuntimeTypeArgumentIntercepted(4),
getRuntimeTypeInfo(1),
@@ -292,38 +292,38 @@
// ignore: UNNECESSARY_CAST
testAsGeneric(dynamic o) => o as GenericClass<int, String>;
-/*element: testAsGenericRaw:
+/*member: testAsGenericRaw:
static=[throwRuntimeError(1)],
type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
*/
// ignore: UNNECESSARY_CAST
testAsGenericRaw(dynamic o) => o as GenericClass;
-/*element: testAsGenericDynamic:
+/*member: testAsGenericDynamic:
static=[throwRuntimeError(1)],
type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
*/
// ignore: UNNECESSARY_CAST
testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
-/*element: testThrow:
+/*member: testThrow:
static=[throwExpression(1),wrapException(1)],
type=[inst:JSString]*/
testThrow() => throw '';
-/*element: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
+/*member: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
testIfNotNull(o) => o?.foo;
-/*element: testTypedIfNotNull:dynamic=[Class.==,Class.field],type=[inst:JSBool,inst:JSNull,param:Class]*/
+/*member: testTypedIfNotNull:dynamic=[Class.==,Class.field],type=[inst:JSBool,inst:JSNull,param:Class]*/
testTypedIfNotNull(Class o) => o?.field;
-/*element: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
+/*member: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
testIfNotNullSet(o) => o?.foo = true;
-/*element: testIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
+/*member: testIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
testIfNull(o) => o ?? true;
-/*element: testSetIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
+/*member: testSetIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
testSetIfNull(o) => o ??= true;
class Class {
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index 0f7f42a..9971b61 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -9,10 +9,10 @@
class B<S, U> {}
-/*element: C.:static=[Object.(0)]*/
+/*member: C.:static=[Object.(0)]*/
class C implements A<int>, B<String, bool> {}
-/*element: testA:
+/*member: testA:
dynamic=[call<A.T>(0)],
static=[
checkSubtype(4),
@@ -34,7 +34,7 @@
*/
testA(c, f) => extractTypeArguments<A>(c, f);
-/*element: testB:
+/*member: testB:
dynamic=[call<B.S,B.U>(0)],
static=[
checkSubtype(4),
@@ -57,7 +57,7 @@
*/
testB(c, f) => extractTypeArguments<B>(c, f);
-/*element: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
+/*member: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
main() {
var c = new C();
testA(c, null);
diff --git a/tests/compiler/dart2js/impact/data/future_or.dart b/tests/compiler/dart2js/impact/data/future_or.dart
index 21f6b17..40cdeea 100644
--- a/tests/compiler/dart2js/impact/data/future_or.dart
+++ b/tests/compiler/dart2js/impact/data/future_or.dart
@@ -4,7 +4,7 @@
import "dart:async";
-/*element: main:
+/*member: main:
dynamic=[runtimeType],
runtimeType=[unknown:FutureOr<int>],
static=[Future.value(1),assertIsSubtype(5),print(1),throwTypeError(1)],
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 3f954f9..53b2ff0 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.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.
-/*element: main:
+/*member: main:
static=[
testDefaultValuesNamed(0),
testDefaultValuesPositional(0),
@@ -28,54 +28,54 @@
testGenericClass();
}
-/*strong.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
-/*strongConst.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+/*strong.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+/*strongConst.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
testDefaultValuesPositional([bool value = false]) {}
-/*strong.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
-/*strongConst.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+/*strong.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+/*strongConst.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
testDefaultValuesNamed({bool value: false}) {}
class ClassFieldInitializer1 {
- /*element: ClassFieldInitializer1.field:type=[inst:JSNull]*/
+ /*member: ClassFieldInitializer1.field:type=[inst:JSNull]*/
var field;
- /*element: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
+ /*member: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
ClassFieldInitializer1(this.field);
}
-/*element: testFieldInitializer1:
+/*member: testFieldInitializer1:
static=[ClassFieldInitializer1.(1)],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testFieldInitializer1() => new ClassFieldInitializer1(42);
class ClassFieldInitializer2 {
- /*element: ClassFieldInitializer2.field:type=[inst:JSNull]*/
+ /*member: ClassFieldInitializer2.field:type=[inst:JSNull]*/
var field;
- /*element: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
+ /*member: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
ClassFieldInitializer2(value) : field = value;
}
-/*element: testFieldInitializer2:
+/*member: testFieldInitializer2:
static=[ClassFieldInitializer2.(1)],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
testFieldInitializer2() => new ClassFieldInitializer2(42);
class ClassFieldInitializer3 {
- /*element: ClassFieldInitializer3.field:type=[inst:JSNull]*/
+ /*member: ClassFieldInitializer3.field:type=[inst:JSNull]*/
var field;
- /*element: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
+ /*member: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
ClassFieldInitializer3.a();
- /*element: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
+ /*member: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
ClassFieldInitializer3.b(value) : field = value;
}
-/*element: testFieldInitializer3:
+/*member: testFieldInitializer3:
static=[ClassFieldInitializer3.a(0),ClassFieldInitializer3.b(1)],
type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
*/
@@ -84,45 +84,45 @@
new ClassFieldInitializer3.b(42);
}
-/*element: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
+/*member: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
class ClassInstanceFieldWithInitializer {
- /*element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
+ /*member: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
var field = false;
}
-/*element: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
+/*member: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
testInstanceFieldWithInitializer() => new ClassInstanceFieldWithInitializer();
-/*element: ClassInstanceFieldTyped.:static=[Object.(0)]*/
+/*member: ClassInstanceFieldTyped.:static=[Object.(0)]*/
class ClassInstanceFieldTyped {
- /*element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
+ /*member: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
int field;
}
-/*element: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
+/*member: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
testInstanceFieldTyped() => new ClassInstanceFieldTyped();
class ClassThisInitializer {
- /*element: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
+ /*member: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
ClassThisInitializer() : this.internal();
- /*element: ClassThisInitializer.internal:static=[Object.(0)]*/
+ /*member: ClassThisInitializer.internal:static=[Object.(0)]*/
ClassThisInitializer.internal();
}
-/*element: testThisInitializer:static=[ClassThisInitializer.(0)]*/
+/*member: testThisInitializer:static=[ClassThisInitializer.(0)]*/
testThisInitializer() => new ClassThisInitializer();
class ClassSuperInitializer extends ClassThisInitializer {
- /*element: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
+ /*member: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
ClassSuperInitializer() : super.internal();
}
-/*element: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
+/*member: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
testSuperInitializer() => new ClassSuperInitializer();
class ClassGeneric<T> {
- /*element: ClassGeneric.:
+ /*member: ClassGeneric.:
static=[
Object.(0),
checkSubtype(4),
@@ -144,5 +144,5 @@
ClassGeneric(T arg);
}
-/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype(5),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype(5),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
testGenericClass() => new ClassGeneric<int>(0);
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 526414c..9fa188c 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -12,13 +12,13 @@
class E {}
-/*element: Class1.:static=[Object.(0)]*/
+/*member: Class1.:static=[Object.(0)]*/
class Class1 {
- /*element: Class1.field1:type=[inst:JSBool,inst:JSNull,param:A]*/
+ /*member: Class1.field1:type=[inst:JSBool,inst:JSNull,param:A]*/
A field1;
}
-/*element: method1:
+/*member: method1:
dynamic=[Class1.field1=],
type=[
impl:A,
@@ -30,16 +30,16 @@
o.field1 = value;
}
-/*element: Class2.:static=[Object.(0)]*/
+/*member: Class2.:static=[Object.(0)]*/
class Class2<T> {
- /*element: Class2.field2:
+ /*member: Class2.field2:
static=*,
type=[inst:*,param:Class2.T]
*/
T field2;
}
-/*element: method2:
+/*member: method2:
dynamic=[Class2.field2=],
static=*,
type=[
@@ -52,13 +52,13 @@
o.field2 = value;
}
-/*element: Class3.:static=[Object.(0)]*/
+/*member: Class3.:static=[Object.(0)]*/
class Class3 {
- /*element: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+ /*member: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
method3(A a, [B b, C c]) {}
}
-/*element: method3:
+/*member: method3:
dynamic=[Class3.method3(3)],
type=[
impl:A,
@@ -72,15 +72,15 @@
o.method3(a, b, c);
}
-/*element: Class4.:static=[Object.(0)]*/
+/*member: Class4.:static=[Object.(0)]*/
class Class4 {
- /*element: Class4.method4:
+ /*member: Class4.method4:
type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]
*/
method4(A a, {B b, C c}) {}
}
-/*element: method4:
+/*member: method4:
dynamic=[Class4.method4(1,b,c)],
type=[
impl:A,
@@ -94,9 +94,9 @@
o.method4(a, c: c, b: b);
}
-/*element: Class5.:static=[Object.(0)]*/
+/*member: Class5.:static=[Object.(0)]*/
class Class5<T1, T2> {
- /*element: Class5.method5:
+ /*member: Class5.method5:
static=*,
type=[
inst:*,
@@ -110,7 +110,7 @@
method5<S1, S2>(T1 a, [T2 b, C c, S1 d, S2 e]) {}
}
-/*element: method5:
+/*member: method5:
dynamic=[Class5.method5<D,E>(5)],
static=*,
type=[
@@ -127,9 +127,9 @@
o.method5<D, E>(a, b, c, d, e);
}
-/*element: Class6.:static=[Object.(0)]*/
+/*member: Class6.:static=[Object.(0)]*/
class Class6<T1, T2> {
- /*element: Class6.method6:
+ /*member: Class6.method6:
static=*,
type=[
inst:*,
@@ -143,7 +143,7 @@
method6<S1, S2>(T1 a, {T2 b, C c, S1 d, S2 e}) {}
}
-/*element: method6:
+/*member: method6:
dynamic=[Class6.method6<D,E>(1,b,c,d,e)],
static=*,
type=[
@@ -160,13 +160,13 @@
o.method6<D, E>(a, d: d, b: b, e: e, c: c);
}
-/*element: Class7.:static=[Object.(0)]*/
+/*member: Class7.:static=[Object.(0)]*/
class Class7 {
- /*element: Class7.f:type=[inst:JSNull]*/
+ /*member: Class7.f:type=[inst:JSNull]*/
A Function(A) get f => null;
}
-/*element: method7:
+/*member: method7:
dynamic=[Class7.f(1),call(1)],
type=[impl:A,inst:JSBool,is:Class7]
*/
@@ -175,19 +175,19 @@
o.f(a);
}
-/*element: F.:static=[Object.(0)]*/
+/*member: F.:static=[Object.(0)]*/
class F<T> {
- /*element: F.method:static=*,type=[inst:*,param:List<F.T>]*/
+ /*member: F.method:static=*,type=[inst:*,param:List<F.T>]*/
T method(List<T> list) => null;
- /*element: F.field:static=*,type=[inst:*,param:F.T]*/
+ /*member: F.field:static=*,type=[inst:*,param:F.T]*/
T field;
}
-/*element: G.:static=[F.(0)]*/
+/*member: G.:static=[F.(0)]*/
class G extends F<int> {}
-/*element: method8:
+/*member: method8:
dynamic=[G.method(1)],
static=*,
type=[impl:List<int>,inst:*,is:G,param:Iterable<int>]
@@ -197,7 +197,7 @@
return g.method(iterable);
}
-/*element: method9:
+/*member: method9:
dynamic=[G.field=],
type=[impl:int,inst:JSBool,inst:JSNull,is:G,param:num]
*/
@@ -206,7 +206,7 @@
return g.field = value;
}
-/*element: main:**/
+/*member: main:**/
main() {
method1(new Class1(), null);
method2(new Class2<A>(), null);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index 8a2c534..ffbbce5 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.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.
-/*element: main:
+/*member: main:
static=[
testClosure(0),
testClosureInvoke(0),
@@ -75,16 +75,16 @@
testDynamicPrivateMethodInvoke();
}
-/*element: topLevelFunction1:*/
+/*member: topLevelFunction1:*/
topLevelFunction1(a) {}
-/*element: topLevelFunction2:type=[inst:JSNull]*/
+/*member: topLevelFunction2:type=[inst:JSNull]*/
topLevelFunction2(a, [b, c]) {}
-/*element: topLevelFunction3:type=[inst:JSNull]*/
+/*member: topLevelFunction3:type=[inst:JSNull]*/
topLevelFunction3(a, {b, c}) {}
-/*element: testTopLevelInvoke:
+/*member: testTopLevelInvoke:
static=[
topLevelFunction1(1),
topLevelFunction2(1),
@@ -115,10 +115,10 @@
topLevelFunction3(15, c: 16, b: 17);
}
-/*element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
+/*member: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
void topLevelFunction1Typed(int a) {}
-/*element: topLevelFunction2Typed:
+/*member: topLevelFunction2Typed:
type=[
inst:JSBool,
inst:JSNull,
@@ -128,7 +128,7 @@
*/
int topLevelFunction2Typed(String a, [num b, double c]) => null;
-/*element: topLevelFunction3Typed:
+/*member: topLevelFunction3Typed:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -152,7 +152,7 @@
return null;
}
-/*element: testTopLevelInvokeTyped:
+/*member: testTopLevelInvokeTyped:
static=[
topLevelFunction1Typed(1),
topLevelFunction2Typed(1),
@@ -188,7 +188,7 @@
topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
}
-/*element: topLevelFunctionTyped1:
+/*member: topLevelFunctionTyped1:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -207,7 +207,7 @@
*/
topLevelFunctionTyped1(void a(num b)) {}
-/*element: topLevelFunctionTyped2:
+/*member: topLevelFunctionTyped2:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -226,7 +226,7 @@
*/
topLevelFunctionTyped2(void a(num b, [String c])) {}
-/*element: topLevelFunctionTyped3:
+/*member: topLevelFunctionTyped3:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -245,7 +245,7 @@
*/
topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
-/*element: topLevelFunctionTyped4:
+/*member: topLevelFunctionTyped4:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -264,7 +264,7 @@
*/
topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
-/*element: testTopLevelFunctionTyped:
+/*member: testTopLevelFunctionTyped:
static=[
topLevelFunctionTyped1(1),
topLevelFunctionTyped2(1),
@@ -279,77 +279,77 @@
topLevelFunctionTyped4(null);
}
-/*element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+/*member: testTopLevelFunctionGet:static=[topLevelFunction1]*/
testTopLevelFunctionGet() => topLevelFunction1;
-/*element: topLevelGetter:type=[inst:JSNull]*/
+/*member: topLevelGetter:type=[inst:JSNull]*/
get topLevelGetter => null;
-/*element: testTopLevelGetterGet:static=[topLevelGetter]*/
+/*member: testTopLevelGetterGet:static=[topLevelGetter]*/
testTopLevelGetterGet() => topLevelGetter;
-/*element: topLevelGetterTyped:type=[inst:JSNull]*/
+/*member: topLevelGetterTyped:type=[inst:JSNull]*/
int get topLevelGetterTyped => null;
-/*element: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
+/*member: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
testTopLevelGetterGetTyped() => topLevelGetterTyped;
-/*element: topLevelSetter=:*/
+/*member: topLevelSetter=:*/
set topLevelSetter(_) {}
-/*element: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
+/*member: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
testTopLevelSetterSet() => topLevelSetter = null;
-/*element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
+/*member: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
void set topLevelSetterTyped(int value) {}
-/*element: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
+/*member: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
testTopLevelSetterSetTyped() => topLevelSetterTyped = null;
-/*element: topLevelField:type=[inst:JSNull]*/
+/*member: topLevelField:type=[inst:JSNull]*/
var topLevelField;
-/*element: testTopLevelField:static=[topLevelField]*/
+/*member: testTopLevelField:static=[topLevelField]*/
testTopLevelField() => topLevelField;
-/*element: topLevelFieldLazy:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
+/*member: topLevelFieldLazy:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
var topLevelFieldLazy = topLevelFunction1(null);
-/*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
+/*member: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
testTopLevelFieldLazy() => topLevelFieldLazy;
-/*strong.element: topLevelFieldConst:type=[inst:JSNull]*/
+/*strong.member: topLevelFieldConst:type=[inst:JSNull]*/
const topLevelFieldConst = null;
-/*strong.element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
-/*strongConst.element: testTopLevelFieldConst:type=[inst:JSNull]*/
+/*strong.member: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+/*strongConst.member: testTopLevelFieldConst:type=[inst:JSNull]*/
testTopLevelFieldConst() => topLevelFieldConst;
-/*element: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
+/*member: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
final topLevelFieldFinal = topLevelFunction1(null);
-/*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
+/*member: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
testTopLevelFieldFinal() => topLevelFieldFinal;
-/*element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
+/*member: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
int topLevelFieldTyped;
-/*element: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
+/*member: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
testTopLevelFieldTyped() => topLevelFieldTyped;
-/*element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
GenericClass topLevelFieldGeneric1;
-/*element: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
+/*member: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
-/*element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
-/*element: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
+/*member: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
-/*element: topLevelFieldGeneric3:
+/*member: topLevelFieldGeneric3:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -369,21 +369,21 @@
*/
GenericClass<int, String> topLevelFieldGeneric3;
-/*element: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
+/*member: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
testTopLevelFieldGeneric3() => topLevelFieldGeneric3;
-/*element: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
+/*member: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
testTopLevelFieldWrite() => topLevelField = null;
class StaticFunctionGetClass {
- /*element: StaticFunctionGetClass.foo:*/
+ /*member: StaticFunctionGetClass.foo:*/
static foo() {}
}
-/*element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+/*member: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
testStaticFunctionGet() => StaticFunctionGetClass.foo;
-/*element: testDynamicInvoke:
+/*member: testDynamicInvoke:
dynamic=[
call(1),
call(1,b),
@@ -421,10 +421,10 @@
o.f9(15, c: 16, b: 17);
}
-/*element: testDynamicGet:dynamic=[foo]*/
+/*member: testDynamicGet:dynamic=[foo]*/
testDynamicGet(o) => o.foo;
-/*element: testDynamicSet:
+/*member: testDynamicSet:
dynamic=[foo=],
type=[
inst:JSDouble,
@@ -437,13 +437,13 @@
testDynamicSet(o) => o.foo = 42;
// TODO(johnniwinther): Remove 'inst:Null'.
-/*element: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
+/*member: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
testLocalWithoutInitializer() {
// ignore: UNUSED_LOCAL_VARIABLE
var l;
}
-/*element: testLocalWithInitializer:
+/*member: testLocalWithInitializer:
type=[
inst:JSDouble,
inst:JSInt,
@@ -457,7 +457,7 @@
var l = 42;
}
-/*element: testLocalWithInitializerTyped:
+/*member: testLocalWithInitializerTyped:
type=[
inst:JSDouble,
inst:JSInt,
@@ -471,7 +471,7 @@
int l = 42;
}
-/*element: testLocalFunction:
+/*member: testLocalFunction:
static=[
computeSignature(3),
def:localFunction,
@@ -491,7 +491,7 @@
localFunction() {}
}
-/*element: testLocalFunctionTyped:
+/*member: testLocalFunctionTyped:
static=[
computeSignature(3),
def:localFunction,
@@ -512,7 +512,7 @@
int localFunction(String a) => null;
}
-/*element: testLocalFunctionInvoke:
+/*member: testLocalFunctionInvoke:
dynamic=[call(0)],
static=[computeSignature(3),
def:localFunction,
@@ -531,7 +531,7 @@
localFunction();
}
-/*element: testLocalFunctionGet:static=[computeSignature(3),
+/*member: testLocalFunctionGet:static=[computeSignature(3),
def:localFunction,
getRuntimeTypeArguments(3),
getRuntimeTypeInfo(1),
@@ -547,7 +547,7 @@
localFunction;
}
-/*element: testClosure:static=[computeSignature(3),
+/*member: testClosure:static=[computeSignature(3),
def:<anonymous>,
getRuntimeTypeArguments(3),
getRuntimeTypeInfo(1),
@@ -562,7 +562,7 @@
() {};
}
-/*element: testClosureInvoke:
+/*member: testClosureInvoke:
dynamic=[call(0)],
static=[computeSignature(3),
def:<anonymous>,
@@ -580,7 +580,7 @@
() {}();
}
-/*element: testInvokeIndex:
+/*member: testInvokeIndex:
dynamic=[[]],
type=[inst:JSDouble,
inst:JSInt,
@@ -591,7 +591,7 @@
*/
testInvokeIndex(o) => o[42];
-/*element: testInvokeIndexSet:
+/*member: testInvokeIndexSet:
dynamic=[[]=],
type=[inst:JSDouble,
inst:JSInt,
@@ -603,7 +603,7 @@
*/
testInvokeIndexSet(o) => o[42] = null;
-/*element: testDynamicPrivateMethodInvoke:
+/*member: testDynamicPrivateMethodInvoke:
dynamic=[_privateMethod(0),call(0)],
type=[inst:JSNull]
*/
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 4eccd23..2f40854 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -7,7 +7,7 @@
import 'package:js/js.dart';
-/*element: main:
+/*member: main:
static=[
testJsInteropClass(0),
testJsInteropMethod(0),
@@ -19,16 +19,16 @@
testJsInteropClass();
}
-/*element: testJsInteropMethod:*/
+/*member: testJsInteropMethod:*/
@JS()
external int testJsInteropMethod();
@JS()
class JsInteropClass {
- /*element: JsInteropClass.:static=[JavaScriptObject.(0)]*/
+ /*member: JsInteropClass.:static=[JavaScriptObject.(0)]*/
external JsInteropClass();
- /*element: JsInteropClass.method:
+ /*member: JsInteropClass.method:
type=[
native:ApplicationCacheErrorEvent,
native:DomError,
@@ -48,7 +48,7 @@
external double method();
}
-/*element: testJsInteropClass:
+/*member: testJsInteropClass:
dynamic=[JavaScriptObject.method(0)],
static=[JsInteropClass.(0)]
*/
@@ -56,10 +56,10 @@
typedef void Callback<T>(T value);
-/*element: GenericClass.:static=[JavaScriptObject.(0)]*/
+/*member: GenericClass.:static=[JavaScriptObject.(0)]*/
@JS()
class GenericClass<T> {
- /*element: GenericClass.method:
+ /*member: GenericClass.method:
static=[
checkSubtype(4),
getRuntimeTypeArgument(3),
@@ -80,7 +80,7 @@
external GenericClass method([Callback<T> callback]);
}
-/*element: testOptionalGenericFunctionTypeArgument:
+/*member: testOptionalGenericFunctionTypeArgument:
dynamic=[JavaScriptObject.method(0)],
static=[GenericClass.(0)]
*/
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index c0e5f7d..afb6bdd 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.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.
-/*element: main:static=[
+/*member: main:static=[
testBoolFromEnvironment(0),
testComplexConstSymbol(0),
testConstSymbol(0),
@@ -59,74 +59,74 @@
testNonEmptyMapLiteral();
}
-/*element: testEmpty:*/
+/*member: testEmpty:*/
testEmpty() {}
-/*element: testNull:type=[inst:JSNull]*/
+/*member: testNull:type=[inst:JSNull]*/
testNull() => null;
-/*element: testTrue:type=[inst:JSBool]*/
+/*member: testTrue:type=[inst:JSBool]*/
testTrue() => true;
-/*element: testFalse:type=[inst:JSBool]*/
+/*member: testFalse:type=[inst:JSBool]*/
testFalse() => false;
-/*element: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
testInt() => 42;
-/*element: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
testDouble() => 37.5;
-/*element: testString:type=[inst:JSString]*/
+/*member: testString:type=[inst:JSString]*/
testString() => 'foo';
-/*element: testStringInterpolation:
+/*member: testStringInterpolation:
dynamic=[toString(0)],
static=[S(1)],type=[inst:JSBool,inst:JSString]
*/
testStringInterpolation() => '${true}';
-/*strong.element: testStringInterpolationConst:
+/*strong.member: testStringInterpolationConst:
dynamic=[toString(0)],
static=[S(1)],type=[inst:JSBool,inst:JSString]
*/
-/*strongConst.element: testStringInterpolationConst:type=[inst:JSString]*/
+/*strongConst.member: testStringInterpolationConst:type=[inst:JSString]*/
testStringInterpolationConst() {
const b = '${true}';
return b;
}
-/*element: testStringJuxtaposition:
+/*member: testStringJuxtaposition:
dynamic=[toString(0)],
static=[S(1)],
type=[inst:JSString]
*/
testStringJuxtaposition() => 'a' 'b';
-/*element: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*member: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
testSymbol() => #main;
-/*strong.element: testConstSymbol:
+/*strong.member: testConstSymbol:
static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
type=[inst:JSString,inst:Symbol]
*/
-/*strongConst.element: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
testConstSymbol() => const Symbol('main');
-/*strong.element: complexSymbolField1:
+/*strong.member: complexSymbolField1:
dynamic=[String.length,int.==],
type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
*/
const complexSymbolField1 = "true".length == 4;
-/*strong.element: complexSymbolField2:
+/*strong.member: complexSymbolField2:
dynamic=[toString(0)],
static=[S(1)],
type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]
*/
const complexSymbolField2 = "true" "false" "${true}${null}";
-/*strong.element: complexSymbolField3:
+/*strong.member: complexSymbolField3:
dynamic=[int.+,int.unary-],
static=[
GenericClass.generative(0),
@@ -178,7 +178,7 @@
override: const GenericClass<int, String>.generative(),
};
-/*strong.element: complexSymbolField:
+/*strong.member: complexSymbolField:
static=[
complexSymbolField1,
complexSymbolField2,
@@ -188,56 +188,56 @@
const complexSymbolField =
complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
-/*strong.element: testComplexConstSymbol:
+/*strong.member: testComplexConstSymbol:
static=[Symbol.(1),Symbol.(1),Symbol.validated(1),complexSymbolField],
type=[impl:String,inst:JSBool,inst:Symbol]
*/
-/*strongConst.element: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
testComplexConstSymbol() => const Symbol(complexSymbolField);
-/*strong.element: testIfNullConstSymbol:
+/*strong.member: testIfNullConstSymbol:
dynamic=[Null.==],
static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
type=[inst:JSNull,inst:JSString,inst:Symbol]
*/
-/*strongConst.element: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
testIfNullConstSymbol() => const Symbol(null ?? 'foo');
-/*element: testTypeLiteral:
+/*member: testTypeLiteral:
static=[createRuntimeType(1)],
type=[inst:Type,inst:TypeImpl,lit:Object]
*/
testTypeLiteral() => Object;
-/*strong.element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
-/*strongConst.element: testBoolFromEnvironment:type=[inst:JSBool]*/
+/*strong.member: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+/*strongConst.member: testBoolFromEnvironment:type=[inst:JSBool]*/
testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
-/*element: testEmptyListLiteral:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteral:type=[inst:List<dynamic>]*/
testEmptyListLiteral() => [];
-/*element: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
testEmptyListLiteralDynamic() => <dynamic>[];
-/*element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
testEmptyListLiteralTyped() => <String>[];
-/*element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
testEmptyListLiteralConstant() => const [];
-/*element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
testNonEmptyListLiteral() => [true];
-/*element: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
+/*member: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
testEmptyMapLiteral() => {};
-/*element: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
+/*member: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
-/*element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
testEmptyMapLiteralTyped() => <String, int>{};
-/*element: testEmptyMapLiteralConstant:
+/*member: testEmptyMapLiteralConstant:
type=[
inst:ConstantMap<dynamic,dynamic>,
inst:ConstantProtoMap<dynamic,dynamic>,
@@ -246,10 +246,10 @@
*/
testEmptyMapLiteralConstant() => const {};
-/*element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
testNonEmptyMapLiteral() => {null: true};
class GenericClass<X, Y> {
- /*strong.element: GenericClass.generative:static=[Object.(0)]*/
+ /*strong.member: GenericClass.generative:static=[Object.(0)]*/
const GenericClass.generative();
}
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index 2f9884d..678528c 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -8,7 +8,7 @@
import 'dart:_js_helper';
import 'dart:html_common';
-/*element: main:static=[testJSCall(0),
+/*member: main:static=[testJSCall(0),
testNativeField(1),
testNativeMethod(0),
testNativeMethodCreates(0),
@@ -22,7 +22,7 @@
testNativeMethodReturns();
}
-/*element: testJSCall:
+/*member: testJSCall:
static=[JS<dynamic>(3)],
type=[inst:JSNull,inst:JSString,native:bool,native:int]
*/
@@ -31,13 +31,13 @@
'#',
null);
-/*element: testNativeMethod:*/
+/*member: testNativeMethod:*/
@JSName('foo')
@SupportedBrowser(SupportedBrowser.CHROME)
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
testNativeMethod() native;
-/*element: testNativeMethodCreates:
+/*member: testNativeMethodCreates:
type=[native:JSArray<JSArray.E>,native:Null,native:int]
*/
@Creates('int|Null|JSArray')
@@ -49,14 +49,14 @@
// dependency on the particular types. If `testNativeMethodReturns` was not
// called `testNativeMethodCreates` would instead trigger the native
// instantiations, so the blame is a bit arbitrary.
-/*element: testNativeMethodReturns:type=[*]*/
+/*member: testNativeMethodReturns:type=[*]*/
@Returns('String|Null|JSArray')
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
testNativeMethodReturns() native;
@Native("NativeClass")
class NativeClass {
- /*element: NativeClass.field:
+ /*member: NativeClass.field:
type=[
inst:JSBool,
inst:JSNull,
@@ -76,7 +76,7 @@
}
}
-/*element: testNativeField:
+/*member: testNativeField:
dynamic=[NativeClass.field],
static=[defineProperty(3)],
type=[inst:JSBool,param:NativeClass]
diff --git a/tests/compiler/dart2js/impact/data/promotion.dart b/tests/compiler/dart2js/impact/data/promotion.dart
index a36673d..6b36fb0 100644
--- a/tests/compiler/dart2js/impact/data/promotion.dart
+++ b/tests/compiler/dart2js/impact/data/promotion.dart
@@ -8,7 +8,7 @@
method() {}
}
-/*element: main:
+/*member: main:
static=[
dynamicToEquals(1),
dynamicToHashCode(1),
@@ -37,58 +37,58 @@
dynamicToNoSuchMethodTearOff(null);
}
-/*element: positiveTyped:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass,param:Class]*/
+/*member: positiveTyped:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass,param:Class]*/
positiveTyped(Class cls) {
if (cls is SubClass) cls.method();
}
-/*element: positiveDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
+/*member: positiveDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
positiveDynamic(dynamic cls) {
if (cls is SubClass) cls.method();
}
-/*element: negativeDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
+/*member: negativeDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
negativeDynamic(dynamic cls) {
if (cls is! SubClass) return;
cls.method();
}
-/*element: dynamicToString:dynamic=[Object.toString(0)]*/
+/*member: dynamicToString:dynamic=[Object.toString(0)]*/
dynamicToString(dynamic cls) {
cls.toString();
}
-/*element: dynamicToStringWrong:dynamic=[call(1),toString(1)],type=[inst:JSNull]*/
+/*member: dynamicToStringWrong:dynamic=[call(1),toString(1)],type=[inst:JSNull]*/
dynamicToStringWrong(dynamic cls) {
cls.toString(null);
}
-/*element: dynamicToStringTearOff:dynamic=[Object.toString]*/
+/*member: dynamicToStringTearOff:dynamic=[Object.toString]*/
dynamicToStringTearOff(dynamic cls) {
cls.toString;
}
-/*element: dynamicToEquals:dynamic=[Object.==],type=[inst:JSNull]*/
+/*member: dynamicToEquals:dynamic=[Object.==],type=[inst:JSNull]*/
dynamicToEquals(dynamic cls) {
cls == null;
}
-/*element: dynamicToHashCode:dynamic=[Object.hashCode]*/
+/*member: dynamicToHashCode:dynamic=[Object.hashCode]*/
dynamicToHashCode(dynamic cls) {
cls.hashCode;
}
-/*element: dynamicToNoSuchMethod:dynamic=[Object.noSuchMethod(1)],type=[inst:JSNull]*/
+/*member: dynamicToNoSuchMethod:dynamic=[Object.noSuchMethod(1)],type=[inst:JSNull]*/
dynamicToNoSuchMethod(dynamic cls) {
cls.noSuchMethod(null);
}
-/*element: dynamicToNoSuchMethodWrong:dynamic=[call(0),noSuchMethod(0)]*/
+/*member: dynamicToNoSuchMethodWrong:dynamic=[call(0),noSuchMethod(0)]*/
dynamicToNoSuchMethodWrong(dynamic cls) {
cls.noSuchMethod();
}
-/*element: dynamicToNoSuchMethodTearOff:dynamic=[Object.noSuchMethod]*/
+/*member: dynamicToNoSuchMethodTearOff:dynamic=[Object.noSuchMethod]*/
dynamicToNoSuchMethodTearOff(dynamic cls) {
cls.noSuchMethod;
}
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index d5d911b..78bfeeb 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -2,9 +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.
-/*element: Class1a.:static=[Object.(0)]*/
+/*member: Class1a.:static=[Object.(0)]*/
class Class1a<T> {
- /*element: Class1a.==:
+ /*member: Class1a.==:
dynamic=[this:Class1a.runtimeType,Object.runtimeType,Type.==],
runtimeType=[equals:Class1a<Class1a.T>/Object]
*/
@@ -13,9 +13,9 @@
}
}
-/*element: Class1b.:static=[Class1a.(0)]*/
+/*member: Class1b.:static=[Class1a.(0)]*/
class Class1b<T> extends Class1a<T> {
- /*element: Class1b.==:
+ /*member: Class1b.==:
dynamic=[this:Class1b.runtimeType,Object.runtimeType,Type.==],
runtimeType=[equals:Object/Class1b<Class1b.T>]
*/
@@ -24,9 +24,9 @@
}
}
-/*element: Class1c.:static=[Object.(0)]*/
+/*member: Class1c.:static=[Object.(0)]*/
class Class1c<T> implements Class1a<T> {
- /*element: Class1c.==:
+ /*member: Class1c.==:
dynamic=[this:Class1c.runtimeType,Object.==,Object.runtimeType,Type.==],
runtimeType=[equals:Class1c<Class1c.T>/Object],
type=[inst:JSNull]
@@ -36,9 +36,9 @@
}
}
-/*element: Class1d.:static=[Object.(0)]*/
+/*member: Class1d.:static=[Object.(0)]*/
class Class1d<T> implements Class1a<T> {
- /*element: Class1d.==:
+ /*member: Class1d.==:
dynamic=[this:Class1d.runtimeType,Object.==,Object.runtimeType,Type.==],
runtimeType=[equals:Object/Class1d<Class1d.T>],
type=[inst:JSNull]
@@ -48,19 +48,19 @@
}
}
-/*element: Class2.:static=[Object.(0)]*/
+/*member: Class2.:static=[Object.(0)]*/
class Class2<T> {}
-/*element: Class3.:static=[Object.(0)]*/
+/*member: Class3.:static=[Object.(0)]*/
class Class3 {
- /*element: Class3.field:type=[inst:JSNull]*/
+ /*member: Class3.field:type=[inst:JSNull]*/
var field;
}
-/*element: Class4.:static=[Object.(0)]*/
+/*member: Class4.:static=[Object.(0)]*/
class Class4 {}
-/*element: toString1:
+/*member: toString1:
dynamic=[Class2.runtimeType,toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -83,7 +83,7 @@
*/
toString1(Class2<int> c) => '${c.runtimeType}';
-/*element: toString2:
+/*member: toString2:
dynamic=[Class2.==,Class2.runtimeType,toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -107,7 +107,7 @@
*/
toString2(Class2<int> c) => '${c?.runtimeType}';
-/*element: toString3:
+/*member: toString3:
dynamic=[Class2.runtimeType,Type.toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -128,7 +128,7 @@
*/
toString3(Class2<int> c) => c.runtimeType.toString();
-/*element: toString4:
+/*member: toString4:
dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -150,7 +150,7 @@
*/
toString4(Class2<int> c) => c.runtimeType?.toString();
-/*element: toString5:
+/*member: toString5:
dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -172,7 +172,7 @@
*/
toString5(Class2<int> c) => c?.runtimeType?.toString();
-/*element: toString6:
+/*member: toString6:
dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],
runtimeType=[string:Class2<int>],
static=[
@@ -194,7 +194,7 @@
*/
toString6(Class2<int> c) => c?.runtimeType.toString();
-/*element: unknown:
+/*member: unknown:
dynamic=[Class2.runtimeType],
runtimeType=[unknown:Class2<int>],
static=[
@@ -215,7 +215,7 @@
*/
unknown(Class2<int> c) => c.runtimeType;
-/*element: equals1:
+/*member: equals1:
dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],
runtimeType=[equals:Class1a<int>/Class1d<int>],
static=[
@@ -238,147 +238,147 @@
*/
equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
-/*element: almostEquals1:
+/*member: almostEquals1:
dynamic=[Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals1(Class3 a) => a.runtimeType == null;
-/*element: almostEquals2:
+/*member: almostEquals2:
dynamic=[Class3.==,Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals2(Class3 a) => a?.runtimeType == null;
-/*element: almostEquals3:
+/*member: almostEquals3:
dynamic=[Class3.runtimeType,Null.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals3(Class3 a) => null == a.runtimeType;
-/*element: almostEquals4:
+/*member: almostEquals4:
dynamic=[Class3.==,Class3.runtimeType,Null.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals4(Class3 a) => null == a?.runtimeType;
-/*element: almostEquals5:
+/*member: almostEquals5:
dynamic=[Class3.field,Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,param:Class3]
*/
almostEquals5(Class3 a) => a.runtimeType == a.field;
-/*element: almostEquals6:
+/*member: almostEquals6:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals6(Class3 a) => a?.runtimeType == a.field;
-/*element: almostEquals7:
+/*member: almostEquals7:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals7(Class3 a) => a.runtimeType == a?.field;
-/*element: almostEquals8:
+/*member: almostEquals8:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals8(Class3 a) => a?.runtimeType == a?.field;
-/*element: almostEquals9:
+/*member: almostEquals9:
dynamic=[Class3.field,Class3.runtimeType,Object.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,param:Class3]
*/
almostEquals9(Class3 a) => a.field == a.runtimeType;
-/*element: almostEquals10:
+/*member: almostEquals10:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals10(Class3 a) => a?.field == a.runtimeType;
-/*element: almostEquals11:
+/*member: almostEquals11:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals11(Class3 a) => a.field == a?.runtimeType;
-/*element: almostEquals12:
+/*member: almostEquals12:
dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostEquals12(Class3 a) => a?.field == a?.runtimeType;
-/*element: almostToString1:
+/*member: almostToString1:
dynamic=[Class3.runtimeType,Type.toString],
runtimeType=[unknown:Class3],
type=[inst:JSBool,param:Class3]
*/
almostToString1(Class3 a) => a.runtimeType.toString;
-/*element: almostToString2:
+/*member: almostToString2:
dynamic=[Class3.==,Class3.runtimeType,Type.==,Type.toString],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostToString2(Class3 a) => a?.runtimeType?.toString;
-/*element: almostToString3:
+/*member: almostToString3:
dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
-/*element: almostToString4:
+/*member: almostToString4:
dynamic=[Class3.==,Class3.runtimeType,Type.noSuchMethod(1)],
runtimeType=[unknown:Class3],
type=[inst:JSBool,inst:JSNull,param:Class3]
*/
almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
-/*element: notEquals1:
+/*member: notEquals1:
dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],
runtimeType=[equals:Class3/Class4],
type=[inst:JSBool,param:Class3,param:Class4]
*/
notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
-/*element: notEquals2:
+/*member: notEquals2:
dynamic=[Class3.==,Class3.runtimeType,Class4.runtimeType,Type.==],
runtimeType=[equals:Class3/Class4],
type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
*/
notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
-/*element: notEquals3:
+/*member: notEquals3:
dynamic=[Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],
runtimeType=[equals:Class3/Class4],
type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
*/
notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
-/*element: notEquals4:
+/*member: notEquals4:
dynamic=[Class3.==,Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],
runtimeType=[equals:Class3/Class4],
type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
*/
notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
-/*element: main:
+/*member: main:
dynamic=[exact:Class1a.==],
static=[
Class1a.(0),
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 7a89d28..77936d3 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.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.
-/*element: main:
+/*member: main:
static=[
testAssert(0),
testAssertWithMessage(0),
@@ -31,7 +31,7 @@
testAssertWithMessage();
}
-/*element: testIfThen:
+/*member: testIfThen:
type=[
inst:JSBool,
inst:JSDouble,
@@ -47,7 +47,7 @@
return 1;
}
-/*element: testIfThenElse:
+/*member: testIfThenElse:
type=[
inst:JSBool,
inst:JSDouble,
@@ -65,7 +65,7 @@
return 1;
}
-/*element: testForIn:
+/*member: testForIn:
dynamic=[
Iterator.current,
Iterator.iterator,
@@ -82,7 +82,7 @@
for (var e in o) {}
}
-/*element: testForInTyped:
+/*member: testForInTyped:
dynamic=[
Iterator.current,
Iterator.iterator,
@@ -100,7 +100,7 @@
for (int e in o) {}
}
-/*element: testTryCatch:
+/*member: testTryCatch:
static=[unwrapException(1)],
type=[
inst:PlainJavaScriptObject,
@@ -110,7 +110,7 @@
try {} catch (e) {}
}
-/*element: testTryCatchOn:
+/*member: testTryCatchOn:
static=[unwrapException(1)],
type=[
catch:String,
@@ -123,7 +123,7 @@
try {} on String catch (e) {}
}
-/*element: testTryCatchStackTrace:
+/*member: testTryCatchStackTrace:
static=[
getTraceFromException(1),
unwrapException(1)],
@@ -137,12 +137,12 @@
try {} catch (e, s) {}
}
-/*element: testTryFinally:*/
+/*member: testTryFinally:*/
testTryFinally() {
try {} finally {}
}
-/*element: testSwitchWithoutFallthrough:
+/*member: testSwitchWithoutFallthrough:
static=[
throwExpression(1),
wrapException(1)],
@@ -171,12 +171,12 @@
}
}
-/*element: testAssert:static=[assertHelper(1)],type=[inst:JSBool]*/
+/*member: testAssert:static=[assertHelper(1)],type=[inst:JSBool]*/
testAssert() {
assert(true);
}
-/*element: testAssertWithMessage:static=[assertTest(1),assertThrow(1)],type=[inst:JSBool,inst:JSString]*/
+/*member: testAssertWithMessage:static=[assertTest(1),assertThrow(1)],type=[inst:JSBool,inst:JSString]*/
testAssertWithMessage() {
assert(true, 'ok');
}
diff --git a/tests/compiler/dart2js/impact/data/this.dart b/tests/compiler/dart2js/impact/data/this.dart
index 73a03d1..f06504e 100644
--- a/tests/compiler/dart2js/impact/data/this.dart
+++ b/tests/compiler/dart2js/impact/data/this.dart
@@ -2,36 +2,36 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: Class.:static=[Object.(0)]*/
+/*member: Class.:static=[Object.(0)]*/
class Class {
- /*element: Class.field1:type=[inst:JSNull]*/
+ /*member: Class.field1:type=[inst:JSNull]*/
var field1;
- /*element: Class.field2:type=[inst:JSNull]*/
+ /*member: Class.field2:type=[inst:JSNull]*/
var field2;
- /*element: Class.method1:dynamic=[this:Class.method2(0)]*/
+ /*member: Class.method1:dynamic=[this:Class.method2(0)]*/
method1() {
method2();
}
- /*element: Class.method2:dynamic=[this:Class.field1=,this:Class.field2]*/
+ /*member: Class.method2:dynamic=[this:Class.field1=,this:Class.field2]*/
method2() {
field1 = field2;
}
}
-/*element: Subclass.:static=[Class.(0)]*/
+/*member: Subclass.:static=[Class.(0)]*/
class Subclass extends Class {
- /*element: Subclass.field1:type=[inst:JSNull]*/
+ /*member: Subclass.field1:type=[inst:JSNull]*/
var field1;
- /*element: Subclass.field2:type=[inst:JSNull]*/
+ /*member: Subclass.field2:type=[inst:JSNull]*/
var field2;
- /*element: Subclass.method1:*/
+ /*member: Subclass.method1:*/
method1() {}
- /*element: Subclass.method2:dynamic=[this:Subclass.method3(0)]*/
+ /*member: Subclass.method2:dynamic=[this:Subclass.method3(0)]*/
method2() {
method3();
}
@@ -39,11 +39,11 @@
method3() {}
}
-/*element: Subtype.:static=[Object.(0)]*/
+/*member: Subtype.:static=[Object.(0)]*/
class Subtype implements Class {
- /*element: Subtype.field1:type=[inst:JSNull]*/
+ /*member: Subtype.field1:type=[inst:JSNull]*/
var field1;
- /*element: Subtype.field2:type=[inst:JSNull]*/
+ /*member: Subtype.field2:type=[inst:JSNull]*/
var field2;
method1() {}
@@ -57,7 +57,7 @@
}
}
-/*element: main:
+/*member: main:
dynamic=[Class.method1(0)],
static=[Class.(0),Subclass.(0),Subtype.(0)]
*/
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index ec60875..879ff50 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -7,7 +7,6 @@
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/universe/feature.dart';
import 'package:compiler/src/universe/use.dart';
@@ -86,8 +85,9 @@
}
}
Id id = computeEntityId(node);
- actualMap[id] = new ActualData<Features>(
- id, features, computeSourceSpanFromTreeNode(node), member);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ actualMap[id] = new ActualData<Features>(id, features,
+ nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
}
@override
diff --git a/tests/compiler/dart2js/impact/libs/constants_lib.dart b/tests/compiler/dart2js/impact/libs/constants_lib.dart
index 051cbea..02bbc81 100644
--- a/tests/compiler/dart2js/impact/libs/constants_lib.dart
+++ b/tests/compiler/dart2js/impact/libs/constants_lib.dart
@@ -2,64 +2,64 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*strong.element: nullLiteralField:type=[inst:JSNull]*/
+/*strong.member: nullLiteralField:type=[inst:JSNull]*/
const dynamic nullLiteralField = null;
-/*strong.element: boolLiteralField:type=[inst:JSBool]*/
+/*strong.member: boolLiteralField:type=[inst:JSBool]*/
const dynamic boolLiteralField = true;
-/*strong.element: intLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
const dynamic intLiteralField = 42;
-/*strong.element: doubleLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
const dynamic doubleLiteralField = 0.5;
-/*strong.element: stringLiteralField:type=[inst:JSString]*/
+/*strong.member: stringLiteralField:type=[inst:JSString]*/
const dynamic stringLiteralField = "foo";
-/*strong.element: symbolLiteralField:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: symbolLiteralField:static=[Symbol.(1)],type=[inst:Symbol]*/
const dynamic symbolLiteralField = #foo;
-/*strong.element: listLiteralField:type=[inst:JSBool,inst:List<bool>]*/
+/*strong.member: listLiteralField:type=[inst:JSBool,inst:List<bool>]*/
const dynamic listLiteralField = [true, false];
-/*strong.element: mapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strong.member: mapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
const dynamic mapLiteralField = {true: false};
-/*strong.element: stringMapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strong.member: stringMapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
const dynamic stringMapLiteralField = {'foo': false};
-/*strong.element: setLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strong.member: setLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
const dynamic setLiteralField = {true, false};
class SuperClass {
- /*element: SuperClass.field1:type=[inst:JSNull]*/
+ /*member: SuperClass.field1:type=[inst:JSNull]*/
final field1;
- /*strong.element: SuperClass.:static=[Object.(0),init:SuperClass.field1]*/
+ /*strong.member: SuperClass.:static=[Object.(0),init:SuperClass.field1]*/
const SuperClass(this.field1);
}
class Class extends SuperClass {
- /*element: Class.field2:type=[inst:JSNull]*/
+ /*member: Class.field2:type=[inst:JSNull]*/
final field2;
- /*strong.element: Class.:static=[SuperClass.(1),init:Class.field2]*/
+ /*strong.member: Class.:static=[SuperClass.(1),init:Class.field2]*/
const Class(field1, this.field2) : super(field1);
static staticMethodField() {}
}
-/*strong.element: instanceConstantField:static=[Class.(2)],type=[inst:JSBool,param:Class]*/
+/*strong.member: instanceConstantField:static=[Class.(2)],type=[inst:JSBool,param:Class]*/
const instanceConstantField = const Class(true, false);
-/*strong.element: typeLiteralField:static=[createRuntimeType(1)],type=[inst:JSBool,inst:Type,inst:TypeImpl,lit:String,param:Type]*/
+/*strong.member: typeLiteralField:static=[createRuntimeType(1)],type=[inst:JSBool,inst:Type,inst:TypeImpl,lit:String,param:Type]*/
const typeLiteralField = String;
-/*element: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
+/*member: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
T id<T>(T t) => t;
-/*strong.element: _instantiation:
+/*strong.member: _instantiation:
static=[
checkSubtype(4),
extractFunctionTypeObjectFromInternal(1),
@@ -82,13 +82,13 @@
*/
const int Function(int) _instantiation = id;
-/*strong.element: instantiationField:static=[_instantiation]*/
+/*strong.member: instantiationField:static=[_instantiation]*/
const dynamic instantiationField = _instantiation;
topLevelMethod() {}
-/*strong.element: topLevelTearOffField:static=[topLevelMethod]*/
+/*strong.member: topLevelTearOffField:static=[topLevelMethod]*/
const dynamic topLevelTearOffField = topLevelMethod;
-/*strong.element: staticTearOffField:static=[Class.staticMethodField]*/
+/*strong.member: staticTearOffField:static=[Class.staticMethodField]*/
const dynamic staticTearOffField = Class.staticMethodField;
diff --git a/tests/compiler/dart2js/inference/callers/field_access.dart b/tests/compiler/dart2js/inference/callers/field_access.dart
index 71699e9..4cad4a1 100644
--- a/tests/compiler/dart2js/inference/callers/field_access.dart
+++ b/tests/compiler/dart2js/inference/callers/field_access.dart
@@ -2,15 +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.
-/*element: B.:[main]*/
+/*member: B.:[main]*/
class A {
- /*element: A.field:[main]*/
+ /*member: A.field:[main]*/
var field;
}
-/*element: A.:[main]*/
+/*member: A.:[main]*/
class B {
- /*element: B.field:[main]*/
+ /*member: B.field:[main]*/
var field;
}
diff --git a/tests/compiler/dart2js/inference/data/abstract_method.dart b/tests/compiler/dart2js/inference/data/abstract_method.dart
index 30a2e1f..b6076c4 100644
--- a/tests/compiler/dart2js/inference/data/abstract_method.dart
+++ b/tests/compiler/dart2js/inference/data/abstract_method.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
abstractEquals();
}
@@ -11,10 +11,10 @@
// Call abstract method implemented by superclass.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
operator ==(_);
}
-/*element: abstractEquals:[exact=JSBool]*/
+/*member: abstractEquals:[exact=JSBool]*/
abstractEquals() => new Class1() /*invoke: [exact=Class1]*/ == new Class1();
diff --git a/tests/compiler/dart2js/inference/data/and_or.dart b/tests/compiler/dart2js/inference/data/and_or.dart
index e1b9c27..36602da 100644
--- a/tests/compiler/dart2js/inference/data/and_or.dart
+++ b/tests/compiler/dart2js/inference/data/and_or.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: X.:[exact=X]*/
+/*member: X.:[exact=X]*/
class X {}
-/*element: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn1() {
var a;
((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
@@ -13,7 +13,7 @@
return a;
}
-/*element: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn2() {
var a;
((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
@@ -21,14 +21,14 @@
return a;
}
-/*element: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn3() {
var a;
a = a == 54 ? 'foo' : 31;
return a;
}
-/*element: returnDyn4:Union([exact=JSUInt31], [exact=X])*/
+/*member: returnDyn4:Union([exact=JSUInt31], [exact=X])*/
returnDyn4() {
var a;
((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
@@ -36,7 +36,7 @@
return a;
}
-/*element: returnDyn5:Union([exact=JSUInt31], [exact=X])*/
+/*member: returnDyn5:Union([exact=JSUInt31], [exact=X])*/
returnDyn5() {
var a;
((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
@@ -44,20 +44,20 @@
return a;
}
-/*element: returnDyn6:Union([exact=JSString], [exact=X])*/
+/*member: returnDyn6:Union([exact=JSString], [exact=X])*/
returnDyn6() {
var a;
a = a == 54 ? 'foo' : new X();
return a;
}
-/*element: returnDyn7b:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn7b:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn7b(
/*Union([exact=JSString], [exact=JSUInt31])*/ x) {
return x;
}
-/*element: returnDyn7:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn7:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn7() {
dynamic a = "foo";
if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -69,13 +69,13 @@
return a;
}
-/*element: returnDyn8:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn8:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn8(
/*Union([exact=JSString], [exact=JSUInt31])*/ x) {
return x;
}
-/*element: test8:Union([exact=JSUInt31], [null|exact=JSString])*/ test8() {
+/*member: test8:Union([exact=JSUInt31], [null|exact=JSString])*/ test8() {
dynamic a = "foo";
if (a. /*Value([exact=JSString], value: "foo")*/ length
/*invoke: [subclass=JSInt]*/ ==
@@ -86,13 +86,13 @@
if ((false && a is! String) || returnDyn8(a)) return a;
}
-/*element: returnDyn9:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn9:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn9(
/*Union([exact=JSString], [exact=JSUInt31])*/ x) {
return x;
}
-/*element: test9:[null]*/
+/*member: test9:[null]*/
test9() {
dynamic a = "foo";
if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -103,11 +103,11 @@
if (!(a is bool && a is bool)) returnDyn9(a);
}
-/*element: returnString:[exact=JSString]*/ returnString(
+/*member: returnString:[exact=JSString]*/ returnString(
/*[exact=JSString]*/ x) =>
x;
-/*element: test10:[null]*/
+/*member: test10:[null]*/
test10() {
dynamic a = "foo";
if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -118,7 +118,7 @@
if (!(a is num) && a is String) returnString(a);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnDyn1();
returnDyn2();
diff --git a/tests/compiler/dart2js/inference/data/as.dart b/tests/compiler/dart2js/inference/data/as.dart
index d7ae559e..3a66972 100644
--- a/tests/compiler/dart2js/inference/data/as.dart
+++ b/tests/compiler/dart2js/inference/data/as.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
asIntWithString();
asIntWithNegative();
@@ -15,10 +15,10 @@
// As int of int and non-int types.
////////////////////////////////////////////////////////////////////////////////
-/*element: _asIntWithString:[exact=JSUInt31]*/
+/*member: _asIntWithString:[exact=JSUInt31]*/
_asIntWithString(/*Union([exact=JSString], [exact=JSUInt31])*/ o) => o as int;
-/*element: asIntWithString:[null]*/
+/*member: asIntWithString:[null]*/
asIntWithString() {
_asIntWithString(0);
_asIntWithString('');
@@ -28,10 +28,10 @@
// As int of known int and an unknown int types.
////////////////////////////////////////////////////////////////////////////////
-/*element: _asIntWithNegative:[subclass=JSInt]*/
+/*member: _asIntWithNegative:[subclass=JSInt]*/
_asIntWithNegative(/*[subclass=JSInt]*/ o) => o as int;
-/*element: asIntWithNegative:[null]*/
+/*member: asIntWithNegative:[null]*/
asIntWithNegative() {
_asIntWithNegative(0);
_asIntWithNegative(/*invoke: [exact=JSUInt31]*/ -1);
@@ -41,10 +41,10 @@
// As int of 0.
////////////////////////////////////////////////////////////////////////////////
-/*element: _asIntOfZero:[exact=JSUInt31]*/
+/*member: _asIntOfZero:[exact=JSUInt31]*/
_asIntOfZero(/*[exact=JSUInt31]*/ o) => o as int;
-/*element: asIntOfZero:[null]*/
+/*member: asIntOfZero:[null]*/
asIntOfZero() {
_asIntOfZero(0);
}
@@ -53,10 +53,10 @@
// As int of -1.
////////////////////////////////////////////////////////////////////////////////
-/*element: _asIntOfMinusOne:[subclass=JSInt]*/
+/*member: _asIntOfMinusOne:[subclass=JSInt]*/
_asIntOfMinusOne(/*[subclass=JSInt]*/ o) => o as int;
-/*element: asIntOfMinusOne:[null]*/
+/*member: asIntOfMinusOne:[null]*/
asIntOfMinusOne() {
_asIntOfMinusOne(/*invoke: [exact=JSUInt31]*/ -1);
}
@@ -65,10 +65,10 @@
// As int of string.
////////////////////////////////////////////////////////////////////////////////
-/*element: _asIntOfString:[empty]*/
+/*member: _asIntOfString:[empty]*/
_asIntOfString(/*Value([exact=JSString], value: "")*/ o) => o as int;
-/*element: asIntOfString:[null]*/
+/*member: asIntOfString:[null]*/
asIntOfString() {
_asIntOfString('');
}
diff --git a/tests/compiler/dart2js/inference/data/assert.dart b/tests/compiler/dart2js/inference/data/assert.dart
index e06b0a5..8f470ae 100644
--- a/tests/compiler/dart2js/inference/data/assert.dart
+++ b/tests/compiler/dart2js/inference/data/assert.dart
@@ -6,7 +6,7 @@
/// file 'assert_ea.dart' contains similar tests for when assertions are
/// _enabled_.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleAssert();
failingAssert();
@@ -22,7 +22,7 @@
// Simple assert statement known to be valid.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleAssert:[null]*/
+/*member: simpleAssert:[null]*/
simpleAssert() {
assert(true);
}
@@ -31,7 +31,7 @@
// Simple assert statement known to be invalid.
////////////////////////////////////////////////////////////////////////////////
-/*element: failingAssert:[exact=JSUInt31]*/
+/*member: failingAssert:[exact=JSUInt31]*/
failingAssert() {
assert(false);
return 0;
@@ -41,7 +41,7 @@
// Simple assert statement with message known to be valid.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleAssertWithMessage:[null]*/
+/*member: simpleAssertWithMessage:[null]*/
simpleAssertWithMessage() {
assert(true, 'foo');
}
@@ -50,14 +50,14 @@
// Assert statement that promotes a local.
////////////////////////////////////////////////////////////////////////////////
-/*element: _promoteLocalAssert:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _promoteLocalAssert:Union([exact=JSString], [exact=JSUInt31])*/
_promoteLocalAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
var local = o;
assert(local is int);
return local;
}
-/*element: promoteLocalAssert:[null]*/
+/*member: promoteLocalAssert:[null]*/
promoteLocalAssert() {
_promoteLocalAssert(0);
_promoteLocalAssert('');
@@ -67,13 +67,13 @@
// Assert statement that promotes a parameter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _promoteParameterAssert:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _promoteParameterAssert:Union([exact=JSString], [exact=JSUInt31])*/
_promoteParameterAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
assert(o is int);
return o;
}
-/*element: promoteParameterAssert:[null]*/
+/*member: promoteParameterAssert:[null]*/
promoteParameterAssert() {
_promoteParameterAssert(0);
_promoteParameterAssert('');
@@ -83,7 +83,7 @@
// Assert statement with an unreachable throw.
////////////////////////////////////////////////////////////////////////////////
-/*element: unreachableThrow:[exact=JSUInt31]*/
+/*member: unreachableThrow:[exact=JSUInt31]*/
unreachableThrow() {
assert(true, throw "unreachable");
return 0;
@@ -93,14 +93,14 @@
// Assert with a side effect in the message.
////////////////////////////////////////////////////////////////////////////////
-/*element: _messageWithSideEffect:[null]*/
+/*member: _messageWithSideEffect:[null]*/
_messageWithSideEffect(/*[exact=JSBool]*/ b) {
var a;
assert(b, a = 42);
return a;
}
-/*element: messageWithSideEffect:[null]*/
+/*member: messageWithSideEffect:[null]*/
messageWithSideEffect() {
_messageWithSideEffect(true);
_messageWithSideEffect(false);
@@ -110,7 +110,7 @@
// Assert with a caught side effect in the message.
////////////////////////////////////////////////////////////////////////////////
-/*element: _messageWithCaughtSideEffect:[null]*/
+/*member: _messageWithCaughtSideEffect:[null]*/
_messageWithCaughtSideEffect(/*[exact=JSBool]*/ b) {
var a;
try {
@@ -119,7 +119,7 @@
return a;
}
-/*element: messageWithCaughtSideEffect:[null]*/
+/*member: messageWithCaughtSideEffect:[null]*/
messageWithCaughtSideEffect() {
_messageWithCaughtSideEffect(true);
_messageWithCaughtSideEffect(false);
diff --git a/tests/compiler/dart2js/inference/data/assert_ea.dart b/tests/compiler/dart2js/inference/data/assert_ea.dart
index 7b216e5..5faff4e 100644
--- a/tests/compiler/dart2js/inference/data/assert_ea.dart
+++ b/tests/compiler/dart2js/inference/data/assert_ea.dart
@@ -6,7 +6,7 @@
/// file 'assert.dart' contains similar tests for when assertions are
/// _disabled_.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleAssert();
failingAssert();
@@ -22,7 +22,7 @@
// Simple assert statement known to be valid.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleAssert:[null]*/
+/*member: simpleAssert:[null]*/
simpleAssert() {
assert(true);
}
@@ -31,7 +31,7 @@
// Simple assert statement known to be invalid.
////////////////////////////////////////////////////////////////////////////////
-/*element: failingAssert:[exact=JSUInt31]*/
+/*member: failingAssert:[exact=JSUInt31]*/
failingAssert() {
assert(false);
return 0;
@@ -41,7 +41,7 @@
// Simple assert statement with message known to be valid.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleAssertWithMessage:[null]*/
+/*member: simpleAssertWithMessage:[null]*/
simpleAssertWithMessage() {
assert(true, 'foo');
}
@@ -50,14 +50,14 @@
// Assert statement that promotes a local.
////////////////////////////////////////////////////////////////////////////////
-/*element: _promoteLocalAssert:[exact=JSUInt31]*/
+/*member: _promoteLocalAssert:[exact=JSUInt31]*/
_promoteLocalAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
var local = o;
assert(local is int);
return local;
}
-/*element: promoteLocalAssert:[null]*/
+/*member: promoteLocalAssert:[null]*/
promoteLocalAssert() {
_promoteLocalAssert(0);
_promoteLocalAssert('');
@@ -67,13 +67,13 @@
// Assert statement that promotes a parameter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _promoteParameterAssert:[exact=JSUInt31]*/
+/*member: _promoteParameterAssert:[exact=JSUInt31]*/
_promoteParameterAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
assert(o is int);
return o;
}
-/*element: promoteParameterAssert:[null]*/
+/*member: promoteParameterAssert:[null]*/
promoteParameterAssert() {
_promoteParameterAssert(0);
_promoteParameterAssert('');
@@ -83,7 +83,7 @@
// Assert statement with an unreachable throw.
////////////////////////////////////////////////////////////////////////////////
-/*element: unreachableThrow:[exact=JSUInt31]*/
+/*member: unreachableThrow:[exact=JSUInt31]*/
unreachableThrow() {
assert(true, throw "unreachable");
return 0;
@@ -93,14 +93,14 @@
// Assert with a side effect in the message.
////////////////////////////////////////////////////////////////////////////////
-/*element: _messageWithSideEffect:[null]*/
+/*member: _messageWithSideEffect:[null]*/
_messageWithSideEffect(/*[exact=JSBool]*/ b) {
var a;
assert(b, a = 42);
return a;
}
-/*element: messageWithSideEffect:[null]*/
+/*member: messageWithSideEffect:[null]*/
messageWithSideEffect() {
_messageWithSideEffect(true);
_messageWithSideEffect(false);
@@ -110,7 +110,7 @@
// Assert with a caught side effect in the message.
////////////////////////////////////////////////////////////////////////////////
-/*element: _messageWithCaughtSideEffect:[null|exact=JSUInt31]*/
+/*member: _messageWithCaughtSideEffect:[null|exact=JSUInt31]*/
_messageWithCaughtSideEffect(/*[exact=JSBool]*/ b) {
var a;
try {
@@ -119,7 +119,7 @@
return a;
}
-/*element: messageWithCaughtSideEffect:[null]*/
+/*member: messageWithCaughtSideEffect:[null]*/
messageWithCaughtSideEffect() {
_messageWithCaughtSideEffect(true);
_messageWithCaughtSideEffect(false);
diff --git a/tests/compiler/dart2js/inference/data/assert_message_throw.dart b/tests/compiler/dart2js/inference/data/assert_message_throw.dart
index d310309..1115952 100644
--- a/tests/compiler/dart2js/inference/data/assert_message_throw.dart
+++ b/tests/compiler/dart2js/inference/data/assert_message_throw.dart
@@ -6,7 +6,7 @@
/// file 'assert_message_throw_ea.dart' contains similar tests for when
/// assertions are _enabled_.
-/*element: main:[null]*/
+/*member: main:[null]*/
main(/*[null|subclass=Object]*/ args) {
test0();
test1(args == null);
@@ -15,7 +15,7 @@
}
// Check that `throw` in the message is handled conditionally.
-/*element: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
test0() {
assert(true, throw "unreachable");
var list = [];
@@ -24,7 +24,7 @@
// Check that side-effects of the assert message is not included after the
// assert.
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1(/*[exact=JSBool]*/ b) {
var a;
assert(b, a = 42);
@@ -33,7 +33,7 @@
// Check that side-effects of the assert message is included after the assert
// through the thrown exception.
-/*element: test2:[null]*/
+/*member: test2:[null]*/
test2(/*[exact=JSBool]*/ b) {
var a;
try {
@@ -43,7 +43,7 @@
}
// Check that type tests are preserved after the assert.
-/*element: test3:[null|subclass=Object]*/
+/*member: test3:[null|subclass=Object]*/
test3(/*[null|subclass=Object]*/ a) {
assert(a is int);
return a;
diff --git a/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart b/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
index c3f0a1b..72e4618 100644
--- a/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
+++ b/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
@@ -6,7 +6,7 @@
/// file 'assert_message_throw.dart' contains similar tests for when assertions
/// are _disabled_.
-/*element: main:[null]*/
+/*member: main:[null]*/
main(/*[null|subclass=Object]*/ args) {
test0();
test1(args == null);
@@ -15,7 +15,7 @@
}
// Check that `throw` in the message is handled conditionally.
-/*element: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
test0() {
assert(true, throw "unreachable");
var list = [];
@@ -24,7 +24,7 @@
// Check that side-effects of the assert message is not included after the
// assert.
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1(/*[exact=JSBool]*/ b) {
var a;
assert(b, a = 42);
@@ -33,7 +33,7 @@
// Check that side-effects of the assert message is included after the assert
// through the thrown exception.
-/*element: test2:[null|exact=JSUInt31]*/
+/*member: test2:[null|exact=JSUInt31]*/
test2(/*[exact=JSBool]*/ b) {
var a;
try {
@@ -43,7 +43,7 @@
}
// Check that type tests are preserved after the assert.
-/*element: test3:[subclass=JSInt]*/
+/*member: test3:[subclass=JSInt]*/
test3(/*[null|subclass=Object]*/ a) {
assert(a is int);
return a;
diff --git a/tests/compiler/dart2js/inference/data/assign_op.dart b/tests/compiler/dart2js/inference/data/assign_op.dart
index 6b6dbaa..94d63dc 100644
--- a/tests/compiler/dart2js/inference/data/assign_op.dart
+++ b/tests/compiler/dart2js/inference/data/assign_op.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
assignPlus();
assignAnd();
@@ -16,25 +16,25 @@
////////////////////////////////////////////////////////////////////////////////
-/*element: assignPlus:[subclass=JSUInt32]*/
+/*member: assignPlus:[subclass=JSUInt32]*/
assignPlus() {
var i = 87;
return i /*invoke: [exact=JSUInt31]*/ += 42;
}
-/*element: assignAnd:[exact=JSUInt31]*/
+/*member: assignAnd:[exact=JSUInt31]*/
assignAnd() {
var i = 87;
return i /*invoke: [exact=JSUInt31]*/ &= 42;
}
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[subclass=JSPositiveInt]*/
+ /*member: Class1.field:[subclass=JSPositiveInt]*/
var field = 87;
}
-/*element: instanceAssignPlus:[subclass=JSPositiveInt]*/
+/*member: instanceAssignPlus:[subclass=JSPositiveInt]*/
instanceAssignPlus() {
var c = new Class1();
return c.
@@ -42,13 +42,13 @@
/*invoke: [subclass=JSPositiveInt]*/ += 42;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[exact=JSUInt31]*/
+ /*member: Class2.field:[exact=JSUInt31]*/
var field = 87;
}
-/*element: instanceAssignAnd:[exact=JSUInt31]*/
+/*member: instanceAssignAnd:[exact=JSUInt31]*/
instanceAssignAnd() {
var c = new Class2();
return c.
@@ -56,7 +56,7 @@
/*invoke: [exact=JSUInt31]*/ &= 42;
}
-/*element: assignIndexPlus:[subclass=JSPositiveInt]*/
+/*member: assignIndexPlus:[subclass=JSPositiveInt]*/
assignIndexPlus() {
var i = [87];
return i
@@ -65,7 +65,7 @@
[0] /*invoke: [subclass=JSPositiveInt]*/ += 42;
}
-/*element: assignIndexAnd:[exact=JSUInt31]*/
+/*member: assignIndexAnd:[exact=JSUInt31]*/
assignIndexAnd() {
var i = [87];
return i
@@ -74,7 +74,7 @@
[0] /*invoke: [exact=JSUInt31]*/ &= 42;
}
-/*element: assignIndexInc:[subclass=JSPositiveInt]*/
+/*member: assignIndexInc:[subclass=JSPositiveInt]*/
assignIndexInc() {
var i = [87];
return i
@@ -83,7 +83,7 @@
[0] /*invoke: [subclass=JSPositiveInt]*/ ++;
}
-/*element: assignIndexDec:[subclass=JSInt]*/
+/*member: assignIndexDec:[subclass=JSInt]*/
assignIndexDec() {
var i = [87];
return
diff --git a/tests/compiler/dart2js/inference/data/async_marker.dart b/tests/compiler/dart2js/inference/data/async_marker.dart
index 724c4d8..97a9464 100644
--- a/tests/compiler/dart2js/inference/data/async_marker.dart
+++ b/tests/compiler/dart2js/inference/data/async_marker.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
asyncMethod();
asyncMethodWithReturn();
@@ -10,16 +10,16 @@
syncStarMethod();
}
-/*element: asyncMethod:[exact=_Future]*/
+/*member: asyncMethod:[exact=_Future]*/
asyncMethod() async {}
-/*element: asyncMethodWithReturn:Union([exact=JSUInt31], [exact=_Future])*/
+/*member: asyncMethodWithReturn:Union([exact=JSUInt31], [exact=_Future])*/
asyncMethodWithReturn() async {
return 0;
}
-/*element: asyncStarMethod:[exact=_ControllerStream]*/
+/*member: asyncStarMethod:[exact=_ControllerStream]*/
asyncStarMethod() async* {}
-/*element: syncStarMethod:[exact=_SyncStarIterable]*/
+/*member: syncStarMethod:[exact=_SyncStarIterable]*/
syncStarMethod() sync* {}
diff --git a/tests/compiler/dart2js/inference/data/await.dart b/tests/compiler/dart2js/inference/data/await.dart
index de21806..1f7bfea 100644
--- a/tests/compiler/dart2js/inference/data/await.dart
+++ b/tests/compiler/dart2js/inference/data/await.dart
@@ -4,7 +4,7 @@
import 'dart:async';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
awaitOfFuture();
awaitOfInt();
@@ -15,10 +15,10 @@
// Await of Future.value.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[null]*/
+/*member: _method1:[null]*/
_method1(/*[null|subclass=JSInt]*/ o) {}
-/*element: awaitOfFuture:[exact=_Future]*/
+/*member: awaitOfFuture:[exact=_Future]*/
awaitOfFuture() async {
var future = new Future.value(0);
var local = await future;
@@ -29,10 +29,10 @@
// Await of int.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method2:[null]*/
+/*member: _method2:[null]*/
_method2(/*[null|subclass=JSInt]*/ o) {}
-/*element: awaitOfInt:[exact=_Future]*/
+/*member: awaitOfInt:[exact=_Future]*/
awaitOfInt() async {
var local = await 0;
_method2(local);
@@ -42,15 +42,15 @@
// Await for of Stream.fromIterable.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method3:[null]*/
+/*member: _method3:[null]*/
_method3(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
o) {}
-/*element: _method4:[null]*/
+/*member: _method4:[null]*/
_method4(/*[null|subclass=JSInt]*/ o) {}
-/*element: awaitForOfStream:[exact=_Future]*/
+/*member: awaitForOfStream:[exact=_Future]*/
awaitForOfStream() async {
var list = [0];
_method3(list);
diff --git a/tests/compiler/dart2js/inference/data/break_continue.dart b/tests/compiler/dart2js/inference/data/break_continue.dart
index 6ef1d84..989c474 100644
--- a/tests/compiler/dart2js/inference/data/break_continue.dart
+++ b/tests/compiler/dart2js/inference/data/break_continue.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
breakInWhile();
noBreakInWhile();
@@ -16,7 +16,7 @@
// A break statement in a while loop.
////////////////////////////////////////////////////////////////////////////////
-/*element: _breakInWhile:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _breakInWhile:Union([exact=JSString], [exact=JSUInt31])*/
_breakInWhile(/*[exact=JSBool]*/ b) {
dynamic local = 42;
while (b) {
@@ -29,7 +29,7 @@
return local;
}
-/*element: breakInWhile:[null]*/
+/*member: breakInWhile:[null]*/
breakInWhile() {
_breakInWhile(true);
_breakInWhile(false);
@@ -39,7 +39,7 @@
// The while loop above _without_ the break statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _noBreakInWhile:[exact=JSUInt31]*/
+/*member: _noBreakInWhile:[exact=JSUInt31]*/
_noBreakInWhile(/*[exact=JSBool]*/ b) {
dynamic local = 42;
while (b) {
@@ -51,7 +51,7 @@
return local;
}
-/*element: noBreakInWhile:[null]*/
+/*member: noBreakInWhile:[null]*/
noBreakInWhile() {
_noBreakInWhile(true);
_noBreakInWhile(false);
@@ -61,7 +61,7 @@
// A continue statement in a while loop.
////////////////////////////////////////////////////////////////////////////////
-/*element: _continueInWhile:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _continueInWhile:Union([exact=JSString], [exact=JSUInt31])*/
_continueInWhile(/*[exact=JSBool]*/ b) {
dynamic local = 42;
while (b) {
@@ -75,7 +75,7 @@
return local;
}
-/*element: continueInWhile:[null]*/
+/*member: continueInWhile:[null]*/
continueInWhile() {
_continueInWhile(true);
_continueInWhile(false);
@@ -85,7 +85,7 @@
// The while loop above _without_ the continue statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _noContinueInWhile:[exact=JSUInt31]*/
+/*member: _noContinueInWhile:[exact=JSUInt31]*/
_noContinueInWhile(/*[exact=JSBool]*/ b) {
dynamic local = 42;
while (b) {
@@ -98,7 +98,7 @@
return local;
}
-/*element: noContinueInWhile:[null]*/
+/*member: noContinueInWhile:[null]*/
noContinueInWhile() {
_noContinueInWhile(true);
_noContinueInWhile(false);
@@ -108,7 +108,7 @@
// A break statement in a labeled statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _breakInIf:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _breakInIf:Union([exact=JSString], [exact=JSUInt31])*/
_breakInIf(/*[exact=JSBool]*/ b) {
dynamic local = 42;
label:
@@ -122,7 +122,7 @@
return local;
}
-/*element: breakInIf:[null]*/
+/*member: breakInIf:[null]*/
breakInIf() {
_breakInIf(true);
_breakInIf(false);
@@ -132,7 +132,7 @@
// The "labeled statement" above _without_ the break statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _noBreakInIf:[exact=JSUInt31]*/
+/*member: _noBreakInIf:[exact=JSUInt31]*/
_noBreakInIf(/*[exact=JSBool]*/ b) {
dynamic local = 42;
{
@@ -143,7 +143,7 @@
return local;
}
-/*element: noBreakInIf:[null]*/
+/*member: noBreakInIf:[null]*/
noBreakInIf() {
_noBreakInIf(true);
_noBreakInIf(false);
diff --git a/tests/compiler/dart2js/inference/data/call_in_loop.dart b/tests/compiler/dart2js/inference/data/call_in_loop.dart
index 5c1a6eb..f91fbc9 100644
--- a/tests/compiler/dart2js/inference/data/call_in_loop.dart
+++ b/tests/compiler/dart2js/inference/data/call_in_loop.dart
@@ -4,9 +4,9 @@
/// Regression test for [ClosureCallSiteTypeInformation] in loops.
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class<T> {
- /*element: Class.method:[null]*/
+ /*member: Class.method:[null]*/
method() {
/*iterator: Container([exact=JSExtendableArray], element: [empty], length: 0)*/
/*current: [exact=ArrayIterator]*/
@@ -20,7 +20,7 @@
}
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new Class(). /*invoke: [exact=Class]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
index 9fc9e74..d9c18f2 100644
--- a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -6,7 +6,7 @@
import "package:expect/expect.dart";
-/*element: f:[subclass=JSInt]*/
+/*member: f:[subclass=JSInt]*/
int f(
int
/*strong.[null|subclass=Object]*/
@@ -18,11 +18,11 @@
typedef int IntToInt(int x);
-/*element: test:[null]*/
+/*member: test:[null]*/
test(/*[null|subclass=Object]*/ a, /*[subclass=Closure]*/ b) =>
Expect.identical(a, b);
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
// It is possible to use `.call` on a function-typed value (even though it is
// redundant). Similarly, it is possible to tear off `.call` on a
diff --git a/tests/compiler/dart2js/inference/data/call_site.dart b/tests/compiler/dart2js/inference/data/call_site.dart
index 5af853c..c945208 100644
--- a/tests/compiler/dart2js/inference/data/call_site.dart
+++ b/tests/compiler/dart2js/inference/data/call_site.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
@@ -25,201 +25,201 @@
test19();
}
-/*element: A1.:[exact=A1]*/
+/*member: A1.:[exact=A1]*/
class A1 {
- /*element: A1.x1:Value([exact=JSString], value: "s")*/
+ /*member: A1.x1:Value([exact=JSString], value: "s")*/
x1(
/*Value([exact=JSString], value: "s")*/ p) =>
p;
}
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1() {
new A1(). /*invoke: [exact=A1]*/ x1("s");
}
-/*element: A2.:[exact=A2]*/
+/*member: A2.:[exact=A2]*/
class A2 {
- /*element: A2.x2:[exact=JSUInt31]*/
+ /*member: A2.x2:[exact=JSUInt31]*/
x2(/*[exact=JSUInt31]*/ p) => p;
}
-/*element: test2:[null]*/
+/*member: test2:[null]*/
test2() {
new A2(). /*invoke: [exact=A2]*/ x2(1);
}
-/*element: A3.:[exact=A3]*/
+/*member: A3.:[exact=A3]*/
class A3 {
- /*element: A3.x3:[empty]*/
+ /*member: A3.x3:[empty]*/
x3(/*[subclass=JSInt]*/ p) => /*invoke: [exact=A3]*/ x3(
p /*invoke: [subclass=JSInt]*/ - 1);
}
-/*element: test3:[null]*/
+/*member: test3:[null]*/
test3() {
new A3(). /*invoke: [exact=A3]*/ x3(1);
}
-/*element: A4.:[exact=A4]*/
+/*member: A4.:[exact=A4]*/
class A4 {
- /*element: A4.x4:[empty]*/
+ /*member: A4.x4:[empty]*/
x4(/*[subclass=JSNumber]*/ p) => /*invoke: [exact=A4]*/ x4(
p /*invoke: [subclass=JSNumber]*/ - 1);
}
-/*element: test4:[null]*/
+/*member: test4:[null]*/
test4() {
new A4(). /*invoke: [exact=A4]*/ x4(1.5);
}
-/*element: A5.:[exact=A5]*/
+/*member: A5.:[exact=A5]*/
class A5 {
- /*element: A5.x5:Union([exact=JSDouble], [exact=JSUInt31])*/
+ /*member: A5.x5:Union([exact=JSDouble], [exact=JSUInt31])*/
x5(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
p;
}
-/*element: test5:[null]*/
+/*member: test5:[null]*/
test5() {
new A5(). /*invoke: [exact=A5]*/ x5(1);
new A5(). /*invoke: [exact=A5]*/ x5(1.5);
}
-/*element: A6.:[exact=A6]*/
+/*member: A6.:[exact=A6]*/
class A6 {
- /*element: A6.x6:Union([exact=JSDouble], [exact=JSUInt31])*/
+ /*member: A6.x6:Union([exact=JSDouble], [exact=JSUInt31])*/
x6(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
p;
}
-/*element: test6:[null]*/
+/*member: test6:[null]*/
test6() {
new A6(). /*invoke: [exact=A6]*/ x6(1.5);
new A6(). /*invoke: [exact=A6]*/ x6(1);
}
-/*element: A7.:[exact=A7]*/
+/*member: A7.:[exact=A7]*/
class A7 {
- /*element: A7.x7:[empty]*/
+ /*member: A7.x7:[empty]*/
x7(
/*Union([exact=JSString], [exact=JSUInt31])*/ p) => /*invoke: [exact=A7]*/ x7("x");
}
-/*element: test7:[null]*/
+/*member: test7:[null]*/
test7() {
new A7(). /*invoke: [exact=A7]*/ x7(1);
}
-/*element: A8.:[exact=A8]*/
+/*member: A8.:[exact=A8]*/
class A8 {
- /*element: A8.x8:[empty]*/
+ /*member: A8.x8:[empty]*/
x8(
/*Union([exact=JSString], [subclass=JsLinkedHashMap])*/ p) =>
/*invoke: [exact=A8]*/ x8("x");
}
-/*element: test8:[null]*/
+/*member: test8:[null]*/
test8() {
new A8(). /*invoke: [exact=A8]*/ x8({});
}
-/*element: A9.:[exact=A9]*/
+/*member: A9.:[exact=A9]*/
class A9 {
- /*element: A9.x9:[empty]*/ x9(
+ /*member: A9.x9:[empty]*/ x9(
/*[exact=JSUInt31]*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2,
/*Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ p3) =>
/*invoke: [exact=A9]*/ x9(p1, "x", {});
}
-/*element: test9:[null]*/
+/*member: test9:[null]*/
test9() {
new A9(). /*invoke: [exact=A9]*/ x9(1, 2, 3);
}
-/*element: A10.:[exact=A10]*/
+/*member: A10.:[exact=A10]*/
class A10 {
- /*element: A10.x10:[empty]*/ x10(
+ /*member: A10.x10:[empty]*/ x10(
/*[exact=JSUInt31]*/ p1,
/*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A10]*/ x10(p1, p2);
}
-/*element: test10:[null]*/
+/*member: test10:[null]*/
test10() {
new A10(). /*invoke: [exact=A10]*/ x10(1, 2);
}
-/*element: A11.:[exact=A11]*/
+/*member: A11.:[exact=A11]*/
class A11 {
- /*element: A11.x11:[empty]*/
+ /*member: A11.x11:[empty]*/
x11(
/*[exact=JSUInt31]*/ p1,
/*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A11]*/ x11(p1, p2);
}
-/*element: f11:[null]*/
+/*member: f11:[null]*/
void f11(/*[null]*/ p) {
p. /*invoke: [null]*/ x11("x", "y");
}
-/*element: test11:[null]*/
+/*member: test11:[null]*/
test11() {
f11(null);
new A11(). /*invoke: [exact=A11]*/ x11(1, 2);
}
-/*element: A12.:[exact=A12]*/
+/*member: A12.:[exact=A12]*/
class A12 {
- /*element: A12.x12:[empty]*/
+ /*member: A12.x12:[empty]*/
x12(
/*Union([exact=JSString], [exact=JSUInt31])*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
/*invoke: [exact=A12]*/ x12(1, 2);
}
-/*element: test12:[null]*/
+/*member: test12:[null]*/
test12() {
new A12(). /*invoke: [exact=A12]*/ x12("x", "y");
}
-/*element: A13.:[exact=A13]*/
+/*member: A13.:[exact=A13]*/
class A13 {
- /*element: A13.x13:[exact=JSUInt31]*/
+ /*member: A13.x13:[exact=JSUInt31]*/
x13(
/*Value([exact=JSString], value: "x")*/ p1,
[/*[exact=JSUInt31]*/ p2 = 1]) =>
1;
}
-/*element: test13:[null]*/
+/*member: test13:[null]*/
test13() {
new A13(). /*invoke: [exact=A13]*/ x13("x", 1);
new A13(). /*invoke: [exact=A13]*/ x13("x");
}
-/*element: A14.:[exact=A14]*/
+/*member: A14.:[exact=A14]*/
class A14 {
- /*element: A14.x14:[exact=JSUInt31]*/
+ /*member: A14.x14:[exact=JSUInt31]*/
x14(
/*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
1;
}
-/*element: f14:[exact=JSUInt31]*/
+/*member: f14:[exact=JSUInt31]*/
f14(/*[exact=A14]*/ p) => p. /*invoke: [exact=A14]*/ x14(2.2);
-/*element: test14:[null]*/
+/*member: test14:[null]*/
test14() {
new A14(). /*invoke: [exact=A14]*/ x14(1);
f14(new A14());
}
-/*element: A15.:[exact=A15]*/
+/*member: A15.:[exact=A15]*/
class A15 {
- /*element: A15.x15:[exact=JSUInt31]*/
+ /*member: A15.x15:[exact=JSUInt31]*/
x15(/*[exact=JSUInt31]*/ p1,
[/*Value([exact=JSString], value: "s")*/ p2 = "s"]) {
p2. /*Value([exact=JSString], value: "s")*/ length;
@@ -227,39 +227,39 @@
}
}
-/*element: test15:[null]*/
+/*member: test15:[null]*/
test15() {
new A15(). /*invoke: [exact=A15]*/ x15(1);
}
-/*element: A16.:[exact=A16]*/
+/*member: A16.:[exact=A16]*/
class A16 {
- /*element: A16.x16:[exact=JSUInt31]*/
+ /*member: A16.x16:[exact=JSUInt31]*/
x16(
/*Value([exact=JSString], value: "x")*/ p1,
[/*[exact=JSBool]*/ p2 = true]) =>
1;
}
-/*element: f16:[empty]*/
+/*member: f16:[empty]*/
f16(/*[null]*/ p) => p. /*invoke: [null]*/ a("x");
-/*element: test16:[null]*/
+/*member: test16:[null]*/
test16() {
new A16(). /*invoke: [exact=A16]*/ x16("x");
new A16(). /*invoke: [exact=A16]*/ x16("x", false);
f16(null);
}
-/*element: A17.:[exact=A17]*/
+/*member: A17.:[exact=A17]*/
class A17 {
- /*element: A17.x17:[exact=JSUInt31]*/
+ /*member: A17.x17:[exact=JSUInt31]*/
x17(/*[exact=JSUInt31]*/ p1,
[/*[exact=JSUInt31]*/ p2 = 1, /*[exact=JSString]*/ p3 = "s"]) =>
1;
}
-/*element: test17:[null]*/
+/*member: test17:[null]*/
test17() {
new A17(). /*invoke: [exact=A17]*/ x17(1);
new A17(). /*invoke: [exact=A17]*/ x17(1, 2);
@@ -274,15 +274,15 @@
d. /*invoke: [exact=A17]*/ x17(1, p2: 2, p3: "x");
}
-/*element: A18.:[exact=A18]*/
+/*member: A18.:[exact=A18]*/
class A18 {
- /*element: A18.x18:[exact=JSUInt31]*/
+ /*member: A18.x18:[exact=JSUInt31]*/
x18(/*[exact=JSUInt31]*/ p1,
[/*[exact=JSBool]*/ p2 = 1, /*[exact=JSDouble]*/ p3 = "s"]) =>
1;
}
-/*element: test18:[null]*/
+/*member: test18:[null]*/
test18() {
new A18(). /*invoke: [exact=A18]*/ x18(1, true, 1.1);
new A18(). /*invoke: [exact=A18]*/ x18(1, false, 2.2);
@@ -292,19 +292,19 @@
b. /*invoke: [exact=A18]*/ x18(1, p2: false, p3: 4.4);
}
-/*element: A19.:[exact=A19]*/
+/*member: A19.:[exact=A19]*/
class A19 {
- /*element: A19.x19:[empty]*/
+ /*member: A19.x19:[empty]*/
x19(
/*Union([exact=JSString], [exact=JSUInt31])*/ p1,
/*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
/*invoke: [subclass=A19]*/ x19(p1, p2);
}
-/*element: B19.:[exact=B19]*/
+/*member: B19.:[exact=B19]*/
class B19 extends A19 {}
-/*element: test19:[null]*/
+/*member: test19:[null]*/
test19() {
new B19(). /*invoke: [exact=B19]*/ x19("a", "b");
new A19(). /*invoke: [exact=A19]*/ x19(1, 2);
diff --git a/tests/compiler/dart2js/inference/data/catch.dart b/tests/compiler/dart2js/inference/data/catch.dart
index 46a150a..d87f53a 100644
--- a/tests/compiler/dart2js/inference/data/catch.dart
+++ b/tests/compiler/dart2js/inference/data/catch.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
catchUntyped();
catchTyped();
@@ -13,7 +13,7 @@
/// Untyped catch clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: catchUntyped:[subclass=Object]*/
+/*member: catchUntyped:[subclass=Object]*/
catchUntyped() {
dynamic local = 0;
try {} catch (e) {
@@ -26,7 +26,7 @@
/// Typed catch clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: catchTyped:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: catchTyped:Union([exact=JSString], [exact=JSUInt31])*/
catchTyped() {
dynamic local = 0;
try {} on String catch (e) {
@@ -39,7 +39,7 @@
/// Catch clause with stack trace.
////////////////////////////////////////////////////////////////////////////////
-/*element: catchStackTrace:[null|subclass=Object]*/
+/*member: catchStackTrace:[null|subclass=Object]*/
catchStackTrace() {
dynamic local = 0;
try {} catch (_, s) {
diff --git a/tests/compiler/dart2js/inference/data/closure.dart b/tests/compiler/dart2js/inference/data/closure.dart
index 544b6ce..e4f2243 100644
--- a/tests/compiler/dart2js/inference/data/closure.dart
+++ b/tests/compiler/dart2js/inference/data/closure.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInClosure();
accessInClosure();
@@ -17,7 +17,7 @@
postfixInClosure();
}
-/*element: returnInClosure:[exact=JSUInt31]*/
+/*member: returnInClosure:[exact=JSUInt31]*/
returnInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -28,7 +28,7 @@
return lines;
}
-/*element: accessInClosure:[exact=JSUInt31]*/
+/*member: accessInClosure:[exact=JSUInt31]*/
accessInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -39,7 +39,7 @@
return lines;
}
-/*element: invokeInClosure:[exact=JSUInt31]*/
+/*member: invokeInClosure:[exact=JSUInt31]*/
invokeInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -50,7 +50,7 @@
return lines;
}
-/*element: operatorInClosure:[exact=JSUInt31]*/
+/*member: operatorInClosure:[exact=JSUInt31]*/
operatorInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -61,7 +61,7 @@
return lines;
}
-/*element: assignInClosure:[subclass=JSInt]*/
+/*member: assignInClosure:[subclass=JSInt]*/
assignInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -72,7 +72,7 @@
return lines;
}
-/*element: assignInTwoClosures:[subclass=JSInt]*/
+/*member: assignInTwoClosures:[subclass=JSInt]*/
assignInTwoClosures() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -86,7 +86,7 @@
return lines;
}
-/*element: accessAssignInClosure:[subclass=JSInt]*/
+/*member: accessAssignInClosure:[subclass=JSInt]*/
accessAssignInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -97,7 +97,7 @@
return lines;
}
-/*element: accessBeforeAssignInClosure:[exact=JSUInt31]*/
+/*member: accessBeforeAssignInClosure:[exact=JSUInt31]*/
accessBeforeAssignInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -109,7 +109,7 @@
return lines;
}
-/*element: accessAfterAssignInClosure:[exact=JSUInt31]*/
+/*member: accessAfterAssignInClosure:[exact=JSUInt31]*/
accessAfterAssignInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -121,7 +121,7 @@
return lines;
}
-/*element: compoundInClosure:[subclass=JSInt]*/
+/*member: compoundInClosure:[subclass=JSInt]*/
compoundInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
@@ -132,7 +132,7 @@
return lines;
}
-/*element: postfixInClosure:[subclass=JSPositiveInt]*/
+/*member: postfixInClosure:[subclass=JSPositiveInt]*/
postfixInClosure() {
/*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
diff --git a/tests/compiler/dart2js/inference/data/closure2.dart b/tests/compiler/dart2js/inference/data/closure2.dart
index 285ff02..5d03f44 100644
--- a/tests/compiler/dart2js/inference/data/closure2.dart
+++ b/tests/compiler/dart2js/inference/data/closure2.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.
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
returnInt1() {
var a = 42;
// ignore: unused_local_variable
@@ -12,7 +12,7 @@
return a;
}
-/*element: returnDyn1:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn1:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
returnDyn1() {
dynamic a = 42;
// ignore: unused_local_variable
@@ -22,7 +22,7 @@
return a;
}
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
returnInt2() {
var a = 42;
// ignore: unused_local_variable
@@ -32,7 +32,7 @@
return a;
}
-/*element: returnDyn2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
returnDyn2() {
dynamic a = 42;
// ignore: unused_local_variable
@@ -46,7 +46,7 @@
return a;
}
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
returnInt3() {
var a = 42;
if (a /*invoke: [exact=JSUInt31]*/ == 53) {
@@ -58,7 +58,7 @@
return a;
}
-/*element: returnDyn3:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn3:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
returnDyn3() {
dynamic a = 42;
if (a /*invoke: Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ == 53) {
@@ -70,7 +70,7 @@
return a;
}
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
returnInt4() {
var a = 42;
/*[exact=JSUInt31]*/ g() {
@@ -80,7 +80,7 @@
return g();
}
-/*element: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
returnNum1() {
dynamic a = 42.5;
try {
@@ -95,7 +95,7 @@
return a;
}
-/*element: returnIntOrNull:[null|exact=JSUInt31]*/
+/*member: returnIntOrNull:[null|exact=JSUInt31]*/
returnIntOrNull() {
/*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
/*current: [exact=ArrayIterator]*/
@@ -111,16 +111,16 @@
return 42;
}
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
- /*element: A.foo:[exact=A]*/
+ /*member: A.foo:[exact=A]*/
foo() {
/*[exact=A]*/ f() => this;
return f();
}
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt1();
returnDyn1();
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer.dart b/tests/compiler/dart2js/inference/data/closure_tracer.dart
index d419c89..82aab01 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer.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.
-/*element: testFunctionStatement:[null|exact=JSUInt31]*/
+/*member: testFunctionStatement:[null|exact=JSUInt31]*/
testFunctionStatement() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -10,7 +10,7 @@
return res;
}
-/*element: testFunctionExpression:[null|exact=JSUInt31]*/
+/*member: testFunctionExpression:[null|exact=JSUInt31]*/
testFunctionExpression() {
var res;
var closure = /*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ a) => res = a;
@@ -18,10 +18,10 @@
return res;
}
-/*element: staticField:[null|subclass=Closure]*/
+/*member: staticField:[null|subclass=Closure]*/
var staticField;
-/*element: testStoredInStatic:[null|exact=JSUInt31]*/
+/*member: testStoredInStatic:[null|exact=JSUInt31]*/
testStoredInStatic() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -31,16 +31,16 @@
}
class A {
- /*element: A.field:[subclass=Closure]*/
+ /*member: A.field:[subclass=Closure]*/
var field;
- /*element: A.:[exact=A]*/
+ /*member: A.:[exact=A]*/
A(this. /*[subclass=Closure]*/ field);
- /*element: A.foo:[exact=JSUInt31]*/
+ /*member: A.foo:[exact=JSUInt31]*/
static foo(/*[exact=JSUInt31]*/ a) => topLevel3 = a;
}
-/*element: testStoredInInstance:[null|exact=JSUInt31]*/
+/*member: testStoredInInstance:[null|exact=JSUInt31]*/
testStoredInInstance() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -49,7 +49,7 @@
return res;
}
-/*element: testStoredInMapOfList:[null|subclass=Object]*/
+/*member: testStoredInMapOfList:[null|subclass=Object]*/
testStoredInMapOfList() {
var res;
/*[null|subclass=Object]*/ closure(/*[null|subclass=Object]*/ a) => res = a;
@@ -69,7 +69,7 @@
return res;
}
-/*element: testStoredInListOfList:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfList:[null|exact=JSUInt31]*/
testStoredInListOfList() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -88,7 +88,7 @@
return res;
}
-/*element: testStoredInListOfListUsingInsert:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfListUsingInsert:[null|exact=JSUInt31]*/
testStoredInListOfListUsingInsert() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -107,7 +107,7 @@
return res;
}
-/*element: testStoredInListOfListUsingAdd:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfListUsingAdd:[null|exact=JSUInt31]*/
testStoredInListOfListUsingAdd() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -127,12 +127,12 @@
return res;
}
-/*element: foo:[null]*/
+/*member: foo:[null]*/
foo(/*[subclass=Closure]*/ closure) {
closure(42);
}
-/*element: testPassedInParameter:[null|exact=JSUInt31]*/
+/*member: testPassedInParameter:[null|exact=JSUInt31]*/
testPassedInParameter() {
var res;
/*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -140,25 +140,25 @@
return res;
}
-/*element: topLevel1:[null|exact=JSUInt31]*/
+/*member: topLevel1:[null|exact=JSUInt31]*/
var topLevel1;
-/*element: foo2:[exact=JSUInt31]*/
+/*member: foo2:[exact=JSUInt31]*/
foo2(/*[exact=JSUInt31]*/ a) => topLevel1 = a;
-/*element: testStaticClosure1:[null|exact=JSUInt31]*/
+/*member: testStaticClosure1:[null|exact=JSUInt31]*/
testStaticClosure1() {
var a = foo2;
a(42);
return topLevel1;
}
-/*element: topLevel2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: topLevel2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
var topLevel2;
-/*element: bar:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: bar:Union([exact=JSDouble], [exact=JSUInt31])*/
bar(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) => topLevel2 = a;
-/*element: testStaticClosure2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testStaticClosure2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
testStaticClosure2() {
var a = bar;
a(42);
@@ -167,23 +167,23 @@
return topLevel2;
}
-/*element: topLevel3:[null|exact=JSUInt31]*/
+/*member: topLevel3:[null|exact=JSUInt31]*/
var topLevel3;
-/*element: testStaticClosure3:[null|exact=JSUInt31]*/ testStaticClosure3() {
+/*member: testStaticClosure3:[null|exact=JSUInt31]*/ testStaticClosure3() {
var a = A.foo;
a(42);
return topLevel3;
}
-/*element: topLevel4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: topLevel4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
var topLevel4;
-/*element: testStaticClosure4Helper:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: testStaticClosure4Helper:Union([exact=JSDouble], [exact=JSUInt31])*/
testStaticClosure4Helper(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) =>
topLevel4 = a;
-/*element: testStaticClosure4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testStaticClosure4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
testStaticClosure4() {
var a = testStaticClosure4Helper;
// Test calling the static after tearing it off.
@@ -192,7 +192,7 @@
return topLevel4;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
testFunctionStatement();
testFunctionExpression();
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index 6bc222f..ba4ae4b 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -4,7 +4,7 @@
// Regression test for issue 28919.
-/*element: foo1:[null]*/
+/*member: foo1:[null]*/
foo1() {
final methods = [];
var res, sum;
@@ -25,18 +25,18 @@
probe1methods(methods);
}
-/*element: probe1res:[null|exact=JSUInt31]*/
+/*member: probe1res:[null|exact=JSUInt31]*/
probe1res(/*[null|exact=JSUInt31]*/ x) => x;
-/*element: probe1sum:[null|subclass=JSPositiveInt]*/
+/*member: probe1sum:[null|subclass=JSPositiveInt]*/
probe1sum(/*[null|subclass=JSPositiveInt]*/ x) => x;
-/*element: probe1methods:Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/
+/*member: probe1methods:Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/
probe1methods(
/*Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/ x) =>
x;
-/*element: nonContainer:[exact=JSExtendableArray]*/
+/*member: nonContainer:[exact=JSExtendableArray]*/
nonContainer(/*[exact=JSUInt31]*/ choice) {
var m = choice /*invoke: [exact=JSUInt31]*/ == 0 ? [] : "<String>";
if (m is! List) throw 123;
@@ -44,7 +44,7 @@
return m;
}
-/*element: foo2:[null]*/
+/*member: foo2:[null]*/
foo2(int /*[exact=JSUInt31]*/ choice) {
final methods = nonContainer(choice);
@@ -69,17 +69,17 @@
probe2methods(methods);
}
-/*element: probe2res:[null|subclass=JSInt]*/
+/*member: probe2res:[null|subclass=JSInt]*/
probe2res(
/*[null|subclass=JSInt]*/
x) =>
x;
-/*element: probe2methods:[exact=JSExtendableArray]*/
+/*member: probe2methods:[exact=JSExtendableArray]*/
probe2methods(/*[exact=JSExtendableArray]*/ x) => x;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
foo1();
foo2(0);
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance.dart b/tests/compiler/dart2js/inference/data/closurization_instance.dart
index a4b1c5f..810e71f 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closurizedCallToString();
}
@@ -11,13 +11,13 @@
// Implicit/explicit .call on instance method tear-off.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.method:[exact=JSUInt31]*/
+ /*member: Class.method:[exact=JSUInt31]*/
method() => 42;
}
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
var local = c. /*[exact=Class]*/ method;
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
index f46b1a5..4f785bf 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance_call.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closurizedCallToString();
}
@@ -12,16 +12,16 @@
// '.call' method in the closed world.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.call:Value([exact=JSBool], value: true)*/
+ /*member: Class.call:Value([exact=JSBool], value: true)*/
call() => true;
- /*element: Class.method:[exact=JSUInt31]*/
+ /*member: Class.method:[exact=JSUInt31]*/
method() => 42;
}
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/closurization_local_call.dart b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
index 65dd652..65439e1 100644
--- a/tests/compiler/dart2js/inference/data/closurization_local_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_local_call.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closurizedCallToString();
}
@@ -12,13 +12,13 @@
// method in the closed world.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.call:Value([exact=JSBool], value: true)*/
+ /*member: Class.call:Value([exact=JSBool], value: true)*/
call() => true;
}
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/closurization_static.dart b/tests/compiler/dart2js/inference/data/closurization_static.dart
index 0da0999..deea1db 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closurizedCallToString();
}
@@ -11,10 +11,10 @@
// Implicit/explicit .call on static method tear-off.
////////////////////////////////////////////////////////////////////////////////
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
method() => 42;
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var local = method;
local. /*invoke: [subclass=Closure]*/ toString();
diff --git a/tests/compiler/dart2js/inference/data/closurization_static_call.dart b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
index c45fd9f..a29e594 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static_call.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closurizedCallToString();
}
@@ -12,16 +12,16 @@
// '.call' method in the closed world.
////////////////////////////////////////////////////////////////////////////////
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
method() => 42;
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.call:Value([exact=JSBool], value: true)*/
+ /*member: Class.call:Value([exact=JSBool], value: true)*/
call() => true;
}
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/conditional.dart b/tests/compiler/dart2js/inference/data/conditional.dart
index d7f799c..e8af4fe 100644
--- a/tests/compiler/dart2js/inference/data/conditional.dart
+++ b/tests/compiler/dart2js/inference/data/conditional.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleConditional();
simpleConditionalTrue();
@@ -19,10 +19,10 @@
/// Simple conditional with unknown condition value.
////////////////////////////////////////////////////////////////////////////////
-/*element: _simpleConditional:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditional:Union([exact=JSString], [exact=JSUInt31])*/
_simpleConditional(/*[exact=JSBool]*/ c) => c ? '' : 0;
-/*element: simpleConditional:[null]*/
+/*member: simpleConditional:[null]*/
simpleConditional() {
_simpleConditional(true);
_simpleConditional(false);
@@ -32,10 +32,10 @@
/// Simple conditional with unknown condition value.
////////////////////////////////////////////////////////////////////////////////
-/*element: _simpleConditionalTrue:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditionalTrue:Union([exact=JSString], [exact=JSUInt31])*/
_simpleConditionalTrue(/*Value([exact=JSBool], value: true)*/ c) => c ? '' : 0;
-/*element: simpleConditionalTrue:[null]*/
+/*member: simpleConditionalTrue:[null]*/
simpleConditionalTrue() {
_simpleConditionalTrue(true);
}
@@ -44,11 +44,11 @@
/// Simple conditional with unknown condition value.
////////////////////////////////////////////////////////////////////////////////
-/*element: _simpleConditionalFalse:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditionalFalse:Union([exact=JSString], [exact=JSUInt31])*/
_simpleConditionalFalse(/*Value([exact=JSBool], value: false)*/ c) =>
c ? '' : 0;
-/*element: simpleConditionalFalse:[null]*/
+/*member: simpleConditionalFalse:[null]*/
simpleConditionalFalse() {
_simpleConditionalFalse(false);
}
@@ -56,11 +56,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is test.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIs:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIs:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalIs(/*[null|exact=JSUInt31]*/ o) =>
o is int ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
-/*element: conditionalIs:[null]*/
+/*member: conditionalIs:[null]*/
conditionalIs() {
_conditionalIs(null);
_conditionalIs(1);
@@ -69,11 +69,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is `int` test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalIsInt(/*[exact=JSUInt31]*/ o) =>
o is int ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
-/*element: conditionalIsInt:[null]*/
+/*member: conditionalIsInt:[null]*/
conditionalIsInt() {
_conditionalIsInt(1);
}
@@ -81,11 +81,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is-not test.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsNot:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsNot:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalIsNot(/*[null|exact=JSUInt31]*/ o) =>
o is! int ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
-/*element: conditionalIsNot:[null]*/
+/*member: conditionalIsNot:[null]*/
conditionalIsNot() {
_conditionalIsNot(null);
_conditionalIsNot(1);
@@ -94,11 +94,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is-not `int` test known to be false.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsNotInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsNotInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalIsNotInt(/*[exact=JSUInt31]*/ o) =>
o is! int ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
-/*element: conditionalIsNotInt:[null]*/
+/*member: conditionalIsNotInt:[null]*/
conditionalIsNotInt() {
_conditionalIsNotInt(1);
}
@@ -106,11 +106,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is test.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalNull(/*[null|exact=JSUInt31]*/ o) =>
o == null ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
-/*element: conditionalNull:[null]*/
+/*member: conditionalNull:[null]*/
conditionalNull() {
_conditionalNull(null);
_conditionalNull(1);
@@ -119,11 +119,11 @@
////////////////////////////////////////////////////////////////////////////////
/// Conditional with an is `int` test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalNotNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalNotNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
_conditionalNotNull(/*[null|exact=JSUInt31]*/ o) =>
o != null ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
-/*element: conditionalNotNull:[null]*/
+/*member: conditionalNotNull:[null]*/
conditionalNotNull() {
_conditionalNotNull(null);
_conditionalNotNull(1);
diff --git a/tests/compiler/dart2js/inference/data/const_closure.dart b/tests/compiler/dart2js/inference/data/const_closure.dart
index 8425f4d..551def4 100644
--- a/tests/compiler/dart2js/inference/data/const_closure.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure.dart
@@ -2,36 +2,36 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method1:[exact=JSUInt31]*/
+/*member: method1:[exact=JSUInt31]*/
method1() {
return 42;
}
-/*element: method2:[exact=JSUInt31]*/
+/*member: method2:[exact=JSUInt31]*/
method2(/*[exact=JSUInt31]*/ a) {
// Called only via [foo2] with a small integer.
return a;
}
-/*strong.element: foo1:[subclass=Closure]*/
-/*omit.element: foo1:[subclass=Closure]*/
+/*strong.member: foo1:[subclass=Closure]*/
+/*omit.member: foo1:[subclass=Closure]*/
const foo1 = method1;
-/*strong.element: foo2:[subclass=Closure]*/
-/*omit.element: foo2:[subclass=Closure]*/
+/*strong.member: foo2:[subclass=Closure]*/
+/*omit.member: foo2:[subclass=Closure]*/
const foo2 = method2;
-/*element: returnInt1:[null|subclass=Object]*/
+/*member: returnInt1:[null|subclass=Object]*/
returnInt1() {
return foo1();
}
-/*element: returnInt2:[null|subclass=Object]*/
+/*member: returnInt2:[null|subclass=Object]*/
returnInt2() {
return foo2(54);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt1();
returnInt2();
diff --git a/tests/compiler/dart2js/inference/data/const_closure2.dart b/tests/compiler/dart2js/inference/data/const_closure2.dart
index 207a431..2dc19f6 100644
--- a/tests/compiler/dart2js/inference/data/const_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure2.dart
@@ -2,22 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
// Called via [foo] with integer then double.
method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
return a;
}
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
const foo = method;
-/*element: returnNum:[null|subclass=Object]*/
+/*member: returnNum:[null|subclass=Object]*/
returnNum(/*Union([exact=JSDouble], [exact=JSUInt31])*/ x) {
return foo(x);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnNum(10);
returnNum(10.5);
diff --git a/tests/compiler/dart2js/inference/data/const_closure3.dart b/tests/compiler/dart2js/inference/data/const_closure3.dart
index 79a36f0..eb19bcb 100644
--- a/tests/compiler/dart2js/inference/data/const_closure3.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure3.dart
@@ -2,22 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
// Called only via [foo2] with a small integer.
method(/*[exact=JSUInt31]*/ a) {
return a;
}
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
const foo = method;
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
returnInt() {
return foo(54);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt();
}
diff --git a/tests/compiler/dart2js/inference/data/const_closure4.dart b/tests/compiler/dart2js/inference/data/const_closure4.dart
index 207a431..2dc19f6 100644
--- a/tests/compiler/dart2js/inference/data/const_closure4.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure4.dart
@@ -2,22 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
// Called via [foo] with integer then double.
method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
return a;
}
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
const foo = method;
-/*element: returnNum:[null|subclass=Object]*/
+/*member: returnNum:[null|subclass=Object]*/
returnNum(/*Union([exact=JSDouble], [exact=JSUInt31])*/ x) {
return foo(x);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnNum(10);
returnNum(10.5);
diff --git a/tests/compiler/dart2js/inference/data/const_closure5.dart b/tests/compiler/dart2js/inference/data/const_closure5.dart
index 89a3abf..57e976e 100644
--- a/tests/compiler/dart2js/inference/data/const_closure5.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure5.dart
@@ -2,22 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
// Called only via [foo2] with a small integer.
method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
return a;
}
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
const foo = method;
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
returnInt() {
return foo(54);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt();
method(55.2);
diff --git a/tests/compiler/dart2js/inference/data/const_closure_default.dart b/tests/compiler/dart2js/inference/data/const_closure_default.dart
index 3217dcb..135ed2a 100644
--- a/tests/compiler/dart2js/inference/data/const_closure_default.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure_default.dart
@@ -4,43 +4,43 @@
// [defaultFn_i] is called only via [foo_i]'s default value with a small integer.
-/*element: defaultFn1:[exact=JSUInt31]*/
+/*member: defaultFn1:[exact=JSUInt31]*/
defaultFn1(/*[exact=JSUInt31]*/ a) => a;
-/*element: defaultFn2:[exact=JSUInt31]*/
+/*member: defaultFn2:[exact=JSUInt31]*/
defaultFn2(/*[exact=JSUInt31]*/ a) => a;
-/*element: defaultFn3:[exact=JSUInt31]*/
+/*member: defaultFn3:[exact=JSUInt31]*/
defaultFn3(/*[exact=JSUInt31]*/ a) => a;
-/*element: defaultFn4:[exact=JSUInt31]*/
+/*member: defaultFn4:[exact=JSUInt31]*/
defaultFn4(/*[exact=JSUInt31]*/ a) => a;
-/*element: defaultFn5:[exact=JSUInt31]*/
+/*member: defaultFn5:[exact=JSUInt31]*/
defaultFn5(/*[exact=JSUInt31]*/ a) => a;
-/*element: defaultFn6:[exact=JSUInt31]*/
+/*member: defaultFn6:[exact=JSUInt31]*/
defaultFn6(/*[exact=JSUInt31]*/ a) => a;
-/*element: foo1:[null|subclass=Object]*/
+/*member: foo1:[null|subclass=Object]*/
foo1([/*[subclass=Closure]*/ fn = defaultFn1]) => fn(54);
-/*element: foo2:[null|subclass=Object]*/
+/*member: foo2:[null|subclass=Object]*/
foo2({/*[subclass=Closure]*/ fn: defaultFn2}) => fn(54);
-/*element: foo3:[null|subclass=Object]*/
+/*member: foo3:[null|subclass=Object]*/
foo3([/*[subclass=Closure]*/ fn = defaultFn3]) => fn(54);
-/*element: foo4:[null|subclass=Object]*/
+/*member: foo4:[null|subclass=Object]*/
foo4({/*[subclass=Closure]*/ fn: defaultFn4}) => fn(54);
-/*element: foo5:[null|subclass=Object]*/
+/*member: foo5:[null|subclass=Object]*/
foo5([/*[null|subclass=Object]*/ fn = defaultFn5]) => fn(54);
-/*element: foo6:[null|subclass=Object]*/
+/*member: foo6:[null|subclass=Object]*/
foo6({/*[null|subclass=Object]*/ fn: defaultFn6}) => fn(54);
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
// Direct calls.
foo1();
diff --git a/tests/compiler/dart2js/inference/data/container_mask_equal.dart b/tests/compiler/dart2js/inference/data/container_mask_equal.dart
index be6deee..c4830df 100644
--- a/tests/compiler/dart2js/inference/data/container_mask_equal.dart
+++ b/tests/compiler/dart2js/inference/data/container_mask_equal.dart
@@ -7,25 +7,25 @@
import 'dart:typed_data';
-/*element: method1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: method1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
method1() => [0];
-/*element: method2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
+/*member: method2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
method2() => [1, 2];
-/*element: method3:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 1)*/
+/*member: method3:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 1)*/
method3() => new Uint8List(1);
-/*element: method4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 2)*/
+/*member: method4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 2)*/
method4() => new Uint8List(2);
-/*element: method1or2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
+/*member: method1or2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
method1or2(/*[exact=JSBool]*/ c) => c ? method1() : method2();
-/*element: method3or4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: null)*/
+/*member: method3or4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: null)*/
method3or4(/*[exact=JSBool]*/ c) => c ? method3() : method4();
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
method1or2(true);
method1or2(false);
diff --git a/tests/compiler/dart2js/inference/data/default_value.dart b/tests/compiler/dart2js/inference/data/default_value.dart
index e9d1b0c..b08d14f 100644
--- a/tests/compiler/dart2js/inference/data/default_value.dart
+++ b/tests/compiler/dart2js/inference/data/default_value.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
positionalWithoutDefaultOnLocal();
positionalWithNullDefaultOnLocal();
@@ -12,35 +12,35 @@
positionalWithOneDefaultOnStatic();
}
-/*element: positionalWithoutDefaultOnLocal:[null]*/
+/*member: positionalWithoutDefaultOnLocal:[null]*/
positionalWithoutDefaultOnLocal() {
/*[null]*/ local([/*[null]*/ parameter]) => parameter;
return local();
}
-/*element: positionalWithNullDefaultOnLocal:[null]*/
+/*member: positionalWithNullDefaultOnLocal:[null]*/
positionalWithNullDefaultOnLocal() {
/*[null]*/ local([/*[null]*/ parameter = null]) => parameter;
return local();
}
-/*element: positionalWithOneDefaultOnLocal:[exact=JSUInt31]*/
+/*member: positionalWithOneDefaultOnLocal:[exact=JSUInt31]*/
positionalWithOneDefaultOnLocal() {
/*[exact=JSUInt31]*/ local([/*[exact=JSUInt31]*/ parameter = 1]) => parameter;
return local();
}
-/*element: positionalWithoutDefaultOnStatic:[null]*/
+/*member: positionalWithoutDefaultOnStatic:[null]*/
positionalWithoutDefaultOnStatic([/*[null]*/ parameter]) {
return parameter;
}
-/*element: positionalWithNullDefaultOnStatic:[null]*/
+/*member: positionalWithNullDefaultOnStatic:[null]*/
positionalWithNullDefaultOnStatic([/*[null]*/ parameter = null]) {
return parameter;
}
-/*element: positionalWithOneDefaultOnStatic:[exact=JSUInt31]*/
+/*member: positionalWithOneDefaultOnStatic:[exact=JSUInt31]*/
positionalWithOneDefaultOnStatic([/*[exact=JSUInt31]*/ parameter = 1]) {
return parameter;
}
diff --git a/tests/compiler/dart2js/inference/data/deferred_load.dart b/tests/compiler/dart2js/inference/data/deferred_load.dart
index af34b6e..41ee085 100644
--- a/tests/compiler/dart2js/inference/data/deferred_load.dart
+++ b/tests/compiler/dart2js/inference/data/deferred_load.dart
@@ -4,10 +4,10 @@
import 'package:expect/expect.dart' deferred as expect;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
callLoadLibrary();
}
-/*element: callLoadLibrary:[null|subclass=Object]*/
+/*member: callLoadLibrary:[null|subclass=Object]*/
callLoadLibrary() => expect.loadLibrary();
diff --git a/tests/compiler/dart2js/inference/data/deferred_load_get.dart b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
index e27bf13..1226ef8 100644
--- a/tests/compiler/dart2js/inference/data/deferred_load_get.dart
+++ b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
@@ -6,12 +6,12 @@
// Synthetic getter added by kernel.
-/*element: __loadLibrary_expect:[null|exact=_Future]*/
+/*member: __loadLibrary_expect:[null|exact=_Future]*/
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
tearOffLoadLibrary();
}
-/*element: tearOffLoadLibrary:[subclass=Closure]*/
+/*member: tearOffLoadLibrary:[subclass=Closure]*/
tearOffLoadLibrary() => expect.loadLibrary;
diff --git a/tests/compiler/dart2js/inference/data/dictionary_types.dart b/tests/compiler/dart2js/inference/data/dictionary_types.dart
index 84dc58c..c2ac48b 100644
--- a/tests/compiler/dart2js/inference/data/dictionary_types.dart
+++ b/tests/compiler/dart2js/inference/data/dictionary_types.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
@@ -11,7 +11,7 @@
test5();
}
-/*element: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
dynamic dictionaryA1 = {
'string': "aString",
'int': 42,
@@ -19,7 +19,7 @@
'list': []
};
-/*element: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+/*member: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
dynamic dictionaryB1 = {
'string': "aString",
'int': 42,
@@ -27,22 +27,22 @@
'list': []
};
-/*element: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
+/*member: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
dynamic otherDict1 = {'stringTwo': "anotherString", 'intTwo': 84};
-/*element: int1:[exact=JSUInt31]*/
+/*member: int1:[exact=JSUInt31]*/
dynamic int1 = 0;
-/*element: anotherInt1:[exact=JSUInt31]*/
+/*member: anotherInt1:[exact=JSUInt31]*/
dynamic anotherInt1 = 0;
-/*element: nullOrInt1:[null|exact=JSUInt31]*/
+/*member: nullOrInt1:[null|exact=JSUInt31]*/
dynamic nullOrInt1 = 0;
-/*element: dynamic1:[null|subclass=Object]*/
+/*member: dynamic1:[null|subclass=Object]*/
dynamic dynamic1 = 0;
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1() {
dictionaryA1
. /*invoke: Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
@@ -64,7 +64,7 @@
['intTwo'];
}
-/*element: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
dynamic dictionaryA2 = {
'string': "aString",
'int': 42,
@@ -72,19 +72,19 @@
'list': []
};
-/*element: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
dynamic dictionaryB2 = {'string': "aString", 'intTwo': 42, 'list': []};
-/*element: nullOrInt2:[null|exact=JSUInt31]*/
+/*member: nullOrInt2:[null|exact=JSUInt31]*/
dynamic nullOrInt2 = 0;
-/*element: aString2:[exact=JSString]*/
+/*member: aString2:[exact=JSString]*/
dynamic aString2 = "";
-/*element: doubleOrNull2:[null|exact=JSDouble]*/
+/*member: doubleOrNull2:[null|exact=JSDouble]*/
dynamic doubleOrNull2 = 22.2;
-/*element: test2:[null]*/
+/*member: test2:[null]*/
test2() {
var union = dictionaryA2
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
@@ -102,36 +102,36 @@
['double'];
}
-/*element: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
dynamic dictionary3 = {
'string': "aString",
'int': 42,
'double': 21.5,
'list': []
};
-/*element: keyD3:Value([exact=JSString], value: "double")*/
+/*member: keyD3:Value([exact=JSString], value: "double")*/
dynamic keyD3 = 'double';
-/*element: keyI3:Value([exact=JSString], value: "int")*/
+/*member: keyI3:Value([exact=JSString], value: "int")*/
dynamic keyI3 = 'int';
-/*element: keyN3:Value([exact=JSString], value: "notFoundInMap")*/
+/*member: keyN3:Value([exact=JSString], value: "notFoundInMap")*/
dynamic keyN3 = 'notFoundInMap';
-/*element: knownDouble3:[exact=JSDouble]*/
+/*member: knownDouble3:[exact=JSDouble]*/
dynamic knownDouble3 = 42.2;
-/*element: intOrNull3:[null|exact=JSUInt31]*/
+/*member: intOrNull3:[null|exact=JSUInt31]*/
dynamic intOrNull3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
[keyI3];
-/*element: justNull3:[null]*/
+/*member: justNull3:[null]*/
dynamic justNull3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
[keyN3];
-/*element: test3:[null]*/
+/*member: test3:[null]*/
test3() {
knownDouble3 = dictionary3
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
@@ -141,9 +141,9 @@
}
class A4 {
-/*element: A4.:[exact=A4]*/
+/*member: A4.:[exact=A4]*/
A4();
-/*element: A4.foo4:[exact=JSUInt31]*/
+/*member: A4.foo4:[exact=JSUInt31]*/
foo4(
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
return value /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ [
@@ -152,17 +152,17 @@
}
class B4 {
-/*element: B4.:[exact=B4]*/
+/*member: B4.:[exact=B4]*/
B4();
-/*element: B4.foo4:[exact=JSUInt31]*/
+/*member: B4.foo4:[exact=JSUInt31]*/
foo4(
/*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
return 0;
}
}
-/*element: test4:[null]*/
+/*member: test4:[null]*/
test4() {
var dictionary = {'anInt': 42, 'aString': "theString"};
var it;
@@ -178,16 +178,16 @@
2);
}
-/*element: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
dynamic dict5 = makeMap5([1, 2]);
-/*element: notInt5:[null|subclass=Object]*/
+/*member: notInt5:[null|subclass=Object]*/
dynamic notInt5 = 0;
-/*element: alsoNotInt5:[null|subclass=Object]*/
+/*member: alsoNotInt5:[null|subclass=Object]*/
dynamic alsoNotInt5 = 0;
-/*element: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
makeMap5(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/ values) {
return {
@@ -200,7 +200,7 @@
};
}
-/*element: test5:[null]*/
+/*member: test5:[null]*/
test5() {
dict5
/*update: Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
diff --git a/tests/compiler/dart2js/inference/data/do.dart b/tests/compiler/dart2js/inference/data/do.dart
index 2c7da87..549d826 100644
--- a/tests/compiler/dart2js/inference/data/do.dart
+++ b/tests/compiler/dart2js/inference/data/do.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleDo();
doNull();
@@ -16,7 +16,7 @@
/// Simple int based do-while loop.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleDo:[null]*/
+/*member: simpleDo:[null]*/
simpleDo() {
var i = 0;
do {
@@ -29,7 +29,7 @@
/// Do-while loop with null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: doNull:[exact=JSString]*/
+/*member: doNull:[exact=JSString]*/
doNull() {
var o;
do {
@@ -42,7 +42,7 @@
/// Do-while loop with not-null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: doNotNull:[exact=JSString]*/
+/*member: doNotNull:[exact=JSString]*/
doNotNull() {
var o = '';
do {
@@ -55,7 +55,7 @@
/// Do-while loop with null test known to be false.
////////////////////////////////////////////////////////////////////////////////
-/*element: doNullFalse:[exact=JSString]*/
+/*member: doNullFalse:[exact=JSString]*/
doNullFalse() {
var o = '';
do {
@@ -68,7 +68,7 @@
/// Do-while loop with not-null test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: doNotNullTrue:[exact=JSString]*/
+/*member: doNotNullTrue:[exact=JSString]*/
doNotNullTrue() {
var o = null;
do {
@@ -81,19 +81,19 @@
/// Do-while loop with not-null test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[null|exact=Class2]*/
+ /*member: Class1.field:[null|exact=Class2]*/
var field;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[null|exact=Class1]*/
+ /*member: Class2.field:[null|exact=Class1]*/
var field;
}
-/*element: _doUnion:Union([null|exact=Class1], [null|exact=Class2])*/
+/*member: _doUnion:Union([null|exact=Class1], [null|exact=Class2])*/
_doUnion(/*[exact=Class1]*/ o) {
do {
o = o. /*Union([exact=Class1], [null|exact=Class2])*/ field;
@@ -101,7 +101,7 @@
return o;
}
-/*element: doUnion:[null]*/
+/*member: doUnion:[null]*/
doUnion() {
var c1 = new Class1();
var c2 = new Class2();
diff --git a/tests/compiler/dart2js/inference/data/enum.dart b/tests/compiler/dart2js/inference/data/enum.dart
index 79b6d84..5e93aea 100644
--- a/tests/compiler/dart2js/inference/data/enum.dart
+++ b/tests/compiler/dart2js/inference/data/enum.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
enumValue();
enumIndex();
@@ -16,12 +16,12 @@
////////////////////////////////////////////////////////////////////////////////
enum Enum1 {
- /*strong.element: Enum1.a:[exact=Enum1]*/
- /*omit.element: Enum1.a:[exact=Enum1]*/
+ /*strong.member: Enum1.a:[exact=Enum1]*/
+ /*omit.member: Enum1.a:[exact=Enum1]*/
a,
}
-/*element: enumValue:[exact=Enum1]*/
+/*member: enumValue:[exact=Enum1]*/
enumValue() => Enum1.a;
////////////////////////////////////////////////////////////////////////////////
@@ -29,12 +29,12 @@
////////////////////////////////////////////////////////////////////////////////
enum Enum2 {
- /*strong.element: Enum2.a:[exact=Enum2]*/
- /*omit.element: Enum2.a:[exact=Enum2]*/
+ /*strong.member: Enum2.a:[exact=Enum2]*/
+ /*omit.member: Enum2.a:[exact=Enum2]*/
a,
}
-/*element: enumIndex:[exact=JSUInt31]*/
+/*member: enumIndex:[exact=JSUInt31]*/
enumIndex() => Enum2.a. /*[exact=Enum2]*/ index;
////////////////////////////////////////////////////////////////////////////////
@@ -42,15 +42,15 @@
////////////////////////////////////////////////////////////////////////////////
enum Enum3 {
- /*strong.element: Enum3.a:[exact=Enum3]*/
- /*omit.element: Enum3.a:[exact=Enum3]*/
+ /*strong.member: Enum3.a:[exact=Enum3]*/
+ /*omit.member: Enum3.a:[exact=Enum3]*/
a,
- /*strong.element: Enum3.b:[exact=Enum3]*/
- /*omit.element: Enum3.b:[exact=Enum3]*/
+ /*strong.member: Enum3.b:[exact=Enum3]*/
+ /*omit.member: Enum3.b:[exact=Enum3]*/
b,
}
-/*element: enumValues:Container([exact=JSUnmodifiableArray], element: [exact=Enum3], length: 2)*/
+/*member: enumValues:Container([exact=JSUnmodifiableArray], element: [exact=Enum3], length: 2)*/
enumValues() => Enum3.values;
////////////////////////////////////////////////////////////////////////////////
@@ -58,12 +58,12 @@
////////////////////////////////////////////////////////////////////////////////
enum Enum4 {
- /*strong.element: Enum4.a:[exact=Enum4]*/
- /*omit.element: Enum4.a:[exact=Enum4]*/
+ /*strong.member: Enum4.a:[exact=Enum4]*/
+ /*omit.member: Enum4.a:[exact=Enum4]*/
a,
}
-/*element: enumToString1:Value([exact=JSString], value: "Enum4.a")*/
+/*member: enumToString1:Value([exact=JSString], value: "Enum4.a")*/
enumToString1() {
return Enum4.a. /*invoke: [exact=Enum4]*/ toString();
}
@@ -73,15 +73,15 @@
////////////////////////////////////////////////////////////////////////////////
enum Enum5 {
- /*strong.element: Enum5.a:[exact=Enum5]*/
- /*omit.element: Enum5.a:[exact=Enum5]*/
+ /*strong.member: Enum5.a:[exact=Enum5]*/
+ /*omit.member: Enum5.a:[exact=Enum5]*/
a,
- /*strong.element: Enum5.b:[exact=Enum5]*/
- /*omit.element: Enum5.b:[exact=Enum5]*/
+ /*strong.member: Enum5.b:[exact=Enum5]*/
+ /*omit.member: Enum5.b:[exact=Enum5]*/
b,
}
-/*element: enumToString2:[exact=JSString]*/
+/*member: enumToString2:[exact=JSString]*/
enumToString2() {
Enum5.b. /*invoke: [exact=Enum5]*/ toString();
return Enum5.a. /*invoke: [exact=Enum5]*/ toString();
diff --git a/tests/compiler/dart2js/inference/data/expose_this.dart b/tests/compiler/dart2js/inference/data/expose_this.dart
index e888229..26a5d7a 100644
--- a/tests/compiler/dart2js/inference/data/expose_this.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
exposeThis1();
exposeThis2();
@@ -17,23 +17,23 @@
// Expose this through a top level method invocation.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[null]*/
+/*member: _method1:[null]*/
_method1(/*[exact=Class1]*/ o) {}
class Class1 {
// The inferred type of the field includes `null` because `this` has been
// exposed before its initialization.
- /*element: Class1.field:[null|exact=JSUInt31]*/
+ /*member: Class1.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1() {
_method1(this);
/*update: [exact=Class1]*/ field = 42;
}
}
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
exposeThis1() => new Class1();
////////////////////////////////////////////////////////////////////////////////
@@ -41,20 +41,20 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field:[null|exact=JSUInt31]*/
+ /*member: Class2.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2() {
/*invoke: [exact=Class2]*/ method();
/*update: [exact=Class2]*/ field = 42;
}
- /*element: Class2.method:[null]*/
+ /*member: Class2.method:[null]*/
method() {}
}
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
exposeThis2() => new Class2();
////////////////////////////////////////////////////////////////////////////////
@@ -62,38 +62,38 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.field:[exact=JSUInt31]*/
+ /*member: Class3.field:[exact=JSUInt31]*/
var field;
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
Class3() {
this;
/*update: [exact=Class3]*/ field = 42;
}
}
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
exposeThis3() => new Class3();
////////////////////////////////////////////////////////////////////////////////
// Expose this through a static field assignment.
////////////////////////////////////////////////////////////////////////////////
-/*element: field1:[null|exact=Class4]*/
+/*member: field1:[null|exact=Class4]*/
var field1;
class Class4 {
- /*element: Class4.field:[null|exact=JSUInt31]*/
+ /*member: Class4.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4() {
field1 = this;
/*update: [exact=Class4]*/ field = 42;
}
}
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
exposeThis4() => new Class4();
////////////////////////////////////////////////////////////////////////////////
@@ -101,17 +101,17 @@
////////////////////////////////////////////////////////////////////////////////
class Class5 {
- /*element: Class5.field:[null|exact=JSUInt31]*/
+ /*member: Class5.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class5.:[exact=Class5]*/
+ /*member: Class5.:[exact=Class5]*/
Class5(/*[null]*/ o) {
o. /*update: [null]*/ field5 = this;
/*update: [exact=Class5]*/ field = 42;
}
}
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
exposeThis5() => new Class5(null);
////////////////////////////////////////////////////////////////////////////////
@@ -119,10 +119,10 @@
////////////////////////////////////////////////////////////////////////////////
class Class6 {
- /*element: Class6.field:[null|exact=JSUInt31]*/
+ /*member: Class6.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class6.:[exact=Class6]*/
+ /*member: Class6.:[exact=Class6]*/
Class6() {
// ignore: UNUSED_LOCAL_VARIABLE
var o;
@@ -131,7 +131,7 @@
}
}
-/*element: exposeThis6:[exact=Class6]*/
+/*member: exposeThis6:[exact=Class6]*/
exposeThis6() => new Class6();
////////////////////////////////////////////////////////////////////////////////
@@ -139,10 +139,10 @@
////////////////////////////////////////////////////////////////////////////////
class Class7 {
- /*element: Class7.field:[null|exact=JSUInt31]*/
+ /*member: Class7.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class7.:[exact=Class7]*/
+ /*member: Class7.:[exact=Class7]*/
Class7() {
// ignore: UNUSED_LOCAL_VARIABLE
var o = this;
@@ -150,5 +150,5 @@
}
}
-/*element: exposeThis7:[exact=Class7]*/
+/*member: exposeThis7:[exact=Class7]*/
exposeThis7() => new Class7();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_closure.dart b/tests/compiler/dart2js/inference/data/expose_this_closure.dart
index 6619281..da43183 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_closure.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_closure.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
exposeThis1();
exposeThis2();
@@ -17,18 +17,18 @@
class Class1 {
// The inferred type of the field does _not_ include `null` because `this`
// is _not_ been exposed.
- /*element: Class1.field1:[exact=JSUInt31]*/
+ /*member: Class1.field1:[exact=JSUInt31]*/
var field1;
- /*element: Class1.field2:[exact=JSUInt31]*/
+ /*member: Class1.field2:[exact=JSUInt31]*/
var field2;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1()
: field1 = 42,
field2 = 87;
}
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
exposeThis1() => new Class1();
////////////////////////////////////////////////////////////////////////////////
@@ -36,19 +36,19 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field1:[exact=JSUInt31]*/
+ /*member: Class2.field1:[exact=JSUInt31]*/
var field1;
- /*element: Class2.field2:[exact=JSUInt31]*/
+ /*member: Class2.field2:[exact=JSUInt31]*/
var field2;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2() {
/*update: [exact=Class2]*/ field1 = 42;
/*update: [exact=Class2]*/ field2 = 87;
}
}
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
exposeThis2() => new Class2();
////////////////////////////////////////////////////////////////////////////////
@@ -56,12 +56,12 @@
////////////////////////////////////////////////////////////////////////////////
class Class4 {
- /*element: Class4.field1:[exact=JSUInt31]*/
+ /*member: Class4.field1:[exact=JSUInt31]*/
var field1;
- /*element: Class4.field2:[exact=JSUInt31]*/
+ /*member: Class4.field2:[exact=JSUInt31]*/
var field2;
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4()
: field1 = 42,
field2 = 87 {
@@ -71,7 +71,7 @@
}
}
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
exposeThis4() => new Class4();
////////////////////////////////////////////////////////////////////////////////
@@ -79,12 +79,12 @@
////////////////////////////////////////////////////////////////////////////////
class Class5 {
- /*element: Class5.field1:[exact=JSUInt31]*/
+ /*member: Class5.field1:[exact=JSUInt31]*/
var field1;
- /*element: Class5.field2:[null|exact=JSUInt31]*/
+ /*member: Class5.field2:[null|exact=JSUInt31]*/
var field2;
- /*element: Class5.:[exact=Class5]*/
+ /*member: Class5.:[exact=Class5]*/
Class5() {
/*update: [exact=Class5]*/ field1 = 42;
/*[exact=JSUInt31]*/ () {
@@ -94,5 +94,5 @@
}
}
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
exposeThis5() => new Class5();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_field.dart b/tests/compiler/dart2js/inference/data/expose_this_field.dart
index 77b4c79..aa3b384 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_field.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_field.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
exposeThis1();
exposeThis2();
@@ -20,16 +20,16 @@
class Class1 {
// The inferred type of the field does _not_ include `null` because it has
// _not_ been read before its initialization.
- /*element: Class1.field:[exact=JSUInt31]*/
+ /*member: Class1.field:[exact=JSUInt31]*/
var field;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1() {
/*update: [exact=Class1]*/ field = 42;
}
}
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
exposeThis1() => new Class1();
////////////////////////////////////////////////////////////////////////////////
@@ -39,16 +39,16 @@
class Class2 {
// The inferred type of the field includes `null` because it has been read
// before its initialization.
- /*element: Class2.field:[null]*/
+ /*member: Class2.field:[null]*/
var field;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2() {
/*update: [exact=Class2]*/ field = /*[exact=Class2]*/ field;
}
}
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
exposeThis2() => new Class2();
////////////////////////////////////////////////////////////////////////////////
@@ -56,17 +56,17 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.field:[null|exact=JSUInt31]*/
+ /*member: Class3.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
Class3() {
/*update: [exact=Class3]*/ field = /*[exact=Class3]*/ field;
/*update: [exact=Class3]*/ field = 42;
}
}
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
exposeThis3() => new Class3();
////////////////////////////////////////////////////////////////////////////////
@@ -74,10 +74,10 @@
////////////////////////////////////////////////////////////////////////////////
class Class4 {
- /*element: Class4.field:[null|exact=JSUInt31]*/
+ /*member: Class4.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4() {
// ignore: UNUSED_LOCAL_VARIABLE
var o = /*[exact=Class4]*/ field;
@@ -85,7 +85,7 @@
}
}
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
exposeThis4() => new Class4();
////////////////////////////////////////////////////////////////////////////////
@@ -93,17 +93,17 @@
////////////////////////////////////////////////////////////////////////////////
class Class5 {
- /*element: Class5.field:[null|subclass=JSPositiveInt]*/
+ /*member: Class5.field:[null|subclass=JSPositiveInt]*/
var field;
- /*element: Class5.:[exact=Class5]*/
+ /*member: Class5.:[exact=Class5]*/
Class5() {
/*[exact=Class5]*/ /*update: [exact=Class5]*/ field /*invoke: [null|subclass=JSPositiveInt]*/ ++;
/*update: [exact=Class5]*/ field = 42;
}
}
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
exposeThis5() => new Class5();
////////////////////////////////////////////////////////////////////////////////
@@ -111,17 +111,17 @@
////////////////////////////////////////////////////////////////////////////////
class Class6 {
- /*element: Class6.field:[subclass=JSPositiveInt]*/
+ /*member: Class6.field:[subclass=JSPositiveInt]*/
var field;
- /*element: Class6.:[exact=Class6]*/
+ /*member: Class6.:[exact=Class6]*/
Class6() {
/*update: [exact=Class6]*/ field = 42;
/*[exact=Class6]*/ /*update: [exact=Class6]*/ field /*invoke: [subclass=JSPositiveInt]*/ ++;
}
}
-/*element: exposeThis6:[exact=Class6]*/
+/*member: exposeThis6:[exact=Class6]*/
exposeThis6() => new Class6();
////////////////////////////////////////////////////////////////////////////////
@@ -129,13 +129,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class7 {
- /*element: Class7.field1:[null|exact=JSUInt31]*/
+ /*member: Class7.field1:[null|exact=JSUInt31]*/
var field1;
- /*element: Class7.field2:[null|exact=JSUInt31]*/
+ /*member: Class7.field2:[null|exact=JSUInt31]*/
var field2;
- /*element: Class7.:[exact=Class7]*/
+ /*member: Class7.:[exact=Class7]*/
Class7() {
// ignore: UNUSED_LOCAL_VARIABLE
var o1 = /*[exact=Class7]*/ field1;
@@ -146,5 +146,5 @@
}
}
-/*element: exposeThis7:[exact=Class7]*/
+/*member: exposeThis7:[exact=Class7]*/
exposeThis7() => new Class7();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_mask.dart b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
index 84feb4a..7dd84bb 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_mask.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
@@ -5,7 +5,7 @@
/// Check that exposure of this is correctly restricted through the receiver
/// mask.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
otherGetter();
otherMethod();
@@ -23,24 +23,24 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.field1a:[exact=JSUInt31]*/
+ /*member: Class1.field1a:[exact=JSUInt31]*/
var field1a;
- /*element: Class1.field1b:[exact=JSUInt31]*/
+ /*member: Class1.field1b:[exact=JSUInt31]*/
var field1b;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1() : field1a = 42 {
/*update: [exact=Class1]*/ field1b = /*[exact=Class1]*/ field1a;
}
}
-/*element: OtherClass1.:[exact=OtherClass1]*/
+/*member: OtherClass1.:[exact=OtherClass1]*/
class OtherClass1 {
- /*element: OtherClass1.field1a:[null]*/
+ /*member: OtherClass1.field1a:[null]*/
get field1a => null;
}
-/*element: otherGetter:[null]*/
+/*member: otherGetter:[null]*/
otherGetter() {
new OtherClass1(). /*[exact=OtherClass1]*/ field1a;
new Class1();
@@ -51,24 +51,24 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field2a:[exact=JSUInt31]*/
+ /*member: Class2.field2a:[exact=JSUInt31]*/
var field2a;
- /*element: Class2.field2b:[exact=JSUInt31]*/
+ /*member: Class2.field2b:[exact=JSUInt31]*/
var field2b;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2() : field2a = 42 {
/*update: [exact=Class2]*/ field2b = /*[exact=Class2]*/ field2a;
}
}
-/*element: OtherClass2.:[exact=OtherClass2]*/
+/*member: OtherClass2.:[exact=OtherClass2]*/
class OtherClass2 {
- /*element: OtherClass2.field2a:[null]*/
+ /*member: OtherClass2.field2a:[null]*/
field2a() {}
}
-/*element: otherMethod:[null]*/
+/*member: otherMethod:[null]*/
otherMethod() {
new OtherClass2(). /*[exact=OtherClass2]*/ field2a;
new Class2();
@@ -79,24 +79,24 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.field3a:[exact=JSUInt31]*/
+ /*member: Class3.field3a:[exact=JSUInt31]*/
var field3a;
- /*element: Class3.field3b:[exact=JSUInt31]*/
+ /*member: Class3.field3b:[exact=JSUInt31]*/
var field3b;
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
Class3() : field3a = 42 {
/*update: [exact=Class3]*/ field3b = /*[exact=Class3]*/ field3a;
}
}
-/*element: OtherClass3.:[exact=OtherClass3]*/
+/*member: OtherClass3.:[exact=OtherClass3]*/
class OtherClass3 {
- /*element: OtherClass3.field3a:[null]*/
+ /*member: OtherClass3.field3a:[null]*/
var field3a;
}
-/*element: otherField:[null]*/
+/*member: otherField:[null]*/
otherField() {
new OtherClass3();
new Class3();
@@ -106,25 +106,25 @@
// Read a field when a field in the superclass has the same name.
////////////////////////////////////////////////////////////////////////////////
-/*element: SuperClass5.:[exact=SuperClass5]*/
+/*member: SuperClass5.:[exact=SuperClass5]*/
class SuperClass5 {
- /*element: SuperClass5.field5a:[null]*/
+ /*member: SuperClass5.field5a:[null]*/
var field5a;
}
class Class5 extends SuperClass5 {
- /*element: Class5.field5a:[exact=JSUInt31]*/
+ /*member: Class5.field5a:[exact=JSUInt31]*/
var field5a;
- /*element: Class5.field5b:[exact=JSUInt31]*/
+ /*member: Class5.field5b:[exact=JSUInt31]*/
var field5b;
- /*element: Class5.:[exact=Class5]*/
+ /*member: Class5.:[exact=Class5]*/
Class5() : field5a = 42 {
/*update: [exact=Class5]*/ field5b = /*[exact=Class5]*/ field5a;
}
}
-/*element: superclassField:[null]*/
+/*member: superclassField:[null]*/
superclassField() {
new SuperClass5();
new Class5();
@@ -135,26 +135,26 @@
////////////////////////////////////////////////////////////////////////////////
class Class4 {
- /*element: Class4.field4a:[exact=JSUInt31]*/
+ /*member: Class4.field4a:[exact=JSUInt31]*/
var field4a;
- /*element: Class4.field4b:[null|exact=JSUInt31]*/
+ /*member: Class4.field4b:[null|exact=JSUInt31]*/
var field4b;
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4() : field4a = 42 {
/*update: [subclass=Class4]*/ field4b = /*[subclass=Class4]*/ field4a;
}
}
class SubClass4 extends Class4 {
- /*element: SubClass4.field4a:[null|exact=JSUInt31]*/
+ /*member: SubClass4.field4a:[null|exact=JSUInt31]*/
var field4a;
- /*element: SubClass4.:[exact=SubClass4]*/
+ /*member: SubClass4.:[exact=SubClass4]*/
SubClass4() : field4a = 42;
}
-/*element: subclassFieldRead:[null]*/
+/*member: subclassFieldRead:[null]*/
subclassFieldRead() {
new Class4();
new SubClass4();
@@ -165,29 +165,29 @@
////////////////////////////////////////////////////////////////////////////////
class Class6 {
- /*element: Class6.field6a:[exact=JSUInt31]*/
+ /*member: Class6.field6a:[exact=JSUInt31]*/
var field6a;
- /*element: Class6.field6b:[null|exact=JSUInt31]*/
+ /*member: Class6.field6b:[null|exact=JSUInt31]*/
var field6b;
- /*element: Class6.:[exact=Class6]*/
+ /*member: Class6.:[exact=Class6]*/
Class6() : field6a = 42 {
/*update: [subclass=Class6]*/ field6b = /*[subclass=Class6]*/ field6a;
}
}
class SubClass6 extends Class6 {
- /*element: SubClass6.field6b:[exact=JSUInt31]*/
+ /*member: SubClass6.field6b:[exact=JSUInt31]*/
var field6b;
- /*element: SubClass6.:[exact=SubClass6]*/
+ /*member: SubClass6.:[exact=SubClass6]*/
SubClass6() : field6b = 42;
- /*element: SubClass6.access:[null|exact=JSUInt31]*/
+ /*member: SubClass6.access:[null|exact=JSUInt31]*/
get access => super.field6b;
}
-/*element: subclassFieldWrite:[null|exact=JSUInt31]*/
+/*member: subclassFieldWrite:[null|exact=JSUInt31]*/
subclassFieldWrite() {
new Class6();
return new SubClass6(). /*[exact=SubClass6]*/ access;
@@ -199,32 +199,32 @@
////////////////////////////////////////////////////////////////////////////////
class Class9 {
- /*element: Class9.field9a:[exact=JSUInt31]*/
+ /*member: Class9.field9a:[exact=JSUInt31]*/
var field9a;
- /*element: Class9.field9b:[null|exact=JSUInt31]*/
+ /*member: Class9.field9b:[null|exact=JSUInt31]*/
var field9b;
- /*element: Class9.:[exact=Class9]*/
+ /*member: Class9.:[exact=Class9]*/
Class9() : field9a = 42 {
/*update: [subclass=Class9]*/ field9b = /*[subclass=Class9]*/ field9a;
}
}
class SubClass9a extends Class9 {
- /*element: SubClass9a.field9b:[exact=JSUInt31]*/
+ /*member: SubClass9a.field9b:[exact=JSUInt31]*/
var field9b;
- /*element: SubClass9a.:[exact=SubClass9a]*/
+ /*member: SubClass9a.:[exact=SubClass9a]*/
SubClass9a() : field9b = 42;
- /*element: SubClass9a.access:[null|exact=JSUInt31]*/
+ /*member: SubClass9a.access:[null|exact=JSUInt31]*/
get access => super.field9b;
}
-/*element: SubClass9b.:[exact=SubClass9b]*/
+/*member: SubClass9b.:[exact=SubClass9b]*/
class SubClass9b extends Class9 {}
-/*element: subclassesFieldWrite:[null|exact=JSUInt31]*/
+/*member: subclassesFieldWrite:[null|exact=JSUInt31]*/
subclassesFieldWrite() {
new Class9();
new SubClass9b();
@@ -236,26 +236,26 @@
////////////////////////////////////////////////////////////////////////////////
class Class7 {
- /*element: Class7.field7a:[exact=JSUInt31]*/
+ /*member: Class7.field7a:[exact=JSUInt31]*/
var field7a;
- /*element: Class7.field7b:[null]*/
+ /*member: Class7.field7b:[null]*/
var field7b;
- /*element: Class7.:[exact=Class7]*/
+ /*member: Class7.:[exact=Class7]*/
Class7() : field7a = 42 {
/*invoke: [subclass=Class7]*/ field7b(/*[subclass=Class7]*/ field7a);
}
}
class SubClass7 extends Class7 {
- /*element: SubClass7.field7b:[null|exact=JSUInt31]*/
+ /*member: SubClass7.field7b:[null|exact=JSUInt31]*/
var field7b;
- /*element: SubClass7.:[exact=SubClass7]*/
+ /*member: SubClass7.:[exact=SubClass7]*/
SubClass7() : field7b = 42;
}
-/*element: subclassFieldInvoke:[null]*/
+/*member: subclassFieldInvoke:[null]*/
subclassFieldInvoke() {
new Class7();
new SubClass7();
@@ -266,10 +266,10 @@
////////////////////////////////////////////////////////////////////////////////
abstract class Class8 {
- /*element: Class8.field8:[null|exact=JSUInt31]*/
+ /*member: Class8.field8:[null|exact=JSUInt31]*/
var field8;
- /*element: Class8.:[subclass=Class8]*/
+ /*member: Class8.:[subclass=Class8]*/
Class8() {
/*invoke: [subclass=Class8]*/ method8();
}
@@ -277,21 +277,21 @@
method8();
}
-/*element: SubClass8a.:[exact=SubClass8a]*/
+/*member: SubClass8a.:[exact=SubClass8a]*/
class SubClass8a extends Class8 {
- /*element: SubClass8a.method8:[null]*/
+ /*member: SubClass8a.method8:[null]*/
method8() {
/*update: [exact=SubClass8a]*/ field8 = 42;
}
}
-/*element: SubClass8b.:[exact=SubClass8b]*/
+/*member: SubClass8b.:[exact=SubClass8b]*/
class SubClass8b extends Class8 {
- /*element: SubClass8b.method8:[null]*/
+ /*member: SubClass8b.method8:[null]*/
method8() {}
}
-/*element: subclassFieldSet:[null]*/
+/*member: subclassFieldSet:[null]*/
subclassFieldSet() {
new SubClass8a();
new SubClass8b();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_super.dart b/tests/compiler/dart2js/inference/data/expose_this_super.dart
index 85d3630..cb7b1cc 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_super.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_super.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
exposeThis1();
exposeThis2();
@@ -14,98 +14,98 @@
// Expose this through super invocation.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super1.:[exact=Class1]*/
+/*member: Super1.:[exact=Class1]*/
abstract class Super1 {
- /*element: Super1.method:[null]*/
+ /*member: Super1.method:[null]*/
method() {}
}
class Class1 extends Super1 {
// The inferred type of the field includes `null` because `this` has been
// exposed before its initialization.
- /*element: Class1.field:[null|exact=JSUInt31]*/
+ /*member: Class1.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1() {
super.method();
/*update: [exact=Class1]*/ field = 42;
}
}
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
exposeThis1() => new Class1();
////////////////////////////////////////////////////////////////////////////////
// Expose this through super access.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super2.:[exact=Class2]*/
+/*member: Super2.:[exact=Class2]*/
abstract class Super2 {
- /*element: Super2.getter:[null]*/
+ /*member: Super2.getter:[null]*/
get getter => null;
}
class Class2 extends Super2 {
- /*element: Class2.field:[null|exact=JSUInt31]*/
+ /*member: Class2.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2() {
super.getter;
/*update: [exact=Class2]*/ field = 42;
}
}
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
exposeThis2() => new Class2();
////////////////////////////////////////////////////////////////////////////////
// Expose this through super access.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super3.:[exact=Class3]*/
+/*member: Super3.:[exact=Class3]*/
abstract class Super3 {
set setter(/*[null]*/ o) {}
}
class Class3 extends Super3 {
- /*element: Class3.field:[null|exact=JSUInt31]*/
+ /*member: Class3.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
Class3() {
super.setter = null;
/*update: [exact=Class3]*/ field = 42;
}
}
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
exposeThis3() => new Class3();
////////////////////////////////////////////////////////////////////////////////
// Expose this in the constructor of a super class.
////////////////////////////////////////////////////////////////////////////////
-/*element: field4:[null|exact=Class4]*/
+/*member: field4:[null|exact=Class4]*/
var field4;
abstract class Super4 {
- /*element: Super4.:[exact=Class4]*/
+ /*member: Super4.:[exact=Class4]*/
Super4() {
field4 = this;
}
}
class Class4 extends Super4 {
- /*element: Class4.field:[null|exact=JSUInt31]*/
+ /*member: Class4.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4() {
/*update: [exact=Class4]*/ field = 42;
}
}
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
exposeThis4() => new Class4();
diff --git a/tests/compiler/dart2js/inference/data/factory.dart b/tests/compiler/dart2js/inference/data/factory.dart
index 624a334..60a789c 100644
--- a/tests/compiler/dart2js/inference/data/factory.dart
+++ b/tests/compiler/dart2js/inference/data/factory.dart
@@ -3,33 +3,33 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.generative:[exact=A]*/
+ /*member: A.generative:[exact=A]*/
A.generative();
factory A.redirect() = B;
- /*element: A.fact:[exact=C]*/
+ /*member: A.fact:[exact=C]*/
factory A.fact() => new C();
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B implements A {}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C implements A {}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
createGenerative();
createRedirecting();
createFactory();
}
-/*element: createGenerative:[exact=A]*/
+/*member: createGenerative:[exact=A]*/
createGenerative() => new A.generative();
-/*element: createRedirecting:[exact=B]*/
+/*member: createRedirecting:[exact=B]*/
createRedirecting() => new A.redirect();
-/*element: createFactory:[exact=C]*/
+/*member: createFactory:[exact=C]*/
createFactory() => new A.fact();
diff --git a/tests/compiler/dart2js/inference/data/field_type.dart b/tests/compiler/dart2js/inference/data/field_type.dart
index d97d431..8e2800b 100644
--- a/tests/compiler/dart2js/inference/data/field_type.dart
+++ b/tests/compiler/dart2js/inference/data/field_type.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
@@ -38,59 +38,59 @@
test30();
}
-/*element: A1.:[exact=A1]*/
+/*member: A1.:[exact=A1]*/
class A1 {
- /*element: A1.f1:[null]*/
+ /*member: A1.f1:[null]*/
int f1;
}
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1() {
new A1();
}
-/*element: A2.:[exact=A2]*/
+/*member: A2.:[exact=A2]*/
class A2 {
- /*element: A2.f2a:[null]*/
+ /*member: A2.f2a:[null]*/
int f2a;
- /*element: A2.f2b:[exact=JSUInt31]*/
+ /*member: A2.f2b:[exact=JSUInt31]*/
int f2b = 1;
}
-/*element: test2:[null]*/
+/*member: test2:[null]*/
test2() {
new A2();
}
class A3 {
- /*element: A3.f3a:[exact=JSUInt31]*/
+ /*member: A3.f3a:[exact=JSUInt31]*/
int f3a;
- /*element: A3.f3b:[null|exact=JSUInt31]*/
+ /*member: A3.f3b:[null|exact=JSUInt31]*/
int f3b;
- /*element: A3.:[exact=A3]*/
+ /*member: A3.:[exact=A3]*/
A3() : f3a = 1;
}
-/*element: test3:[null]*/
+/*member: test3:[null]*/
test3() {
new A3(). /*update: [exact=A3]*/ f3b = 2;
}
class A4 {
- /*element: A4.f4a:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A4.f4a:Union([exact=JSString], [exact=JSUInt31])*/
dynamic f4a;
- /*element: A4.f4b:Value([null|exact=JSString], value: "a")*/
+ /*member: A4.f4b:Value([null|exact=JSString], value: "a")*/
dynamic f4b;
- /*element: A4.:[exact=A4]*/
+ /*member: A4.:[exact=A4]*/
A4() : f4a = 1;
}
-/*element: test4:[null]*/
+/*member: test4:[null]*/
test4() {
A4 a = new A4();
a. /*update: [exact=A4]*/ f4a = "a";
@@ -98,13 +98,13 @@
}
class A5 {
- /*element: A5.f5a:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A5.f5a:Union([exact=JSString], [exact=JSUInt31])*/
dynamic f5a = 1;
- /*element: A5.f5b:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A5.f5b:Union([exact=JSString], [exact=JSUInt31])*/
dynamic f5b = 1;
- /*element: A5.:[exact=A5]*/
+ /*member: A5.:[exact=A5]*/
A5(/*[exact=JSBool]*/ x) {
/*update: [exact=A5]*/ f5a = "1";
if (x) {
@@ -115,20 +115,20 @@
}
}
-/*element: test5:[null]*/
+/*member: test5:[null]*/
test5() {
new A5(true);
new A5(false);
}
class A6 {
- /*element: A6.f6a:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A6.f6a:Union([exact=JSString], [exact=JSUInt31])*/
dynamic f6a = 1;
- /*element: A6.f6b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+ /*member: A6.f6b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
dynamic f6b = 1;
- /*element: A6.:[exact=A6]*/
+ /*member: A6.:[exact=A6]*/
A6(/*[exact=JSBool]*/ x) {
/*update: [exact=A6]*/ f6a = "1";
if (x) {
@@ -144,20 +144,20 @@
}
}
-/*element: test6:[null]*/
+/*member: test6:[null]*/
test6() {
new A6(true);
new A6(false);
}
class A7 {
- /*element: A7.f7a:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+ /*member: A7.f7a:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
dynamic f7a = 1;
- /*element: A7.f7b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+ /*member: A7.f7b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
dynamic f7b = 1;
- /*element: A7.:[exact=A7]*/
+ /*member: A7.:[exact=A7]*/
A7(/*[exact=JSBool]*/ x) {
/*update: [exact=A7]*/ f7a = "1";
if (x) {
@@ -174,17 +174,17 @@
}
}
-/*element: test7:[null]*/
+/*member: test7:[null]*/
test7() {
new A7(true);
new A7(false);
}
class A8 {
- /*element: A8.f8:Value([null|exact=JSString], value: "1")*/
+ /*member: A8.f8:Value([null|exact=JSString], value: "1")*/
dynamic f8;
- /*element: A8.:[exact=A8]*/
+ /*member: A8.:[exact=A8]*/
A8(/*[exact=JSBool]*/ x) {
if (x) {
/*update: [exact=A8]*/ f8 = "1";
@@ -192,17 +192,17 @@
}
}
-/*element: test8:[null]*/
+/*member: test8:[null]*/
test8() {
new A8(true);
new A8(false);
}
class A9 {
- /*element: A9.f9:Value([null|exact=JSString], value: "1")*/
+ /*member: A9.f9:Value([null|exact=JSString], value: "1")*/
dynamic f9;
- /*element: A9.:[exact=A9]*/
+ /*member: A9.:[exact=A9]*/
A9(/*[exact=JSBool]*/ x) {
if (x) {
} else {
@@ -211,30 +211,30 @@
}
}
-/*element: test9:[null]*/
+/*member: test9:[null]*/
test9() {
new A9(true);
new A9(false);
}
class A10 {
- /*element: A10.f10:[exact=JSUInt31]*/
+ /*member: A10.f10:[exact=JSUInt31]*/
int f10;
- /*element: A10.:[exact=A10]*/
+ /*member: A10.:[exact=A10]*/
A10() {
/*update: [exact=A10]*/ f10 = 1;
}
- /*element: A10.m10:[subclass=JSUInt32]*/
+ /*member: A10.m10:[subclass=JSUInt32]*/
m10() => /*[exact=A10]*/ f10 /*invoke: [exact=JSUInt31]*/ + 1;
}
-/*element: f10:[null]*/
+/*member: f10:[null]*/
void f10(/*[null]*/ x) {
x. /*update: [null]*/ f10 = "2";
}
-/*element: test10:[null]*/
+/*member: test10:[null]*/
test10() {
A10 a;
f10(a);
@@ -242,86 +242,86 @@
a. /*invoke: [exact=A10]*/ m10();
}
-/*element: S11.:[exact=S11]*/
+/*member: S11.:[exact=S11]*/
class S11 {
- /*element: S11.fs11:[exact=JSUInt31]*/
+ /*member: S11.fs11:[exact=JSUInt31]*/
int fs11 = 1;
- /*element: S11.ms11:[null]*/
+ /*member: S11.ms11:[null]*/
ms11() {
/*update: [exact=A11]*/ fs11 = 1;
}
}
-/*element: A11.:[exact=A11]*/
+/*member: A11.:[exact=A11]*/
class A11 extends S11 {
- /*element: A11.m11:[null]*/
+ /*member: A11.m11:[null]*/
m11() {
/*invoke: [exact=A11]*/ ms11();
}
}
-/*element: test11:[null]*/
+/*member: test11:[null]*/
test11() {
A11 a = new A11();
a. /*invoke: [exact=A11]*/ m11();
}
class S12 {
- /*element: S12.fs12:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: S12.fs12:Union([exact=JSString], [exact=JSUInt31])*/
dynamic fs12 = 1;
- /*element: S12.:[exact=S12]*/
+ /*member: S12.:[exact=S12]*/
S12() {
/*update: [exact=A12]*/ fs12 = "2";
}
}
-/*element: A12.:[exact=A12]*/
+/*member: A12.:[exact=A12]*/
class A12 extends S12 {}
-/*element: test12:[null]*/
+/*member: test12:[null]*/
test12() {
new A12();
}
class S13 {
-/*element: S13.fs13:[exact=JSUInt31]*/
+/*member: S13.fs13:[exact=JSUInt31]*/
int fs13;
- /*element: S13.:[exact=S13]*/
+ /*member: S13.:[exact=S13]*/
S13() {
/*update: [exact=A13]*/ fs13 = 1;
}
}
class A13 extends S13 {
- /*element: A13.:[exact=A13]*/
+ /*member: A13.:[exact=A13]*/
A13() {
/*update: [exact=A13]*/ fs13 = 1;
}
}
-/*element: test13:[null]*/
+/*member: test13:[null]*/
test13() {
new A13();
}
class A14 {
- /*element: A14.f14:[exact=JSUInt31]*/
+ /*member: A14.f14:[exact=JSUInt31]*/
var f14;
- /*element: A14.:[exact=A14]*/
+ /*member: A14.:[exact=A14]*/
A14() {
/*update: [exact=A14]*/ f14 = 1;
}
- /*element: A14.other:[exact=A14]*/
+ /*member: A14.other:[exact=A14]*/
A14.other() {
/*update: [exact=A14]*/ f14 = 2;
}
}
-/*element: test14:[null]*/
+/*member: test14:[null]*/
test14() {
// ignore: unused_local_variable
A14 a = new A14();
@@ -329,21 +329,21 @@
}
class A15 {
- /*element: A15.f15:Union([exact=JSExtendableArray], [exact=JSString])*/
+ /*member: A15.f15:Union([exact=JSExtendableArray], [exact=JSString])*/
var f15;
- /*element: A15.:[exact=A15]*/
+ /*member: A15.:[exact=A15]*/
A15() {
/*update: [exact=A15]*/ f15 = "1";
}
- /*element: A15.other:[exact=A15]*/
+ /*member: A15.other:[exact=A15]*/
A15.other() {
/*update: [exact=A15]*/ f15 = new List();
}
}
-/*element: test15:[null]*/
+/*member: test15:[null]*/
test15() {
// ignore: unused_local_variable
A15 a = new A15();
@@ -354,33 +354,33 @@
// TODO(johnniwinther): Investigate why these include `null`. The ast version
// didn't.
- /*element: A16.f16:Union([exact=JSUInt31], [null|exact=JSString])*/
+ /*member: A16.f16:Union([exact=JSUInt31], [null|exact=JSString])*/
var f16;
- /*element: A16.:[exact=A16]*/
+ /*member: A16.:[exact=A16]*/
A16() {
/*update: [exact=A16]*/ f16 = "1";
}
- /*element: A16.other:[exact=A16]*/
+ /*member: A16.other:[exact=A16]*/
A16.other() : f16 = 1 {}
}
-/*element: test16:[null]*/
+/*member: test16:[null]*/
test16() {
// ignore: unused_local_variable
A16 a = new A16();
a = new A16.other();
}
-/*element: g17:[exact=JSUInt31]*/
+/*member: g17:[exact=JSUInt31]*/
g17([/*[exact=A17]*/ p]) => p. /*update: [exact=A17]*/ f17 = 1;
class A17 {
-/*element: A17.f17:[null|exact=JSUInt31]*/
+/*member: A17.f17:[null|exact=JSUInt31]*/
var f17;
- /*element: A17.:[exact=A17]*/
+ /*member: A17.:[exact=A17]*/
A17(/*[exact=JSBool]*/ x) {
var a;
if (x) {
@@ -392,23 +392,23 @@
}
}
-/*element: test17:[null]*/
+/*member: test17:[null]*/
test17() {
new A17(true);
new A17(false);
}
class A18 {
- /*element: A18.f18a:[exact=JSUInt31]*/
+ /*member: A18.f18a:[exact=JSUInt31]*/
var f18a;
- /*element: A18.f18b:Value([exact=JSString], value: "1")*/
+ /*member: A18.f18b:Value([exact=JSString], value: "1")*/
var f18b;
- /*element: A18.f18c:Union([exact=JSUInt31], [null|exact=A18])*/
+ /*member: A18.f18c:Union([exact=JSUInt31], [null|exact=A18])*/
var f18c;
- /*element: A18.:[exact=A18]*/
+ /*member: A18.:[exact=A18]*/
A18(/*[exact=JSBool]*/ x) {
/*update: [exact=A18]*/ f18a = 1;
var a;
@@ -423,23 +423,23 @@
}
}
-/*element: test18:[null]*/
+/*member: test18:[null]*/
test18() {
new A18(true);
new A18(false);
}
class A19 {
- /*element: A19.f19a:[exact=JSUInt31]*/
+ /*member: A19.f19a:[exact=JSUInt31]*/
var f19a;
- /*element: A19.f19b:Value([exact=JSString], value: "1")*/
+ /*member: A19.f19b:Value([exact=JSString], value: "1")*/
var f19b;
- /*element: A19.f19c:Union([exact=JSUInt31], [null|exact=A19])*/
+ /*member: A19.f19c:Union([exact=JSUInt31], [null|exact=A19])*/
var f19c;
- /*element: A19.:[exact=A19]*/
+ /*member: A19.:[exact=A19]*/
A19(/*[exact=JSBool]*/ x) {
/*update: [exact=A19]*/ f19a = 1;
var a;
@@ -455,17 +455,17 @@
}
}
-/*element: test19:[null]*/
+/*member: test19:[null]*/
test19() {
new A19(true);
new A19(false);
}
class A20 {
- /*element: A20.f20:[null]*/
+ /*member: A20.f20:[null]*/
var f20;
- /*element: A20.:[exact=A20]*/
+ /*member: A20.:[exact=A20]*/
A20() {
dynamic a = this;
/*iterator: [exact=A20]*/
@@ -481,16 +481,16 @@
bool moveNext() => false;
}
-/*element: test20:[null]*/
+/*member: test20:[null]*/
test20() {
new A20();
}
class A20b extends Iterable implements Iterator {
- /*element: A20b.f20b:[null|exact=JSUInt31]*/
+ /*member: A20b.f20b:[null|exact=JSUInt31]*/
var f20b;
- /*element: A20b.:[exact=A20b]*/
+ /*member: A20b.:[exact=A20b]*/
A20b() {
dynamic a = this;
/*iterator: [exact=A20b]*/
@@ -499,29 +499,29 @@
for (/*update: [exact=A20b]*/ f20b in a) {}
}
- /*element: A20b.iterator:[exact=A20b]*/
+ /*member: A20b.iterator:[exact=A20b]*/
@override
get iterator => this;
- /*element: A20b.current:[exact=JSUInt31]*/
+ /*member: A20b.current:[exact=JSUInt31]*/
@override
get current => 42;
- /*element: A20b.moveNext:Value([exact=JSBool], value: false)*/
+ /*member: A20b.moveNext:Value([exact=JSBool], value: false)*/
@override
bool moveNext() => false;
}
-/*element: test20b:[null]*/
+/*member: test20b:[null]*/
test20b() {
new A20b();
}
class A21 {
- /*element: A21.f21:[null|exact=JSUInt31]*/
+ /*member: A21.f21:[null|exact=JSUInt31]*/
var f21;
- /*element: A21.:[exact=A21]*/
+ /*member: A21.:[exact=A21]*/
A21() {
dynamic a = this;
/*iterator: [exact=A21]*/
@@ -536,16 +536,16 @@
get iterator => null;
}
-/*element: test21:[null]*/
+/*member: test21:[null]*/
test21() {
new A21();
}
class A21b extends Iterable {
- /*element: A21b.f21:[null|exact=JSUInt31]*/
+ /*member: A21b.f21:[null|exact=JSUInt31]*/
var f21;
- /*element: A21b.:[exact=A21b]*/
+ /*member: A21b.:[exact=A21b]*/
A21b() {
dynamic a = this;
/*iterator: [exact=A21b]*/
@@ -557,27 +557,27 @@
/*update: [exact=A21b]*/ f21 = 42;
}
- /*element: A21b.iterator:[null]*/
+ /*member: A21b.iterator:[null]*/
@override
get iterator => null;
}
-/*element: test21b:[null]*/
+/*member: test21b:[null]*/
test21b() {
new A21b();
}
class A22 {
- /*element: A22.f22a:[exact=JSUInt31]*/
+ /*member: A22.f22a:[exact=JSUInt31]*/
var f22a;
- /*element: A22.f22b:[exact=JSUInt31]*/
+ /*member: A22.f22b:[exact=JSUInt31]*/
var f22b;
- /*element: A22.f22c:Value([null|exact=JSString], value: "foo")*/
+ /*member: A22.f22c:Value([null|exact=JSString], value: "foo")*/
var f22c;
- /*element: A22.:[exact=A22]*/
+ /*member: A22.:[exact=A22]*/
A22() {
/*update: [exact=A22]*/ f22a = 42;
/*update: [exact=A22]*/ f22b = /*[exact=A22]*/ f22a == null
@@ -587,25 +587,25 @@
}
}
-/*element: test22:[null]*/
+/*member: test22:[null]*/
test22() {
new A22();
}
class A23 {
- /*element: A23.f23a:[null|exact=JSUInt31]*/
+ /*member: A23.f23a:[null|exact=JSUInt31]*/
var f23a = 42;
- /*element: A23.f23b:[null|exact=JSUInt31]*/
+ /*member: A23.f23b:[null|exact=JSUInt31]*/
var f23b = 42;
- /*element: A23.f23c:[null|exact=JSUInt31]*/
+ /*member: A23.f23c:[null|exact=JSUInt31]*/
var f23c = 42;
- /*element: A23.f23d:[null|exact=JSUInt31]*/
+ /*member: A23.f23d:[null|exact=JSUInt31]*/
var f23d = 42;
- /*element: A23.:[exact=A23]*/
+ /*member: A23.:[exact=A23]*/
A23() {
// Test string interpolation.
'${/*update: [exact=A23]*/ f23a = null}';
@@ -620,31 +620,31 @@
}
}
-/*element: test23:[null]*/
+/*member: test23:[null]*/
test23() {
new A23();
}
class A24 {
- /*element: A24.f24a:[subclass=JSPositiveInt]*/
+ /*member: A24.f24a:[subclass=JSPositiveInt]*/
var f24a = 42;
- /*element: A24.f24b:[subclass=JSPositiveInt]*/
+ /*member: A24.f24b:[subclass=JSPositiveInt]*/
var f24b = 42;
- /*element: A24.f24c:[exact=JSUInt31]*/
+ /*member: A24.f24c:[exact=JSUInt31]*/
var f24c = 42;
- /*element: A24.f24d:[exact=JSUInt31]*/
+ /*member: A24.f24d:[exact=JSUInt31]*/
final f24d;
- /*element: A24.f24e:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+ /*member: A24.f24e:Union([exact=JSUInt31], [null|exact=JSDouble])*/
var f24e;
-/*element: A24.f24f:Value([null|exact=JSString], value: "foo")*/
+/*member: A24.f24f:Value([null|exact=JSString], value: "foo")*/
var f24f = null;
- /*element: A24.:[exact=A24]*/
+ /*member: A24.:[exact=A24]*/
A24() : f24d = 42 {
/*[subclass=A24]*/ /*update: [subclass=A24]*/ f24a
/*invoke: [subclass=JSPositiveInt]*/ ++;
@@ -654,7 +654,7 @@
this. /*update: [subclass=A24]*/ f24f = f24f;
}
- /*element: A24.foo:[exact=A24]*/
+ /*member: A24.foo:[exact=A24]*/
A24.foo(/*[subclass=A24]*/ other)
: f24c = other. /*[subclass=A24]*/ f24c,
f24d = other. /*[subclass=A24]*/ f24d,
@@ -662,58 +662,58 @@
. /*invoke: [subclass=A24]*/
bar24();
- /*element: A24.+:Value([exact=JSString], value: "foo")*/
+ /*member: A24.+:Value([exact=JSString], value: "foo")*/
operator +(/*[empty]*/ other) => 'foo';
- /*element: A24.bar24:[exact=JSDouble]*/
+ /*member: A24.bar24:[exact=JSDouble]*/
bar24() => 42.5;
}
-/*element: B24.:[exact=B24]*/
+/*member: B24.:[exact=B24]*/
class B24 extends A24 {
- /*element: B24.bar24:[exact=JSUInt31]*/
+ /*member: B24.bar24:[exact=JSUInt31]*/
@override
bar24() => 42;
}
-/*element: test24:[null]*/
+/*member: test24:[null]*/
test24() {
new A24();
new A24.foo(new A24());
new A24.foo(new B24());
}
-/*element: A25.:[exact=A25]*/
+/*member: A25.:[exact=A25]*/
class A25 {
- /*element: A25.f25:[exact=JSUInt31]*/
+ /*member: A25.f25:[exact=JSUInt31]*/
var f25 = 42;
}
-/*element: B25.:[exact=B25]*/
+/*member: B25.:[exact=B25]*/
class B25 {
- /*element: B25.f25:Value([exact=JSString], value: "42")*/
+ /*member: B25.f25:Value([exact=JSString], value: "42")*/
var f25 = '42';
}
-/*element: test25:[null]*/
+/*member: test25:[null]*/
test25() {
new B25();
new A25(). /*update: [exact=A25]*/ f25 = new A25(). /*[exact=A25]*/ f25;
}
-/*element: A26.:[exact=A26]*/
+/*member: A26.:[exact=A26]*/
class A26 {
- /*element: A26.f26:[subclass=JSPositiveInt]*/
+ /*member: A26.f26:[subclass=JSPositiveInt]*/
var f26 = 42;
}
-/*element: B26.:[exact=B26]*/
+/*member: B26.:[exact=B26]*/
class B26 {
- /*element: B26.f26:[exact=JSUInt31]*/
+ /*member: B26.f26:[exact=JSUInt31]*/
var f26 = 54;
}
-/*element: test26:[null]*/
+/*member: test26:[null]*/
test26() {
new A26(). /*update: [exact=A26]*/ f26 = <dynamic>[new B26(), new A26()]
/*Container([exact=JSExtendableArray], element: Union([exact=A26], [exact=B26]), length: 2)*/
@@ -724,39 +724,39 @@
}
class A27 {
- /*element: A27.f27a:[exact=JSUInt31]*/
+ /*member: A27.f27a:[exact=JSUInt31]*/
var f27a;
- /*element: A27.f27b:[null|exact=JSUInt31]*/
+ /*member: A27.f27b:[null|exact=JSUInt31]*/
var f27b;
- /*element: A27.:[exact=A27]*/
+ /*member: A27.:[exact=A27]*/
A27() {
this. /*update: [subclass=A27]*/ f27a = 42;
this. /*update: [subclass=A27]*/ f27b = 42;
}
}
-/*element: B27.:[exact=B27]*/
+/*member: B27.:[exact=B27]*/
class B27 extends A27 {
@override
set f27b(/*[exact=JSUInt31]*/ value) {}
}
-/*element: test27:[null]*/
+/*member: test27:[null]*/
test27() {
new A27();
new B27();
}
class A28 {
- /*element: A28.f28a:[exact=JSUInt31]*/
+ /*member: A28.f28a:[exact=JSUInt31]*/
var f28a;
- /*element: A28.f28b:[null|exact=JSUInt31]*/
+ /*member: A28.f28b:[null|exact=JSUInt31]*/
var f28b;
- /*element: A28.:[exact=A28]*/
+ /*member: A28.:[exact=A28]*/
A28(/*[exact=JSUInt31]*/ x) {
this. /*update: [exact=A28]*/ f28a = x;
if (x /*invoke: [exact=JSUInt31]*/ == 0) return;
@@ -764,20 +764,20 @@
}
}
-/*element: test28:[null]*/
+/*member: test28:[null]*/
test28() {
new A28(0);
new A28(1);
}
class A29 {
- /*element: A29.f29a:[exact=JSUInt31]*/
+ /*member: A29.f29a:[exact=JSUInt31]*/
var f29a;
- /*element: A29.f29b:[null|exact=JSUInt31]*/
+ /*member: A29.f29b:[null|exact=JSUInt31]*/
var f29b;
- /*element: A29.:[exact=A29]*/
+ /*member: A29.:[exact=A29]*/
A29(/*[exact=JSUInt31]*/ x) {
this. /*update: [exact=A29]*/ f29a = x;
if (x /*invoke: [exact=JSUInt31]*/ == 0) {
@@ -788,23 +788,23 @@
}
}
-/*element: test29:[null]*/
+/*member: test29:[null]*/
test29() {
new A29(0);
new A29(1);
}
class A30 {
- /*element: A30.f30a:[exact=JSUInt31]*/
+ /*member: A30.f30a:[exact=JSUInt31]*/
var f30a;
- /*element: A30.f30b:[exact=JSUInt31]*/
+ /*member: A30.f30b:[exact=JSUInt31]*/
var f30b;
- /*element: A30.f30c:[null|exact=JSUInt31]*/
+ /*member: A30.f30c:[null|exact=JSUInt31]*/
var f30c;
- /*element: A30.:[exact=A30]*/
+ /*member: A30.:[exact=A30]*/
A30(/*[exact=JSUInt31]*/ x) {
this. /*update: [exact=A30]*/ f30a = x;
if (x /*invoke: [exact=JSUInt31]*/ == 0) {
@@ -817,7 +817,7 @@
}
}
-/*element: test30:[null]*/
+/*member: test30:[null]*/
test30() {
new A30(0);
new A30(1);
diff --git a/tests/compiler/dart2js/inference/data/fields.dart b/tests/compiler/dart2js/inference/data/fields.dart
index a5ee8d8..3fbf03a 100644
--- a/tests/compiler/dart2js/inference/data/fields.dart
+++ b/tests/compiler/dart2js/inference/data/fields.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
fieldGetUnset();
fieldGetUnsetInitialized();
@@ -14,36 +14,36 @@
/// Get an uninitialized field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- var /*element: Class1.field:[null]*/ field;
+ var /*member: Class1.field:[null]*/ field;
}
-/*element: fieldGetUnset:[null]*/
+/*member: fieldGetUnset:[null]*/
fieldGetUnset() => new Class1(). /*[exact=Class1]*/ field;
////////////////////////////////////////////////////////////////////////////////
/// Get a field initialized to `null`.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- var /*element: Class4.field:[null]*/ field = null;
+ var /*member: Class4.field:[null]*/ field = null;
}
-/*element: fieldGetUnsetInitialized:[null]*/
+/*member: fieldGetUnsetInitialized:[null]*/
fieldGetUnsetInitialized() => new Class4(). /*[exact=Class4]*/ field;
////////////////////////////////////////////////////////////////////////////////
/// Set an uninitialized field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- var /*element: Class2.field:[null|exact=JSUInt31]*/ field;
+ var /*member: Class2.field:[null|exact=JSUInt31]*/ field;
}
-/*element: fieldSet:[null]*/
+/*member: fieldSet:[null]*/
fieldSet() {
new Class2(). /*update: [exact=Class2]*/ field = 0;
}
@@ -52,12 +52,12 @@
/// Return the setting of an uninitialized field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- var /*element: Class3.field:[null|exact=JSUInt31]*/ field;
+ var /*member: Class3.field:[null|exact=JSUInt31]*/ field;
}
-/*element: fieldSetReturn:[exact=JSUInt31]*/
+/*member: fieldSetReturn:[exact=JSUInt31]*/
fieldSetReturn() {
return new Class3(). /*update: [exact=Class3]*/ field = 0;
}
diff --git a/tests/compiler/dart2js/inference/data/final_field.dart b/tests/compiler/dart2js/inference/data/final_field.dart
index 0a1c13e..c0558d0 100644
--- a/tests/compiler/dart2js/inference/data/final_field.dart
+++ b/tests/compiler/dart2js/inference/data/final_field.dart
@@ -3,40 +3,40 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.intField:[exact=JSUInt31]*/
+ /*member: A.intField:[exact=JSUInt31]*/
final intField;
- /*element: A.giveUpField1:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A.giveUpField1:Union([exact=JSString], [exact=JSUInt31])*/
final giveUpField1;
- /*element: A.giveUpField2:Union([exact=A], [exact=JSString])*/
+ /*member: A.giveUpField2:Union([exact=A], [exact=JSString])*/
final giveUpField2;
- /*element: A.fieldParameter:[exact=JSUInt31]*/
+ /*member: A.fieldParameter:[exact=JSUInt31]*/
final fieldParameter;
- /*element: A.:[exact=A]*/
+ /*member: A.:[exact=A]*/
A()
: intField = 42,
giveUpField1 = 'foo',
giveUpField2 = 'foo',
fieldParameter = 54;
- /*element: A.bar:[exact=A]*/
+ /*member: A.bar:[exact=A]*/
A.bar()
: intField = 54,
giveUpField1 = 42,
giveUpField2 = new A(),
fieldParameter = 87;
- /*element: A.foo:[exact=A]*/
+ /*member: A.foo:[exact=A]*/
A.foo(this. /*[exact=JSUInt31]*/ fieldParameter)
: intField = 87,
giveUpField1 = 42,
giveUpField2 = 'foo';
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new A();
new A.bar();
diff --git a/tests/compiler/dart2js/inference/data/final_field2.dart b/tests/compiler/dart2js/inference/data/final_field2.dart
index 7b7a9aff..d4ee03f 100644
--- a/tests/compiler/dart2js/inference/data/final_field2.dart
+++ b/tests/compiler/dart2js/inference/data/final_field2.dart
@@ -6,13 +6,13 @@
// inferring types for fields.
class A {
- /*element: A.intField:[exact=JSUInt31]*/
+ /*member: A.intField:[exact=JSUInt31]*/
final intField;
- /*element: A.stringField:Value([exact=JSString], value: "foo")*/
+ /*member: A.stringField:Value([exact=JSString], value: "foo")*/
final stringField;
- /*element: A.:[exact=A]*/
+ /*member: A.:[exact=A]*/
A()
: intField = 42,
stringField = 'foo';
@@ -22,7 +22,7 @@
stringField = 42;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new A();
}
diff --git a/tests/compiler/dart2js/inference/data/final_field3.dart b/tests/compiler/dart2js/inference/data/final_field3.dart
index f39e555..87925cb 100644
--- a/tests/compiler/dart2js/inference/data/final_field3.dart
+++ b/tests/compiler/dart2js/inference/data/final_field3.dart
@@ -5,17 +5,17 @@
// Test that we are analyzing field parameters correctly.
class A {
- /*element: A.dynamicField:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A.dynamicField:Union([exact=JSString], [exact=JSUInt31])*/
final dynamicField;
- /*element: A.:[exact=A]*/
+ /*member: A.:[exact=A]*/
A() : dynamicField = 42;
- /*element: A.bar:[exact=A]*/
+ /*member: A.bar:[exact=A]*/
A.bar(this. /*Value([exact=JSString], value: "foo")*/ dynamicField);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new A();
new A.bar('foo');
diff --git a/tests/compiler/dart2js/inference/data/finalized_type_variable.dart b/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
index 197852a..663a7fb 100644
--- a/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
@@ -2,21 +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.
-/*element: AppView.:[subclass=AppView]*/
+/*member: AppView.:[subclass=AppView]*/
abstract class AppView<T> {
- /*element: AppView.ctx:Union([exact=CardComponent2], [null|exact=CardComponent])*/
+ /*member: AppView.ctx:Union([exact=CardComponent2], [null|exact=CardComponent])*/
T ctx;
}
-/*element: CardComponent.:[exact=CardComponent]*/
+/*member: CardComponent.:[exact=CardComponent]*/
class CardComponent {
- /*element: CardComponent.title:Value([null|exact=JSString], value: "foo")*/
+ /*member: CardComponent.title:Value([null|exact=JSString], value: "foo")*/
String title;
}
-/*element: ViewCardComponent.:[exact=ViewCardComponent]*/
+/*member: ViewCardComponent.:[exact=ViewCardComponent]*/
class ViewCardComponent extends AppView<CardComponent> {
- /*element: ViewCardComponent._title:Value([null|exact=JSString], value: "foo")*/
+ /*member: ViewCardComponent._title:Value([null|exact=JSString], value: "foo")*/
var _title;
@pragma('dart2js:noInline')
@@ -30,22 +30,22 @@
}
}
- /*element: ViewCardComponent.checkBinding:Value([exact=JSBool], value: true)*/
+ /*member: ViewCardComponent.checkBinding:Value([exact=JSBool], value: true)*/
checkBinding(
/*Value([null|exact=JSString], value: "foo")*/ a,
/*Value([exact=JSString], value: "foo")*/ b) =>
true;
}
-/*element: CardComponent2.:[exact=CardComponent2]*/
+/*member: CardComponent2.:[exact=CardComponent2]*/
class CardComponent2 {
- /*element: CardComponent2.title:Value([null|exact=JSString], value: "bar")*/
+ /*member: CardComponent2.title:Value([null|exact=JSString], value: "bar")*/
String title;
}
-/*element: ViewCardComponent2.:[exact=ViewCardComponent2]*/
+/*member: ViewCardComponent2.:[exact=ViewCardComponent2]*/
class ViewCardComponent2 extends AppView<CardComponent2> {
- /*element: ViewCardComponent2._title:Value([null|exact=JSString], value: "bar")*/
+ /*member: ViewCardComponent2._title:Value([null|exact=JSString], value: "bar")*/
var _title;
@pragma('dart2js:noInline')
@@ -59,14 +59,14 @@
}
}
- /*element: ViewCardComponent2.checkBinding:Value([exact=JSBool], value: true)*/
+ /*member: ViewCardComponent2.checkBinding:Value([exact=JSBool], value: true)*/
checkBinding(
/*Value([null|exact=JSString], value: "bar")*/ a,
/*Value([exact=JSString], value: "bar")*/ b) =>
true;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
var c1 = new ViewCardComponent();
c1. /*update: [exact=ViewCardComponent]*/ ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/inference/data/for.dart b/tests/compiler/dart2js/inference/data/for.dart
index c1f31a4..b3829b7 100644
--- a/tests/compiler/dart2js/inference/data/for.dart
+++ b/tests/compiler/dart2js/inference/data/for.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleFor();
forNull();
@@ -18,7 +18,7 @@
/// Simple int based for loop.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleFor:[null]*/
+/*member: simpleFor:[null]*/
simpleFor() {
for (var i = 0;
i /*invoke: [subclass=JSPositiveInt]*/ < 10;
@@ -31,7 +31,7 @@
/// For loop with null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: forNull:[null]*/
+/*member: forNull:[null]*/
forNull() {
var local;
for (var o; o == null; o = o. /*invoke: [null]*/ toString()) {
@@ -44,7 +44,7 @@
/// For loop with not-null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: forNotNull:[null|exact=JSString]*/
+/*member: forNotNull:[null|exact=JSString]*/
forNotNull() {
var local;
for (var o = ''; o != null; o = o. /*invoke: [exact=JSString]*/ toString()) {
@@ -57,7 +57,7 @@
/// For loop with null test known to be false.
////////////////////////////////////////////////////////////////////////////////
-/*element: forNullFalse:[null]*/
+/*member: forNullFalse:[null]*/
forNullFalse() {
var local;
for (var o = ''; o == null; o = o. /*invoke: [null]*/ toString()) {
@@ -70,7 +70,7 @@
/// For loop with not-null test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: forNotNullTrue:[null]*/
+/*member: forNotNullTrue:[null]*/
forNotNullTrue() {
var local;
for (var o = null; o != null; o = o. /*invoke: [empty]*/ toString()) {
@@ -83,19 +83,19 @@
/// For loop with not-null test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[null|exact=Class2]*/
+ /*member: Class1.field:[null|exact=Class2]*/
var field;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[null|exact=Class1]*/
+ /*member: Class2.field:[null|exact=Class1]*/
var field;
}
-/*element: _forUnion:Union([exact=Class1], [null|exact=Class2])*/
+/*member: _forUnion:Union([exact=Class1], [null|exact=Class2])*/
_forUnion(/*[exact=Class1]*/ o) {
for (;
o = o. /*Union([exact=Class1], [null|exact=Class2])*/ field;
@@ -103,7 +103,7 @@
return o;
}
-/*element: forUnion:[null]*/
+/*member: forUnion:[null]*/
forUnion() {
var c1 = new Class1();
var c2 = new Class2();
@@ -116,25 +116,25 @@
/// For loop with is test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.field:[null|exact=Class4]*/
+ /*member: Class3.field:[null|exact=Class4]*/
var field;
}
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field:[null|exact=Class3]*/
+ /*member: Class4.field:[null|exact=Class3]*/
var field;
}
-/*element: _forIs:Union([exact=Class3], [null|exact=Class4])*/
+/*member: _forIs:Union([exact=Class3], [null|exact=Class4])*/
_forIs(/*[exact=Class3]*/ o) {
for (; o is Class3; o = o. /*[exact=Class3]*/ field) {}
return o;
}
-/*element: forIs:[null]*/
+/*member: forIs:[null]*/
forIs() {
var c1 = new Class3();
var c2 = new Class4();
@@ -147,19 +147,19 @@
/// For loop with is-not test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
class Class5 {
- /*element: Class5.field:[null|exact=Class6]*/
+ /*member: Class5.field:[null|exact=Class6]*/
var field;
}
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
class Class6 {
- /*element: Class6.field:[null|exact=Class5]*/
+ /*member: Class6.field:[null|exact=Class5]*/
var field;
}
-/*element: _forIsNot:Union([exact=Class5], [null|exact=Class6])*/
+/*member: _forIsNot:Union([exact=Class5], [null|exact=Class6])*/
_forIsNot(/*[exact=Class5]*/ o) {
for (;
o is! Class6;
@@ -167,7 +167,7 @@
return o;
}
-/*element: forIsNot:[null]*/
+/*member: forIsNot:[null]*/
forIsNot() {
var c1 = new Class5();
var c2 = new Class6();
diff --git a/tests/compiler/dart2js/inference/data/for_in.dart b/tests/compiler/dart2js/inference/data/for_in.dart
index c622275..301bcf7 100644
--- a/tests/compiler/dart2js/inference/data/for_in.dart
+++ b/tests/compiler/dart2js/inference/data/for_in.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
forInDirect();
forInReturn();
@@ -14,7 +14,7 @@
// For-in loop directly on a list literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: forInDirect:[null]*/
+/*member: forInDirect:[null]*/
forInDirect() {
/*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
/*current: [exact=ArrayIterator]*/
@@ -28,7 +28,7 @@
// Return element from a for-in loop on a list literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: forInReturn:[null|subclass=JSInt]*/
+/*member: forInReturn:[null|subclass=JSInt]*/
forInReturn() {
/*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
/*current: [exact=ArrayIterator]*/
@@ -43,7 +43,7 @@
// Return element from a for-in loop on known list type.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forInReturn:[null|subclass=Object]*/
+/*member: _forInReturn:[null|subclass=Object]*/
_forInReturn(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/ list) {
/*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
@@ -55,7 +55,7 @@
}
}
-/*element: forInReturnMulti:[null]*/
+/*member: forInReturnMulti:[null]*/
forInReturnMulti() {
_forInReturn([1, 2]);
_forInReturn([1, 2, 3]);
@@ -66,7 +66,7 @@
// loop on known list type.
////////////////////////////////////////////////////////////////////////////////
-/*element: forInReturnNonNull:[subclass=JSInt]*/
+/*member: forInReturnNonNull:[subclass=JSInt]*/
forInReturnNonNull() {
/*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
/*current: [exact=ArrayIterator]*/
diff --git a/tests/compiler/dart2js/inference/data/foreign.dart b/tests/compiler/dart2js/inference/data/foreign.dart
index 525c027..8c07276 100644
--- a/tests/compiler/dart2js/inference/data/foreign.dart
+++ b/tests/compiler/dart2js/inference/data/foreign.dart
@@ -11,7 +11,7 @@
/// ignore: IMPORT_INTERNAL_LIBRARY, UNUSED_IMPORT
import 'dart:_interceptors';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
jsCallInt();
jsCallEmpty();
@@ -28,35 +28,35 @@
jsGetStaticState();
}
-/*element: jsCallEmpty:[null|subclass=Object]*/
+/*member: jsCallEmpty:[null|subclass=Object]*/
jsCallEmpty() => JS('', '#', 0);
-/*element: jsCallInt:[subclass=JSInt]*/
+/*member: jsCallInt:[subclass=JSInt]*/
jsCallInt() => JS('int', '#', 0);
-/*element: jsCallVoid:[null|subclass=Object]*/
+/*member: jsCallVoid:[null|subclass=Object]*/
jsCallVoid() => JS('void', '#', 0);
-/*element: jsCallUnion:Union([exact=JSString], [subclass=JSInt])*/
+/*member: jsCallUnion:Union([exact=JSString], [subclass=JSInt])*/
jsCallUnion() => JS('int|String', '#', 0);
-/*element: jsBuiltin_rawRtiToJsConstructorName:[exact=JSString]*/
+/*member: jsBuiltin_rawRtiToJsConstructorName:[exact=JSString]*/
jsBuiltin_rawRtiToJsConstructorName() {
return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
}
-/*element: jsEmbeddedGlobal_getTypeFromName:[null|subclass=Object]*/
+/*member: jsEmbeddedGlobal_getTypeFromName:[null|subclass=Object]*/
jsEmbeddedGlobal_getTypeFromName() {
return JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
}
-/*element: jsEmbeddedGlobal_libraries:[null|exact=JSExtendableArray]*/
+/*member: jsEmbeddedGlobal_libraries:[null|exact=JSExtendableArray]*/
jsEmbeddedGlobal_libraries() {
return JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
}
-/*element: jsStringConcat:[exact=JSString]*/
+/*member: jsStringConcat:[exact=JSString]*/
jsStringConcat() => JS_STRING_CONCAT('a', 'b');
-/*element: jsGetStaticState:[null|subclass=Object]*/
+/*member: jsGetStaticState:[null|subclass=Object]*/
jsGetStaticState() => JS_GET_STATIC_STATE();
diff --git a/tests/compiler/dart2js/inference/data/general.dart b/tests/compiler/dart2js/inference/data/general.dart
index a00c12b..678911c 100644
--- a/tests/compiler/dart2js/inference/data/general.dart
+++ b/tests/compiler/dart2js/inference/data/general.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.
-/*element: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
returnNum1(/*Value([exact=JSBool], value: true)*/ a) {
if (a)
return 1;
@@ -10,7 +10,7 @@
return 2.5;
}
-/*element: returnNum2:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum2:Union([exact=JSDouble], [exact=JSUInt31])*/
returnNum2(/*Value([exact=JSBool], value: true)*/ a) {
if (a)
return 1.4;
@@ -18,7 +18,7 @@
return 2;
}
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
returnInt1(/*Value([exact=JSBool], value: true)*/ a) {
if (a)
return 1;
@@ -26,7 +26,7 @@
return 2;
}
-/*element: returnDouble:[exact=JSDouble]*/
+/*member: returnDouble:[exact=JSDouble]*/
returnDouble(/*Value([exact=JSBool], value: true)*/ a) {
if (a)
return 1.5;
@@ -34,7 +34,7 @@
return 2.5;
}
-/*element: returnGiveUp:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnGiveUp:Union([exact=JSString], [exact=JSUInt31])*/
returnGiveUp(/*Value([exact=JSBool], value: true)*/ a) {
if (a)
return 1;
@@ -42,66 +42,66 @@
return 'foo';
}
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
returnInt2() {
var a = 42;
return a /*invoke: [exact=JSUInt31]*/ ++;
}
-/*element: returnInt5:[subclass=JSUInt32]*/
+/*member: returnInt5:[subclass=JSUInt32]*/
returnInt5() {
var a = 42;
return /*invoke: [exact=JSUInt31]*/ ++a;
}
-/*element: returnInt6:[subclass=JSUInt32]*/
+/*member: returnInt6:[subclass=JSUInt32]*/
returnInt6() {
var a = 42;
a /*invoke: [exact=JSUInt31]*/ ++;
return a;
}
-/*element: returnIntOrNull:[null|exact=JSUInt31]*/
+/*member: returnIntOrNull:[null|exact=JSUInt31]*/
returnIntOrNull(/*Value([exact=JSBool], value: true)*/ a) {
if (a) return 42;
}
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
returnInt3(/*Value([exact=JSBool], value: true)*/ a) {
if (a) return 42;
throw 42;
}
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
returnInt4() {
return (42);
}
-/*element: returnInt7:[subclass=JSPositiveInt]*/
+/*member: returnInt7:[subclass=JSPositiveInt]*/
returnInt7() {
return 42. /*invoke: [exact=JSUInt31]*/ abs();
}
-/*element: returnInt8:[subclass=JSPositiveInt]*/
+/*member: returnInt8:[subclass=JSPositiveInt]*/
returnInt8() {
return 42. /*invoke: [exact=JSUInt31]*/ remainder(54);
}
-/*element: returnEmpty1:[empty]*/
+/*member: returnEmpty1:[empty]*/
returnEmpty1() {
// Ensure that we don't intrisify a wrong call to [int.remainder].
dynamic a = 42;
return a. /*invoke: [exact=JSUInt31]*/ remainder();
}
-/*element: returnEmpty2:[empty]*/
+/*member: returnEmpty2:[empty]*/
returnEmpty2() {
// Ensure that we don't intrisify a wrong call to [int.abs].
dynamic a = 42;
return a. /*invoke: [exact=JSUInt31]*/ abs(42);
}
-/*element: testIsCheck1:[subclass=JSInt]*/
+/*member: testIsCheck1:[subclass=JSInt]*/
testIsCheck1(/*[null|subclass=Object]*/ a) {
if (a is int) {
return a;
@@ -110,7 +110,7 @@
}
}
-/*element: testIsCheck2:[subclass=JSInt]*/
+/*member: testIsCheck2:[subclass=JSInt]*/
testIsCheck2(/*[null|subclass=Object]*/ a) {
if (a is! int) {
return 0;
@@ -119,7 +119,7 @@
}
}
-/*element: testIsCheck3:[null|subclass=JSInt]*/
+/*member: testIsCheck3:[null|subclass=JSInt]*/
testIsCheck3(/*[null|subclass=Object]*/ a) {
if (a is! int) {
print('hello');
@@ -128,7 +128,7 @@
}
}
-/*element: testIsCheck4:[subclass=JSInt]*/
+/*member: testIsCheck4:[subclass=JSInt]*/
testIsCheck4(/*[null|subclass=Object]*/ a) {
if (a is int) {
return a;
@@ -137,7 +137,7 @@
}
}
-/*element: testIsCheck5:[subclass=JSInt]*/
+/*member: testIsCheck5:[subclass=JSInt]*/
testIsCheck5(/*[null|subclass=Object]*/ a) {
if (a is! int) {
return 42;
@@ -146,7 +146,7 @@
}
}
-/*element: testIsCheck6:[null|subclass=Object]*/
+/*member: testIsCheck6:[null|subclass=Object]*/
testIsCheck6(/*[null|subclass=Object]*/ a) {
if (a is! int) {
return a;
@@ -155,7 +155,7 @@
}
}
-/*element: testIsCheck7:[subclass=JSInt]*/
+/*member: testIsCheck7:[subclass=JSInt]*/
testIsCheck7(/*[null|subclass=Object]*/ a) {
if (a == 'foo' && a is int) {
return a;
@@ -164,7 +164,7 @@
}
}
-/*element: testIsCheck8:[null|subclass=Object]*/
+/*member: testIsCheck8:[null|subclass=Object]*/
testIsCheck8(/*[null|subclass=Object]*/ a) {
if (a == 'foo' || a is int) {
return a;
@@ -173,27 +173,27 @@
}
}
-/*element: testIsCheck9:[subclass=JSInt]*/
+/*member: testIsCheck9:[subclass=JSInt]*/
testIsCheck9(/*[null|subclass=Object]*/ a) {
return a is int ? a : 42;
}
-/*element: testIsCheck10:[null|subclass=Object]*/
+/*member: testIsCheck10:[null|subclass=Object]*/
testIsCheck10(/*[null|subclass=Object]*/ a) {
return a is! int ? a : 42;
}
-/*element: testIsCheck11:[subclass=JSInt]*/
+/*member: testIsCheck11:[subclass=JSInt]*/
testIsCheck11(/*[null|subclass=Object]*/ a) {
return a is! int ? 42 : a;
}
-/*element: testIsCheck12:[null|subclass=Object]*/
+/*member: testIsCheck12:[null|subclass=Object]*/
testIsCheck12(/*[null|subclass=Object]*/ a) {
return a is int ? 42 : a;
}
-/*element: testIsCheck13:[subclass=JSInt]*/
+/*member: testIsCheck13:[subclass=JSInt]*/
testIsCheck13(/*[null|subclass=Object]*/ a) {
while (a is int) {
return a;
@@ -201,7 +201,7 @@
return 42;
}
-/*element: testIsCheck14:[null|subclass=Object]*/
+/*member: testIsCheck14:[null|subclass=Object]*/
testIsCheck14(/*[null|subclass=Object]*/ a) {
while (a is! int) {
return 42;
@@ -210,7 +210,7 @@
}
// TODO(29309): Change to [subclass=JSInt] when 29309 is fixed.
-/*element: testIsCheck15:[null|subclass=Object]*/
+/*member: testIsCheck15:[null|subclass=Object]*/
testIsCheck15(/*[null|subclass=Object]*/ a) {
dynamic c = 42;
do {
@@ -220,7 +220,7 @@
return 42;
}
-/*element: testIsCheck16:[null|subclass=Object]*/
+/*member: testIsCheck16:[null|subclass=Object]*/
testIsCheck16(/*[null|subclass=Object]*/ a) {
dynamic c = 42;
do {
@@ -230,7 +230,7 @@
return 42;
}
-/*element: testIsCheck17:[subclass=JSInt]*/
+/*member: testIsCheck17:[subclass=JSInt]*/
testIsCheck17(/*[null|subclass=Object]*/ a) {
dynamic c = 42;
for (; c is int;) {
@@ -240,7 +240,7 @@
return 42;
}
-/*element: testIsCheck18:[null|subclass=Object]*/
+/*member: testIsCheck18:[null|subclass=Object]*/
testIsCheck18(/*[null|subclass=Object]*/ a) {
dynamic c = 42;
for (; c is int;) {
@@ -250,7 +250,7 @@
return c;
}
-/*element: testIsCheck19:[null|subclass=Object]*/
+/*member: testIsCheck19:[null|subclass=Object]*/
testIsCheck19(/*[null|subclass=Object]*/ a) {
dynamic c = 42;
for (; c is! int;) {
@@ -260,7 +260,7 @@
return 42;
}
-/*element: testIsCheck20:[exact=JSUInt31]*/
+/*member: testIsCheck20:[exact=JSUInt31]*/
testIsCheck20() {
var c = topLevelGetter();
if (c != null && c is! bool && c is! int) {
@@ -272,7 +272,7 @@
}
}
-/*element: testIsCheck21:Union([subclass=JSArray], [subclass=JSInt])*/
+/*member: testIsCheck21:Union([subclass=JSArray], [subclass=JSInt])*/
testIsCheck21(/*[null|subclass=Object]*/ a) {
if (a is int || a is List) {
return a;
@@ -281,30 +281,30 @@
}
}
-/*element: testIsCheck22:Union([subclass=JSArray], [subclass=JSInt])*/
+/*member: testIsCheck22:Union([subclass=JSArray], [subclass=JSInt])*/
testIsCheck22(/*[null|subclass=Object]*/ a) {
return (a is int || a is List) ? a : 42;
}
-/*element: testIsCheck23:[subclass=JSInt]*/
+/*member: testIsCheck23:[subclass=JSInt]*/
testIsCheck23(/*[null|subclass=Object]*/ a) {
if (a is! int) throw 'foo';
return a;
}
-/*element: testIsCheck24:[subclass=JSInt]*/
+/*member: testIsCheck24:[subclass=JSInt]*/
testIsCheck24(/*[null|subclass=Object]*/ a) {
if (a is! int) return 42;
return a;
}
-/*element: testIsCheck25:[null|subclass=Object]*/
+/*member: testIsCheck25:[null|subclass=Object]*/
testIsCheck25(/*[null|subclass=Object]*/ a) {
if (a is int) throw 'foo';
return a;
}
-/*element: testIsCheck26:[subclass=JSInt]*/
+/*member: testIsCheck26:[subclass=JSInt]*/
testIsCheck26(/*[null|subclass=Object]*/ a) {
if (a is int) {
} else {
@@ -313,7 +313,7 @@
return a;
}
-/*element: testIsCheck27:[subclass=JSInt]*/
+/*member: testIsCheck27:[subclass=JSInt]*/
testIsCheck27(/*[null|subclass=Object]*/ a) {
if (a is int) {
} else {
@@ -322,20 +322,20 @@
return a;
}
-/*element: testIsCheck28:[null|subclass=Object]*/
+/*member: testIsCheck28:[null|subclass=Object]*/
testIsCheck28(/*[null|subclass=Object]*/ a) {
if (a is int) {
} else {}
return a;
}
-/*element: testIsCheck29:[null|subclass=Object]*/
+/*member: testIsCheck29:[null|subclass=Object]*/
testIsCheck29(/*[null|subclass=Object]*/ a) {
if (a is int) {}
return a;
}
-/*element: testIf1:[null|exact=JSUInt31]*/
+/*member: testIf1:[null|exact=JSUInt31]*/
testIf1(/*[null|subclass=Object]*/ a) {
var c = null;
if (a) {
@@ -344,7 +344,7 @@
return c;
}
-/*element: testIf2:[null|exact=JSUInt31]*/
+/*member: testIf2:[null|exact=JSUInt31]*/
testIf2(/*[null|subclass=Object]*/ a) {
var c = null;
if (a) {
@@ -354,12 +354,12 @@
return c;
}
-/*element: returnAsString:[null|exact=JSString]*/
+/*member: returnAsString:[null|exact=JSString]*/
returnAsString() {
return topLevelGetter() as String;
}
-/*element: returnIntAsNum:[exact=JSUInt31]*/
+/*member: returnIntAsNum:[exact=JSUInt31]*/
returnIntAsNum() {
dynamic a = 0;
return a as num;
@@ -367,19 +367,19 @@
typedef int Foo();
-/*element: returnAsTypedef:[null|subclass=Closure]*/
+/*member: returnAsTypedef:[null|subclass=Closure]*/
returnAsTypedef() {
return topLevelGetter() as Foo;
}
-/*element: testDeadCode:[exact=JSUInt31]*/
+/*member: testDeadCode:[exact=JSUInt31]*/
testDeadCode() {
return 42;
// ignore: dead_code
return 'foo';
}
-/*element: testLabeledIf:[null|exact=JSUInt31]*/
+/*member: testLabeledIf:[null|exact=JSUInt31]*/
testLabeledIf(/*Value([exact=JSBool], value: true)*/ a) {
var c;
L1:
@@ -394,7 +394,7 @@
return c;
}
-/*element: testSwitch1:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testSwitch1:Union([exact=JSUInt31], [null|exact=JSDouble])*/
testSwitch1() {
var a = null;
switch (topLevelGetter) {
@@ -408,7 +408,7 @@
return a;
}
-/*element: testSwitch2:[exact=JSUInt31]*/
+/*member: testSwitch2:[exact=JSUInt31]*/
testSwitch2() {
var a = null;
switch (topLevelGetter) {
@@ -424,7 +424,7 @@
return a;
}
-/*element: testSwitch3:Union([exact=JSString], [null|subclass=JSNumber])*/
+/*member: testSwitch3:Union([exact=JSString], [null|subclass=JSNumber])*/
testSwitch3() {
dynamic a = 42;
var b;
@@ -440,7 +440,7 @@
return b;
}
-/*element: testSwitch4:[exact=JSUInt31]*/
+/*member: testSwitch4:[exact=JSUInt31]*/
testSwitch4() {
switch (topLevelGetter) {
case 1:
@@ -451,7 +451,7 @@
return 42;
}
-/*element: testSwitch5:[exact=JSUInt31]*/
+/*member: testSwitch5:[exact=JSUInt31]*/
testSwitch5() {
switch (topLevelGetter) {
case 1:
@@ -461,7 +461,7 @@
}
}
-/*element: testContinue1:Union([exact=JSString], [null|subclass=JSNumber])*/
+/*member: testContinue1:Union([exact=JSString], [null|subclass=JSNumber])*/
testContinue1() {
dynamic a = 42;
var b;
@@ -475,7 +475,7 @@
return b;
}
-/*element: testBreak1:Union([null|exact=JSString], [subclass=JSUInt32])*/
+/*member: testBreak1:Union([null|exact=JSString], [subclass=JSUInt32])*/
testBreak1() {
var a = 42;
var b;
@@ -487,7 +487,7 @@
return b;
}
-/*element: testContinue2:Union([exact=JSString], [null|subclass=JSUInt32])*/
+/*member: testContinue2:Union([exact=JSString], [null|subclass=JSUInt32])*/
testContinue2() {
var a = 42;
var b;
@@ -502,7 +502,7 @@
return b;
}
-/*element: testBreak2:[null|subclass=JSUInt32]*/
+/*member: testBreak2:[null|subclass=JSUInt32]*/
testBreak2() {
dynamic a = 42;
var b;
@@ -516,7 +516,7 @@
return b;
}
-/*element: testReturnElementOfConstList1:[exact=JSUInt31]*/
+/*member: testReturnElementOfConstList1:[exact=JSUInt31]*/
testReturnElementOfConstList1() {
return const [
42
@@ -524,19 +524,19 @@
0];
}
-/*element: testReturnElementOfConstList2:[exact=JSUInt31]*/
+/*member: testReturnElementOfConstList2:[exact=JSUInt31]*/
testReturnElementOfConstList2() {
return topLevelConstList /*Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/ [
0];
}
-/*element: testReturnItselfOrInt:[exact=JSUInt31]*/
+/*member: testReturnItselfOrInt:[exact=JSUInt31]*/
testReturnItselfOrInt(/*[null|subclass=Object]*/ a) {
if (a) return 42;
return testReturnItselfOrInt(a);
}
-/*element: testDoWhile1:Value([exact=JSString], value: "foo")*/
+/*member: testDoWhile1:Value([exact=JSString], value: "foo")*/
testDoWhile1() {
dynamic a = 42;
do {
@@ -546,7 +546,7 @@
return a;
}
-/*element: testDoWhile2:[null]*/
+/*member: testDoWhile2:[null]*/
testDoWhile2() {
dynamic a = 42;
do {
@@ -558,7 +558,7 @@
return a;
}
-/*element: testDoWhile3:[exact=JSUInt31]*/
+/*member: testDoWhile3:[exact=JSUInt31]*/
testDoWhile3() {
dynamic a = 42;
do {
@@ -570,7 +570,7 @@
return a;
}
-/*element: testDoWhile4:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: testDoWhile4:Union([exact=JSDouble], [exact=JSUInt31])*/
testDoWhile4() {
dynamic a = 'foo';
do {
@@ -581,14 +581,14 @@
return a;
}
-/*element: testSpecialization1:[subclass=Object]*/
+/*member: testSpecialization1:[subclass=Object]*/
testSpecialization1() {
var a = topLevelGetter();
a - 42;
return a;
}
-/*element: testSpecialization2:[null|subclass=Object]*/
+/*member: testSpecialization2:[null|subclass=Object]*/
testSpecialization2() {
var a = topLevelGetter();
// Make [a] a captured variable. This should disable receiver
@@ -600,7 +600,7 @@
return a;
}
-/*element: testSpecialization3:[null|exact=JSUInt31]*/
+/*member: testSpecialization3:[null|exact=JSUInt31]*/
testSpecialization3() {
var a = returnDynamic() ? null : 42;
a. /*invoke: [null|exact=JSUInt31]*/ toString();
@@ -609,191 +609,191 @@
return a;
}
-/*element: testReturnNull1:[null]*/
+/*member: testReturnNull1:[null]*/
testReturnNull1(/*[null|subclass=Object]*/ a) {
if (a == null) return a;
return null;
}
-/*element: testReturnNull2:[null]*/
+/*member: testReturnNull2:[null]*/
testReturnNull2(/*[null|subclass=Object]*/ a) {
if (a != null) return null;
return a;
}
-/*element: testReturnNull3:[subclass=Object]*/
+/*member: testReturnNull3:[subclass=Object]*/
testReturnNull3(/*[null|subclass=Object]*/ a) {
if (a == null) return 42;
return a;
}
-/*element: testReturnNull4:[null]*/
+/*member: testReturnNull4:[null]*/
testReturnNull4() {
var a = topLevelGetter();
if (a == null) return a;
return null;
}
-/*element: testReturnNull5:[null]*/
+/*member: testReturnNull5:[null]*/
testReturnNull5() {
var a = topLevelGetter();
if (a != null) return null;
return a;
}
-/*element: testReturnNull6:[subclass=Object]*/
+/*member: testReturnNull6:[subclass=Object]*/
testReturnNull6() {
var a = topLevelGetter();
if (a == null) return 42;
return a;
}
-/*element: testReturnNotEquals:[exact=JSBool]*/
+/*member: testReturnNotEquals:[exact=JSBool]*/
testReturnNotEquals() {
return new A() /*invoke: [exact=A]*/ != 54;
}
-/*element: testReturnInvokeDynamicGetter:[null|subclass=Object]*/
+/*member: testReturnInvokeDynamicGetter:[null|subclass=Object]*/
testReturnInvokeDynamicGetter() => new A(). /*invoke: [exact=A]*/ myFactory();
-/*element: topLevelConstList:Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: topLevelConstList:Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/
var topLevelConstList = const [42];
-/*element: topLevelGetter:[exact=JSUInt31]*/
+/*member: topLevelGetter:[exact=JSUInt31]*/
get topLevelGetter => 42;
-/*element: returnDynamic:[null|subclass=Object]*/
+/*member: returnDynamic:[null|subclass=Object]*/
returnDynamic() => topLevelGetter(42);
-/*element: returnTopLevelGetter:[exact=JSUInt31]*/
+/*member: returnTopLevelGetter:[exact=JSUInt31]*/
returnTopLevelGetter() => topLevelGetter;
class A {
factory A() = A.generative;
- /*element: A.generative:[exact=A]*/
+ /*member: A.generative:[exact=A]*/
A.generative();
- /*element: A.==:[exact=JSBool]*/
+ /*member: A.==:[exact=JSBool]*/
operator ==(/*Union([exact=JSString], [exact=JSUInt31])*/ other) =>
42 as dynamic;
- /*element: A.myField:[exact=JSUInt31]*/
+ /*member: A.myField:[exact=JSUInt31]*/
get myField => 42;
set myField(/*[subclass=JSUInt32]*/ a) {}
- /*element: A.returnInt1:[subclass=JSUInt32]*/
+ /*member: A.returnInt1:[subclass=JSUInt32]*/
returnInt1() => /*invoke: [exact=JSUInt31]*/ ++ /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
- /*element: A.returnInt2:[subclass=JSUInt32]*/
+ /*member: A.returnInt2:[subclass=JSUInt32]*/
returnInt2() => /*invoke: [exact=JSUInt31]*/ ++this
. /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
- /*element: A.returnInt3:[subclass=JSUInt32]*/
+ /*member: A.returnInt3:[subclass=JSUInt32]*/
returnInt3() =>
this. /*[subclass=A]*/ /*update: [subclass=A]*/ myField /*invoke: [exact=JSUInt31]*/ +=
42;
- /*element: A.returnInt4:[subclass=JSUInt32]*/
+ /*member: A.returnInt4:[subclass=JSUInt32]*/
returnInt4() => /*[subclass=A]*/ /*update: [subclass=A]*/ myField /*invoke: [exact=JSUInt31]*/ +=
42;
- /*element: A.[]:[exact=JSUInt31]*/
+ /*member: A.[]:[exact=JSUInt31]*/
operator [](/*[exact=JSUInt31]*/ index) => 42;
- /*element: A.[]=:[null]*/
+ /*member: A.[]=:[null]*/
operator []=(/*[exact=JSUInt31]*/ index, /*[subclass=JSUInt32]*/ value) {}
- /*element: A.returnInt5:[subclass=JSUInt32]*/
+ /*member: A.returnInt5:[subclass=JSUInt32]*/
returnInt5() => /*invoke: [exact=JSUInt31]*/ ++this /*[subclass=A]*/ /*update: [subclass=A]*/ [
0];
- /*element: A.returnInt6:[subclass=JSUInt32]*/
+ /*member: A.returnInt6:[subclass=JSUInt32]*/
returnInt6() => this /*[subclass=A]*/ /*update: [subclass=A]*/ [
0] /*invoke: [exact=JSUInt31]*/ += 1;
- /*element: A.myFactory:[subclass=Closure]*/
+ /*member: A.myFactory:[subclass=Closure]*/
get myFactory => /*[exact=JSUInt31]*/ () => 42;
}
class B extends A {
- /*element: B.:[exact=B]*/
+ /*member: B.:[exact=B]*/
B() : super.generative();
- /*element: B.returnInt1:[subclass=JSUInt32]*/
+ /*member: B.returnInt1:[subclass=JSUInt32]*/
returnInt1() => /*invoke: [exact=JSUInt31]*/ ++new A()
. /*[exact=A]*/ /*update: [exact=A]*/ myField;
- /*element: B.returnInt2:[subclass=JSUInt32]*/
+ /*member: B.returnInt2:[subclass=JSUInt32]*/
returnInt2() => new A()
. /*[exact=A]*/ /*update: [exact=A]*/ myField /*invoke: [exact=JSUInt31]*/ += 4;
- /*element: B.returnInt3:[subclass=JSUInt32]*/
+ /*member: B.returnInt3:[subclass=JSUInt32]*/
returnInt3() => /*invoke: [exact=JSUInt31]*/ ++new A() /*[exact=A]*/ /*update: [exact=A]*/ [
0];
- /*element: B.returnInt4:[subclass=JSUInt32]*/
+ /*member: B.returnInt4:[subclass=JSUInt32]*/
returnInt4() => new A() /*[exact=A]*/ /*update: [exact=A]*/ [
0] /*invoke: [exact=JSUInt31]*/ += 42;
- /*element: B.returnInt5:[subclass=JSUInt32]*/
+ /*member: B.returnInt5:[subclass=JSUInt32]*/
returnInt5() => /*invoke: [exact=JSUInt31]*/ ++super.myField;
- /*element: B.returnInt6:[subclass=JSUInt32]*/
+ /*member: B.returnInt6:[subclass=JSUInt32]*/
returnInt6() => super.myField /*invoke: [exact=JSUInt31]*/ += 4;
- /*element: B.returnInt7:[subclass=JSUInt32]*/
+ /*member: B.returnInt7:[subclass=JSUInt32]*/
returnInt7() => /*invoke: [exact=JSUInt31]*/ ++super[0];
- /*element: B.returnInt8:[subclass=JSUInt32]*/
+ /*member: B.returnInt8:[subclass=JSUInt32]*/
returnInt8() => super[0] /*invoke: [exact=JSUInt31]*/ += 54;
- /*element: B.returnInt9:[exact=JSUInt31]*/
+ /*member: B.returnInt9:[exact=JSUInt31]*/
returnInt9() => super.myField;
}
class C {
- /*element: C.myField:[subclass=JSPositiveInt]*/
+ /*member: C.myField:[subclass=JSPositiveInt]*/
var myField = 42;
- /*element: C.:[exact=C]*/
+ /*member: C.:[exact=C]*/
C();
- /*element: C.returnInt1:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt1:[subclass=JSPositiveInt]*/
returnInt1() => /*invoke: [subclass=JSPositiveInt]*/ ++ /*[exact=C]*/ /*update: [exact=C]*/ myField;
- /*element: C.returnInt2:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt2:[subclass=JSPositiveInt]*/
returnInt2() => /*invoke: [subclass=JSPositiveInt]*/ ++this
. /*[exact=C]*/ /*update: [exact=C]*/ myField;
- /*element: C.returnInt3:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt3:[subclass=JSPositiveInt]*/
returnInt3() =>
this. /*[exact=C]*/ /*update: [exact=C]*/ myField /*invoke: [subclass=JSPositiveInt]*/ +=
42;
- /*element: C.returnInt4:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt4:[subclass=JSPositiveInt]*/
returnInt4() => /*[exact=C]*/ /*update: [exact=C]*/ myField /*invoke: [subclass=JSPositiveInt]*/ +=
42;
- /*element: C.[]:[subclass=JSPositiveInt]*/
+ /*member: C.[]:[subclass=JSPositiveInt]*/
operator [](/*[exact=JSUInt31]*/ index) => /*[exact=C]*/ myField;
- /*element: C.[]=:[null]*/
+ /*member: C.[]=:[null]*/
operator []=(
/*[exact=JSUInt31]*/ index,
/*[subclass=JSPositiveInt]*/ value) {}
- /*element: C.returnInt5:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt5:[subclass=JSPositiveInt]*/
returnInt5() => /*invoke: [subclass=JSPositiveInt]*/ ++this /*[exact=C]*/ /*update: [exact=C]*/ [
0];
- /*element: C.returnInt6:[subclass=JSPositiveInt]*/
+ /*member: C.returnInt6:[subclass=JSPositiveInt]*/
returnInt6() => this /*[exact=C]*/ /*update: [exact=C]*/ [
0] /*invoke: [subclass=JSPositiveInt]*/ += 1;
}
-/*element: testCascade1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
+/*member: testCascade1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
testCascade1() {
return [1, 2, 3]
.. /*invoke: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
@@ -802,7 +802,7 @@
add(5);
}
-/*element: testCascade2:[exact=CascadeHelper]*/
+/*member: testCascade2:[exact=CascadeHelper]*/
testCascade2() {
return new CascadeHelper()
.. /*update: [exact=CascadeHelper]*/ a = "hello"
@@ -811,19 +811,19 @@
/*invoke: [subclass=JSPositiveInt]*/ += 1;
}
-/*element: CascadeHelper.:[exact=CascadeHelper]*/
+/*member: CascadeHelper.:[exact=CascadeHelper]*/
class CascadeHelper {
- /*element: CascadeHelper.a:Value([null|exact=JSString], value: "hello")*/
+ /*member: CascadeHelper.a:Value([null|exact=JSString], value: "hello")*/
var a;
- /*element: CascadeHelper.b:[null|exact=JSUInt31]*/
+ /*member: CascadeHelper.b:[null|exact=JSUInt31]*/
var b;
- /*element: CascadeHelper.i:[subclass=JSPositiveInt]*/
+ /*member: CascadeHelper.i:[subclass=JSPositiveInt]*/
var i = 0;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
// Ensure a function class is being instantiated.
/*[exact=JSUInt31]*/ () => 42;
diff --git a/tests/compiler/dart2js/inference/data/general6.dart b/tests/compiler/dart2js/inference/data/general6.dart
index f28acc0..fab306e 100644
--- a/tests/compiler/dart2js/inference/data/general6.dart
+++ b/tests/compiler/dart2js/inference/data/general6.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.
-/*element: foo:[exact=JSUInt31]*/
+/*member: foo:[exact=JSUInt31]*/
foo() {
var a = [1, 2, 3];
return a
@@ -10,7 +10,7 @@
first;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
foo();
}
diff --git a/tests/compiler/dart2js/inference/data/general7.dart b/tests/compiler/dart2js/inference/data/general7.dart
index 2fb6105..bd8da3f3 100644
--- a/tests/compiler/dart2js/inference/data/general7.dart
+++ b/tests/compiler/dart2js/inference/data/general7.dart
@@ -6,10 +6,10 @@
/// file 'general7_ea.dart' contains similar tests for when assertions are
/// _enabled_.
-/*element: foo:[null]*/
+/*member: foo:[null]*/
foo(/*[exact=JSUInt31]*/ x, [/*[null]*/ y]) => y;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
assert(foo('Hi', true), foo(true));
foo(1);
diff --git a/tests/compiler/dart2js/inference/data/general7_ea.dart b/tests/compiler/dart2js/inference/data/general7_ea.dart
index 50e5667..733c016 100644
--- a/tests/compiler/dart2js/inference/data/general7_ea.dart
+++ b/tests/compiler/dart2js/inference/data/general7_ea.dart
@@ -6,13 +6,13 @@
/// file 'general7.dart' contains similar tests for when assertions are
/// _disabled_.
-/*element: foo:Value([null|exact=JSBool], value: true)*/
+/*member: foo:Value([null|exact=JSBool], value: true)*/
foo(
/*Union([exact=JSBool], [exact=JSString], [exact=JSUInt31])*/ x,
[/*Value([null|exact=JSBool], value: true)*/ y]) =>
y;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
assert(foo('Hi', true), foo(true));
foo(1);
diff --git a/tests/compiler/dart2js/inference/data/general8a.dart b/tests/compiler/dart2js/inference/data/general8a.dart
index d94138e..8f3815a 100644
--- a/tests/compiler/dart2js/inference/data/general8a.dart
+++ b/tests/compiler/dart2js/inference/data/general8a.dart
@@ -2,12 +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.
-/*element: foo:Value([exact=JSBool], value: false)*/
+/*member: foo:Value([exact=JSBool], value: false)*/
foo(/*Value([exact=JSBool], value: false)*/ x) {
return x;
}
-/*element: bar:[null]*/
+/*member: bar:[null]*/
bar(/*Value([exact=JSBool], value: false)*/ x) {
if (x) {
print("aaa");
@@ -16,7 +16,7 @@
}
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
bar(foo(false));
bar(foo(foo(false)));
diff --git a/tests/compiler/dart2js/inference/data/general8b.dart b/tests/compiler/dart2js/inference/data/general8b.dart
index 594a093..baed070 100644
--- a/tests/compiler/dart2js/inference/data/general8b.dart
+++ b/tests/compiler/dart2js/inference/data/general8b.dart
@@ -2,13 +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.
-/*element: foo:[exact=JSBool]*/
+/*member: foo:[exact=JSBool]*/
foo(/*[exact=JSUInt31]*/ x) {
if (x /*invoke: [exact=JSUInt31]*/ > 3) return true;
return false;
}
-/*element: bar:[null]*/
+/*member: bar:[null]*/
bar(/*[exact=JSBool]*/ x) {
if (x) {
print("aaa");
@@ -17,7 +17,7 @@
}
}
-/*element: main:[null]*/ main() {
+/*member: main:[null]*/ main() {
bar(foo(5));
bar(foo(6));
}
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure.dart b/tests/compiler/dart2js/inference/data/global_field_closure.dart
index d40bfaab..34f39b7 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure.dart
@@ -2,40 +2,40 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method1:[exact=JSUInt31]*/
+/*member: method1:[exact=JSUInt31]*/
method1() {
return 42;
}
-/*element: method2:[exact=JSUInt31]*/
+/*member: method2:[exact=JSUInt31]*/
// Called only via [foo2] with a small integer.
method2(/*[exact=JSUInt31]*/ a) {
return a;
}
-/*strong.element: foo1:[null|subclass=Closure]*/
-/*omit.element: foo1:[null|subclass=Closure]*/
-/*strongConst.element: foo1:[subclass=Closure]*/
-/*omitConst.element: foo1:[subclass=Closure]*/
+/*strong.member: foo1:[null|subclass=Closure]*/
+/*omit.member: foo1:[null|subclass=Closure]*/
+/*strongConst.member: foo1:[subclass=Closure]*/
+/*omitConst.member: foo1:[subclass=Closure]*/
var foo1 = method1;
-/*strong.element: foo2:[null|subclass=Closure]*/
-/*omit.element: foo2:[null|subclass=Closure]*/
-/*strongConst.element: foo2:[subclass=Closure]*/
-/*omitConst.element: foo2:[subclass=Closure]*/
+/*strong.member: foo2:[null|subclass=Closure]*/
+/*omit.member: foo2:[null|subclass=Closure]*/
+/*strongConst.member: foo2:[subclass=Closure]*/
+/*omitConst.member: foo2:[subclass=Closure]*/
var foo2 = method2;
-/*element: returnInt1:[null|subclass=Object]*/
+/*member: returnInt1:[null|subclass=Object]*/
returnInt1() {
return foo1();
}
-/*element: returnInt2:[null|subclass=Object]*/
+/*member: returnInt2:[null|subclass=Object]*/
returnInt2() {
return foo2(54);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt1();
returnInt2();
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure2.dart b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
index f4199e9..3946304 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
@@ -2,24 +2,24 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
// Called only via [foo] with a small integer.
method(/*[exact=JSUInt31]*/ a) {
return a;
}
-/*strong.element: foo:[null|subclass=Closure]*/
-/*omit.element: foo:[null|subclass=Closure]*/
-/*strongConst.element: foo:[subclass=Closure]*/
-/*omitConst.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[null|subclass=Closure]*/
+/*omit.member: foo:[null|subclass=Closure]*/
+/*strongConst.member: foo:[subclass=Closure]*/
+/*omitConst.member: foo:[subclass=Closure]*/
var foo = method;
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
returnInt() {
return foo(54);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt();
}
diff --git a/tests/compiler/dart2js/inference/data/if.dart b/tests/compiler/dart2js/inference/data/if.dart
index abe28a0..ecb1a6f 100644
--- a/tests/compiler/dart2js/inference/data/if.dart
+++ b/tests/compiler/dart2js/inference/data/if.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleIfThen();
simpleIfThenElse();
@@ -12,13 +12,13 @@
// Test if-then statement
////////////////////////////////////////////////////////////////////////////////
-/*element: _simpleIfThen:[null|exact=JSUInt31]*/
+/*member: _simpleIfThen:[null|exact=JSUInt31]*/
_simpleIfThen(/*[exact=JSBool]*/ c) {
if (c) return 1;
return null;
}
-/*element: simpleIfThen:[null]*/
+/*member: simpleIfThen:[null]*/
simpleIfThen() {
_simpleIfThen(true);
_simpleIfThen(false);
@@ -28,7 +28,7 @@
// Test if-then-else statement
////////////////////////////////////////////////////////////////////////////////
-/*element: _simpleIfThenElse:[null|exact=JSUInt31]*/
+/*member: _simpleIfThenElse:[null|exact=JSUInt31]*/
_simpleIfThenElse(/*[exact=JSBool]*/ c) {
if (c)
return 1;
@@ -36,7 +36,7 @@
return null;
}
-/*element: simpleIfThenElse:[null]*/
+/*member: simpleIfThenElse:[null]*/
simpleIfThenElse() {
_simpleIfThenElse(true);
_simpleIfThenElse(false);
diff --git a/tests/compiler/dart2js/inference/data/if_null.dart b/tests/compiler/dart2js/inference/data/if_null.dart
index 640ef25..988f649 100644
--- a/tests/compiler/dart2js/inference/data/if_null.dart
+++ b/tests/compiler/dart2js/inference/data/if_null.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
ifNull();
ifNotNullInvoke();
@@ -13,10 +13,10 @@
// If-null on parameter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _ifNull:[exact=JSUInt31]*/
+/*member: _ifNull:[exact=JSUInt31]*/
_ifNull(/*[null|exact=JSUInt31]*/ o) => o ?? 0;
-/*element: ifNull:[null]*/
+/*member: ifNull:[null]*/
ifNull() {
_ifNull(null);
_ifNull(0);
@@ -26,14 +26,14 @@
// If-not-null access on parameter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _ifNotNullInvoke:[null|exact=JSBool]*/
+/*member: _ifNotNullInvoke:[null|exact=JSBool]*/
_ifNotNullInvoke(/*[null|exact=JSUInt31]*/ o) {
return o?.
/*[exact=JSUInt31]*/
isEven;
}
-/*element: ifNotNullInvoke:[null]*/
+/*member: ifNotNullInvoke:[null]*/
ifNotNullInvoke() {
_ifNotNullInvoke(null);
_ifNotNullInvoke(0);
@@ -43,12 +43,12 @@
// As above but unconditional access.
////////////////////////////////////////////////////////////////////////////////
-/*element: _notIfNotNullInvoke:[exact=JSBool]*/
+/*member: _notIfNotNullInvoke:[exact=JSBool]*/
_notIfNotNullInvoke(/*[null|exact=JSUInt31]*/ o) {
return o. /*[null|exact=JSUInt31]*/ isEven;
}
-/*element: notIfNotNullInvoke:[null]*/
+/*member: notIfNotNullInvoke:[null]*/
notIfNotNullInvoke() {
_notIfNotNullInvoke(null);
_notIfNotNullInvoke(0);
diff --git a/tests/compiler/dart2js/inference/data/index.dart b/tests/compiler/dart2js/inference/data/index.dart
index 21a1d93..bfa90b5a 100644
--- a/tests/compiler/dart2js/inference/data/index.dart
+++ b/tests/compiler/dart2js/inference/data/index.dart
@@ -6,7 +6,7 @@
// Lookup into a singleton list.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexSingle:[exact=JSUInt31]*/
+/*member: listIndexSingle:[exact=JSUInt31]*/
listIndexSingle() {
var list = [0];
return list
@@ -18,7 +18,7 @@
// Lookup into a list with multiple elements.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexMultiple:[exact=JSUInt31]*/
+/*member: listIndexMultiple:[exact=JSUInt31]*/
listIndexMultiple() {
var list = [0, 1, 2, 3];
return list
@@ -30,7 +30,7 @@
// Lookup into a list with an out-of-range index.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexBad:[exact=JSUInt31]*/
+/*member: listIndexBad:[exact=JSUInt31]*/
listIndexBad() {
var list = [0, 1];
return list
@@ -42,7 +42,7 @@
// Lookup into a list with mixed element types.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexMixed:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: listIndexMixed:Union([exact=JSString], [exact=JSUInt31])*/
listIndexMixed() {
var list = [0, ''];
return list
@@ -54,7 +54,7 @@
// Lookup into a singleton map.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapLookupSingle:[null|exact=JSUInt31]*/
+/*member: mapLookupSingle:[null|exact=JSUInt31]*/
mapLookupSingle() {
var map = {0: 1};
return map
@@ -66,7 +66,7 @@
// Lookup into a map with multiple entries.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapLookupMultiple:[null|exact=JSUInt31]*/
+/*member: mapLookupMultiple:[null|exact=JSUInt31]*/
mapLookupMultiple() {
var map = {0: 1, 2: 3, 4: 5};
return map
@@ -78,7 +78,7 @@
// Lookup into a map with a missing key.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapLookupMissing:[null|exact=JSUInt31]*/
+/*member: mapLookupMissing:[null|exact=JSUInt31]*/
mapLookupMissing() {
var map = {0: 1};
return map
@@ -90,7 +90,7 @@
// Lookup into a map with mixed key types.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapLookupMixedKeys:[null|exact=JSUInt31]*/
+/*member: mapLookupMixedKeys:[null|exact=JSUInt31]*/
mapLookupMixedKeys() {
var map = {0: 1, '': 2};
return map
@@ -102,7 +102,7 @@
// Lookup into a map with mixed value types.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapLookupMixedValues:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: mapLookupMixedValues:Union([exact=JSUInt31], [null|exact=JSString])*/
mapLookupMixedValues() {
var map = {0: 1, 2: ''};
return map
@@ -114,7 +114,7 @@
// Lookup into a singleton map with String keys.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryLookupSingle:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryLookupSingle:Value([exact=JSString], value: "bar")*/
dictionaryLookupSingle() {
var map = {'foo': 'bar'};
return map
@@ -126,7 +126,7 @@
// Lookup into a map with String keys.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryLookupMultiple:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryLookupMultiple:Value([exact=JSString], value: "boz")*/
dictionaryLookupMultiple() {
var map = {'foo': 'bar', 'baz': 'boz'};
return map
@@ -138,7 +138,7 @@
// Lookup into a map with String keys with a missing key.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryLookupMissing:[null]*/
+/*member: dictionaryLookupMissing:[null]*/
dictionaryLookupMissing() {
var map = {'foo': 'bar', 'baz': 'boz'};
return map
@@ -150,7 +150,7 @@
// Lookup into a string-to-int map.
////////////////////////////////////////////////////////////////////////////////
-/*element: intDictionaryLookupSingle:[exact=JSUInt31]*/
+/*member: intDictionaryLookupSingle:[exact=JSUInt31]*/
intDictionaryLookupSingle() {
var map = {'foo': 0};
return map
@@ -162,32 +162,32 @@
// Index access on custom class.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.[]:[exact=JSUInt31]*/
+ /*member: Class1.[]:[exact=JSUInt31]*/
operator [](/*[exact=JSUInt31]*/ index) => index;
}
-/*element: customIndex:[exact=JSUInt31]*/
+/*member: customIndex:[exact=JSUInt31]*/
customIndex() => new Class1() /*[exact=Class1]*/ [42];
////////////////////////////////////////////////////////////////////////////////
// Index access on custom class through `this`.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.[]:[exact=JSUInt31]*/
+ /*member: Class2.[]:[exact=JSUInt31]*/
operator [](/*[exact=JSUInt31]*/ index) => index;
- /*element: Class2.method:[exact=JSUInt31]*/
+ /*member: Class2.method:[exact=JSUInt31]*/
method() => this /*[exact=Class2]*/ [42];
}
-/*element: customIndexThis:[exact=JSUInt31]*/
+/*member: customIndexThis:[exact=JSUInt31]*/
customIndexThis() => new Class2(). /*invoke: [exact=Class2]*/ method();
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
listIndexSingle();
listIndexMultiple();
diff --git a/tests/compiler/dart2js/inference/data/index_call.dart b/tests/compiler/dart2js/inference/data/index_call.dart
index 1bab3af..a2c6006 100644
--- a/tests/compiler/dart2js/inference/data/index_call.dart
+++ b/tests/compiler/dart2js/inference/data/index_call.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
listIndexCall();
listIndexExplicitCall();
@@ -13,7 +13,7 @@
multiMapListIndexCall();
}
-/*element: listIndexCall:[null|subclass=Object]*/
+/*member: listIndexCall:[null|subclass=Object]*/
listIndexCall() {
var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ a}) => a;
var a = [closure];
@@ -21,7 +21,7 @@
[0](a: 0);
}
-/*element: listIndexExplicitCall:[null|subclass=Object]*/
+/*member: listIndexExplicitCall:[null|subclass=Object]*/
listIndexExplicitCall() {
var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ b}) => b;
var a = [closure];
@@ -30,7 +30,7 @@
.call(b: 0);
}
-/*element: multiListIndex:[subclass=JSPositiveInt]*/
+/*member: multiListIndex:[subclass=JSPositiveInt]*/
multiListIndex() {
var a = [
[0]
@@ -43,7 +43,7 @@
. /*invoke: [exact=JSUInt31]*/ abs();
}
-/*element: multiListIndexCall:[null|subclass=Object]*/
+/*member: multiListIndexCall:[null|subclass=Object]*/
multiListIndexCall() {
var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ c}) => c;
var a = [
@@ -56,7 +56,7 @@
[0](c: 0);
}
-/*element: multiMapIndex:[subclass=JSPositiveInt]*/
+/*member: multiMapIndex:[subclass=JSPositiveInt]*/
multiMapIndex() {
var a = {
'a': {'b': 0}
@@ -69,7 +69,7 @@
abs();
}
-/*element: multiMapIndexCall:[null|subclass=Object]*/
+/*member: multiMapIndexCall:[null|subclass=Object]*/
multiMapIndexCall() {
var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ d}) => d;
var a = {
@@ -81,7 +81,7 @@
['b'](d: 0);
}
-/*element: multiMapListIndexCall:[null|subclass=Object]*/
+/*member: multiMapListIndexCall:[null|subclass=Object]*/
multiMapListIndexCall() {
var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ d}) => d;
var a = {
diff --git a/tests/compiler/dart2js/inference/data/index_postfix.dart b/tests/compiler/dart2js/inference/data/index_postfix.dart
index 5eefc77..a861cfb 100644
--- a/tests/compiler/dart2js/inference/data/index_postfix.dart
+++ b/tests/compiler/dart2js/inference/data/index_postfix.dart
@@ -2,14 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
listIndexPostfixIncrement();
listIndexPostfixDecrement();
superIndexPostfixIncrement();
}
-/*element: listIndexPostfixIncrement:[subclass=JSPositiveInt]*/
+/*member: listIndexPostfixIncrement:[subclass=JSPositiveInt]*/
listIndexPostfixIncrement() {
var list = [0];
return list
@@ -19,7 +19,7 @@
/*invoke: [subclass=JSPositiveInt]*/ ++;
}
-/*element: listIndexPostfixDecrement:[subclass=JSInt]*/
+/*member: listIndexPostfixDecrement:[subclass=JSInt]*/
listIndexPostfixDecrement() {
var list = [0];
return list
@@ -29,22 +29,22 @@
/*invoke: [subclass=JSInt]*/ --;
}
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
class Super1 {
- /*element: Super1.[]:[exact=JSUInt31]*/
+ /*member: Super1.[]:[exact=JSUInt31]*/
operator [](/*[exact=JSUInt31]*/ index) => 42;
- /*element: Super1.[]=:[null]*/
+ /*member: Super1.[]=:[null]*/
operator []=(/*[exact=JSUInt31]*/ index, /*[subclass=JSUInt32]*/ value) {}
}
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 extends Super1 {
- /*element: Class1.method:[exact=JSUInt31]*/
+ /*member: Class1.method:[exact=JSUInt31]*/
method() => super[0] /*invoke: [exact=JSUInt31]*/ ++;
}
-/*element: superIndexPostfixIncrement:[null]*/
+/*member: superIndexPostfixIncrement:[null]*/
superIndexPostfixIncrement() {
new Class1(). /*invoke: [exact=Class1]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/index_set.dart b/tests/compiler/dart2js/inference/data/index_set.dart
index 2e18237..fe5ec45 100644
--- a/tests/compiler/dart2js/inference/data/index_set.dart
+++ b/tests/compiler/dart2js/inference/data/index_set.dart
@@ -6,7 +6,7 @@
// Update to a singleton list.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexSetSingle:[exact=JSUInt31]*/
+/*member: listIndexSetSingle:[exact=JSUInt31]*/
listIndexSetSingle() {
var list = [0];
return list
@@ -18,7 +18,7 @@
// Update to a list with multiple elements.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexSetMultiple:[exact=JSUInt31]*/
+/*member: listIndexSetMultiple:[exact=JSUInt31]*/
listIndexSetMultiple() {
var list = [0, 1, 2, 3];
return list
@@ -30,7 +30,7 @@
// Update to a list with an out-of-range index.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexSetBad:[exact=JSUInt31]*/
+/*member: listIndexSetBad:[exact=JSUInt31]*/
listIndexSetBad() {
var list = [0, 1];
return list
@@ -42,7 +42,7 @@
// Update to a list with mixed element types.
////////////////////////////////////////////////////////////////////////////////
-/*element: listIndexSetMixed:[exact=JSUInt31]*/
+/*member: listIndexSetMixed:[exact=JSUInt31]*/
listIndexSetMixed() {
dynamic list = [''];
return list
@@ -54,7 +54,7 @@
// Update to a empty map.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateEmpty:[exact=JSUInt31]*/
+/*member: mapUpdateEmpty:[exact=JSUInt31]*/
mapUpdateEmpty() {
var map = {};
return map
@@ -66,7 +66,7 @@
// Update to a singleton map.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateSingle:[exact=JSUInt31]*/
+/*member: mapUpdateSingle:[exact=JSUInt31]*/
mapUpdateSingle() {
var map = {0: 1};
return map
@@ -78,7 +78,7 @@
// Update to a map with multiple entries.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateMultiple:[exact=JSUInt31]*/
+/*member: mapUpdateMultiple:[exact=JSUInt31]*/
mapUpdateMultiple() {
var map = {0: 1, 2: 3, 4: 5};
return map
@@ -90,7 +90,7 @@
// Update to a map with a missing key.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateMissing:[exact=JSUInt31]*/
+/*member: mapUpdateMissing:[exact=JSUInt31]*/
mapUpdateMissing() {
var map = {0: 1};
return map
@@ -102,7 +102,7 @@
// Update to a map with mixed key types.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateMixedKeys:[exact=JSUInt31]*/
+/*member: mapUpdateMixedKeys:[exact=JSUInt31]*/
mapUpdateMixedKeys() {
dynamic map = {'': 2};
return map
@@ -114,7 +114,7 @@
// Update to a map with mixed value types.
////////////////////////////////////////////////////////////////////////////////
-/*element: mapUpdateMixedValues:[exact=JSUInt31]*/
+/*member: mapUpdateMixedValues:[exact=JSUInt31]*/
mapUpdateMixedValues() {
dynamic map = {2: ''};
return map
@@ -126,7 +126,7 @@
// Update to an empty map with String keys.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryUpdateEmpty:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryUpdateEmpty:Value([exact=JSString], value: "bar")*/
dictionaryUpdateEmpty() {
var map = {};
return map
@@ -138,7 +138,7 @@
// Update to a singleton map with String keys with a new value.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryUpdateSingle:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryUpdateSingle:Value([exact=JSString], value: "boz")*/
dictionaryUpdateSingle() {
var map = {'foo': 'bar'};
return map
@@ -150,7 +150,7 @@
// Update to a singleton map with String keys with the same value.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryReUpdateSingle:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryReUpdateSingle:Value([exact=JSString], value: "bar")*/
dictionaryReUpdateSingle() {
var map = {'foo': 'bar'};
return map
@@ -162,7 +162,7 @@
// Update to a map with String keys.
////////////////////////////////////////////////////////////////////////////////
-/*element: dictionaryUpdateMultiple:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryUpdateMultiple:Value([exact=JSString], value: "boz")*/
dictionaryUpdateMultiple() {
var map = {'foo': 'bar'};
return map
@@ -174,7 +174,7 @@
// Update to a string-to-int map.
////////////////////////////////////////////////////////////////////////////////
-/*element: intDictionaryUpdateSingle:[exact=JSUInt31]*/
+/*member: intDictionaryUpdateSingle:[exact=JSUInt31]*/
intDictionaryUpdateSingle() {
var map = {};
return map
@@ -182,7 +182,7 @@
['foo'] = 0;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
listIndexSetSingle();
listIndexSetMultiple();
diff --git a/tests/compiler/dart2js/inference/data/init_get.dart b/tests/compiler/dart2js/inference/data/init_get.dart
index ec8e9a2..e940e1e 100644
--- a/tests/compiler/dart2js/inference/data/init_get.dart
+++ b/tests/compiler/dart2js/inference/data/init_get.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: getter:[exact=JSUInt31]*/
+/*member: getter:[exact=JSUInt31]*/
get getter => 42;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
getGetter();
getGetterInFinalField();
@@ -20,53 +20,53 @@
// Access a top level getter directly.
////////////////////////////////////////////////////////////////////////////////
-/*element: getGetter:[exact=JSUInt31]*/
+/*member: getGetter:[exact=JSUInt31]*/
getGetter() => getter;
////////////////////////////////////////////////////////////////////////////////
// Access a top level getter in a final instance field initializer.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[exact=JSUInt31]*/
+ /*member: Class1.field:[exact=JSUInt31]*/
final field = getter;
}
-/*element: getGetterInFinalField:[exact=JSUInt31]*/
+/*member: getGetterInFinalField:[exact=JSUInt31]*/
getGetterInFinalField() => new Class1(). /*[exact=Class1]*/ field;
////////////////////////////////////////////////////////////////////////////////
// Access a top level getter in a non-final instance field initializer.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[exact=JSUInt31]*/
+ /*member: Class2.field:[exact=JSUInt31]*/
var field = getter;
}
-/*element: getGetterInField:[exact=JSUInt31]*/
+/*member: getGetterInField:[exact=JSUInt31]*/
getGetterInField() => new Class2(). /*[exact=Class2]*/ field;
////////////////////////////////////////////////////////////////////////////////
// Access a top level getter in a final top level field initializer.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field1:[null|exact=JSUInt31]*/
+/*member: _field1:[null|exact=JSUInt31]*/
final _field1 = getter;
-/*element: getGetterInFinalTopLevelField:[null|exact=JSUInt31]*/
+/*member: getGetterInFinalTopLevelField:[null|exact=JSUInt31]*/
getGetterInFinalTopLevelField() => _field1;
////////////////////////////////////////////////////////////////////////////////
// Access a top level getter in a non-final top level field initializer.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field2:[null|exact=JSUInt31]*/
+/*member: _field2:[null|exact=JSUInt31]*/
var _field2 = getter;
-/*element: getGetterInTopLevelField:[null|exact=JSUInt31]*/
+/*member: getGetterInTopLevelField:[null|exact=JSUInt31]*/
getGetterInTopLevelField() => _field2;
////////////////////////////////////////////////////////////////////////////////
@@ -74,11 +74,11 @@
////////////////////////////////////////////////////////////////////////////////
abstract class Class3 {
- /*element: Class3.field:[null|exact=JSUInt31]*/
+ /*member: Class3.field:[null|exact=JSUInt31]*/
static final field = getter;
}
-/*element: getGetterInFinalStaticField:[null|exact=JSUInt31]*/
+/*member: getGetterInFinalStaticField:[null|exact=JSUInt31]*/
getGetterInFinalStaticField() => Class3.field;
////////////////////////////////////////////////////////////////////////////////
@@ -86,9 +86,9 @@
////////////////////////////////////////////////////////////////////////////////
abstract class Class4 {
- /*element: Class4.field:[null|exact=JSUInt31]*/
+ /*member: Class4.field:[null|exact=JSUInt31]*/
static var field = getter;
}
-/*element: getGetterInStaticField:[null|exact=JSUInt31]*/
+/*member: getGetterInStaticField:[null|exact=JSUInt31]*/
getGetterInStaticField() => Class4.field;
diff --git a/tests/compiler/dart2js/inference/data/initializer.dart b/tests/compiler/dart2js/inference/data/initializer.dart
index 933f92e..b059fef 100644
--- a/tests/compiler/dart2js/inference/data/initializer.dart
+++ b/tests/compiler/dart2js/inference/data/initializer.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
initializingFormal();
fieldInitializer();
@@ -15,14 +15,14 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.field:[exact=JSUInt31]*/
+ /*member: Class1.field:[exact=JSUInt31]*/
var field;
- /*element: Class1.:[exact=Class1]*/
+ /*member: Class1.:[exact=Class1]*/
Class1(this. /*[exact=JSUInt31]*/ field);
}
-/*element: initializingFormal:[exact=Class1]*/
+/*member: initializingFormal:[exact=Class1]*/
initializingFormal() => new Class1(0);
////////////////////////////////////////////////////////////////////////////////
@@ -30,14 +30,14 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field:[exact=JSUInt31]*/
+ /*member: Class2.field:[exact=JSUInt31]*/
var field;
- /*element: Class2.:[exact=Class2]*/
+ /*member: Class2.:[exact=Class2]*/
Class2(/*[exact=JSUInt31]*/ field) : this.field = field;
}
-/*element: fieldInitializer:[exact=Class2]*/
+/*member: fieldInitializer:[exact=Class2]*/
fieldInitializer() => new Class2(0);
////////////////////////////////////////////////////////////////////////////////
@@ -45,17 +45,17 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.field:[exact=JSUInt31]*/
+ /*member: Class3.field:[exact=JSUInt31]*/
var field;
- /*element: Class3._:[exact=Class3]*/
+ /*member: Class3._:[exact=Class3]*/
Class3._(this. /*[exact=JSUInt31]*/ field);
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
Class3(/*[exact=JSUInt31]*/ field) : this._(field);
}
-/*element: thisInitializer:[exact=Class3]*/
+/*member: thisInitializer:[exact=Class3]*/
thisInitializer() => new Class3(0);
////////////////////////////////////////////////////////////////////////////////
@@ -63,17 +63,17 @@
////////////////////////////////////////////////////////////////////////////////
abstract class SuperClass4 {
- /*element: SuperClass4.field:[exact=JSUInt31]*/
+ /*member: SuperClass4.field:[exact=JSUInt31]*/
var field;
- /*element: SuperClass4.:[exact=Class4]*/
+ /*member: SuperClass4.:[exact=Class4]*/
SuperClass4(this. /*[exact=JSUInt31]*/ field);
}
class Class4 extends SuperClass4 {
- /*element: Class4.:[exact=Class4]*/
+ /*member: Class4.:[exact=Class4]*/
Class4(/*[exact=JSUInt31]*/ field) : super(field);
}
-/*element: superInitializer:[exact=Class4]*/
+/*member: superInitializer:[exact=Class4]*/
superInitializer() => new Class4(0);
diff --git a/tests/compiler/dart2js/inference/data/instance.dart b/tests/compiler/dart2js/inference/data/instance.dart
index a38bd26..9559f1ba 100644
--- a/tests/compiler/dart2js/inference/data/instance.dart
+++ b/tests/compiler/dart2js/inference/data/instance.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
thisExact();
thisSubclass();
@@ -17,29 +17,29 @@
/// Return `this` of a class with no subclasses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.method:[exact=Class1]*/
+ /*member: Class1.method:[exact=Class1]*/
method() => this;
}
-/*element: thisExact:[exact=Class1]*/
+/*member: thisExact:[exact=Class1]*/
thisExact() => new Class1(). /*invoke: [exact=Class1]*/ method();
////////////////////////////////////////////////////////////////////////////////
/// Return `this` of a class with an instantiated subclass.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2a.:[exact=Class2a]*/
+/*member: Class2a.:[exact=Class2a]*/
class Class2a {
- /*element: Class2a.method:[subclass=Class2a]*/
+ /*member: Class2a.method:[subclass=Class2a]*/
method() => this;
}
-/*element: Class2b.:[exact=Class2b]*/
+/*member: Class2b.:[exact=Class2b]*/
class Class2b extends Class2a {}
-/*element: thisSubclass:[subclass=Class2a]*/
+/*member: thisSubclass:[subclass=Class2a]*/
thisSubclass() {
new Class2b();
return new Class2a(). /*invoke: [exact=Class2a]*/ method();
@@ -49,15 +49,15 @@
/// Return `this` of a class with no instantiated subclasses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3a.:[exact=Class3a]*/
+/*member: Class3a.:[exact=Class3a]*/
class Class3a {
- /*element: Class3a.method:[exact=Class3a]*/
+ /*member: Class3a.method:[exact=Class3a]*/
method() => this;
}
class Class3b extends Class3a {}
-/*element: thisSubclassExact:[exact=Class3a]*/
+/*member: thisSubclassExact:[exact=Class3a]*/
thisSubclassExact() {
return new Class3a(). /*invoke: [exact=Class3a]*/ method();
}
@@ -66,16 +66,16 @@
/// Return `this` of a class that is mixed into an instantiated class.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4a.:[exact=Class4a]*/
+/*member: Class4a.:[exact=Class4a]*/
class Class4a {
- /*element: Class4a.method:[subtype=Class4a]*/
+ /*member: Class4a.method:[subtype=Class4a]*/
method() => this;
}
-/*element: Class4b.:[exact=Class4b]*/
+/*member: Class4b.:[exact=Class4b]*/
class Class4b extends Object with Class4a {}
-/*element: thisSubtype:[subtype=Class4a]*/
+/*member: thisSubtype:[subtype=Class4a]*/
thisSubtype() {
new Class4b();
return new Class4a(). /*invoke: [exact=Class4a]*/ method();
@@ -85,15 +85,15 @@
/// Return `this` of a class that is mixed into an uninstantiated class.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5a.:[exact=Class5a]*/
+/*member: Class5a.:[exact=Class5a]*/
class Class5a {
- /*element: Class5a.method:[exact=Class5a]*/
+ /*member: Class5a.method:[exact=Class5a]*/
method() => this;
}
class Class5b extends Object with Class5a {}
-/*element: thisSubtypeExact:[exact=Class5a]*/
+/*member: thisSubtypeExact:[exact=Class5a]*/
thisSubtypeExact() {
return new Class5a(). /*invoke: [exact=Class5a]*/ method();
}
@@ -102,16 +102,16 @@
/// Return `this` of a mixed in class that is itself instantiated.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class6a.:[exact=Class6a]*/
+/*member: Class6a.:[exact=Class6a]*/
class Class6a {
- /*element: Class6a.method:[subtype=Class6a]*/
+ /*member: Class6a.method:[subtype=Class6a]*/
method() => this;
}
-/*element: Class6b.:[exact=Class6b]*/
+/*member: Class6b.:[exact=Class6b]*/
class Class6b extends Object with Class6a {}
-/*element: thisSubtypeMixedIn:[subtype=Class6a]*/
+/*member: thisSubtypeMixedIn:[subtype=Class6a]*/
thisSubtypeMixedIn() {
new Class6a();
return new Class6b(). /*invoke: [exact=Class6b]*/ method();
@@ -122,14 +122,14 @@
////////////////////////////////////////////////////////////////////////////////
class Class7a {
- /*element: Class7a.method:[exact=Class7b]*/
+ /*member: Class7a.method:[exact=Class7b]*/
method() => this;
}
-/*element: Class7b.:[exact=Class7b]*/
+/*member: Class7b.:[exact=Class7b]*/
class Class7b extends Object with Class7a {}
-/*element: thisSubtypeExactMixedIn:[exact=Class7b]*/
+/*member: thisSubtypeExactMixedIn:[exact=Class7b]*/
thisSubtypeExactMixedIn() {
return new Class7b(). /*invoke: [exact=Class7b]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/issue13354.dart b/tests/compiler/dart2js/inference/data/issue13354.dart
index 24a47b0..a0c669e 100644
--- a/tests/compiler/dart2js/inference/data/issue13354.dart
+++ b/tests/compiler/dart2js/inference/data/issue13354.dart
@@ -4,25 +4,25 @@
// Regression test for issue 13354.
-/*element: bar:[exact=JSUInt31]*/
+/*member: bar:[exact=JSUInt31]*/
bar() => 42;
-/*element: baz:[subclass=Closure]*/
+/*member: baz:[subclass=Closure]*/
baz() => bar;
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
- /*element: A.foo:[exact=JSUInt31]*/
+ /*member: A.foo:[exact=JSUInt31]*/
foo() => 42;
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:[subclass=Closure]*/
+ /*member: B.foo:[subclass=Closure]*/
foo() => super.foo;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
baz();
new B(). /*invoke: [exact=B]*/ foo();
diff --git a/tests/compiler/dart2js/inference/data/js_interop.dart b/tests/compiler/dart2js/inference/data/js_interop.dart
index e55c5dfe..2a0f3f9 100644
--- a/tests/compiler/dart2js/inference/data/js_interop.dart
+++ b/tests/compiler/dart2js/inference/data/js_interop.dart
@@ -7,7 +7,7 @@
import 'package:js/js.dart';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
anonymousClass();
jsInteropClass();
@@ -16,29 +16,29 @@
@JS()
@anonymous
class Class1 {
- /*element: Class1.:[null|subclass=Object]*/
+ /*member: Class1.:[null|subclass=Object]*/
external factory Class1(
{/*[exact=JSUInt31]*/ a, /*Value([exact=JSString], value: "")*/ b});
}
-/*element: anonymousClass:[null|subclass=JavaScriptObject]*/
+/*member: anonymousClass:[null|subclass=JavaScriptObject]*/
anonymousClass() => new Class1(a: 1, b: '');
@JS()
class JsInteropClass {
- /*element: JsInteropClass.:[null|subclass=Object]*/
+ /*member: JsInteropClass.:[null|subclass=Object]*/
external JsInteropClass();
- /*element: JsInteropClass.getter:[null|subclass=Object]*/
+ /*member: JsInteropClass.getter:[null|subclass=Object]*/
external int get getter;
external void set setter(int /*[subclass=JSInt]*/ value);
- /*element: JsInteropClass.method:[null|subclass=Object]*/
+ /*member: JsInteropClass.method:[null|subclass=Object]*/
external int method(int /*[exact=JSUInt31]*/ a);
}
-/*element: jsInteropClass:[subclass=JSInt]*/
+/*member: jsInteropClass:[subclass=JSInt]*/
jsInteropClass() {
JsInteropClass cls = new JsInteropClass();
return cls. /*update: [null|subclass=JavaScriptObject]*/ setter =
diff --git a/tests/compiler/dart2js/inference/data/list.dart b/tests/compiler/dart2js/inference/data/list.dart
index 967ed10..2a650bd 100644
--- a/tests/compiler/dart2js/inference/data/list.dart
+++ b/tests/compiler/dart2js/inference/data/list.dart
@@ -4,7 +4,7 @@
import 'dart:typed_data';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
emptyList();
nullList();
@@ -29,66 +29,66 @@
newUint8List();
}
-/*element: emptyList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: emptyList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
emptyList() => [];
-/*element: constList:Container([exact=JSUnmodifiableArray], element: [empty], length: 0)*/
+/*member: constList:Container([exact=JSUnmodifiableArray], element: [empty], length: 0)*/
constList() => const [];
-/*element: nullList:Container([exact=JSExtendableArray], element: [null], length: 1)*/
+/*member: nullList:Container([exact=JSExtendableArray], element: [null], length: 1)*/
nullList() => [null];
-/*element: constNullList:Container([exact=JSUnmodifiableArray], element: [null], length: 1)*/
+/*member: constNullList:Container([exact=JSUnmodifiableArray], element: [null], length: 1)*/
constNullList() => const [null];
-/*element: intList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
+/*member: intList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
intList() => [1, 2, 3];
-/*element: newList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: newList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
newList() => new List();
-/*element: newFixedList:Container([exact=JSFixedArray], element: [null], length: 2)*/
+/*member: newFixedList:Container([exact=JSFixedArray], element: [null], length: 2)*/
newFixedList() => new List(2);
-/*element: newFilledList:Container([exact=JSFixedArray], element: Value([exact=JSString], value: ""), length: 3)*/
+/*member: newFilledList:Container([exact=JSFixedArray], element: Value([exact=JSString], value: ""), length: 3)*/
newFilledList() => new List.filled(3, '');
-/*element: newFloat32x4List:[exact=NativeFloat32x4List]*/
+/*member: newFloat32x4List:[exact=NativeFloat32x4List]*/
newFloat32x4List() => new Float32x4List(4);
-/*element: newInt32x4List:[exact=NativeInt32x4List]*/
+/*member: newInt32x4List:[exact=NativeInt32x4List]*/
newInt32x4List() => new Int32x4List(5);
-/*element: newFloat64x2List:[exact=NativeFloat64x2List]*/
+/*member: newFloat64x2List:[exact=NativeFloat64x2List]*/
newFloat64x2List() => new Float64x2List(6);
-/*element: newFloat32List:Container([exact=NativeFloat32List], element: [subclass=JSNumber], length: 7)*/
+/*member: newFloat32List:Container([exact=NativeFloat32List], element: [subclass=JSNumber], length: 7)*/
newFloat32List() => new Float32List(7);
-/*element: newFloat64List:Container([exact=NativeFloat64List], element: [subclass=JSNumber], length: 8)*/
+/*member: newFloat64List:Container([exact=NativeFloat64List], element: [subclass=JSNumber], length: 8)*/
newFloat64List() => new Float64List(8);
-/*element: newInt16List:Container([exact=NativeInt16List], element: [subclass=JSInt], length: 9)*/
+/*member: newInt16List:Container([exact=NativeInt16List], element: [subclass=JSInt], length: 9)*/
newInt16List() => new Int16List(9);
////////////////////////////////////////////////////////////////////////////////
// Create a Int32List using an unchanged non-final top-level field as length.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field1:[exact=JSUInt31]*/
+/*member: _field1:[exact=JSUInt31]*/
var _field1 = 10;
-/*element: newInt32List:Container([exact=NativeInt32List], element: [subclass=JSInt], length: 10)*/
+/*member: newInt32List:Container([exact=NativeInt32List], element: [subclass=JSInt], length: 10)*/
newInt32List() => new Int32List(_field1);
////////////////////////////////////////////////////////////////////////////////
// Create a Int32List using a changed non-final top-level field as length.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field1b:[subclass=JSPositiveInt]*/
+/*member: _field1b:[subclass=JSPositiveInt]*/
var _field1b = 10;
-/*element: newInt32List2:Container([exact=NativeInt32List], element: [subclass=JSInt], length: null)*/
+/*member: newInt32List2:Container([exact=NativeInt32List], element: [subclass=JSInt], length: null)*/
newInt32List2() {
_field1b /*invoke: [subclass=JSPositiveInt]*/ ++;
return new Int32List(_field1b);
@@ -98,35 +98,35 @@
// Create a Int8List using a final top-level field as length.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field2:[exact=JSUInt31]*/
+/*member: _field2:[exact=JSUInt31]*/
final _field2 = 11;
-/*element: newInt8List:Container([exact=NativeInt8List], element: [subclass=JSInt], length: 11)*/
+/*member: newInt8List:Container([exact=NativeInt8List], element: [subclass=JSInt], length: 11)*/
newInt8List() => new Int8List(_field2);
////////////////////////////////////////////////////////////////////////////////
// Create a Uint16List using a const top-level field as length.
////////////////////////////////////////////////////////////////////////////////
-/*strong.element: _field3:[exact=JSUInt31]*/
-/*omit.element: _field3:[exact=JSUInt31]*/
+/*strong.member: _field3:[exact=JSUInt31]*/
+/*omit.member: _field3:[exact=JSUInt31]*/
const _field3 = 12;
-/*element: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
+/*member: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
newUint16List() => new Uint16List(_field3);
////////////////////////////////////////////////////////////////////////////////
// Create a Uint32List using a parenthesized literal int as length.
////////////////////////////////////////////////////////////////////////////////
-/*element: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: 13)*/
+/*member: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: 13)*/
newUint32List() => new Uint32List((13));
////////////////////////////////////////////////////////////////////////////////
// Create a Uint8ClampedList using a constant multiplication as length.
////////////////////////////////////////////////////////////////////////////////
-/*element: newUint8ClampedList:Container([exact=NativeUint8ClampedList], element: [exact=JSUInt31], length: null)*/
+/*member: newUint8ClampedList:Container([exact=NativeUint8ClampedList], element: [exact=JSUInt31], length: null)*/
newUint8ClampedList() =>
new Uint8ClampedList(2 /*invoke: [exact=JSUInt31]*/ * 7);
@@ -135,10 +135,10 @@
////////////////////////////////////////////////////////////////////////////////
abstract class Class1 {
- /*strong.element: Class1.field:[exact=JSUInt31]*/
- /*omit.element: Class1.field:[exact=JSUInt31]*/
+ /*strong.member: Class1.field:[exact=JSUInt31]*/
+ /*omit.member: Class1.field:[exact=JSUInt31]*/
static const field = 15;
}
-/*element: newUint8List:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 15)*/
+/*member: newUint8List:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 15)*/
newUint8List() => new Uint8List(Class1.field);
diff --git a/tests/compiler/dart2js/inference/data/list_huge.dart b/tests/compiler/dart2js/inference/data/list_huge.dart
new file mode 100644
index 0000000..3ef9fba
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/list_huge.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.
+
+// Test for Container type for Lists with huge or negative sizes.
+
+/*member: main:[null]*/
+main() {
+ hugeList1();
+ hugeList2();
+ hugeList3();
+ hugeList4();
+}
+
+/*member: _huge1:[subclass=JSPositiveInt]*/
+final _huge1 = 5000000000;
+
+/*member: hugeList1:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList1() => List(_huge1);
+
+/*strong.member: _huge2a:[subclass=JSPositiveInt]*/
+/*omit.member: _huge2a:[subclass=JSPositiveInt]*/
+const _huge2a = 10000000000
+ /*strong.invoke: [subclass=JSPositiveInt]*/
+ /*omit.invoke: [subclass=JSPositiveInt]*/
+ *
+ 10000000000;
+
+/*strong.member: _huge2b:[null|subclass=JSPositiveInt]*/
+/*omit.member: _huge2b:[null|subclass=JSPositiveInt]*/
+/*strongConst.member: _huge2b:[subclass=JSPositiveInt]*/
+/*omitConst.member: _huge2b:[subclass=JSPositiveInt]*/
+final _huge2b = _huge2a;
+
+/*member: hugeList2:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList2() => List(_huge2b);
+
+/*strong.member: _huge3a:[subclass=JSInt]*/
+/*omit.member: _huge3a:[subclass=JSInt]*/
+const _huge3a =
+ /*strong.invoke: [exact=JSUInt31]*/
+ /*omit.invoke: [exact=JSUInt31]*/
+ -10000000;
+
+/*strong.member: _huge3b:[null|subclass=JSInt]*/
+/*omit.member: _huge3b:[null|subclass=JSInt]*/
+/*strongConst.member: _huge3b:[subclass=JSInt]*/
+/*omitConst.member: _huge3b:[subclass=JSInt]*/
+final _huge3b = _huge3a;
+
+/*member: hugeList3:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList3() => List(_huge3b);
+
+// 'Small' limits are still tracked.
+
+/*member: _huge4:[exact=JSUInt31]*/
+final _huge4 = 10000000;
+
+/*member: hugeList4:Container([exact=JSFixedArray], element: [null], length: 10000000)*/
+hugeList4() => List(_huge4);
diff --git a/tests/compiler/dart2js/inference/data/list_tracer2.dart b/tests/compiler/dart2js/inference/data/list_tracer2.dart
index 356c791..37e2e2c 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer2.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer2.dart
@@ -5,10 +5,10 @@
// We used to always nullify the element type of a list we are tracing in
// the presence of a fixed length list constructor call.
-/*element: myList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: myList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
var myList = [42];
-/*element: main:[exact=JSUInt31]*/
+/*member: main:[exact=JSUInt31]*/
main() {
/// ignore: unused_local_variable
var a = new List(42);
diff --git a/tests/compiler/dart2js/inference/data/list_tracer3.dart b/tests/compiler/dart2js/inference/data/list_tracer3.dart
index 7782208..2c56101 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer3.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer3.dart
@@ -5,13 +5,13 @@
// We used to always nullify the element type of a list we are tracing in
// the presence of a fixed length list constructor call.
-/*element: myList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [subclass=JSNumber]), length: null)*/
+/*member: myList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [subclass=JSNumber]), length: null)*/
var myList = [];
-/*element: otherList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
+/*member: otherList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
var otherList = ['foo', 42];
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
dynamic a = otherList
/*Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
diff --git a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
index c528722..460ca33 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
@@ -7,13 +7,13 @@
// TODO(johnniwinther): Fix inference for strong mode. List elements should not
// be [empty].
-/*element: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
+/*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
var myList = new Float32List(42);
-/*element: myOtherList:Container([null|exact=NativeUint8List], element: [exact=JSUInt31], length: 32)*/
+/*member: myOtherList:Container([null|exact=NativeUint8List], element: [exact=JSUInt31], length: 32)*/
var myOtherList = new Uint8List(32);
-/*element: main:[subclass=JSNumber]*/
+/*member: main:[subclass=JSNumber]*/
main() {
// ignore: unused_local_variable
var a = new Float32List(9);
diff --git a/tests/compiler/dart2js/inference/data/local_functions.dart b/tests/compiler/dart2js/inference/data/local_functions.dart
index 6570789..6d08b0a 100644
--- a/tests/compiler/dart2js/inference/data/local_functions.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
namedLocalFunctionInvoke();
unnamedLocalFunctionInvoke();
@@ -21,7 +21,7 @@
// Invocation of a named local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: namedLocalFunctionInvoke:[exact=JSUInt31]*/
+/*member: namedLocalFunctionInvoke:[exact=JSUInt31]*/
namedLocalFunctionInvoke() {
/*[exact=JSUInt31]*/ local() => 0;
return local();
@@ -31,7 +31,7 @@
// Invocation of an unnamed local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: unnamedLocalFunctionInvoke:[null|subclass=JSInt]*/
+/*member: unnamedLocalFunctionInvoke:[null|subclass=JSInt]*/
unnamedLocalFunctionInvoke() {
var local = /*[exact=JSUInt31]*/ () => 0;
return local();
@@ -41,7 +41,7 @@
// Access of a named local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: namedLocalFunctionGet:[subclass=Closure]*/
+/*member: namedLocalFunctionGet:[subclass=Closure]*/
namedLocalFunctionGet() {
/*[exact=JSUInt31]*/ local() => 0;
return local;
@@ -51,7 +51,7 @@
// Call a named local function recursively.
////////////////////////////////////////////////////////////////////////////////
-/*element: recursiveLocalFunction:[subclass=Closure]*/
+/*member: recursiveLocalFunction:[subclass=Closure]*/
recursiveLocalFunction() {
/*[subclass=Closure]*/ local() => local;
return local();
@@ -61,7 +61,7 @@
// Call a named local function with a missing argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: namedLocalFunctionInvokeMissingArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeMissingArgument:[null|subclass=Object]*/
@pragma('dart2js:disableFinal')
namedLocalFunctionInvokeMissingArgument() {
/*[exact=JSUInt31]*/ local(/*[empty]*/ x) => 0;
@@ -73,7 +73,7 @@
// Call a named local function with an extra argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: namedLocalFunctionInvokeExtraArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeExtraArgument:[null|subclass=Object]*/
@pragma('dart2js:disableFinal')
namedLocalFunctionInvokeExtraArgument() {
/*[exact=JSUInt31]*/ local() => 0;
@@ -85,7 +85,7 @@
// Call a named local function with an extra named argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: namedLocalFunctionInvokeExtraNamedArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeExtraNamedArgument:[null|subclass=Object]*/
@pragma('dart2js:disableFinal')
namedLocalFunctionInvokeExtraNamedArgument() {
/*[exact=JSUInt31]*/ local() => 0;
@@ -97,7 +97,7 @@
// Implicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: closureToString:[exact=JSString]*/
+/*member: closureToString:[exact=JSString]*/
closureToString() {
var local = /*[null]*/ () {};
local();
@@ -108,7 +108,7 @@
// Explicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: closureCallToString:[exact=JSString]*/
+/*member: closureCallToString:[exact=JSString]*/
closureCallToString() {
var local = /*[null]*/ () {};
local.call();
@@ -119,13 +119,13 @@
// Operator == on the result of a parameter invocation.
////////////////////////////////////////////////////////////////////////////////
-/*element: _callCompare:[subclass=Closure]*/
+/*member: _callCompare:[subclass=Closure]*/
_callCompare(int /*[subclass=Closure]*/ compare({a, b})) {
compare(a: 0, b: 1) /*invoke: [null|subclass=JSInt]*/ == 0;
return compare;
}
-/*element: callCompare:[null]*/
+/*member: callCompare:[null]*/
callCompare() {
_callCompare(/*[subclass=JSInt]*/
({/*[exact=JSUInt31]*/ a, /*[exact=JSUInt31]*/ b}) =>
@@ -136,19 +136,19 @@
// Invocation on the result of a parameter invocation.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.method1:[null]*/
+ /*member: Class1.method1:[null]*/
method1() {}
}
-/*element: _callClosure:[subclass=Closure]*/
+/*member: _callClosure:[subclass=Closure]*/
_callClosure(/*[subclass=Closure]*/ f({c})) {
f(c: new Class1()).method1();
return f;
}
-/*element: callClosure:[null]*/
+/*member: callClosure:[null]*/
callClosure() {
_callClosure(/*[exact=Class1]*/ ({/*[exact=Class1]*/ c}) => c);
}
diff --git a/tests/compiler/dart2js/inference/data/local_functions_call.dart b/tests/compiler/dart2js/inference/data/local_functions_call.dart
index 586bf73..42cc5b1 100644
--- a/tests/compiler/dart2js/inference/data/local_functions_call.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions_call.dart
@@ -6,7 +6,7 @@
// with a different expectancy because the closed world contains less '.call'
// methods.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closureCallToString();
}
@@ -15,7 +15,7 @@
// Explicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: closureCallToString:[exact=JSString]*/
+/*member: closureCallToString:[exact=JSString]*/
closureCallToString() {
var local = /*[null]*/ () {};
local.call();
diff --git a/tests/compiler/dart2js/inference/data/locals.dart b/tests/compiler/dart2js/inference/data/locals.dart
index 1e0839f..bf0f271 100644
--- a/tests/compiler/dart2js/inference/data/locals.dart
+++ b/tests/compiler/dart2js/inference/data/locals.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
uninitializedLocal();
initializedLocal();
@@ -15,33 +15,33 @@
complexAssignmentLocal();
}
-/*element: uninitializedLocal:[null]*/
+/*member: uninitializedLocal:[null]*/
uninitializedLocal() {
var local;
return local;
}
-/*element: initializedLocal:[exact=JSUInt31]*/
+/*member: initializedLocal:[exact=JSUInt31]*/
initializedLocal() {
var local = 0;
return local;
}
-/*element: updatedLocal:[exact=JSUInt31]*/
+/*member: updatedLocal:[exact=JSUInt31]*/
updatedLocal() {
var local2;
local2 = 0;
return local2;
}
-/*element: invokeLocal:[null]*/
+/*member: invokeLocal:[null]*/
invokeLocal() {
var local2 = 0;
local2. /*invoke: [exact=JSUInt31]*/ toString();
return null;
}
-/*element: postfixLocal:[null]*/
+/*member: postfixLocal:[null]*/
postfixLocal() {
// ignore: UNUSED_LOCAL_VARIABLE
var local2 = 0;
@@ -49,13 +49,13 @@
return null;
}
-/*element: postfixLocalUsed:[exact=JSUInt31]*/
+/*member: postfixLocalUsed:[exact=JSUInt31]*/
postfixLocalUsed() {
var local2 = 0;
return local2 /*invoke: [exact=JSUInt31]*/ ++;
}
-/*element: prefixLocal:[null]*/
+/*member: prefixLocal:[null]*/
prefixLocal() {
// ignore: UNUSED_LOCAL_VARIABLE
var local2 = 0;
@@ -63,13 +63,13 @@
return null;
}
-/*element: prefixLocalUsed:[subclass=JSUInt32]*/
+/*member: prefixLocalUsed:[subclass=JSUInt32]*/
prefixLocalUsed() {
var local2 = 0;
return /*invoke: [exact=JSUInt31]*/ ++local2;
}
-/*element: complexAssignmentLocal:[subclass=JSUInt32]*/
+/*member: complexAssignmentLocal:[subclass=JSUInt32]*/
complexAssignmentLocal() {
var local2 = 0;
return local2 /*invoke: [exact=JSUInt31]*/ += 42;
diff --git a/tests/compiler/dart2js/inference/data/locals_trust.dart b/tests/compiler/dart2js/inference/data/locals_trust.dart
index e57e350..0580621 100644
--- a/tests/compiler/dart2js/inference/data/locals_trust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_trust.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
trustLocals();
trustFunctions();
@@ -13,13 +13,13 @@
// Test that we trust the explicit type of a local.
////////////////////////////////////////////////////////////////////////////////
-/*element: _trustLocals:[exact=JSBool]*/ _trustLocals(
+/*member: _trustLocals:[exact=JSBool]*/ _trustLocals(
int Function(int) /*[null|subclass=Closure]*/ f) {
int c = f(0);
return c /*invoke: [null|subclass=JSInt]*/ == 0;
}
-/*element: trustLocals:[null]*/
+/*member: trustLocals:[null]*/
trustLocals() {
_trustLocals(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
_trustLocals(null);
@@ -29,14 +29,14 @@
// Test that we infer the type of a dynamic local from the type of the function.
////////////////////////////////////////////////////////////////////////////////
-/*element: _trustFunctions:[exact=JSBool]*/
+/*member: _trustFunctions:[exact=JSBool]*/
_trustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
dynamic c = f(0);
c = f(0);
return c /*invoke: [null|subclass=JSInt]*/ == 0;
}
-/*element: trustFunctions:[null]*/
+/*member: trustFunctions:[null]*/
trustFunctions() {
_trustFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
_trustFunctions(null);
@@ -46,13 +46,13 @@
// Test that we infer the type of a 'var' local from the type of the function.
////////////////////////////////////////////////////////////////////////////////
-/*element: _inferFromFunctions:[exact=JSBool]*/
+/*member: _inferFromFunctions:[exact=JSBool]*/
_inferFromFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
var c = f(0);
return c /*invoke: [null|subclass=JSInt]*/ == 0;
}
-/*element: inferFromFunctions:[null]*/
+/*member: inferFromFunctions:[null]*/
inferFromFunctions() {
_inferFromFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
_inferFromFunctions(null);
diff --git a/tests/compiler/dart2js/inference/data/logical.dart b/tests/compiler/dart2js/inference/data/logical.dart
index 6a60279..ed24935 100644
--- a/tests/compiler/dart2js/inference/data/logical.dart
+++ b/tests/compiler/dart2js/inference/data/logical.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnTrue();
returnFalse();
@@ -43,24 +43,24 @@
/// Return `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnTrue:Value([exact=JSBool], value: true)*/
+/*member: returnTrue:Value([exact=JSBool], value: true)*/
returnTrue() => true;
////////////////////////////////////////////////////////////////////////////////
/// Return `false`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnFalse:Value([exact=JSBool], value: false)*/
+/*member: returnFalse:Value([exact=JSBool], value: false)*/
returnFalse() => false;
////////////////////////////////////////////////////////////////////////////////
/// Return negation of a boolean value.
////////////////////////////////////////////////////////////////////////////////
-/*element: _returnNot:[exact=JSBool]*/
+/*member: _returnNot:[exact=JSBool]*/
_returnNot(/*[exact=JSBool]*/ o) => !o;
-/*element: returnNot:[null]*/
+/*member: returnNot:[null]*/
returnNot() {
_returnNot(true);
_returnNot(false);
@@ -70,30 +70,30 @@
/// Return negation of `false`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotFalse:[exact=JSBool]*/
+/*member: returnNotFalse:[exact=JSBool]*/
returnNotFalse() => !false;
////////////////////////////////////////////////////////////////////////////////
/// Return negation of `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotTrue:[exact=JSBool]*/
+/*member: returnNotTrue:[exact=JSBool]*/
returnNotTrue() => !true;
////////////////////////////////////////////////////////////////////////////////
/// Return negation of `null`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotOfNull:[exact=JSBool]*/
+/*member: returnNotOfNull:[exact=JSBool]*/
returnNotOfNull() => !null;
////////////////////////////////////////////////////////////////////////////////
/// Return value of an is test.
////////////////////////////////////////////////////////////////////////////////
-/*element: _returnIs:[exact=JSBool]*/
+/*member: _returnIs:[exact=JSBool]*/
_returnIs(/*[null|exact=JSUInt31]*/ o) => o is int;
-/*element: returnIs:[null]*/
+/*member: returnIs:[null]*/
returnIs() {
_returnIs(null);
_returnIs(1);
@@ -102,22 +102,22 @@
////////////////////////////////////////////////////////////////////////////////
/// Return value of an is `int` test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnIsOneInt:[exact=JSBool]*/
+/*member: returnIsOneInt:[exact=JSBool]*/
returnIsOneInt() => 1 is int;
////////////////////////////////////////////////////////////////////////////////
/// Return value of an is `int` test known to be false.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnIsNullInt:[exact=JSBool]*/
+/*member: returnIsNullInt:[exact=JSBool]*/
returnIsNullInt() => null is int;
////////////////////////////////////////////////////////////////////////////////
/// Return value of a negated is test.
////////////////////////////////////////////////////////////////////////////////
-/*element: _returnNotIs:[exact=JSBool]*/
+/*member: _returnNotIs:[exact=JSBool]*/
_returnNotIs(/*[null|exact=JSUInt31]*/ o) => o is! int;
-/*element: returnNotIs:[null]*/
+/*member: returnNotIs:[null]*/
returnNotIs() {
_returnNotIs(null);
_returnNotIs(1);
@@ -126,23 +126,23 @@
////////////////////////////////////////////////////////////////////////////////
/// Return value of a negated is `int` test known to be false.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotIsOneInt:[exact=JSBool]*/
+/*member: returnNotIsOneInt:[exact=JSBool]*/
returnNotIsOneInt() => 1 is! int;
////////////////////////////////////////////////////////////////////////////////
/// Return value of a negated is `int` test known to be true.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotIsNullInt:[exact=JSBool]*/
+/*member: returnNotIsNullInt:[exact=JSBool]*/
returnNotIsNullInt() => null is! int;
////////////////////////////////////////////////////////////////////////////////
/// Return logical and of booleans values.
////////////////////////////////////////////////////////////////////////////////
-/*element: _returnLogicalAnd:[exact=JSBool]*/
+/*member: _returnLogicalAnd:[exact=JSBool]*/
_returnLogicalAnd(/*[exact=JSBool]*/ a, /*[exact=JSBool]*/ b) => a && b;
-/*element: returnLogicalAnd:[null]*/
+/*member: returnLogicalAnd:[null]*/
returnLogicalAnd() {
_returnLogicalAnd(true, true);
_returnLogicalAnd(false, false);
@@ -152,14 +152,14 @@
/// Return logical and of `true` && `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalAndTrueTrue:[exact=JSBool]*/
+/*member: returnLogicalAndTrueTrue:[exact=JSBool]*/
returnLogicalAndTrueTrue() => true && true;
////////////////////////////////////////////////////////////////////////////////
/// Return logical and of `false` && `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalAndFalseTrue:[exact=JSBool]*/
+/*member: returnLogicalAndFalseTrue:[exact=JSBool]*/
/// ignore: dead_code
returnLogicalAndFalseTrue() => false && true;
@@ -167,25 +167,25 @@
/// Return logical and of `null` && `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalAndNullTrue:[exact=JSBool]*/
+/*member: returnLogicalAndNullTrue:[exact=JSBool]*/
returnLogicalAndNullTrue() => null && true;
////////////////////////////////////////////////////////////////////////////////
/// Return logical and of is test and use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:Value([exact=JSBool], value: true)*/
+ /*member: Class1.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalAndIs:[exact=JSBool]*/
+/*member: _returnLogicalAndIs:[exact=JSBool]*/
_returnLogicalAndIs(/*[null|exact=Class1]*/ o) {
return o is Class1 && o. /*[exact=Class1]*/ field;
}
-/*element: returnLogicalAndIs:[null]*/
+/*member: returnLogicalAndIs:[null]*/
returnLogicalAndIs() {
_returnLogicalAndIs(new Class1());
_returnLogicalAndIs(null);
@@ -195,20 +195,20 @@
/// Return logical and of is-not test and use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:Value([exact=JSBool], value: true)*/
+ /*member: Class2.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalAndIsNot:[exact=JSBool]*/
+/*member: _returnLogicalAndIsNot:[exact=JSBool]*/
_returnLogicalAndIsNot(/*[null|exact=Class2]*/ o) {
// TODO(johnniwinther): Use negative type knowledge to show that the receiver
// is [null].
return o is! Class2 && o. /*[null|exact=Class2]*/ field;
}
-/*element: returnLogicalAndIsNot:[null]*/
+/*member: returnLogicalAndIsNot:[null]*/
returnLogicalAndIsNot() {
_returnLogicalAndIsNot(new Class2());
_returnLogicalAndIsNot(null);
@@ -218,18 +218,18 @@
/// Return logical and of null test and use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.field:Value([exact=JSBool], value: true)*/
+ /*member: Class3.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalAndNull:[exact=JSBool]*/
+/*member: _returnLogicalAndNull:[exact=JSBool]*/
_returnLogicalAndNull(/*[null|exact=Class3]*/ o) {
return o == null && o. /*[null]*/ field;
}
-/*element: returnLogicalAndNull:[null]*/
+/*member: returnLogicalAndNull:[null]*/
returnLogicalAndNull() {
_returnLogicalAndNull(new Class3());
_returnLogicalAndNull(null);
@@ -239,18 +239,18 @@
/// Return logical and of not null test and use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field:Value([exact=JSBool], value: true)*/
+ /*member: Class4.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalAndNotNull:[exact=JSBool]*/
+/*member: _returnLogicalAndNotNull:[exact=JSBool]*/
_returnLogicalAndNotNull(/*[null|exact=Class4]*/ o) {
return o != null && o. /*[exact=Class4]*/ field;
}
-/*element: returnLogicalAndNotNull:[null]*/
+/*member: returnLogicalAndNotNull:[null]*/
returnLogicalAndNotNull() {
_returnLogicalAndNotNull(new Class4());
_returnLogicalAndNotNull(null);
@@ -260,10 +260,10 @@
/// Return logical or of booleans values.
////////////////////////////////////////////////////////////////////////////////
-/*element: _returnLogicalOr:[exact=JSBool]*/
+/*member: _returnLogicalOr:[exact=JSBool]*/
_returnLogicalOr(/*[exact=JSBool]*/ a, /*[exact=JSBool]*/ b) => a || b;
-/*element: returnLogicalOr:[null]*/
+/*member: returnLogicalOr:[null]*/
returnLogicalOr() {
_returnLogicalOr(true, true);
_returnLogicalOr(false, false);
@@ -273,41 +273,41 @@
/// Return logical or of `false` || `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalOrFalseTrue:[exact=JSBool]*/
+/*member: returnLogicalOrFalseTrue:[exact=JSBool]*/
returnLogicalOrFalseTrue() => false || true;
////////////////////////////////////////////////////////////////////////////////
/// Return logical or of `false` || `false`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalOrFalseFalse:[exact=JSBool]*/
+/*member: returnLogicalOrFalseFalse:[exact=JSBool]*/
returnLogicalOrFalseFalse() => false || false;
////////////////////////////////////////////////////////////////////////////////
/// Return logical or of `null` || `true`.
////////////////////////////////////////////////////////////////////////////////
-/*element: returnLogicalOrNullTrue:[exact=JSBool]*/
+/*member: returnLogicalOrNullTrue:[exact=JSBool]*/
returnLogicalOrNullTrue() => null || true;
////////////////////////////////////////////////////////////////////////////////
/// Return logical or of is test or use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
class Class5 {
- /*element: Class5.field:Value([exact=JSBool], value: true)*/
+ /*member: Class5.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalOrIs:[exact=JSBool]*/
+/*member: _returnLogicalOrIs:[exact=JSBool]*/
_returnLogicalOrIs(/*[null|exact=Class5]*/ o) {
// TODO(johnniwinther): Use negative type knowledge to show that the receiver
// is [null].
return o is Class5 || o. /*[null|exact=Class5]*/ field;
}
-/*element: returnLogicalOrIs:[null]*/
+/*member: returnLogicalOrIs:[null]*/
returnLogicalOrIs() {
_returnLogicalOrIs(new Class5());
_returnLogicalOrIs(null);
@@ -317,18 +317,18 @@
/// Return logical or of is-not test or use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
class Class6 {
- /*element: Class6.field:Value([exact=JSBool], value: true)*/
+ /*member: Class6.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalOrIsNot:[exact=JSBool]*/
+/*member: _returnLogicalOrIsNot:[exact=JSBool]*/
_returnLogicalOrIsNot(/*[null|exact=Class6]*/ o) {
return o is! Class6 || o. /*[exact=Class6]*/ field;
}
-/*element: returnLogicalOrIsNot:[null]*/
+/*member: returnLogicalOrIsNot:[null]*/
returnLogicalOrIsNot() {
_returnLogicalOrIsNot(new Class6());
_returnLogicalOrIsNot(null);
@@ -338,18 +338,18 @@
/// Return logical or of null test or use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
class Class7 {
- /*element: Class7.field:Value([exact=JSBool], value: true)*/
+ /*member: Class7.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalOrNull:[exact=JSBool]*/
+/*member: _returnLogicalOrNull:[exact=JSBool]*/
_returnLogicalOrNull(/*[null|exact=Class7]*/ o) {
return o == null || o. /*[exact=Class7]*/ field;
}
-/*element: returnLogicalOrNull:[null]*/
+/*member: returnLogicalOrNull:[null]*/
returnLogicalOrNull() {
_returnLogicalOrNull(new Class7());
_returnLogicalOrNull(null);
@@ -359,18 +359,18 @@
/// Return logical or of not null test or use.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
class Class8 {
- /*element: Class8.field:Value([exact=JSBool], value: true)*/
+ /*member: Class8.field:Value([exact=JSBool], value: true)*/
final bool field = true;
}
-/*element: _returnLogicalOrNotNull:[exact=JSBool]*/
+/*member: _returnLogicalOrNotNull:[exact=JSBool]*/
_returnLogicalOrNotNull(/*[null|exact=Class8]*/ o) {
return o != null || o. /*[null]*/ field;
}
-/*element: returnLogicalOrNotNull:[null]*/
+/*member: returnLogicalOrNotNull:[null]*/
returnLogicalOrNotNull() {
_returnLogicalOrNotNull(new Class8());
_returnLogicalOrNotNull(null);
diff --git a/tests/compiler/dart2js/inference/data/logical_if.dart b/tests/compiler/dart2js/inference/data/logical_if.dart
index a950eb5..ba19f3a 100644
--- a/tests/compiler/dart2js/inference/data/logical_if.dart
+++ b/tests/compiler/dart2js/inference/data/logical_if.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
promotedIfThen();
promotedIfThenElse();
@@ -30,17 +30,17 @@
// Test if-then statement with is-test
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {}
-/*element: _promotedIfThen:[null]*/
+/*member: _promotedIfThen:[null]*/
_promotedIfThen(/*Union([exact=Class1], [exact=JSUInt31])*/ o) {
if (o is Class1) {
o. /*invoke: [exact=Class1]*/ toString();
}
}
-/*element: promotedIfThen:[null]*/
+/*member: promotedIfThen:[null]*/
promotedIfThen() {
_promotedIfThen(0);
_promotedIfThen(new Class1());
@@ -50,10 +50,10 @@
// Test if-then-else statement with is-test
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {}
-/*element: _promotedIfThenElse:[null]*/
+/*member: _promotedIfThenElse:[null]*/
_promotedIfThenElse(/*Union([exact=Class2], [exact=JSUInt31])*/ o) {
if (o is Class2) {
o. /*invoke: [exact=Class2]*/ toString();
@@ -64,7 +64,7 @@
}
}
-/*element: promotedIfThenElse:[null]*/
+/*member: promotedIfThenElse:[null]*/
promotedIfThenElse() {
_promotedIfThenElse(0);
_promotedIfThenElse(new Class2());
@@ -74,10 +74,10 @@
// Test if-then-else statement with negated is-test
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {}
-/*element: _promotedNotIfThenElse:[null]*/
+/*member: _promotedNotIfThenElse:[null]*/
_promotedNotIfThenElse(/*Union([exact=Class3], [exact=JSUInt31])*/ o) {
if (o is! Class3) {
o. /*invoke: Union([exact=Class3], [exact=JSUInt31])*/ toString();
@@ -86,7 +86,7 @@
}
}
-/*element: promotedNotIfThenElse:[null]*/
+/*member: promotedNotIfThenElse:[null]*/
promotedNotIfThenElse() {
_promotedNotIfThenElse(0);
_promotedNotIfThenElse(new Class3());
@@ -96,10 +96,10 @@
// Test if-then statement with is-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {}
-/*element: _promotedAndIfThen:[null]*/
+/*member: _promotedAndIfThen:[null]*/
_promotedAndIfThen(
/*Union([exact=Class4], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -108,7 +108,7 @@
}
}
-/*element: promotedAndIfThen:[null]*/
+/*member: promotedAndIfThen:[null]*/
promotedAndIfThen() {
_promotedAndIfThen(0, true);
_promotedAndIfThen(new Class4(), false);
@@ -118,10 +118,10 @@
// Test if-then-else statement with is-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
class Class5 {}
-/*element: _promotedAndIfThenElse:[null]*/
+/*member: _promotedAndIfThenElse:[null]*/
_promotedAndIfThenElse(
/*Union([exact=Class5], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -134,7 +134,7 @@
}
}
-/*element: promotedAndIfThenElse:[null]*/
+/*member: promotedAndIfThenElse:[null]*/
promotedAndIfThenElse() {
_promotedAndIfThenElse(0, true);
_promotedAndIfThenElse(new Class5(), false);
@@ -144,10 +144,10 @@
// Test if-then-else statement with negated is-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
class Class6 {}
-/*element: _promotedNotAndIfThenElse:[null]*/
+/*member: _promotedNotAndIfThenElse:[null]*/
_promotedNotAndIfThenElse(
/*Union([exact=Class6], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -158,7 +158,7 @@
}
}
-/*element: promotedNotAndIfThenElse:[null]*/
+/*member: promotedNotAndIfThenElse:[null]*/
promotedNotAndIfThenElse() {
_promotedNotAndIfThenElse(0, true);
_promotedNotAndIfThenElse(new Class6(), false);
@@ -168,10 +168,10 @@
// Test if-then statement with is-test in ||
////////////////////////////////////////////////////////////////////////////////
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
class Class7 {}
-/*element: _promotedOrIfThen:[null]*/
+/*member: _promotedOrIfThen:[null]*/
_promotedOrIfThen(
/*Union([exact=Class7], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -180,7 +180,7 @@
}
}
-/*element: promotedOrIfThen:[null]*/
+/*member: promotedOrIfThen:[null]*/
promotedOrIfThen() {
_promotedOrIfThen(0, true);
_promotedOrIfThen(new Class7(), false);
@@ -190,10 +190,10 @@
// Test if-then-else statement with is-test in ||
////////////////////////////////////////////////////////////////////////////////
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
class Class8 {}
-/*element: _promotedOrIfThenElse:[null]*/
+/*member: _promotedOrIfThenElse:[null]*/
_promotedOrIfThenElse(
/*Union([exact=Class8], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -206,7 +206,7 @@
}
}
-/*element: promotedOrIfThenElse:[null]*/
+/*member: promotedOrIfThenElse:[null]*/
promotedOrIfThenElse() {
_promotedOrIfThenElse(0, true);
_promotedOrIfThenElse(new Class8(), false);
@@ -216,10 +216,10 @@
// Test if-then-else statement with negated is-test in ||
////////////////////////////////////////////////////////////////////////////////
-/*element: Class9.:[exact=Class9]*/
+/*member: Class9.:[exact=Class9]*/
class Class9 {}
-/*element: _promotedNotOrIfThenElse:[null]*/
+/*member: _promotedNotOrIfThenElse:[null]*/
_promotedNotOrIfThenElse(
/*Union([exact=Class9], [exact=JSUInt31])*/ o,
/*[exact=JSBool]*/ c) {
@@ -230,7 +230,7 @@
}
}
-/*element: promotedNotOrIfThenElse:[null]*/
+/*member: promotedNotOrIfThenElse:[null]*/
promotedNotOrIfThenElse() {
_promotedNotOrIfThenElse(0, true);
_promotedNotOrIfThenElse(new Class9(), false);
@@ -240,10 +240,10 @@
// Test if-then statement with doubly negated is-test
////////////////////////////////////////////////////////////////////////////////
-/*element: Class10.:[exact=Class10]*/
+/*member: Class10.:[exact=Class10]*/
class Class10 {}
-/*element: _promotedNotNotIfThen:[null]*/
+/*member: _promotedNotNotIfThen:[null]*/
_promotedNotNotIfThen(/*Union([exact=Class10], [exact=JSUInt31])*/ o) {
if (!(o is! Class10)) {
o
@@ -253,7 +253,7 @@
}
}
-/*element: promotedNotNotIfThen:[null]*/
+/*member: promotedNotNotIfThen:[null]*/
promotedNotNotIfThen() {
_promotedNotNotIfThen(0);
_promotedNotNotIfThen(new Class10());
@@ -263,10 +263,10 @@
// Test if-then-else statement with negated is-test in parentheses
////////////////////////////////////////////////////////////////////////////////
-/*element: Class11.:[exact=Class11]*/
+/*member: Class11.:[exact=Class11]*/
class Class11 {}
-/*element: _promotedParenNotIfThenElse:[null]*/
+/*member: _promotedParenNotIfThenElse:[null]*/
_promotedParenNotIfThenElse(
/*Union([exact=Class11], [exact=JSUInt31])*/ o) {
if (!(o is Class11)) {
@@ -281,7 +281,7 @@
}
}
-/*element: promotedParenNotIfThenElse:[null]*/
+/*member: promotedParenNotIfThenElse:[null]*/
promotedParenNotIfThenElse() {
_promotedParenNotIfThenElse(0);
_promotedParenNotIfThenElse(new Class11());
@@ -291,14 +291,14 @@
// Test if-then statement with null-test
////////////////////////////////////////////////////////////////////////////////
-/*element: _nullIfThen:[null]*/
+/*member: _nullIfThen:[null]*/
_nullIfThen(/*[null|exact=JSUInt31]*/ o) {
if (o == null) {
o. /*invoke: [null]*/ toString();
}
}
-/*element: nullIfThen:[null]*/
+/*member: nullIfThen:[null]*/
nullIfThen() {
_nullIfThen(0);
_nullIfThen(null);
@@ -308,7 +308,7 @@
// Test if-then-else statement null-test
////////////////////////////////////////////////////////////////////////////////
-/*element: _nullIfThenElse:[null]*/
+/*member: _nullIfThenElse:[null]*/
_nullIfThenElse(/*[null|exact=JSUInt31]*/ o) {
if (o == null) {
o. /*invoke: [null]*/ toString();
@@ -317,7 +317,7 @@
}
}
-/*element: nullIfThenElse:[null]*/
+/*member: nullIfThenElse:[null]*/
nullIfThenElse() {
_nullIfThenElse(0);
_nullIfThenElse(null);
@@ -327,14 +327,14 @@
// Test if-then statement with negated null-test
////////////////////////////////////////////////////////////////////////////////
-/*element: _notNullIfThen:[null]*/
+/*member: _notNullIfThen:[null]*/
_notNullIfThen(/*[null|exact=JSUInt31]*/ o) {
if (o != null) {
o. /*invoke: [exact=JSUInt31]*/ toString();
}
}
-/*element: notNullIfThen:[null]*/
+/*member: notNullIfThen:[null]*/
notNullIfThen() {
_notNullIfThen(0);
_notNullIfThen(null);
@@ -344,7 +344,7 @@
// Test if-then-else statement with negated null-test
////////////////////////////////////////////////////////////////////////////////
-/*element: _notNullIfThenElse:[null]*/
+/*member: _notNullIfThenElse:[null]*/
_notNullIfThenElse(/*[null|exact=JSUInt31]*/ o) {
if (o != null) {
o. /*invoke: [exact=JSUInt31]*/ toString();
@@ -353,7 +353,7 @@
}
}
-/*element: notNullIfThenElse:[null]*/
+/*member: notNullIfThenElse:[null]*/
notNullIfThenElse() {
_notNullIfThenElse(0);
_notNullIfThenElse(null);
@@ -363,14 +363,14 @@
// Test if-then statement with null-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: _nullAndIfThen:[null]*/
+/*member: _nullAndIfThen:[null]*/
_nullAndIfThen(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
if (o == null && c) {
o. /*invoke: [null]*/ toString();
}
}
-/*element: nullAndIfThen:[null]*/
+/*member: nullAndIfThen:[null]*/
nullAndIfThen() {
_nullAndIfThen(0, true);
_nullAndIfThen(null, false);
@@ -380,7 +380,7 @@
// Test if-then-else statement null-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: _nullAndIfThenElse:[null]*/
+/*member: _nullAndIfThenElse:[null]*/
_nullAndIfThenElse(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
if (o == null && c) {
o. /*invoke: [null]*/ toString();
@@ -389,7 +389,7 @@
}
}
-/*element: nullAndIfThenElse:[null]*/
+/*member: nullAndIfThenElse:[null]*/
nullAndIfThenElse() {
_nullAndIfThenElse(0, true);
_nullAndIfThenElse(null, false);
@@ -399,14 +399,14 @@
// Test if-then statement with negated null-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: _notNullAndIfThen:[null]*/
+/*member: _notNullAndIfThen:[null]*/
_notNullAndIfThen(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
if (o != null && c) {
o. /*invoke: [exact=JSUInt31]*/ toString();
}
}
-/*element: notNullAndIfThen:[null]*/
+/*member: notNullAndIfThen:[null]*/
notNullAndIfThen() {
_notNullAndIfThen(0, true);
_notNullAndIfThen(null, false);
@@ -416,7 +416,7 @@
// Test if-then-else statement with negated null-test in &&
////////////////////////////////////////////////////////////////////////////////
-/*element: _notNullAndIfThenElse:[null]*/
+/*member: _notNullAndIfThenElse:[null]*/
_notNullAndIfThenElse(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
if (o != null && c) {
o. /*invoke: [exact=JSUInt31]*/ toString();
@@ -425,7 +425,7 @@
}
}
-/*element: notNullAndIfThenElse:[null]*/
+/*member: notNullAndIfThenElse:[null]*/
notNullAndIfThenElse() {
_notNullAndIfThenElse(0, true);
_notNullAndIfThenElse(null, false);
diff --git a/tests/compiler/dart2js/inference/data/map.dart b/tests/compiler/dart2js/inference/data/map.dart
index 52931ef..bef703b 100644
--- a/tests/compiler/dart2js/inference/data/map.dart
+++ b/tests/compiler/dart2js/inference/data/map.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
emptyMap();
nullMap();
@@ -14,26 +14,26 @@
constIntStringMap();
}
-/*element: emptyMap:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: emptyMap:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
emptyMap() => {};
-/*element: constMap:Dictionary([subclass=ConstantMap], key: [empty], value: [null], map: {})*/
+/*member: constMap:Dictionary([subclass=ConstantMap], key: [empty], value: [null], map: {})*/
constMap() => const {};
-/*element: nullMap:Map([subclass=JsLinkedHashMap], key: [null], value: [null])*/
+/*member: nullMap:Map([subclass=JsLinkedHashMap], key: [null], value: [null])*/
nullMap() => {null: null};
-/*element: constNullMap:Map([subclass=ConstantMap], key: [null], value: [null])*/
+/*member: constNullMap:Map([subclass=ConstantMap], key: [null], value: [null])*/
constNullMap() => const {null: null};
-/*element: stringIntMap:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
+/*member: stringIntMap:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
stringIntMap() => {'a': 1, 'b': 2, 'c': 3};
-/*element: intStringMap:Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
+/*member: intStringMap:Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
intStringMap() => {1: 'a', 2: 'b', 3: 'c'};
-/*element: constStringIntMap:Dictionary([subclass=ConstantMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
+/*member: constStringIntMap:Dictionary([subclass=ConstantMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
constStringIntMap() => const {'a': 1, 'b': 2, 'c': 3};
-/*element: constIntStringMap:Map([subclass=ConstantMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
+/*member: constIntStringMap:Map([subclass=ConstantMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
constIntStringMap() => const {1: 'a', 2: 'b', 3: 'c'};
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 3ee2393..42a1d9f 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.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.
-/*element: closure:[exact=JSUInt31]*/
+/*member: closure:[exact=JSUInt31]*/
int closure(
int
/*strong.Union([exact=JSDouble], [exact=JSUInt31])*/
@@ -14,18 +14,18 @@
}
class A {
- /*strong.element: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
- /*omit.element: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+ /*strong.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+ /*omit.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
static const DEFAULT = const {'fun': closure};
- /*element: A.map:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+ /*member: A.map:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
final map;
- /*element: A.:[exact=A]*/
+ /*member: A.:[exact=A]*/
A([/*[null]*/ maparg]) : map = maparg == null ? DEFAULT : maparg;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
var a = new A();
a. /*[exact=A]*/ map
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_keys.dart b/tests/compiler/dart2js/inference/data/map_tracer_keys.dart
index 576a02a..2798d02 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_keys.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_keys.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
@@ -12,18 +12,18 @@
test6();
}
-/*element: aDouble1:[null|exact=JSDouble]*/
+/*member: aDouble1:[null|exact=JSDouble]*/
dynamic aDouble1 = 42.5;
-/*element: aList1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
dynamic aList1 = [42];
-/*element: consume1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume1(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
-/*element: test1:[null]*/
+/*member: test1:[null]*/
test1() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
@@ -43,18 +43,18 @@
consume1(aList1);
}
-/*element: aDouble2:[null|exact=JSDouble]*/
+/*member: aDouble2:[null|exact=JSDouble]*/
dynamic aDouble2 = 42.5;
-/*element: aList2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
dynamic aList2 = [42];
-/*element: consume2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume2(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
-/*element: test2:[null]*/
+/*member: test2:[null]*/
test2() {
dynamic theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
@@ -74,18 +74,18 @@
consume2(aList2);
}
-/*element: aDouble3:Union([exact=JSDouble], [null|exact=JSExtendableArray])*/
+/*member: aDouble3:Union([exact=JSDouble], [null|exact=JSExtendableArray])*/
dynamic aDouble3 = 42.5;
-/*element: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
dynamic aList3 = [42];
-/*element: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume3(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
-/*element: test3:[null]*/
+/*member: test3:[null]*/
test3() {
dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
@@ -105,18 +105,18 @@
consume3(aList3);
}
-/*element: aDouble4:[null|exact=JSDouble]*/
+/*member: aDouble4:[null|exact=JSDouble]*/
dynamic aDouble4 = 42.5;
-/*element: aList4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
dynamic aList4 = [42];
-/*element: consume4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume4(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
-/*element: test4:[null]*/
+/*member: test4:[null]*/
test4() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': 5.5};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
@@ -133,18 +133,18 @@
consume4(aList4);
}
-/*element: aDouble5:[null|exact=JSDouble]*/
+/*member: aDouble5:[null|exact=JSDouble]*/
dynamic aDouble5 = 42.5;
-/*element: aList5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
dynamic aList5 = [42];
-/*element: consume5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
consume5(
/*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
x;
-/*element: test5:[null]*/
+/*member: test5:[null]*/
test5() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, aList5: 5.5};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
@@ -161,17 +161,17 @@
consume5(aList5);
}
-/*element: aDouble6:Union([null|exact=JSDouble], [null|exact=JSExtendableArray])*/
+/*member: aDouble6:Union([null|exact=JSDouble], [null|exact=JSExtendableArray])*/
dynamic aDouble6 = 42.5;
-/*element: aList6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
dynamic aList6 = [42];
-/*element: consume6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume6(
/*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
-/*element: test6:[null]*/
+/*member: test6:[null]*/
test6() {
var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': aList6};
/*iterator: [exact=LinkedHashMapKeyIterable]*/
diff --git a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
index 909a33e..8528a7e 100644
--- a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
+++ b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
@@ -10,14 +10,14 @@
import '../libs/mixin_constructor_default_parameter_values_lib.dart';
class Mixin {
- /*element: Mixin.foo:[exact=JSString]*/
+ /*member: Mixin.foo:[exact=JSString]*/
String get foo => "Mixin:$this";
}
// ignore: MIXIN_HAS_NO_CONSTRUCTORS
class D = C with Mixin;
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
// ignore: NEW_WITH_UNDEFINED_CONSTRUCTOR
print(new D.a(42). /*[exact=D]*/ foo);
diff --git a/tests/compiler/dart2js/inference/data/narrowing.dart b/tests/compiler/dart2js/inference/data/narrowing.dart
index 4ab579c..ba26c79 100644
--- a/tests/compiler/dart2js/inference/data/narrowing.dart
+++ b/tests/compiler/dart2js/inference/data/narrowing.dart
@@ -5,75 +5,75 @@
/// Regression test for Issue #33761: is-checks and null-checks were assumed to
/// be true even in nested non-condition contexts.
-/*element: argIsNonNull1:[null]*/
+/*member: argIsNonNull1:[null]*/
argIsNonNull1(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull1:[null]*/
+/*member: nonNull1:[null]*/
void nonNull1() {
var x = 1;
if (x == null) return;
argIsNonNull1(x);
}
-/*element: argIsNonNull2:[null]*/
+/*member: argIsNonNull2:[null]*/
argIsNonNull2(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull2:[null]*/
+/*member: nonNull2:[null]*/
void nonNull2() {
var x = 1;
if ((x == null) /*invoke: [exact=JSBool]*/ == true) return;
argIsNonNull2(x);
}
-/*element: argIsNonNull3:[null]*/
+/*member: argIsNonNull3:[null]*/
argIsNonNull3(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull3:[null]*/
+/*member: nonNull3:[null]*/
void nonNull3() {
var x = 1;
if ((x == null) /*invoke: [exact=JSBool]*/ != false) return;
argIsNonNull3(x);
}
-/*element: argIsNonNull4:[null]*/
+/*member: argIsNonNull4:[null]*/
argIsNonNull4(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: discard:Value([exact=JSBool], value: false)*/
+/*member: discard:Value([exact=JSBool], value: false)*/
discard(/*[exact=JSBool]*/ x) => false;
-/*element: nonNull4:[null]*/
+/*member: nonNull4:[null]*/
void nonNull4() {
var x = 1;
if (discard(x != null)) return;
argIsNonNull4(x);
}
-/*element: argIsNonNull5:[null]*/
+/*member: argIsNonNull5:[null]*/
argIsNonNull5(/*[null|exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull5:[null]*/
+/*member: nonNull5:[null]*/
void nonNull5() {
var x = 1;
if (x != null ? false : false) return;
argIsNonNull5(x);
}
-/*element: argIsNonNull6:[null]*/
+/*member: argIsNonNull6:[null]*/
argIsNonNull6(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull6:[null]*/
+/*member: nonNull6:[null]*/
void nonNull6() {
var x = 1;
if ((/*[exact=JSBool]*/ (/*[exact=JSBool]*/ y) => y && false)(x != null))
@@ -81,12 +81,12 @@
argIsNonNull6(x);
}
-/*element: argIsNonNull7:[null]*/
+/*member: argIsNonNull7:[null]*/
argIsNonNull7(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull7:[null]*/
+/*member: nonNull7:[null]*/
void nonNull7() {
var f = false;
var x = 1;
@@ -94,12 +94,12 @@
argIsNonNull7(x);
}
-/*element: argIsNonNull8:[null]*/
+/*member: argIsNonNull8:[null]*/
argIsNonNull8(/*[exact=JSUInt31]*/ x) {
print('>> is null: ${x == null}');
}
-/*element: nonNull8:[null]*/
+/*member: nonNull8:[null]*/
void nonNull8() {
var f = false;
var x = 1;
@@ -107,7 +107,7 @@
argIsNonNull8(x);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
void main() {
nonNull1();
nonNull2();
diff --git a/tests/compiler/dart2js/inference/data/native.dart b/tests/compiler/dart2js/inference/data/native.dart
index e9ec7b9..a1bfd75 100644
--- a/tests/compiler/dart2js/inference/data/native.dart
+++ b/tests/compiler/dart2js/inference/data/native.dart
@@ -2,12 +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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
nativeMethod();
}
-/*element: nativeMethod:[null|subclass=Object]*/
+/*member: nativeMethod:[null|subclass=Object]*/
nativeMethod()
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
diff --git a/tests/compiler/dart2js/inference/data/native2.dart b/tests/compiler/dart2js/inference/data/native2.dart
index bae53e9..e9b712c 100644
--- a/tests/compiler/dart2js/inference/data/native2.dart
+++ b/tests/compiler/dart2js/inference/data/native2.dart
@@ -6,16 +6,16 @@
import 'dart:_foreign_helper' as foreign show JS;
import 'dart:html';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
createElement();
createRectangle();
}
-/*element: createElement:[null|subclass=Element]*/
+/*member: createElement:[null|subclass=Element]*/
Element createElement()
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
-/*element: createRectangle:[subclass=DomRectReadOnly]*/
+/*member: createRectangle:[subclass=DomRectReadOnly]*/
createRectangle() => foreign.JS('Rectangle', "#", null);
diff --git a/tests/compiler/dart2js/inference/data/native3.dart b/tests/compiler/dart2js/inference/data/native3.dart
index 73e458f..f2e7167 100644
--- a/tests/compiler/dart2js/inference/data/native3.dart
+++ b/tests/compiler/dart2js/inference/data/native3.dart
@@ -4,12 +4,12 @@
import 'dart:html';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
createRectangle();
}
-/*element: createRectangle:[null|subclass=DomRectReadOnly]*/
+/*member: createRectangle:[null|subclass=DomRectReadOnly]*/
Rectangle createRectangle()
// ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
native;
diff --git a/tests/compiler/dart2js/inference/data/new.dart b/tests/compiler/dart2js/inference/data/new.dart
index 35ad6d3..fb9e9ff 100644
--- a/tests/compiler/dart2js/inference/data/new.dart
+++ b/tests/compiler/dart2js/inference/data/new.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
generativeConstructorCall();
factoryConstructorCall1();
@@ -22,10 +22,10 @@
/// Call default constructor of a field-less class.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {}
-/*element: generativeConstructorCall:[exact=Class1]*/
+/*member: generativeConstructorCall:[exact=Class1]*/
generativeConstructorCall() => new Class1();
////////////////////////////////////////////////////////////////////////////////
@@ -33,11 +33,11 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.:[null]*/
+ /*member: Class2.:[null]*/
factory Class2() => null;
}
-/*element: factoryConstructorCall1:[null]*/
+/*member: factoryConstructorCall1:[null]*/
factoryConstructorCall1() => new Class2();
////////////////////////////////////////////////////////////////////////////////
@@ -45,13 +45,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.:[exact=Class3]*/
+ /*member: Class3.:[exact=Class3]*/
factory Class3() => new Class3.named();
- /*element: Class3.named:[exact=Class3]*/
+ /*member: Class3.named:[exact=Class3]*/
Class3.named();
}
-/*element: factoryConstructorCall2:[exact=Class3]*/
+/*member: factoryConstructorCall2:[exact=Class3]*/
factoryConstructorCall2() => new Class3();
////////////////////////////////////////////////////////////////////////////////
@@ -59,14 +59,14 @@
////////////////////////////////////////////////////////////////////////////////
class Class4a {
- /*element: Class4a.:[exact=Class4b]*/
+ /*member: Class4a.:[exact=Class4b]*/
factory Class4a() => new Class4b();
}
-/*element: Class4b.:[exact=Class4b]*/
+/*member: Class4b.:[exact=Class4b]*/
class Class4b implements Class4a {}
-/*element: factoryConstructorCall3:[exact=Class4b]*/
+/*member: factoryConstructorCall3:[exact=Class4b]*/
factoryConstructorCall3() => new Class4a();
////////////////////////////////////////////////////////////////////////////////
@@ -74,13 +74,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class5 {
- final /*element: Class5.field:[exact=JSUInt31]*/ field;
+ final /*member: Class5.field:[exact=JSUInt31]*/ field;
- /*element: Class5.:[exact=Class5]*/
+ /*member: Class5.:[exact=Class5]*/
Class5(this. /*[exact=JSUInt31]*/ field);
}
-/*element: classWithFinalFieldInitializer:[exact=Class5]*/
+/*member: classWithFinalFieldInitializer:[exact=Class5]*/
classWithFinalFieldInitializer() => new Class5(0);
////////////////////////////////////////////////////////////////////////////////
@@ -88,13 +88,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class6 {
- var /*element: Class6.field:[exact=JSUInt31]*/ field;
+ var /*member: Class6.field:[exact=JSUInt31]*/ field;
- /*element: Class6.:[exact=Class6]*/
+ /*member: Class6.:[exact=Class6]*/
Class6(this. /*[exact=JSUInt31]*/ field);
}
-/*element: classWithNonFinalFieldInitializer:[exact=Class6]*/
+/*member: classWithNonFinalFieldInitializer:[exact=Class6]*/
classWithNonFinalFieldInitializer() => new Class6(0);
////////////////////////////////////////////////////////////////////////////////
@@ -102,13 +102,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class7 {
- var /*element: Class7.field:[exact=JSUInt31]*/ field;
+ var /*member: Class7.field:[exact=JSUInt31]*/ field;
- /*element: Class7.:[exact=Class7]*/
+ /*member: Class7.:[exact=Class7]*/
Class7(/*[exact=JSUInt31]*/ value) : this.field = value;
}
-/*element: classWithExplicitFieldInitializer:[exact=Class7]*/
+/*member: classWithExplicitFieldInitializer:[exact=Class7]*/
classWithExplicitFieldInitializer() => new Class7(0);
////////////////////////////////////////////////////////////////////////////////
@@ -116,15 +116,15 @@
////////////////////////////////////////////////////////////////////////////////
class Class8 {
- var /*element: Class8.field:[exact=JSUInt31]*/ field;
+ var /*member: Class8.field:[exact=JSUInt31]*/ field;
- /*element: Class8.:[exact=Class8]*/
+ /*member: Class8.:[exact=Class8]*/
Class8(/*[exact=JSUInt31]*/ value) {
this. /*update: [exact=Class8]*/ field = value;
}
}
-/*element: classWithFieldInitializerInBody:[exact=Class8]*/
+/*member: classWithFieldInitializerInBody:[exact=Class8]*/
classWithFieldInitializerInBody() => new Class8(0);
////////////////////////////////////////////////////////////////////////////////
@@ -133,13 +133,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class9 {
- var /*element: Class9.field:[null]*/ field = null;
+ var /*member: Class9.field:[null]*/ field = null;
- /*element: Class9.:[exact=Class9]*/
+ /*member: Class9.:[exact=Class9]*/
Class9() {}
}
-/*element: classWithNullNoFieldInitializerInBody:[exact=Class9]*/
+/*member: classWithNullNoFieldInitializerInBody:[exact=Class9]*/
classWithNullNoFieldInitializerInBody() => new Class9();
////////////////////////////////////////////////////////////////////////////////
@@ -148,15 +148,15 @@
////////////////////////////////////////////////////////////////////////////////
class Class10 {
- var /*element: Class10.field:[exact=JSUInt31]*/ field = null;
+ var /*member: Class10.field:[exact=JSUInt31]*/ field = null;
- /*element: Class10.:[exact=Class10]*/
+ /*member: Class10.:[exact=Class10]*/
Class10(/*[exact=JSUInt31]*/ value) {
this. /*update: [exact=Class10]*/ field = value;
}
}
-/*element: classWithNullFieldInitializerInBody:[exact=Class10]*/
+/*member: classWithNullFieldInitializerInBody:[exact=Class10]*/
classWithNullFieldInitializerInBody() => new Class10(0);
////////////////////////////////////////////////////////////////////////////////
@@ -165,18 +165,18 @@
////////////////////////////////////////////////////////////////////////////////
class Class11 {
- var /*element: Class11.field:[null|exact=JSUInt31]*/ field = null;
+ var /*member: Class11.field:[null|exact=JSUInt31]*/ field = null;
- /*element: Class11.a:[exact=Class11]*/
+ /*member: Class11.a:[exact=Class11]*/
Class11.a(/*[exact=JSUInt31]*/ value) {
this. /*update: [exact=Class11]*/ field = value;
}
- /*element: Class11.b:[exact=Class11]*/
+ /*member: Class11.b:[exact=Class11]*/
Class11.b() {}
}
-/*element: classWithNullMaybeFieldInitializerInBody:[exact=Class11]*/
+/*member: classWithNullMaybeFieldInitializerInBody:[exact=Class11]*/
classWithNullMaybeFieldInitializerInBody() {
new Class11.a(0);
return new Class11.b();
@@ -187,13 +187,13 @@
////////////////////////////////////////////////////////////////////////////////
class Class12 {
- final /*element: Class12.field:[null]*/ field = null;
+ final /*member: Class12.field:[null]*/ field = null;
- /*element: Class12.:[exact=Class12]*/
+ /*member: Class12.:[exact=Class12]*/
Class12();
}
-/*element: classWithNullFinalFieldInitializer:[exact=Class12]*/
+/*member: classWithNullFinalFieldInitializer:[exact=Class12]*/
classWithNullFinalFieldInitializer() {
return new Class12();
}
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index 2803433..6fc1c46 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -1,4 +1,4 @@
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
missingGetter();
missingMethod();
@@ -10,9 +10,9 @@
// Access missing getter.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.noSuchMethod:[exact=JSUInt31]*/
+ /*member: Class1.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
/*strong.[null|subclass=Object]*/
@@ -22,23 +22,23 @@
_) =>
42;
- /*element: Class1.method:[exact=JSUInt31]*/
+ /*member: Class1.method:[exact=JSUInt31]*/
method() {
dynamic a = this;
return a. /*[exact=Class1]*/ missingGetter;
}
}
-/*element: missingGetter:[exact=JSUInt31]*/
+/*member: missingGetter:[exact=JSUInt31]*/
missingGetter() => new Class1(). /*invoke: [exact=Class1]*/ method();
////////////////////////////////////////////////////////////////////////////////
// Invoke missing method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.noSuchMethod:[exact=JSUInt31]*/
+ /*member: Class2.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
Invocation
/*strong.[null|subclass=Object]*/
@@ -48,23 +48,23 @@
_) =>
42;
- /*element: Class2.method:[exact=JSUInt31]*/
+ /*member: Class2.method:[exact=JSUInt31]*/
method() {
dynamic a = this;
return a. /*invoke: [exact=Class2]*/ missingMethod();
}
}
-/*element: missingMethod:[exact=JSUInt31]*/
+/*member: missingMethod:[exact=JSUInt31]*/
missingMethod() => new Class2(). /*invoke: [exact=Class2]*/ method();
////////////////////////////////////////////////////////////////////////////////
// Pass closure to missing method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.noSuchMethod:[null|subclass=Object]*/
+ /*member: Class3.noSuchMethod:[null|subclass=Object]*/
noSuchMethod(
Invocation
/*strong.[null|subclass=Object]*/
@@ -81,7 +81,7 @@
first;
}
- /*element: Class3.method:[null|subclass=Object]*/
+ /*member: Class3.method:[null|subclass=Object]*/
method() {
dynamic a = this;
return a. /*invoke: [exact=Class3]*/ missingMethod(
@@ -89,7 +89,7 @@
}
}
-/*element: closureThroughMissingMethod:[null|subclass=Object]*/
+/*member: closureThroughMissingMethod:[null|subclass=Object]*/
closureThroughMissingMethod() =>
new Class3(). /*invoke: [exact=Class3]*/ method();
@@ -97,12 +97,12 @@
// Pass closure to missing setter.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field:[null|subclass=Object]*/
+ /*member: Class4.field:[null|subclass=Object]*/
var field;
- /*element: Class4.noSuchMethod:[null]*/
+ /*member: Class4.noSuchMethod:[null]*/
noSuchMethod(
Invocation
/*strong.[null|subclass=Object]*/
@@ -120,7 +120,7 @@
return null;
}
- /*element: Class4.method:[null]*/
+ /*member: Class4.method:[null]*/
method() {
dynamic a = this;
a. /*update: [exact=Class4]*/ missingSetter =
@@ -129,6 +129,6 @@
}
}
-/*element: closureThroughMissingSetter:[null]*/
+/*member: closureThroughMissingSetter:[null]*/
closureThroughMissingSetter() =>
new Class4(). /*invoke: [exact=Class4]*/ method();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index eeaed0e..c80bfb6 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -2,9 +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.
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
- /*element: A.noSuchMethod:[exact=JSUInt31]*/
+ /*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
/*strong.[null|subclass=Object]*/
/*omit.[null|exact=JSInvocationMirror]*/
@@ -14,48 +14,48 @@
42;
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:[exact=JSUInt31]*/
+ /*member: B.foo:[exact=JSUInt31]*/
/*invoke: [subclass=B]*/ foo();
}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C extends B {
- /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
}
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
dynamic a = [new B(), new C()]
/*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
[0];
-/*element: test1:[exact=JSUInt31]*/
+/*member: test1:[exact=JSUInt31]*/
test1() {
dynamic e = new A();
return e. /*invoke: [exact=A]*/ foo();
}
-/*element: test2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
test2() => a. /*invoke: [null|subclass=B]*/ foo();
-/*element: test3:[exact=JSUInt31]*/
+/*member: test3:[exact=JSUInt31]*/
test3() => new B(). /*invoke: [exact=B]*/ foo();
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test4() => new C(). /*invoke: [exact=C]*/ foo();
-/*element: test5:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test5:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
test5() {
dynamic e = (a ? new A() : new B());
return e. /*invoke: [subclass=A]*/ foo();
}
-/*element: test6:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test6:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index 3bce145..45a3251 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -2,9 +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.
-/*element: A.:[subclass=B]*/
+/*member: A.:[subclass=B]*/
abstract class A {
- /*element: A.noSuchMethod:[exact=JSUInt31]*/
+ /*member: A.noSuchMethod:[exact=JSUInt31]*/
noSuchMethod(
/*strong.[null|subclass=Object]*/
/*omit.[null|exact=JSInvocationMirror]*/
@@ -14,24 +14,24 @@
42;
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C extends B {
- /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
}
-/*element: D.:[exact=D]*/
+/*member: D.:[exact=D]*/
class D implements A {
- /*element: D.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: D.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
- /*element: D.noSuchMethod:[exact=JSDouble]*/
+ /*member: D.noSuchMethod:[exact=JSDouble]*/
noSuchMethod(
/*strong.[null|subclass=Object]*/
/*omit.[null|exact=JSInvocationMirror]*/
@@ -41,67 +41,67 @@
42.5;
}
-/*element: a:Union([exact=D], [null|subclass=B])*/
+/*member: a:Union([exact=D], [null|subclass=B])*/
dynamic a = [new B(), new C(), new D()]
/*Container([exact=JSExtendableArray], element: Union([exact=D], [subclass=B]), length: 3)*/
[0];
-/*element: test1:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test1:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test1() => a. /*invoke: Union([exact=D], [null|subclass=B])*/ foo();
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test2() => new B(). /*invoke: [exact=B]*/ foo();
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test3() => new C(). /*invoke: [exact=C]*/ foo();
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test4() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test5() {
dynamic e = (a ? new B() : new D());
return e. /*invoke: Union([exact=B], [exact=D])*/ foo();
}
// Can hit A.noSuchMethod, D.noSuchMethod and Object.noSuchMethod.
-/*element: test6:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: test6:Union([exact=JSDouble], [exact=JSUInt31])*/
test6() => a. /*invoke: Union([exact=D], [null|subclass=B])*/ bar();
// Can hit A.noSuchMethod.
-/*element: test7:[exact=JSUInt31]*/
+/*member: test7:[exact=JSUInt31]*/
test7() {
dynamic e = new B();
return e. /*invoke: [exact=B]*/ bar();
}
-/*element: test8:[exact=JSUInt31]*/
+/*member: test8:[exact=JSUInt31]*/
test8() {
dynamic e = new C();
return e. /*invoke: [exact=C]*/ bar();
}
-/*element: test9:[exact=JSUInt31]*/
+/*member: test9:[exact=JSUInt31]*/
test9() {
dynamic e = (a ? new B() : new C());
return e. /*invoke: [subclass=B]*/ bar();
}
// Can hit A.noSuchMethod and D.noSuchMethod.
-/*element: test10:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: test10:Union([exact=JSDouble], [exact=JSUInt31])*/
test10() {
dynamic e = (a ? new B() : new D());
return e. /*invoke: Union([exact=B], [exact=D])*/ bar();
}
// Can hit D.noSuchMethod.
-/*element: test11:[exact=JSDouble]*/
+/*member: test11:[exact=JSDouble]*/
test11() {
dynamic e = new D();
return e. /*invoke: [exact=D]*/ bar();
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 07c56bd..0a41b65 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -2,11 +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.
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
// We may ignore this for type inference because syntactically it always
// throws an exception.
- /*element: A.noSuchMethod:[empty]*/
+ /*member: A.noSuchMethod:[empty]*/
noSuchMethod(
/*strong.[null|subclass=Object]*/
/*omit.[null|exact=JSInvocationMirror]*/
@@ -16,47 +16,47 @@
throw 'foo';
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C extends B {
- /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+ /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
foo() => {};
}
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
dynamic a = [new B(), new C()]
/*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
[0];
-/*element: test1:[empty]*/
+/*member: test1:[empty]*/
test1() {
dynamic e = new A();
return e. /*invoke: [exact=A]*/ foo();
}
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test2() => a. /*invoke: [null|subclass=B]*/ foo();
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test3() => new B(). /*invoke: [exact=B]*/ foo();
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test4() => new C(). /*invoke: [exact=C]*/ foo();
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test5() {
dynamic e = (a ? new A() : new B());
return e. /*invoke: [subclass=A]*/ foo();
}
-/*element: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method4.dart b/tests/compiler/dart2js/inference/data/no_such_method4.dart
index 13af644..7e489ec 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method4.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method4.dart
@@ -2,55 +2,55 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
// We may ignore this for type inference because it forwards to a default
// noSuchMethod implementation, which always throws an exception.
noSuchMethod(im) => super.noSuchMethod(im);
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+ /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
{};
}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C extends B {
- /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+ /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
{};
}
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
dynamic a = [new B(), new C()]
/*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
[0];
-/*element: test1:[empty]*/
+/*member: test1:[empty]*/
test1() {
dynamic e = new A();
return e. /*invoke: [exact=A]*/ foo();
}
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test2() => a. /*invoke: [null|subclass=B]*/ foo();
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test3() => new B(). /*invoke: [exact=B]*/ foo();
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test4() => new C(). /*invoke: [exact=C]*/ foo();
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test5() {
dynamic e = (a ? new A() : new B());
return e. /*invoke: [subclass=A]*/ foo();
}
-/*element: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
test1();
test2();
diff --git a/tests/compiler/dart2js/inference/data/non_null.dart b/tests/compiler/dart2js/inference/data/non_null.dart
index da87bbe..96be59d 100644
--- a/tests/compiler/dart2js/inference/data/non_null.dart
+++ b/tests/compiler/dart2js/inference/data/non_null.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
nonNullStaticField();
nonNullInstanceField1();
@@ -10,42 +10,42 @@
nonNullLocal();
}
-/*element: staticField:[null|exact=JSUInt31]*/
+/*member: staticField:[null|exact=JSUInt31]*/
var staticField;
-/*element: nonNullStaticField:[exact=JSUInt31]*/
+/*member: nonNullStaticField:[exact=JSUInt31]*/
nonNullStaticField() => staticField ??= 42;
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[null|exact=JSUInt31]*/
+ /*member: Class1.field:[null|exact=JSUInt31]*/
var field;
}
-/*element: nonNullInstanceField1:[exact=JSUInt31]*/
+/*member: nonNullInstanceField1:[exact=JSUInt31]*/
nonNullInstanceField1() {
return new Class1(). /*[exact=Class1]*/ /*update: [exact=Class1]*/ field ??=
42;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[null|exact=JSUInt31]*/
+ /*member: Class2.field:[null|exact=JSUInt31]*/
var field;
- /*element: Class2.method:[exact=JSUInt31]*/
+ /*member: Class2.method:[exact=JSUInt31]*/
method() {
return /*[exact=Class2]*/ /*update: [exact=Class2]*/ field ??= 42;
}
}
-/*element: nonNullInstanceField2:[exact=JSUInt31]*/
+/*member: nonNullInstanceField2:[exact=JSUInt31]*/
nonNullInstanceField2() {
return new Class2(). /*invoke: [exact=Class2]*/ method();
}
// TODO(johnniwinther): We should infer that the returned value cannot be null.
-/*element: nonNullLocal:[null|exact=JSUInt31]*/
+/*member: nonNullLocal:[null|exact=JSUInt31]*/
nonNullLocal() {
var local = null;
return local ??= 42;
diff --git a/tests/compiler/dart2js/inference/data/null.dart b/tests/compiler/dart2js/inference/data/null.dart
index 0a220f0..9e53378 100644
--- a/tests/compiler/dart2js/inference/data/null.dart
+++ b/tests/compiler/dart2js/inference/data/null.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
ifThenNullCheck(0);
ifThenNullCheck(null);
@@ -22,7 +22,7 @@
ifThenNotNullGradualCheck2(null, 0);
}
-/*element: ifThenNullCheck:[exact=JSUInt31]*/
+/*member: ifThenNullCheck:[exact=JSUInt31]*/
ifThenNullCheck(int /*[null|exact=JSUInt31]*/ value) {
if (value == null) {
return 0;
@@ -30,7 +30,7 @@
return value;
}
-/*element: ifThenElseNullCheck:[exact=JSUInt31]*/
+/*member: ifThenElseNullCheck:[exact=JSUInt31]*/
ifThenElseNullCheck(int /*[null|exact=JSUInt31]*/ value) {
if (value == null) {
return 0;
@@ -39,7 +39,7 @@
}
}
-/*element: ifNotThenNullCheck:[exact=JSUInt31]*/
+/*member: ifNotThenNullCheck:[exact=JSUInt31]*/
ifNotThenNullCheck(int /*[null|exact=JSUInt31]*/ value) {
if (value != null) {
return value;
@@ -47,7 +47,7 @@
return 0;
}
-/*element: ifNotThenElseNullCheck:[exact=JSUInt31]*/
+/*member: ifNotThenElseNullCheck:[exact=JSUInt31]*/
ifNotThenElseNullCheck(int /*[null|exact=JSUInt31]*/ value) {
if (value != null) {
return value;
@@ -56,7 +56,7 @@
}
}
-/*element: ifThenNotNullComplexCheck:[exact=JSUInt31]*/
+/*member: ifThenNotNullComplexCheck:[exact=JSUInt31]*/
ifThenNotNullComplexCheck(
int /*[null|exact=JSUInt31]*/ a, int /*[null|exact=JSUInt31]*/ b) {
if (a != null && a /*invoke: [exact=JSUInt31]*/ != b) {
@@ -65,7 +65,7 @@
return 0;
}
-/*element: ifThenElseNotNullComplexCheck:[null|exact=JSUInt31]*/
+/*member: ifThenElseNotNullComplexCheck:[null|exact=JSUInt31]*/
ifThenElseNotNullComplexCheck(
int /*[null|exact=JSUInt31]*/ a, int /*[null|exact=JSUInt31]*/ b) {
if (a != null && a /*invoke: [exact=JSUInt31]*/ != b) {
@@ -74,7 +74,7 @@
return a;
}
-/*element: ifThenNotNullGradualCheck1:[exact=JSUInt31]*/
+/*member: ifThenNotNullGradualCheck1:[exact=JSUInt31]*/
ifThenNotNullGradualCheck1(
int /*[null|exact=JSUInt31]*/ a, int /*[exact=JSUInt31]*/ b) {
if (a /*invoke: [null|exact=JSUInt31]*/ != b) {
@@ -85,7 +85,7 @@
return 0;
}
-/*element: ifThenNotNullGradualCheck2:[exact=JSUInt31]*/
+/*member: ifThenNotNullGradualCheck2:[exact=JSUInt31]*/
ifThenNotNullGradualCheck2(
int /*[null|exact=JSUInt31]*/ a, int /*[exact=JSUInt31]*/ b) {
if (a != null) {
diff --git a/tests/compiler/dart2js/inference/data/optimizer_hints.dart b/tests/compiler/dart2js/inference/data/optimizer_hints.dart
index 919332e..c51ce4f 100644
--- a/tests/compiler/dart2js/inference/data/optimizer_hints.dart
+++ b/tests/compiler/dart2js/inference/data/optimizer_hints.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
assumeDynamic();
notAssumeDynamic();
@@ -18,11 +18,11 @@
// the 'dynamic' type.
////////////////////////////////////////////////////////////////////////////////
-/*element: _assumeDynamic:[null|subclass=Object]*/
+/*member: _assumeDynamic:[null|subclass=Object]*/
@pragma('dart2js:assumeDynamic')
_assumeDynamic(/*[null|subclass=Object]*/ o) => o;
-/*element: assumeDynamic:[null]*/
+/*member: assumeDynamic:[null]*/
assumeDynamic() {
_assumeDynamic(0);
}
@@ -31,10 +31,10 @@
// As above but without the annotation.
////////////////////////////////////////////////////////////////////////////////
-/*element: _notAssumeDynamic:[exact=JSUInt31]*/
+/*member: _notAssumeDynamic:[exact=JSUInt31]*/
_notAssumeDynamic(/*[exact=JSUInt31]*/ o) => o;
-/*element: notAssumeDynamic:[null]*/
+/*member: notAssumeDynamic:[null]*/
notAssumeDynamic() {
_notAssumeDynamic(0);
}
@@ -43,7 +43,7 @@
// No annotation is needed to trust return type annotation.
////////////////////////////////////////////////////////////////////////////////
-/*element: trustReturnTypeString:[null|exact=JSString]*/
+/*member: trustReturnTypeString:[null|exact=JSString]*/
String trustReturnTypeString() {
return _assumeDynamic(0);
}
@@ -52,10 +52,10 @@
// No annotation is needed to trust parameter type annotation.
////////////////////////////////////////////////////////////////////////////////
-/*element: _trustParameterTypeString:[null]*/
+/*member: _trustParameterTypeString:[null]*/
_trustParameterTypeString(String /*[null|exact=JSString]*/ o) {}
-/*element: trustParameterTypeString:[null]*/
+/*member: trustParameterTypeString:[null]*/
trustParameterTypeString() {
_trustParameterTypeString(_assumeDynamic(0));
}
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index 27b45a3..e9b8e84 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -4,7 +4,7 @@
import 'package:expect/expect.dart';
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
trustParameters();
}
@@ -13,7 +13,7 @@
// Test that we trust the explicit type of a parameter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _trustParameters:[exact=JSUInt31]*/
+/*member: _trustParameters:[exact=JSUInt31]*/
_trustParameters(
int
/*strong.Union([exact=JSString], [exact=JSUInt31])*/
@@ -24,7 +24,7 @@
return i;
}
-/*element: trustParameters:[null]*/
+/*member: trustParameters:[null]*/
trustParameters() {
dynamic f = _trustParameters;
Expect.equals(0, f(0));
diff --git a/tests/compiler/dart2js/inference/data/postfix.dart b/tests/compiler/dart2js/inference/data/postfix.dart
index edd497f..8cba579 100644
--- a/tests/compiler/dart2js/inference/data/postfix.dart
+++ b/tests/compiler/dart2js/inference/data/postfix.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
localPostfixInc();
localPostfixDec();
@@ -18,7 +18,7 @@
// Postfix increment on local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: localPostfixInc:[exact=JSUInt31]*/
+/*member: localPostfixInc:[exact=JSUInt31]*/
localPostfixInc() {
var local;
if (local == null) {
@@ -31,7 +31,7 @@
// Postfix decrement on local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: localPostfixDec:[exact=JSUInt31]*/
+/*member: localPostfixDec:[exact=JSUInt31]*/
localPostfixDec() {
var local;
if (local == null) {
@@ -44,10 +44,10 @@
// Postfix increment on static field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _staticField1:[null|subclass=JSPositiveInt]*/
+/*member: _staticField1:[null|subclass=JSPositiveInt]*/
var _staticField1;
-/*element: staticFieldPostfixInc:[subclass=JSPositiveInt]*/
+/*member: staticFieldPostfixInc:[subclass=JSPositiveInt]*/
staticFieldPostfixInc() {
if (_staticField1 == null) {
_staticField1 = 0;
@@ -59,10 +59,10 @@
// Postfix decrement on static field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _staticField2:[null|subclass=JSInt]*/
+/*member: _staticField2:[null|subclass=JSInt]*/
var _staticField2;
-/*element: staticFieldPostfixDec:[subclass=JSInt]*/
+/*member: staticFieldPostfixDec:[subclass=JSInt]*/
staticFieldPostfixDec() {
if (_staticField2 == null) {
_staticField2 = 0;
@@ -74,13 +74,13 @@
// Postfix increment on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field1:[null|subclass=JSPositiveInt]*/
+ /*member: Class1.field1:[null|subclass=JSPositiveInt]*/
var field1;
}
-/*element: instanceFieldPostfixInc:[subclass=JSPositiveInt]*/
+/*member: instanceFieldPostfixInc:[subclass=JSPositiveInt]*/
instanceFieldPostfixInc() {
var c = new Class1();
if (c. /*[exact=Class1]*/ field1 == null) {
@@ -96,13 +96,13 @@
// Postfix decrement on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field2:[null|subclass=JSInt]*/
+ /*member: Class2.field2:[null|subclass=JSInt]*/
var field2;
}
-/*element: instanceFieldPostfixDec:[subclass=JSInt]*/
+/*member: instanceFieldPostfixDec:[subclass=JSInt]*/
instanceFieldPostfixDec() {
var c = new Class2();
if (c. /*[exact=Class2]*/ field2 == null) {
@@ -118,13 +118,13 @@
// Conditional postfix increment on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.field3:[null|subclass=JSPositiveInt]*/
+ /*member: Class3.field3:[null|subclass=JSPositiveInt]*/
var field3;
}
-/*element: conditionalInstanceFieldPostfixInc:[null|subclass=JSPositiveInt]*/
+/*member: conditionalInstanceFieldPostfixInc:[null|subclass=JSPositiveInt]*/
conditionalInstanceFieldPostfixInc() {
var c = new Class3();
if (c. /*[exact=Class3]*/ field3 == null) {
@@ -140,13 +140,13 @@
// Conditional postfix decrement on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field4:[null|subclass=JSInt]*/
+ /*member: Class4.field4:[null|subclass=JSInt]*/
var field4;
}
-/*element: conditionalInstanceFieldPostfixDec:[null|subclass=JSInt]*/
+/*member: conditionalInstanceFieldPostfixDec:[null|subclass=JSInt]*/
conditionalInstanceFieldPostfixDec() {
var c = new Class4();
if (c. /*[exact=Class4]*/ field4 == null) {
diff --git a/tests/compiler/dart2js/inference/data/postfix_prefix.dart b/tests/compiler/dart2js/inference/data/postfix_prefix.dart
index 92a47c2..9342997 100644
--- a/tests/compiler/dart2js/inference/data/postfix_prefix.dart
+++ b/tests/compiler/dart2js/inference/data/postfix_prefix.dart
@@ -2,49 +2,49 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: index:[empty]*/
+/*member: index:[empty]*/
dynamic get index => throw '';
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
- /*element: A.foo:Value([exact=JSString], value: "string")*/
+ /*member: A.foo:Value([exact=JSString], value: "string")*/
get foo => 'string';
set foo(/*[subclass=JSNumber]*/ value) {}
- /*element: A.[]:Value([exact=JSString], value: "string")*/
+ /*member: A.[]:Value([exact=JSString], value: "string")*/
operator [](/*[empty]*/ index) => 'string';
- /*element: A.[]=:[null]*/
+ /*member: A.[]=:[null]*/
operator []=(/*[empty]*/ index, /*[subclass=JSNumber]*/ value) {}
- /*element: A.returnDynamic1:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A.returnDynamic1:Union([exact=JSString], [exact=JSUInt31])*/
returnDynamic1() => /*[subclass=A]*/ /*update: [subclass=A]*/ foo
/*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --;
- /*element: A.returnNum1:[subclass=JSNumber]*/
+ /*member: A.returnNum1:[subclass=JSNumber]*/
returnNum1() => /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --
/*[subclass=A]*/ /*update: [subclass=A]*/ foo;
- /*element: A.returnNum2:[subclass=JSNumber]*/
+ /*member: A.returnNum2:[subclass=JSNumber]*/
returnNum2() => /*[subclass=A]*/ /*update: [subclass=A]*/ foo
/*invoke: Union([exact=JSString], [exact=JSUInt31])*/ -= 42;
- /*element: A.returnDynamic2:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: A.returnDynamic2:Union([exact=JSString], [exact=JSUInt31])*/
returnDynamic2() => this
/*[subclass=A]*/ /*update: [subclass=A]*/ [index]
/*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --;
- /*element: A.returnNum3:[subclass=JSNumber]*/
+ /*member: A.returnNum3:[subclass=JSNumber]*/
returnNum3() => /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --this
/*[subclass=A]*/ /*update: [subclass=A]*/ [index];
- /*element: A.returnNum4:[subclass=JSNumber]*/
+ /*member: A.returnNum4:[subclass=JSNumber]*/
returnNum4() => this
/*[subclass=A]*/ /*update: [subclass=A]*/ [index]
/*invoke: Union([exact=JSString], [exact=JSUInt31])*/ -= 42;
- /*element: A.returnEmpty3:[empty]*/
+ /*member: A.returnEmpty3:[empty]*/
returnEmpty3() {
dynamic a = this;
return a. /*[subclass=A]*/ /*update: [subclass=A]*/
@@ -52,14 +52,14 @@
/*invoke: [empty]*/ --;
}
- /*element: A.returnEmpty1:[empty]*/
+ /*member: A.returnEmpty1:[empty]*/
returnEmpty1() {
dynamic a = this;
return /*invoke: [empty]*/ --a
. /*[subclass=A]*/ /*update: [subclass=A]*/ bar;
}
- /*element: A.returnEmpty2:[empty]*/
+ /*member: A.returnEmpty2:[empty]*/
returnEmpty2() {
dynamic a = this;
return a. /*[subclass=A]*/ /*update: [subclass=A]*/ bar
@@ -67,41 +67,41 @@
}
}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {
- /*element: B.foo:[exact=JSUInt31]*/
+ /*member: B.foo:[exact=JSUInt31]*/
get foo => 42;
- /*element: B.[]:[exact=JSUInt31]*/
+ /*member: B.[]:[exact=JSUInt31]*/
operator [](/*[empty]*/ index) => 42;
- /*element: B.returnString1:Value([exact=JSString], value: "string")*/
+ /*member: B.returnString1:Value([exact=JSString], value: "string")*/
returnString1() =>
super.foo /*invoke: Value([exact=JSString], value: "string")*/ --;
- /*element: B.returnDynamic1:[empty]*/
+ /*member: B.returnDynamic1:[empty]*/
returnDynamic1() =>
/*invoke: Value([exact=JSString], value: "string")*/
--super.foo;
- /*element: B.returnDynamic2:[empty]*/
+ /*member: B.returnDynamic2:[empty]*/
returnDynamic2() =>
super.foo /*invoke: Value([exact=JSString], value: "string")*/ -= 42;
- /*element: B.returnString2:Value([exact=JSString], value: "string")*/
+ /*member: B.returnString2:Value([exact=JSString], value: "string")*/
returnString2() => super[index]
/*invoke: Value([exact=JSString], value: "string")*/ --;
- /*element: B.returnDynamic3:[empty]*/
+ /*member: B.returnDynamic3:[empty]*/
returnDynamic3() =>
/*invoke: Value([exact=JSString], value: "string")*/
--super[index];
- /*element: B.returnDynamic4:[empty]*/
+ /*member: B.returnDynamic4:[empty]*/
returnDynamic4() => super[index]
/*invoke: Value([exact=JSString], value: "string")*/ -= 42;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new A()
.. /*invoke: [exact=A]*/ returnNum1()
diff --git a/tests/compiler/dart2js/inference/data/prefix.dart b/tests/compiler/dart2js/inference/data/prefix.dart
index 32118ab..544ae70 100644
--- a/tests/compiler/dart2js/inference/data/prefix.dart
+++ b/tests/compiler/dart2js/inference/data/prefix.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
localPrefixInc();
localPrefixDec();
@@ -18,7 +18,7 @@
// Prefix increment on local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: localPrefixInc:[subclass=JSUInt32]*/
+/*member: localPrefixInc:[subclass=JSUInt32]*/
localPrefixInc() {
var local;
if (local == null) {
@@ -31,7 +31,7 @@
// Prefix decrement on local variable.
////////////////////////////////////////////////////////////////////////////////
-/*element: localPrefixDec:[subclass=JSInt]*/
+/*member: localPrefixDec:[subclass=JSInt]*/
localPrefixDec() {
var local;
if (local == null) {
@@ -44,10 +44,10 @@
// Prefix increment on static field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _staticField1:[null|subclass=JSPositiveInt]*/
+/*member: _staticField1:[null|subclass=JSPositiveInt]*/
var _staticField1;
-/*element: staticFieldPrefixInc:[subclass=JSPositiveInt]*/
+/*member: staticFieldPrefixInc:[subclass=JSPositiveInt]*/
staticFieldPrefixInc() {
if (_staticField1 == null) {
_staticField1 = 0;
@@ -59,10 +59,10 @@
// Prefix decrement on static field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _staticField2:[null|subclass=JSInt]*/
+/*member: _staticField2:[null|subclass=JSInt]*/
var _staticField2;
-/*element: staticFieldPrefixDec:[subclass=JSInt]*/
+/*member: staticFieldPrefixDec:[subclass=JSInt]*/
staticFieldPrefixDec() {
if (_staticField2 == null) {
_staticField2 = 0;
@@ -74,13 +74,13 @@
// Prefix increment on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field1:[null|subclass=JSPositiveInt]*/
+ /*member: Class1.field1:[null|subclass=JSPositiveInt]*/
var field1;
}
-/*element: instanceFieldPrefixInc:[subclass=JSPositiveInt]*/
+/*member: instanceFieldPrefixInc:[subclass=JSPositiveInt]*/
instanceFieldPrefixInc() {
var c = new Class1();
if (c. /*[exact=Class1]*/ field1 == null) {
@@ -97,13 +97,13 @@
// Prefix decrement on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field2:[null|subclass=JSInt]*/
+ /*member: Class2.field2:[null|subclass=JSInt]*/
var field2;
}
-/*element: instanceFieldPrefixDec:[subclass=JSInt]*/
+/*member: instanceFieldPrefixDec:[subclass=JSInt]*/
instanceFieldPrefixDec() {
var c = new Class2();
if (c. /*[exact=Class2]*/ field2 == null) {
@@ -120,13 +120,13 @@
// Conditional prefix increment on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.field3:[null|subclass=JSPositiveInt]*/
+ /*member: Class3.field3:[null|subclass=JSPositiveInt]*/
var field3;
}
-/*element: conditionalInstanceFieldPrefixInc:[null|subclass=JSPositiveInt]*/
+/*member: conditionalInstanceFieldPrefixInc:[null|subclass=JSPositiveInt]*/
conditionalInstanceFieldPrefixInc() {
var c = new Class3();
if (c. /*[exact=Class3]*/ field3 == null) {
@@ -143,13 +143,13 @@
// Conditional prefix decrement on instance field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field4:[null|subclass=JSInt]*/
+ /*member: Class4.field4:[null|subclass=JSInt]*/
var field4;
}
-/*element: conditionalInstanceFieldPrefixDec:[null|subclass=JSInt]*/
+/*member: conditionalInstanceFieldPrefixDec:[null|subclass=JSInt]*/
conditionalInstanceFieldPrefixDec() {
var c = new Class4();
if (c. /*[exact=Class4]*/ field4 == null) {
diff --git a/tests/compiler/dart2js/inference/data/refine_captured_locals.dart b/tests/compiler/dart2js/inference/data/refine_captured_locals.dart
index f11fc71..5a13864 100644
--- a/tests/compiler/dart2js/inference/data/refine_captured_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_captured_locals.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
refineBeforeCapture();
refineAfterCapture();
@@ -14,13 +14,13 @@
// Refine a local before it has been captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.method1:[null]*/
+ /*member: Class1.method1:[null]*/
method1() {}
}
-/*element: _refineBeforeCapture:[exact=Class1]*/
+/*member: _refineBeforeCapture:[exact=Class1]*/
_refineBeforeCapture(/*[null|exact=Class1]*/ o) {
o. /*invoke: [null|exact=Class1]*/ method1();
o. /*invoke: [exact=Class1]*/ method1();
@@ -29,7 +29,7 @@
return localFunction();
}
-/*element: refineBeforeCapture:[null]*/
+/*member: refineBeforeCapture:[null]*/
refineBeforeCapture() {
_refineBeforeCapture(new Class1());
_refineBeforeCapture(null);
@@ -39,16 +39,16 @@
// Refine a local after it has been captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.method3:[null]*/
+ /*member: Class3.method3:[null]*/
method3() {}
}
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {}
-/*element: _refineAfterCapture:Union([exact=Class3], [exact=Class4])*/
+/*member: _refineAfterCapture:Union([exact=Class3], [exact=Class4])*/
_refineAfterCapture(/*Union([exact=Class3], [exact=Class4])*/ o) {
/*Union([exact=Class3], [exact=Class4])*/ localFunction() => o;
@@ -58,7 +58,7 @@
return localFunction();
}
-/*element: refineAfterCapture:[null]*/
+/*member: refineAfterCapture:[null]*/
refineAfterCapture() {
_refineAfterCapture(new Class3());
_refineAfterCapture(new Class4());
@@ -68,16 +68,16 @@
// Refine a local after it has been captured in a nested local function.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
class Class5 {
- /*element: Class5.method5:[null]*/
+ /*member: Class5.method5:[null]*/
method5() {}
}
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
class Class6 {}
-/*element: _refineAfterNestedCapture:Union([exact=Class5], [exact=Class6])*/
+/*member: _refineAfterNestedCapture:Union([exact=Class5], [exact=Class6])*/
_refineAfterNestedCapture(/*Union([exact=Class5], [exact=Class6])*/ o) {
/*Union([exact=Class5], [exact=Class6])*/ localFunction() {
/*Union([exact=Class5], [exact=Class6])*/ nestedFunction() => o;
@@ -90,7 +90,7 @@
return localFunction();
}
-/*element: refineAfterNestedCapture:[null]*/
+/*member: refineAfterNestedCapture:[null]*/
refineAfterNestedCapture() {
_refineAfterNestedCapture(new Class5());
_refineAfterNestedCapture(new Class6());
@@ -100,16 +100,16 @@
// Refine a local in a local function after it has been captured.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
class Class7 {
- /*element: Class7.method7:[null]*/
+ /*member: Class7.method7:[null]*/
method7() {}
}
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
class Class8 {}
-/*element: _refineAfterCaptureInNested:Union([exact=Class7], [exact=Class8])*/
+/*member: _refineAfterCaptureInNested:Union([exact=Class7], [exact=Class8])*/
_refineAfterCaptureInNested(/*Union([exact=Class7], [exact=Class8])*/ o) {
/*Union([exact=Class7], [exact=Class8])*/ localFunction(
/*Union([exact=Class7], [exact=Class8])*/ p) {
@@ -124,7 +124,7 @@
return localFunction(o);
}
-/*element: refineAfterCaptureInNested:[null]*/
+/*member: refineAfterCaptureInNested:[null]*/
refineAfterCaptureInNested() {
_refineAfterCaptureInNested(new Class7());
_refineAfterCaptureInNested(new Class8());
diff --git a/tests/compiler/dart2js/inference/data/refine_locals.dart b/tests/compiler/dart2js/inference/data/refine_locals.dart
index b14eede..64f339d 100644
--- a/tests/compiler/dart2js/inference/data/refine_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_locals.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
refineToClass();
refineToClosure();
@@ -13,31 +13,31 @@
// accesses and updates.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.method0:[null]*/
+ /*member: Class1.method0:[null]*/
method0() {}
- /*element: Class1.method1:[null]*/
+ /*member: Class1.method1:[null]*/
method1() {}
- /*element: Class1.field0:[null|exact=JSUInt31]*/
+ /*member: Class1.field0:[null|exact=JSUInt31]*/
var field0;
- /*element: Class1.field1:[null|exact=JSUInt31]*/
+ /*member: Class1.field1:[null|exact=JSUInt31]*/
var field1;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.method0:[null]*/
+ /*member: Class2.method0:[null]*/
method0() {}
- /*element: Class2.method2:[null]*/
+ /*member: Class2.method2:[null]*/
method2() {}
- /*element: Class2.field0:[null]*/
+ /*member: Class2.field0:[null]*/
var field0;
- /*element: Class2.field2:[null]*/
+ /*member: Class2.field2:[null]*/
var field2;
}
-/*element: _refineUnion:Union([exact=Class1], [exact=Class2])*/
+/*member: _refineUnion:Union([exact=Class1], [exact=Class2])*/
_refineUnion(/*Union([null|exact=Class1], [null|exact=Class2])*/ o) {
o. /*invoke: Union([null|exact=Class1], [null|exact=Class2])*/ method0();
o. /*invoke: Union([exact=Class1], [exact=Class2])*/ method1();
@@ -45,28 +45,28 @@
return o;
}
-/*element: _refineFromMethod:[exact=Class1]*/
+/*member: _refineFromMethod:[exact=Class1]*/
_refineFromMethod(/*[null|exact=Class1]*/ o) {
o. /*invoke: [null|exact=Class1]*/ method0();
o. /*invoke: [exact=Class1]*/ method1();
return o;
}
-/*element: _refineFromGetter:[exact=Class2]*/
+/*member: _refineFromGetter:[exact=Class2]*/
_refineFromGetter(/*[null|exact=Class2]*/ o) {
o. /*[null|exact=Class2]*/ field0;
o. /*[exact=Class2]*/ field2;
return o;
}
-/*element: _refineFromSetter:[exact=Class1]*/
+/*member: _refineFromSetter:[exact=Class1]*/
_refineFromSetter(/*[null|exact=Class1]*/ o) {
o. /*update: [null|exact=Class1]*/ field0 = 0;
o. /*update: [exact=Class1]*/ field1 = 0;
return o;
}
-/*element: _noRefinementNullAware:[null|exact=Class1]*/
+/*member: _noRefinementNullAware:[null|exact=Class1]*/
_noRefinementNullAware(/*[null|exact=Class1]*/ o) {
o
?.
@@ -75,7 +75,7 @@
return o;
}
-/*element: _noRefinementNullSelectors:[exact=Class2]*/
+/*member: _noRefinementNullSelectors:[exact=Class2]*/
_noRefinementNullSelectors(/*[null|exact=Class2]*/ o) {
o /*invoke: [null|exact=Class2]*/ == 2;
o. /*[null|exact=Class2]*/ hashCode;
@@ -88,18 +88,18 @@
return o;
}
-/*element: _noRefinementUpdatedVariable:[null|exact=Class1]*/
+/*member: _noRefinementUpdatedVariable:[null|exact=Class1]*/
_noRefinementUpdatedVariable(/*[null|exact=Class1]*/ o) {
(o = o). /*invoke: [null|exact=Class1]*/ method1();
(o = o). /*invoke: [null|exact=Class1]*/ method0();
return o;
}
-/*element: _condition:Value([exact=JSBool], value: false)*/
+/*member: _condition:Value([exact=JSBool], value: false)*/
@pragma('dart2js:assumeDynamic')
get _condition => false;
-/*element: refineToClass:[null]*/
+/*member: refineToClass:[null]*/
refineToClass() {
var nullOrClass1 = _condition ? null : new Class1();
var nullOrClass2 = _condition ? null : new Class2();
@@ -118,21 +118,21 @@
// Refine the type of a local variable through a sequence of invocations.
////////////////////////////////////////////////////////////////////////////////
-/*element: _refineToClosureLocal:[subclass=Closure]*/
+/*member: _refineToClosureLocal:[subclass=Closure]*/
_refineToClosureLocal() {
var f = /*[null]*/ ({/*[exact=JSUInt31]*/ a}) {};
f(a: 0);
return f;
}
-/*element: _refineToClosureLocalCall:[subclass=Closure]*/
+/*member: _refineToClosureLocalCall:[subclass=Closure]*/
_refineToClosureLocalCall() {
var f = /*[null]*/ ({/*[exact=JSUInt31]*/ b}) {};
f.call(b: 0);
return f;
}
-/*element: refineToClosure:[null]*/
+/*member: refineToClosure:[null]*/
refineToClosure() {
_refineToClosureLocal();
_refineToClosureLocalCall();
diff --git a/tests/compiler/dart2js/inference/data/refine_order.dart b/tests/compiler/dart2js/inference/data/refine_order.dart
index 9bfe307..1a0b93e 100644
--- a/tests/compiler/dart2js/inference/data/refine_order.dart
+++ b/tests/compiler/dart2js/inference/data/refine_order.dart
@@ -2,16 +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.
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.field:[exact=JSUInt31]*/
+ /*member: Class.field:[exact=JSUInt31]*/
var field = 42;
- /*element: Class.method:[null]*/
+ /*member: Class.method:[null]*/
method([/*[null|exact=JSUInt31]*/ a, /*[null|exact=JSUInt31]*/ b]) {}
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new Class();
statementOrderFieldAccess(null);
@@ -31,7 +31,7 @@
// Accesses in statements.
////////////////////////////////////////////////////////////////////////////////
-/*element: statementOrderFieldAccess:[null]*/
+/*member: statementOrderFieldAccess:[null]*/
@pragma('dart2js:assumeDynamic')
statementOrderFieldAccess(/*[null|subclass=Object]*/ o) {
o.field;
@@ -42,7 +42,7 @@
// Updates in statements.
////////////////////////////////////////////////////////////////////////////////
-/*element: statementOrderFieldUpdate:[null]*/
+/*member: statementOrderFieldUpdate:[null]*/
@pragma('dart2js:assumeDynamic')
statementOrderFieldUpdate(/*[null|subclass=Object]*/ o) {
o.field = 42;
@@ -53,7 +53,7 @@
// Invocations in statements.
////////////////////////////////////////////////////////////////////////////////
-/*element: statementOrderInvocation:[null]*/
+/*member: statementOrderInvocation:[null]*/
@pragma('dart2js:assumeDynamic')
statementOrderInvocation(/*[null|subclass=Object]*/ o) {
o.method(null);
@@ -64,7 +64,7 @@
// Access in argument before method call.
////////////////////////////////////////////////////////////////////////////////
-/*element: receiverVsArgument:[null]*/
+/*member: receiverVsArgument:[null]*/
@pragma('dart2js:assumeDynamic')
receiverVsArgument(/*[null|subclass=Object]*/ o) {
// TODO(johnniwinther): The arguments should refine the receiver.
@@ -76,7 +76,7 @@
// Access in multiple arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: argumentsOrder:[null]*/
+/*member: argumentsOrder:[null]*/
@pragma('dart2js:assumeDynamic')
argumentsOrder(/*[null|subclass=Object]*/ o) {
// TODO(johnniwinther): The arguments should refine the receiver.
@@ -88,7 +88,7 @@
// Access in both sides of an operator call.
////////////////////////////////////////////////////////////////////////////////
-/*element: operatorOrder:[null]*/
+/*member: operatorOrder:[null]*/
@pragma('dart2js:assumeDynamic')
operatorOrder(/*[null|subclass=Object]*/ o) {
o.field /*invoke: [exact=JSUInt31]*/ < o. /*[subclass=Object]*/ field;
@@ -99,7 +99,7 @@
// Assign after access in right-hand side.
////////////////////////////////////////////////////////////////////////////////
-/*element: updateVsRhs:[null]*/
+/*member: updateVsRhs:[null]*/
@pragma('dart2js:assumeDynamic')
updateVsRhs(/*[null|subclass=Object]*/ o) {
// TODO(johnniwinther): The right-hand side should refine the left-hand side
@@ -112,7 +112,7 @@
// Access in both sides of a logical or.
////////////////////////////////////////////////////////////////////////////////
-/*element: logicalOr:[null]*/
+/*member: logicalOr:[null]*/
@pragma('dart2js:assumeDynamic')
logicalOr(/*[null|subclass=Object]*/ o) {
o.field || o. /*[subclass=Object]*/ field;
@@ -123,7 +123,7 @@
// Access in condition of a conditional expression.
////////////////////////////////////////////////////////////////////////////////
-/*element: conditionalCondition:[null]*/
+/*member: conditionalCondition:[null]*/
@pragma('dart2js:assumeDynamic')
conditionalCondition(/*[null|subclass=Object]*/ o) {
o.field ? o. /*[subclass=Object]*/ field : o. /*[subclass=Object]*/ field;
@@ -134,7 +134,7 @@
// Access both branches of a conditional expression.
////////////////////////////////////////////////////////////////////////////////
-/*element: conditionalBothBranches:[null]*/
+/*member: conditionalBothBranches:[null]*/
@pragma('dart2js:assumeDynamic')
conditionalBothBranches(/*[null|subclass=Object]*/ o) {
// ignore: DEAD_CODE
@@ -146,7 +146,7 @@
// Access in only one branch of a conditional expression.
////////////////////////////////////////////////////////////////////////////////
-/*element: conditionalOneBranchOnly:[null]*/
+/*member: conditionalOneBranchOnly:[null]*/
@pragma('dart2js:assumeDynamic')
conditionalOneBranchOnly(/*[null|subclass=Object]*/ o) {
// ignore: DEAD_CODE
diff --git a/tests/compiler/dart2js/inference/data/return.dart b/tests/compiler/dart2js/inference/data/return.dart
index 3e6d17c..01a574f 100644
--- a/tests/compiler/dart2js/inference/data/return.dart
+++ b/tests/compiler/dart2js/inference/data/return.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
return null;
}
diff --git a/tests/compiler/dart2js/inference/data/simple.dart b/tests/compiler/dart2js/inference/data/simple.dart
index a4429ce..81fcc94 100644
--- a/tests/compiler/dart2js/inference/data/simple.dart
+++ b/tests/compiler/dart2js/inference/data/simple.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
zero();
one();
@@ -28,113 +28,113 @@
/// Return a zero integer literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: zero:[exact=JSUInt31]*/
+/*member: zero:[exact=JSUInt31]*/
zero() => 0;
////////////////////////////////////////////////////////////////////////////////
/// Return a positive integer literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: one:[exact=JSUInt31]*/
+/*member: one:[exact=JSUInt31]*/
one() => 1;
////////////////////////////////////////////////////////////////////////////////
/// Return a double literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: half:[exact=JSDouble]*/
+/*member: half:[exact=JSDouble]*/
half() => 0.5;
////////////////////////////////////////////////////////////////////////////////
/// Return an integer valued zero double literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: zeroPointZero:[exact=JSUInt31]*/
+/*member: zeroPointZero:[exact=JSUInt31]*/
zeroPointZero() => 0.0;
////////////////////////////////////////////////////////////////////////////////
/// Return an integer valued double literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: onePointZero:[exact=JSUInt31]*/
+/*member: onePointZero:[exact=JSUInt31]*/
onePointZero() => 1.0;
////////////////////////////////////////////////////////////////////////////////
/// Return a >31bit integer literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: large:[subclass=JSUInt32]*/
+/*member: large:[subclass=JSUInt32]*/
large() => 2147483648;
////////////////////////////////////////////////////////////////////////////////
/// Return a >32bit integer literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: huge:[subclass=JSPositiveInt]*/
+/*member: huge:[subclass=JSPositiveInt]*/
huge() => 4294967296;
////////////////////////////////////////////////////////////////////////////////
/// Return a negative integer literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: minusOne:[subclass=JSInt]*/
+/*member: minusOne:[subclass=JSInt]*/
minusOne() => /*invoke: [exact=JSUInt31]*/ -1;
////////////////////////////////////////////////////////////////////////////////
/// Return a negative double literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: minusHalf:[subclass=JSNumber]*/
+/*member: minusHalf:[subclass=JSNumber]*/
minusHalf() => /*invoke: [exact=JSDouble]*/ -0.5;
////////////////////////////////////////////////////////////////////////////////
/// Return an empty string.
////////////////////////////////////////////////////////////////////////////////
-/*element: emptyString:Value([exact=JSString], value: "")*/
+/*member: emptyString:Value([exact=JSString], value: "")*/
emptyString() => '';
////////////////////////////////////////////////////////////////////////////////
/// Return a non-empty string.
////////////////////////////////////////////////////////////////////////////////
-/*element: nonEmptyString:Value([exact=JSString], value: "foo")*/
+/*member: nonEmptyString:Value([exact=JSString], value: "foo")*/
nonEmptyString() => 'foo';
////////////////////////////////////////////////////////////////////////////////
/// Return a string juxtaposition.
////////////////////////////////////////////////////////////////////////////////
-/*element: stringJuxtaposition:[exact=JSString]*/
+/*member: stringJuxtaposition:[exact=JSString]*/
stringJuxtaposition() => 'foo' 'bar';
////////////////////////////////////////////////////////////////////////////////
/// Return a string constant interpolation.
////////////////////////////////////////////////////////////////////////////////
-/*element: stringConstantInterpolation:[exact=JSString]*/
+/*member: stringConstantInterpolation:[exact=JSString]*/
stringConstantInterpolation() => 'foo${'bar'}';
////////////////////////////////////////////////////////////////////////////////
/// Return a string non-constant interpolation.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[exact=JSBool]*/
+/*member: _method1:[exact=JSBool]*/
_method1(/*[exact=JSBool]*/ c) => c;
-/*element: stringNonConstantInterpolation:[exact=JSString]*/
+/*member: stringNonConstantInterpolation:[exact=JSString]*/
stringNonConstantInterpolation() => 'foo${_method1(true)}${_method1(false)}';
////////////////////////////////////////////////////////////////////////////////
/// Return a symbol literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: symbolLiteral:[exact=Symbol]*/
+/*member: symbolLiteral:[exact=Symbol]*/
symbolLiteral() => #main;
////////////////////////////////////////////////////////////////////////////////
/// Return a type literal.
////////////////////////////////////////////////////////////////////////////////
-/*element: typeLiteral:[exact=TypeImpl]*/
+/*member: typeLiteral:[exact=TypeImpl]*/
typeLiteral() => Object;
diff --git a/tests/compiler/dart2js/inference/data/static.dart b/tests/compiler/dart2js/inference/data/static.dart
index 4b65a4c..2187263 100644
--- a/tests/compiler/dart2js/inference/data/static.dart
+++ b/tests/compiler/dart2js/inference/data/static.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleStaticCall();
staticCallWithPositionalArguments1();
@@ -39,10 +39,10 @@
/// Call a static method that has a constant return value.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleStaticCall:[exact=JSUInt31]*/
+/*member: simpleStaticCall:[exact=JSUInt31]*/
simpleStaticCall() => _returnInt();
-/*element: _returnInt:[exact=JSUInt31]*/
+/*member: _returnInt:[exact=JSUInt31]*/
_returnInt() => 0;
////////////////////////////////////////////////////////////////////////////////
@@ -50,10 +50,10 @@
/// is returned.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithPositionalArguments1:[exact=JSUInt31]*/
+/*member: staticCallWithPositionalArguments1:[exact=JSUInt31]*/
staticCallWithPositionalArguments1() => _returnFirst(0, 0.5);
-/*element: _returnFirst:[exact=JSUInt31]*/
+/*member: _returnFirst:[exact=JSUInt31]*/
_returnFirst(/*[exact=JSUInt31]*/ a, /*[exact=JSDouble]*/ b) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -61,10 +61,10 @@
/// is returned.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithPositionalArguments2:[exact=JSDouble]*/
+/*member: staticCallWithPositionalArguments2:[exact=JSDouble]*/
staticCallWithPositionalArguments2() => _returnSecond(0, 0.5);
-/*element: _returnSecond:[exact=JSDouble]*/
+/*member: _returnSecond:[exact=JSDouble]*/
_returnSecond(/*[exact=JSUInt31]*/ a, /*[exact=JSDouble]*/ b) => b;
////////////////////////////////////////////////////////////////////////////////
@@ -72,10 +72,10 @@
/// value. Only one call site with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments1:[null]*/
+/*member: staticCallWithOptionalArguments1:[null]*/
staticCallWithOptionalArguments1() => _returnDefaultNull();
-/*element: _returnDefaultNull:[null]*/
+/*member: _returnDefaultNull:[null]*/
_returnDefaultNull([/*[null]*/ a]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -83,10 +83,10 @@
/// value of `null`. Only one call site with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments2:[null]*/
+/*member: staticCallWithOptionalArguments2:[null]*/
staticCallWithOptionalArguments2() => _returnDefaultNullExplicit();
-/*element: _returnDefaultNullExplicit:[null]*/
+/*member: _returnDefaultNullExplicit:[null]*/
_returnDefaultNullExplicit([/*[null]*/ a = null]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -94,10 +94,10 @@
/// explicit argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments3:[exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments3:[exact=JSUInt31]*/
staticCallWithOptionalArguments3() => _returnDefaultNullCalled(0);
-/*element: _returnDefaultNullCalled:[exact=JSUInt31]*/
+/*member: _returnDefaultNullCalled:[exact=JSUInt31]*/
_returnDefaultNullCalled([/*[exact=JSUInt31]*/ a]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -105,13 +105,13 @@
/// with an explicit argument and one with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments4a:[null|exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments4a:[null|exact=JSUInt31]*/
staticCallWithOptionalArguments4a() => _returnDefaultNullCalledTwice();
-/*element: staticCallWithOptionalArguments4b:[null|exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments4b:[null|exact=JSUInt31]*/
staticCallWithOptionalArguments4b() => _returnDefaultNullCalledTwice(0);
-/*element: _returnDefaultNullCalledTwice:[null|exact=JSUInt31]*/
+/*member: _returnDefaultNullCalledTwice:[null|exact=JSUInt31]*/
_returnDefaultNullCalledTwice([/*[null|exact=JSUInt31]*/ a]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -119,10 +119,10 @@
/// Only one call site with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments5:[exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments5:[exact=JSUInt31]*/
staticCallWithOptionalArguments5() => _returnDefaultZero();
-/*element: _returnDefaultZero:[exact=JSUInt31]*/
+/*member: _returnDefaultZero:[exact=JSUInt31]*/
_returnDefaultZero([/*[exact=JSUInt31]*/ a = 0]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -130,10 +130,10 @@
/// Only one call site with an argument of a different type.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithOptionalArguments6:[exact=JSDouble]*/
+/*member: staticCallWithOptionalArguments6:[exact=JSDouble]*/
staticCallWithOptionalArguments6() => _returnDefaultZeroCalled(0.5);
-/*element: _returnDefaultZeroCalled:[exact=JSDouble]*/
+/*member: _returnDefaultZeroCalled:[exact=JSDouble]*/
_returnDefaultZeroCalled([/*[exact=JSDouble]*/ a = 0]) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -141,10 +141,10 @@
/// Only one call site with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithNamedArguments1:[exact=JSUInt31]*/
+/*member: staticCallWithNamedArguments1:[exact=JSUInt31]*/
staticCallWithNamedArguments1() => _returnNamedDefaultZero();
-/*element: _returnNamedDefaultZero:[exact=JSUInt31]*/
+/*member: _returnNamedDefaultZero:[exact=JSUInt31]*/
_returnNamedDefaultZero({/*[exact=JSUInt31]*/ a: 0}) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -152,10 +152,10 @@
/// Only one call site with an argument of a different type.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithNamedArguments2:[exact=JSDouble]*/
+/*member: staticCallWithNamedArguments2:[exact=JSDouble]*/
staticCallWithNamedArguments2() => _returnNamedDefaultZeroCalled(a: 0.5);
-/*element: _returnNamedDefaultZeroCalled:[exact=JSDouble]*/
+/*member: _returnNamedDefaultZeroCalled:[exact=JSDouble]*/
_returnNamedDefaultZeroCalled({/*[exact=JSDouble]*/ a: 0}) => a;
////////////////////////////////////////////////////////////////////////////////
@@ -163,55 +163,55 @@
/// explicit argument and one with no arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: staticCallWithNamedArguments3a:[null|exact=JSDouble]*/
+/*member: staticCallWithNamedArguments3a:[null|exact=JSDouble]*/
staticCallWithNamedArguments3a() => _returnNamedNullCalledTwice();
-/*element: staticCallWithNamedArguments3b:[null|exact=JSDouble]*/
+/*member: staticCallWithNamedArguments3b:[null|exact=JSDouble]*/
staticCallWithNamedArguments3b() => _returnNamedNullCalledTwice(a: 0.5);
-/*element: _returnNamedNullCalledTwice:[null|exact=JSDouble]*/
+/*member: _returnNamedNullCalledTwice:[null|exact=JSDouble]*/
_returnNamedNullCalledTwice({/*[null|exact=JSDouble]*/ a}) => a;
////////////////////////////////////////////////////////////////////////////////
/// Call an uninitialized top level field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field1:[null]*/
+/*member: _field1:[null]*/
dynamic _field1;
-/*element: invokeStaticFieldUninitialized:[null|subclass=Object]*/
+/*member: invokeStaticFieldUninitialized:[null|subclass=Object]*/
invokeStaticFieldUninitialized() => _field1();
////////////////////////////////////////////////////////////////////////////////
/// Call a top level field initialized to a tear-off of a top level method.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[exact=JSUInt31]*/
+/*member: _method1:[exact=JSUInt31]*/
_method1() => 42;
-/*strong.element: _field2:[null|subclass=Closure]*/
-/*omit.element: _field2:[null|subclass=Closure]*/
-/*strongConst.element: _field2:[subclass=Closure]*/
-/*omitConst.element: _field2:[subclass=Closure]*/
+/*strong.member: _field2:[null|subclass=Closure]*/
+/*omit.member: _field2:[null|subclass=Closure]*/
+/*strongConst.member: _field2:[subclass=Closure]*/
+/*omitConst.member: _field2:[subclass=Closure]*/
dynamic _field2 = _method1;
-/*element: invokeStaticFieldTearOff:[null|subclass=Object]*/
+/*member: invokeStaticFieldTearOff:[null|subclass=Object]*/
invokeStaticFieldTearOff() => _field2();
////////////////////////////////////////////////////////////////////////////////
/// Call a top level field initialized to a tear-off of a top level method.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method5:Value([exact=JSString], value: "")*/
+/*member: _method5:Value([exact=JSString], value: "")*/
String _method5() => '';
-/*strong.element: _field5:[null|subclass=Closure]*/
-/*omit.element: _field5:[null|subclass=Closure]*/
-/*strongConst.element: _field5:[subclass=Closure]*/
-/*omitConst.element: _field5:[subclass=Closure]*/
+/*strong.member: _field5:[null|subclass=Closure]*/
+/*omit.member: _field5:[null|subclass=Closure]*/
+/*strongConst.member: _field5:[subclass=Closure]*/
+/*omitConst.member: _field5:[subclass=Closure]*/
String Function() _field5 = _method5;
-/*element: invokeStaticTypedFieldTearOff:[null|exact=JSString]*/
+/*member: invokeStaticTypedFieldTearOff:[null|exact=JSString]*/
invokeStaticTypedFieldTearOff() => _field5();
////////////////////////////////////////////////////////////////////////////////
@@ -219,51 +219,51 @@
/// taking one argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method2:[exact=JSUInt31]*/
+/*member: _method2:[exact=JSUInt31]*/
_method2(/*[exact=JSUInt31]*/ o) => 42;
-/*strong.element: _field3:[null|subclass=Closure]*/
-/*omit.element: _field3:[null|subclass=Closure]*/
-/*strongConst.element: _field3:[subclass=Closure]*/
-/*omitConst.element: _field3:[subclass=Closure]*/
+/*strong.member: _field3:[null|subclass=Closure]*/
+/*omit.member: _field3:[null|subclass=Closure]*/
+/*strongConst.member: _field3:[subclass=Closure]*/
+/*omitConst.member: _field3:[subclass=Closure]*/
dynamic _field3 = _method2;
-/*element: invokeStaticFieldTearOffParameters:[null|subclass=Object]*/
+/*member: invokeStaticFieldTearOffParameters:[null|subclass=Object]*/
invokeStaticFieldTearOffParameters() => _field3(42);
////////////////////////////////////////////////////////////////////////////////
/// Call a top level getter returning a tear-off of a top level method.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method3:[exact=JSUInt31]*/
+/*member: _method3:[exact=JSUInt31]*/
_method3() => 42;
-/*element: _getter1:[subclass=Closure]*/
+/*member: _getter1:[subclass=Closure]*/
get _getter1 => _method3;
-/*element: invokeStaticGetterTearOff:[null|subclass=Object]*/
+/*member: invokeStaticGetterTearOff:[null|subclass=Object]*/
invokeStaticGetterTearOff() => _getter1();
////////////////////////////////////////////////////////////////////////////////
/// Call a typed top level getter returning a tear-off of a top level method.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method6:[exact=JSUInt31]*/
+/*member: _method6:[exact=JSUInt31]*/
int _method6() => 0;
-/*strong.element: _field7:[null|subclass=Closure]*/
-/*omit.element: _field7:[null|subclass=Closure]*/
-/*strongConst.element: _field7:[subclass=Closure]*/
-/*omitConst.element: _field7:[subclass=Closure]*/
+/*strong.member: _field7:[null|subclass=Closure]*/
+/*omit.member: _field7:[null|subclass=Closure]*/
+/*strongConst.member: _field7:[subclass=Closure]*/
+/*omitConst.member: _field7:[subclass=Closure]*/
int Function() _field7 = _method6;
-/*strong.element: _getter3:[null|subclass=Closure]*/
-/*omit.element: _getter3:[null|subclass=Closure]*/
-/*strongConst.element: _getter3:[subclass=Closure]*/
-/*omitConst.element: _getter3:[subclass=Closure]*/
+/*strong.member: _getter3:[null|subclass=Closure]*/
+/*omit.member: _getter3:[null|subclass=Closure]*/
+/*strongConst.member: _getter3:[subclass=Closure]*/
+/*omitConst.member: _getter3:[subclass=Closure]*/
int Function() get _getter3 => _field7;
-/*element: invokeStaticTypedGetterTearOff:[null|subclass=JSInt]*/
+/*member: invokeStaticTypedGetterTearOff:[null|subclass=JSInt]*/
invokeStaticTypedGetterTearOff() => _getter3();
////////////////////////////////////////////////////////////////////////////////
@@ -271,13 +271,13 @@
/// arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method4:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _method4:Union([exact=JSString], [exact=JSUInt31])*/
T _method4<T>(T /*Union([exact=JSString], [exact=JSUInt31])*/ t) => t;
-/*element: invokeStaticGenericMethod1:[exact=JSUInt31]*/
+/*member: invokeStaticGenericMethod1:[exact=JSUInt31]*/
invokeStaticGenericMethod1() => _method4(0);
-/*element: invokeStaticGenericMethod2:[exact=JSString]*/
+/*member: invokeStaticGenericMethod2:[exact=JSString]*/
invokeStaticGenericMethod2() => _method4('');
////////////////////////////////////////////////////////////////////////////////
@@ -285,13 +285,13 @@
/// arguments.
////////////////////////////////////////////////////////////////////////////////
-/*element: _getter2:[subclass=Closure]*/
+/*member: _getter2:[subclass=Closure]*/
T Function<T>(T) get _getter2 => _method4;
-/*element: invokeStaticGenericGetter1:[null|subclass=JSInt]*/
+/*member: invokeStaticGenericGetter1:[null|subclass=JSInt]*/
invokeStaticGenericGetter1() => _getter2(0);
-/*element: invokeStaticGenericGetter2:[null|exact=JSString]*/
+/*member: invokeStaticGenericGetter2:[null|exact=JSString]*/
invokeStaticGenericGetter2() => _getter2('');
////////////////////////////////////////////////////////////////////////////////
@@ -299,14 +299,14 @@
/// arguments.
////////////////////////////////////////////////////////////////////////////////
-/*strong.element: _field4:[null|subclass=Closure]*/
-/*omit.element: _field4:[null|subclass=Closure]*/
-/*strongConst.element: _field4:[subclass=Closure]*/
-/*omitConst.element: _field4:[subclass=Closure]*/
+/*strong.member: _field4:[null|subclass=Closure]*/
+/*omit.member: _field4:[null|subclass=Closure]*/
+/*strongConst.member: _field4:[subclass=Closure]*/
+/*omitConst.member: _field4:[subclass=Closure]*/
T Function<T>(T) _field4 = _method4;
-/*element: invokeStaticGenericField1:[null|subclass=JSInt]*/
+/*member: invokeStaticGenericField1:[null|subclass=JSInt]*/
invokeStaticGenericField1() => _field4(0);
-/*element: invokeStaticGenericField2:[null|exact=JSString]*/
+/*member: invokeStaticGenericField2:[null|exact=JSString]*/
invokeStaticGenericField2() => _field4('');
diff --git a/tests/compiler/dart2js/inference/data/static_get.dart b/tests/compiler/dart2js/inference/data/static_get.dart
index 032a9ed..0a3bf8a 100644
--- a/tests/compiler/dart2js/inference/data/static_get.dart
+++ b/tests/compiler/dart2js/inference/data/static_get.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
getTopLevelFieldUninitialized();
getStaticFieldUninitialized();
@@ -22,10 +22,10 @@
/// Static get of an uninitialized top level field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field1:[null]*/
+/*member: _field1:[null]*/
var _field1;
-/*element: getTopLevelFieldUninitialized:[null]*/
+/*member: getTopLevelFieldUninitialized:[null]*/
getTopLevelFieldUninitialized() => _field1;
////////////////////////////////////////////////////////////////////////////////
@@ -33,21 +33,21 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.field:[null]*/
+ /*member: Class1.field:[null]*/
static var field;
}
-/*element: getStaticFieldUninitialized:[null]*/
+/*member: getStaticFieldUninitialized:[null]*/
getStaticFieldUninitialized() => Class1.field;
////////////////////////////////////////////////////////////////////////////////
/// Static get of an initialized top level field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _field2:[exact=JSUInt31]*/
+/*member: _field2:[exact=JSUInt31]*/
var _field2 = 42;
-/*element: getTopLevelFieldInitialized:[exact=JSUInt31]*/
+/*member: getTopLevelFieldInitialized:[exact=JSUInt31]*/
getTopLevelFieldInitialized() => _field2;
////////////////////////////////////////////////////////////////////////////////
@@ -55,11 +55,11 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field:[exact=JSUInt31]*/
+ /*member: Class2.field:[exact=JSUInt31]*/
static var field = 42;
}
-/*element: getStaticFieldInitialized:[exact=JSUInt31]*/
+/*member: getStaticFieldInitialized:[exact=JSUInt31]*/
getStaticFieldInitialized() => Class2.field;
////////////////////////////////////////////////////////////////////////////////
@@ -67,13 +67,13 @@
/// null.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method3:[exact=JSUInt31]*/
+/*member: _method3:[exact=JSUInt31]*/
_method3() => 42;
-/*element: _field3:[null|exact=JSUInt31]*/
+/*member: _field3:[null|exact=JSUInt31]*/
var _field3 = _method3();
-/*element: getTopLevelFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
+/*member: getTopLevelFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
getTopLevelFieldInitializedPotentiallyNull() => _field3;
////////////////////////////////////////////////////////////////////////////////
@@ -81,24 +81,24 @@
////////////////////////////////////////////////////////////////////////////////
class Class3 {
- /*element: Class3.method:[exact=JSUInt31]*/
+ /*member: Class3.method:[exact=JSUInt31]*/
static method() => 42;
- /*element: Class3.field:[null|exact=JSUInt31]*/
+ /*member: Class3.field:[null|exact=JSUInt31]*/
static var field = method();
}
-/*element: getStaticFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
+/*member: getStaticFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
getStaticFieldInitializedPotentiallyNull() => Class3.field;
////////////////////////////////////////////////////////////////////////////////
/// Static get of a top level method.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method4:[exact=JSUInt31]*/
+/*member: _method4:[exact=JSUInt31]*/
_method4() => 42;
-/*element: getTopLevelMethod:[subclass=Closure]*/
+/*member: getTopLevelMethod:[subclass=Closure]*/
getTopLevelMethod() => _method4;
////////////////////////////////////////////////////////////////////////////////
@@ -106,21 +106,21 @@
////////////////////////////////////////////////////////////////////////////////
class Class4 {
- /*element: Class4.method:[exact=JSUInt31]*/
+ /*member: Class4.method:[exact=JSUInt31]*/
static method() => 42;
}
-/*element: getStaticMethod:[subclass=Closure]*/
+/*member: getStaticMethod:[subclass=Closure]*/
getStaticMethod() => Class4.method;
////////////////////////////////////////////////////////////////////////////////
/// Static get of a top level getter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _getter1:[exact=JSUInt31]*/
+/*member: _getter1:[exact=JSUInt31]*/
get _getter1 => 42;
-/*element: getTopLevelGetter:[exact=JSUInt31]*/
+/*member: getTopLevelGetter:[exact=JSUInt31]*/
getTopLevelGetter() => _getter1;
////////////////////////////////////////////////////////////////////////////////
@@ -128,9 +128,9 @@
////////////////////////////////////////////////////////////////////////////////
class Class5 {
- /*element: Class5.getter:[exact=JSUInt31]*/
+ /*member: Class5.getter:[exact=JSUInt31]*/
static get getter => 42;
}
-/*element: getStaticGetter:[exact=JSUInt31]*/
+/*member: getStaticGetter:[exact=JSUInt31]*/
getStaticGetter() => Class5.getter;
diff --git a/tests/compiler/dart2js/inference/data/static_set.dart b/tests/compiler/dart2js/inference/data/static_set.dart
index 9510845..80c95eb 100644
--- a/tests/compiler/dart2js/inference/data/static_set.dart
+++ b/tests/compiler/dart2js/inference/data/static_set.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
setTopLevelFieldUninitialized();
setStaticFieldUninitialized();
@@ -17,10 +17,10 @@
/// Static set of an uninitialized top level field.
////////////////////////////////////////////////////////////////////////////////
-/*element: field1:[null|exact=JSUInt31]*/
+/*member: field1:[null|exact=JSUInt31]*/
var field1;
-/*element: setTopLevelFieldUninitialized:[exact=JSUInt31]*/
+/*member: setTopLevelFieldUninitialized:[exact=JSUInt31]*/
setTopLevelFieldUninitialized() => field1 = 42;
////////////////////////////////////////////////////////////////////////////////
@@ -28,21 +28,21 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.field:[null|exact=JSUInt31]*/
+ /*member: Class1.field:[null|exact=JSUInt31]*/
static var field;
}
-/*element: setStaticFieldUninitialized:[exact=JSUInt31]*/
+/*member: setStaticFieldUninitialized:[exact=JSUInt31]*/
setStaticFieldUninitialized() => Class1.field = 42;
////////////////////////////////////////////////////////////////////////////////
/// Static set of an initialized top level field.
////////////////////////////////////////////////////////////////////////////////
-/*element: field2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: field2:Union([exact=JSString], [exact=JSUInt31])*/
dynamic field2 = '';
-/*element: setTopLevelFieldInitialized:[exact=JSUInt31]*/
+/*member: setTopLevelFieldInitialized:[exact=JSUInt31]*/
setTopLevelFieldInitialized() => field2 = 42;
////////////////////////////////////////////////////////////////////////////////
@@ -50,11 +50,11 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.field:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: Class2.field:Union([exact=JSString], [exact=JSUInt31])*/
static dynamic field = '';
}
-/*element: setStaticFieldInitialized:[exact=JSUInt31]*/
+/*member: setStaticFieldInitialized:[exact=JSUInt31]*/
setStaticFieldInitialized() => Class2.field = 42;
////////////////////////////////////////////////////////////////////////////////
@@ -63,7 +63,7 @@
set _setter1(/*[exact=JSUInt31]*/ value) {}
-/*element: setTopLevelSetter:[exact=JSUInt31]*/
+/*member: setTopLevelSetter:[exact=JSUInt31]*/
setTopLevelSetter() => _setter1 = 42;
////////////////////////////////////////////////////////////////////////////////
@@ -74,5 +74,5 @@
static set setter(/*[exact=JSUInt31]*/ value) {}
}
-/*element: setStaticSetter:[exact=JSUInt31]*/
+/*member: setStaticSetter:[exact=JSUInt31]*/
setStaticSetter() => Class3.setter = 42;
diff --git a/tests/compiler/dart2js/inference/data/static_type.dart b/tests/compiler/dart2js/inference/data/static_type.dart
index b25a3a8..d9b0e0b 100644
--- a/tests/compiler/dart2js/inference/data/static_type.dart
+++ b/tests/compiler/dart2js/inference/data/static_type.dart
@@ -3,19 +3,19 @@
// BSD-style license that can be found in the LICENSE file.
class C<T> {
- /*element: C.field:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: C.field:Union([exact=JSString], [exact=JSUInt31])*/
final T field;
- /*element: C.fixedFunctionField:[subclass=Closure]*/
+ /*member: C.fixedFunctionField:[subclass=Closure]*/
int Function() fixedFunctionField = /*[exact=JSUInt31]*/ () => 0;
- /*element: C.functionField:[null|subclass=Closure]*/
+ /*member: C.functionField:[null|subclass=Closure]*/
T Function() functionField;
- /*element: C.genericFunctionField:[null|subclass=Closure]*/
+ /*member: C.genericFunctionField:[null|subclass=Closure]*/
S Function<S>(S) genericFunctionField;
- /*element: C.:[exact=C]*/
+ /*member: C.:[exact=C]*/
C(this. /*Union([exact=JSString], [exact=JSUInt31])*/ field) {
/*update: [subclass=C]*/ functionField =
/*Union([exact=JSString], [exact=JSUInt31])*/
@@ -25,125 +25,125 @@
/*update: [subclass=C]*/ genericFunctionField = local;
}
- /*element: C.method:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: C.method:Union([exact=JSString], [exact=JSUInt31])*/
T method() => /*[subclass=C]*/ field;
- /*element: C.+:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: C.+:Union([exact=JSString], [exact=JSUInt31])*/
T operator +(T /*Union([exact=JSString], [exact=JSUInt31])*/ t) =>
/*[subclass=C]*/ field;
- /*element: C.getter:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: C.getter:Union([exact=JSString], [exact=JSUInt31])*/
T get getter => /*[subclass=C]*/ field;
- /*element: C.fixedFunctionGetter:[subclass=Closure]*/
+ /*member: C.fixedFunctionGetter:[subclass=Closure]*/
int Function() get fixedFunctionGetter => /*[exact=JSUInt31]*/ () => 0;
- /*element: C.functionGetter:[null|subclass=Closure]*/
+ /*member: C.functionGetter:[null|subclass=Closure]*/
T Function() get functionGetter => /*[subclass=C]*/ functionField;
- /*element: C.genericFunctionGetter:[null|subclass=Closure]*/
+ /*member: C.genericFunctionGetter:[null|subclass=Closure]*/
S Function<S>(S) get genericFunctionGetter =>
/*[subclass=C]*/ genericFunctionField;
- /*element: C.genericMethod:Union([exact=JSString], [exact=JSUInt31])*/
+ /*member: C.genericMethod:Union([exact=JSString], [exact=JSUInt31])*/
S genericMethod<S>(S /*Union([exact=JSString], [exact=JSUInt31])*/ s) => s;
}
class D1 extends C<int> {
- /*element: D1.:[exact=D1]*/
+ /*member: D1.:[exact=D1]*/
D1(int /*[exact=JSUInt31]*/ field) : super(field);
- /*element: D1.superFieldAccess:[exact=JSUInt31]*/
+ /*member: D1.superFieldAccess:[exact=JSUInt31]*/
superFieldAccess() => super.field;
- /*element: D1.superFieldInvoke:[null|subclass=JSInt]*/
+ /*member: D1.superFieldInvoke:[null|subclass=JSInt]*/
superFieldInvoke() => super.functionField();
- /*element: D1.superFixedFieldInvoke:[null|subclass=JSInt]*/
+ /*member: D1.superFixedFieldInvoke:[null|subclass=JSInt]*/
superFixedFieldInvoke() => super.fixedFunctionField();
- /*element: D1.superMethodInvoke:[exact=JSUInt31]*/
+ /*member: D1.superMethodInvoke:[exact=JSUInt31]*/
superMethodInvoke() => super.method();
- /*element: D1.superOperatorInvoke:[exact=JSUInt31]*/
+ /*member: D1.superOperatorInvoke:[exact=JSUInt31]*/
superOperatorInvoke() => super + 0;
- /*element: D1.superGetterAccess:[exact=JSUInt31]*/
+ /*member: D1.superGetterAccess:[exact=JSUInt31]*/
superGetterAccess() => super.getter;
- /*element: D1.superGetterInvoke:[null|subclass=JSInt]*/
+ /*member: D1.superGetterInvoke:[null|subclass=JSInt]*/
superGetterInvoke() => super.functionGetter();
- /*element: D1.superFixedGetterInvoke:[null|subclass=JSInt]*/
+ /*member: D1.superFixedGetterInvoke:[null|subclass=JSInt]*/
superFixedGetterInvoke() => super.fixedFunctionGetter();
- /*element: D1.superGenericFieldInvoke1:[null|exact=JSString]*/
+ /*member: D1.superGenericFieldInvoke1:[null|exact=JSString]*/
superGenericFieldInvoke1() => super.genericFunctionField('');
- /*element: D1.superGenericFieldInvoke2:[null|subclass=JSInt]*/
+ /*member: D1.superGenericFieldInvoke2:[null|subclass=JSInt]*/
superGenericFieldInvoke2() => super.genericFunctionField(0);
- /*element: D1.superGenericMethodInvoke1:[exact=JSString]*/
+ /*member: D1.superGenericMethodInvoke1:[exact=JSString]*/
superGenericMethodInvoke1() => super.genericMethod('');
- /*element: D1.superGenericMethodInvoke2:[exact=JSUInt31]*/
+ /*member: D1.superGenericMethodInvoke2:[exact=JSUInt31]*/
superGenericMethodInvoke2() => super.genericMethod(0);
- /*element: D1.superGenericGetterInvoke1:[null|exact=JSString]*/
+ /*member: D1.superGenericGetterInvoke1:[null|exact=JSString]*/
superGenericGetterInvoke1() => super.genericFunctionGetter('');
- /*element: D1.superGenericGetterInvoke2:[null|subclass=JSInt]*/
+ /*member: D1.superGenericGetterInvoke2:[null|subclass=JSInt]*/
superGenericGetterInvoke2() => super.genericFunctionGetter(0);
}
class D2 extends C<String> {
- /*element: D2.:[exact=D2]*/
+ /*member: D2.:[exact=D2]*/
D2(String /*Value([exact=JSString], value: "")*/ field) : super(field);
- /*element: D2.superFieldAccess:[exact=JSString]*/
+ /*member: D2.superFieldAccess:[exact=JSString]*/
superFieldAccess() => super.field;
- /*element: D2.superFieldInvoke:[null|exact=JSString]*/
+ /*member: D2.superFieldInvoke:[null|exact=JSString]*/
superFieldInvoke() => super.functionField();
- /*element: D2.superFixedFieldInvoke:[null|subclass=JSInt]*/
+ /*member: D2.superFixedFieldInvoke:[null|subclass=JSInt]*/
superFixedFieldInvoke() => super.fixedFunctionField();
- /*element: D2.superMethodInvoke:[exact=JSString]*/
+ /*member: D2.superMethodInvoke:[exact=JSString]*/
superMethodInvoke() => super.method();
- /*element: D2.superOperatorInvoke:[exact=JSString]*/
+ /*member: D2.superOperatorInvoke:[exact=JSString]*/
superOperatorInvoke() => super + '';
- /*element: D2.superGetterAccess:[exact=JSString]*/
+ /*member: D2.superGetterAccess:[exact=JSString]*/
superGetterAccess() => super.getter;
- /*element: D2.superGetterInvoke:[null|exact=JSString]*/
+ /*member: D2.superGetterInvoke:[null|exact=JSString]*/
superGetterInvoke() => super.functionGetter();
- /*element: D2.superFixedGetterInvoke:[null|subclass=JSInt]*/
+ /*member: D2.superFixedGetterInvoke:[null|subclass=JSInt]*/
superFixedGetterInvoke() => super.fixedFunctionGetter();
- /*element: D2.superGenericFieldInvoke1:[null|exact=JSString]*/
+ /*member: D2.superGenericFieldInvoke1:[null|exact=JSString]*/
superGenericFieldInvoke1() => super.genericFunctionField('');
- /*element: D2.superGenericFieldInvoke2:[null|subclass=JSInt]*/
+ /*member: D2.superGenericFieldInvoke2:[null|subclass=JSInt]*/
superGenericFieldInvoke2() => super.genericFunctionField(0);
- /*element: D2.superGenericMethodInvoke1:[exact=JSString]*/
+ /*member: D2.superGenericMethodInvoke1:[exact=JSString]*/
superGenericMethodInvoke1() => super.genericMethod('');
- /*element: D2.superGenericMethodInvoke2:[exact=JSUInt31]*/
+ /*member: D2.superGenericMethodInvoke2:[exact=JSUInt31]*/
superGenericMethodInvoke2() => super.genericMethod(0);
- /*element: D2.superGenericGetterInvoke1:[null|exact=JSString]*/
+ /*member: D2.superGenericGetterInvoke1:[null|exact=JSString]*/
superGenericGetterInvoke1() => super.genericFunctionGetter('');
- /*element: D2.superGenericGetterInvoke2:[null|subclass=JSInt]*/
+ /*member: D2.superGenericGetterInvoke2:[null|subclass=JSInt]*/
superGenericGetterInvoke2() => super.genericFunctionGetter(0);
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
closureInvoke();
localFunctionInvoke();
@@ -200,20 +200,20 @@
.. /*invoke: [exact=D2]*/ superGenericGetterInvoke2();
}
-/*element: closureInvoke:[null|subclass=JSInt]*/
+/*member: closureInvoke:[null|subclass=JSInt]*/
closureInvoke() {
int Function() f = /*[exact=JSUInt31]*/ () => 0;
return f();
}
-/*element: localFunctionInvoke:[exact=JSUInt31]*/
+/*member: localFunctionInvoke:[exact=JSUInt31]*/
localFunctionInvoke() {
/*[exact=JSUInt31]*/
int local() => 0;
return local();
}
-/*element: genericLocalFunctionInvoke:[null]*/
+/*member: genericLocalFunctionInvoke:[null]*/
genericLocalFunctionInvoke() {
/*Union([exact=JSString], [exact=JSUInt31])*/
S local<S>(S /*Union([exact=JSString], [exact=JSUInt31])*/ s) => s;
@@ -222,121 +222,121 @@
local(''). /*invoke: [exact=JSString]*/ toString();
}
-/*element: fieldAccess1:[exact=JSUInt31]*/
+/*member: fieldAccess1:[exact=JSUInt31]*/
fieldAccess1() {
C<int> c = new C<int>(0);
return c. /*[exact=C]*/ field;
}
-/*element: fieldAccess2:[exact=JSString]*/
+/*member: fieldAccess2:[exact=JSString]*/
fieldAccess2() {
C<String> c = new C<String>('');
return c. /*[exact=C]*/ field;
}
-/*element: fixedFieldInvoke:[null|subclass=JSInt]*/
+/*member: fixedFieldInvoke:[null|subclass=JSInt]*/
fixedFieldInvoke() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ fixedFunctionField();
}
-/*element: fieldInvoke1:[null|subclass=JSInt]*/
+/*member: fieldInvoke1:[null|subclass=JSInt]*/
fieldInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ functionField();
}
-/*element: fieldInvoke2:[null|exact=JSString]*/
+/*member: fieldInvoke2:[null|exact=JSString]*/
fieldInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ functionField();
}
-/*element: methodInvoke1:[exact=JSUInt31]*/
+/*member: methodInvoke1:[exact=JSUInt31]*/
methodInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ method();
}
-/*element: methodInvoke2:[exact=JSString]*/
+/*member: methodInvoke2:[exact=JSString]*/
methodInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ method();
}
-/*element: operatorInvoke1:[exact=JSUInt31]*/
+/*member: operatorInvoke1:[exact=JSUInt31]*/
operatorInvoke1() {
C<int> c = new C<int>(0);
return c /*invoke: [exact=C]*/ + 0;
}
-/*element: operatorInvoke2:[exact=JSString]*/
+/*member: operatorInvoke2:[exact=JSString]*/
operatorInvoke2() {
C<String> c = new C<String>('');
return c /*invoke: [exact=C]*/ + '';
}
-/*element: fixedGetterInvoke:[null|subclass=JSInt]*/
+/*member: fixedGetterInvoke:[null|subclass=JSInt]*/
fixedGetterInvoke() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ fixedFunctionGetter();
}
-/*element: getterAccess1:[exact=JSUInt31]*/
+/*member: getterAccess1:[exact=JSUInt31]*/
getterAccess1() {
C<int> c = new C<int>(0);
return c. /*[exact=C]*/ getter;
}
-/*element: getterAccess2:[exact=JSString]*/
+/*member: getterAccess2:[exact=JSString]*/
getterAccess2() {
C<String> c = new C<String>('');
return c. /*[exact=C]*/ getter;
}
-/*element: getterInvoke1:[null|subclass=JSInt]*/
+/*member: getterInvoke1:[null|subclass=JSInt]*/
getterInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ functionGetter();
}
-/*element: getterInvoke2:[null|exact=JSString]*/
+/*member: getterInvoke2:[null|exact=JSString]*/
getterInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ functionGetter();
}
-/*element: genericFieldInvoke1:[null|exact=JSString]*/
+/*member: genericFieldInvoke1:[null|exact=JSString]*/
genericFieldInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ genericFunctionField('');
}
-/*element: genericFieldInvoke2:[null|subclass=JSInt]*/
+/*member: genericFieldInvoke2:[null|subclass=JSInt]*/
genericFieldInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ genericFunctionField(0);
}
-/*element: genericMethodInvoke1:[exact=JSString]*/
+/*member: genericMethodInvoke1:[exact=JSString]*/
genericMethodInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ genericMethod('');
}
-/*element: genericMethodInvoke2:[exact=JSUInt31]*/
+/*member: genericMethodInvoke2:[exact=JSUInt31]*/
genericMethodInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ genericMethod(0);
}
-/*element: genericGetterInvoke1:[null|exact=JSString]*/
+/*member: genericGetterInvoke1:[null|exact=JSString]*/
genericGetterInvoke1() {
C<int> c = new C<int>(0);
return c. /*invoke: [exact=C]*/ genericFunctionGetter('');
}
-/*element: genericGetterInvoke2:[null|subclass=JSInt]*/
+/*member: genericGetterInvoke2:[null|subclass=JSInt]*/
genericGetterInvoke2() {
C<String> c = new C<String>('');
return c. /*invoke: [exact=C]*/ genericFunctionGetter(0);
diff --git a/tests/compiler/dart2js/inference/data/super_get.dart b/tests/compiler/dart2js/inference/data/super_get.dart
index d1f15f2..680d080 100644
--- a/tests/compiler/dart2js/inference/data/super_get.dart
+++ b/tests/compiler/dart2js/inference/data/super_get.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
superFieldAccess();
superGetterAccess();
@@ -13,19 +13,19 @@
// Access of super field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
class Super1 {
- /*element: Super1.field:[exact=JSUInt31]*/
+ /*member: Super1.field:[exact=JSUInt31]*/
var field = 42;
}
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
class Sub1 extends Super1 {
- /*element: Sub1.method:[exact=JSUInt31]*/
+ /*member: Sub1.method:[exact=JSUInt31]*/
method() => super.field;
}
-/*element: superFieldAccess:[null]*/
+/*member: superFieldAccess:[null]*/
superFieldAccess() {
new Sub1(). /*invoke: [exact=Sub1]*/ method();
}
@@ -34,19 +34,19 @@
// Access of super getter.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
class Super2 {
- /*element: Super2.getter:[exact=JSUInt31]*/
+ /*member: Super2.getter:[exact=JSUInt31]*/
get getter => 42;
}
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
class Sub2 extends Super2 {
- /*element: Sub2.method:[exact=JSUInt31]*/
+ /*member: Sub2.method:[exact=JSUInt31]*/
method() => super.getter;
}
-/*element: superGetterAccess:[null]*/
+/*member: superGetterAccess:[null]*/
superGetterAccess() {
new Sub2(). /*invoke: [exact=Sub2]*/ method();
}
@@ -55,19 +55,19 @@
// Access of super method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super3.:[exact=Super3]*/
+/*member: Super3.:[exact=Super3]*/
class Super3 {
- /*element: Super3.superMethod:[null]*/
+ /*member: Super3.superMethod:[null]*/
superMethod() {}
}
-/*element: Sub3.:[exact=Sub3]*/
+/*member: Sub3.:[exact=Sub3]*/
class Sub3 extends Super3 {
- /*element: Sub3.method:[subclass=Closure]*/
+ /*member: Sub3.method:[subclass=Closure]*/
method() => super.superMethod;
}
-/*element: superMethodAccess:[null]*/
+/*member: superMethodAccess:[null]*/
superMethodAccess() {
new Sub3(). /*invoke: [exact=Sub3]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/super_invoke.dart b/tests/compiler/dart2js/inference/data/super_invoke.dart
index 4d8c081..8392f1d 100644
--- a/tests/compiler/dart2js/inference/data/super_invoke.dart
+++ b/tests/compiler/dart2js/inference/data/super_invoke.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
superMethodInvoke();
superFieldInvoke();
@@ -14,22 +14,22 @@
// Invocation of super method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
class Super1 {
- /*element: Super1.method:[exact=JSUInt31]*/
+ /*member: Super1.method:[exact=JSUInt31]*/
method() => 42;
}
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
class Sub1 extends Super1 {
- /*element: Sub1.method:[subclass=JSPositiveInt]*/
+ /*member: Sub1.method:[subclass=JSPositiveInt]*/
method() {
var a = super.method();
return a. /*invoke: [exact=JSUInt31]*/ abs();
}
}
-/*element: superMethodInvoke:[null]*/
+/*member: superMethodInvoke:[null]*/
superMethodInvoke() {
new Sub1(). /*invoke: [exact=Sub1]*/ method();
}
@@ -38,24 +38,24 @@
// Invocation of super field.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[exact=JSUInt31]*/
+/*member: _method1:[exact=JSUInt31]*/
_method1() => 42;
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
class Super2 {
- /*element: Super2.field:[subclass=Closure]*/
+ /*member: Super2.field:[subclass=Closure]*/
var field = _method1;
}
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
class Sub2 extends Super2 {
- /*element: Sub2.method:[null|subclass=Object]*/
+ /*member: Sub2.method:[null|subclass=Object]*/
method() {
return super.field();
}
}
-/*element: superFieldInvoke:[null]*/
+/*member: superFieldInvoke:[null]*/
superFieldInvoke() {
new Sub2(). /*invoke: [exact=Sub2]*/ method();
}
@@ -64,24 +64,24 @@
// Invocation of super getter.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method2:[exact=JSUInt31]*/
+/*member: _method2:[exact=JSUInt31]*/
_method2() => 42;
-/*element: Super3.:[exact=Super3]*/
+/*member: Super3.:[exact=Super3]*/
class Super3 {
- /*element: Super3.getter:[subclass=Closure]*/
+ /*member: Super3.getter:[subclass=Closure]*/
get getter => _method2;
}
-/*element: Sub3.:[exact=Sub3]*/
+/*member: Sub3.:[exact=Sub3]*/
class Sub3 extends Super3 {
- /*element: Sub3.method:[null|subclass=Object]*/
+ /*member: Sub3.method:[null|subclass=Object]*/
method() {
return super.getter();
}
}
-/*element: superGetterInvoke:[null]*/
+/*member: superGetterInvoke:[null]*/
superGetterInvoke() {
new Sub3(). /*invoke: [exact=Sub3]*/ method();
}
@@ -90,24 +90,24 @@
// Invocation of abstract super method that overrides a concrete method.
////////////////////////////////////////////////////////////////////////////////
-/*element: SuperSuper10.:[exact=SuperSuper10]*/
+/*member: SuperSuper10.:[exact=SuperSuper10]*/
class SuperSuper10 {
- /*element: SuperSuper10.method:[exact=JSUInt31]*/
+ /*member: SuperSuper10.method:[exact=JSUInt31]*/
method() => 42;
}
-/*element: Super10.:[exact=Super10]*/
+/*member: Super10.:[exact=Super10]*/
class Super10 extends SuperSuper10 {
method();
}
-/*element: Sub10.:[exact=Sub10]*/
+/*member: Sub10.:[exact=Sub10]*/
class Sub10 extends Super10 {
- /*element: Sub10.method:[exact=JSUInt31]*/
+ /*member: Sub10.method:[exact=JSUInt31]*/
method() => super.method();
}
-/*element: overridingAbstractSuperMethodInvoke:[null]*/
+/*member: overridingAbstractSuperMethodInvoke:[null]*/
overridingAbstractSuperMethodInvoke() {
new Sub10(). /*invoke: [exact=Sub10]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/super_set.dart b/tests/compiler/dart2js/inference/data/super_set.dart
index e4f5314..1365c01 100644
--- a/tests/compiler/dart2js/inference/data/super_set.dart
+++ b/tests/compiler/dart2js/inference/data/super_set.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
superFieldUpdate();
superSetterUpdate();
@@ -12,22 +12,22 @@
// Update of super field.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
class Super1 {
- /*element: Super1.field:Union([exact=JSUInt31], [exact=Sub1])*/
+ /*member: Super1.field:Union([exact=JSUInt31], [exact=Sub1])*/
dynamic field = 42;
}
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
class Sub1 extends Super1 {
- /*element: Sub1.method:[subclass=Closure]*/
+ /*member: Sub1.method:[subclass=Closure]*/
method() {
var a = super.field = new Sub1();
return a. /*[exact=Sub1]*/ method;
}
}
-/*element: superFieldUpdate:[null]*/
+/*member: superFieldUpdate:[null]*/
superFieldUpdate() {
new Sub1(). /*invoke: [exact=Sub1]*/ method();
}
@@ -36,21 +36,21 @@
// Update of super setter.
////////////////////////////////////////////////////////////////////////////////
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
class Super2 {
set setter(/*[exact=Sub2]*/ value) {}
}
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
class Sub2 extends Super2 {
- /*element: Sub2.method:[subclass=Closure]*/
+ /*member: Sub2.method:[subclass=Closure]*/
method() {
var a = super.setter = new Sub2();
return a. /*[exact=Sub2]*/ method;
}
}
-/*element: superSetterUpdate:[null]*/
+/*member: superSetterUpdate:[null]*/
superSetterUpdate() {
new Sub2(). /*invoke: [exact=Sub2]*/ method();
}
diff --git a/tests/compiler/dart2js/inference/data/switch.dart b/tests/compiler/dart2js/inference/data/switch.dart
index c5a44ad..c7e9cb4 100644
--- a/tests/compiler/dart2js/inference/data/switch.dart
+++ b/tests/compiler/dart2js/inference/data/switch.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
switchWithoutDefault();
switchWithDefault();
@@ -15,7 +15,7 @@
// Switch statement without default case.
////////////////////////////////////////////////////////////////////////////////
-/*element: _switchWithoutDefault:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: _switchWithoutDefault:Union([exact=JSUInt31], [null|exact=JSString])*/
_switchWithoutDefault(/*[exact=JSUInt31]*/ o) {
var local;
switch (o) {
@@ -29,7 +29,7 @@
return local;
}
-/*element: switchWithoutDefault:[null]*/
+/*member: switchWithoutDefault:[null]*/
switchWithoutDefault() {
_switchWithoutDefault(0);
_switchWithoutDefault(1);
@@ -39,7 +39,7 @@
// Switch statement with default case.
////////////////////////////////////////////////////////////////////////////////
-/*element: _switchWithDefault:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithDefault:Union([exact=JSString], [exact=JSUInt31])*/
_switchWithDefault(/*[exact=JSUInt31]*/ o) {
var local;
switch (o) {
@@ -54,7 +54,7 @@
return local;
}
-/*element: switchWithDefault:[null]*/
+/*member: switchWithDefault:[null]*/
switchWithDefault() {
_switchWithDefault(0);
_switchWithDefault(1);
@@ -64,7 +64,7 @@
// Switch statement with default case without break.
////////////////////////////////////////////////////////////////////////////////
-/*element: _switchWithDefaultWithoutBreak:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithDefaultWithoutBreak:Union([exact=JSString], [exact=JSUInt31])*/
_switchWithDefaultWithoutBreak(/*[exact=JSUInt31]*/ o) {
var local;
switch (o) {
@@ -78,7 +78,7 @@
return local;
}
-/*element: switchWithDefaultWithoutBreak:[null]*/
+/*member: switchWithDefaultWithoutBreak:[null]*/
switchWithDefaultWithoutBreak() {
_switchWithDefaultWithoutBreak(0);
_switchWithDefaultWithoutBreak(1);
@@ -88,7 +88,7 @@
// Switch statement with continue.
////////////////////////////////////////////////////////////////////////////////
-/*element: _switchWithContinue:Union([exact=JSBool], [exact=JSString], [null|exact=JSUInt31])*/
+/*member: _switchWithContinue:Union([exact=JSBool], [exact=JSString], [null|exact=JSUInt31])*/
_switchWithContinue(/*[exact=JSUInt31]*/ o) {
dynamic local;
switch (o) {
@@ -107,7 +107,7 @@
return local;
}
-/*element: switchWithContinue:[null]*/
+/*member: switchWithContinue:[null]*/
switchWithContinue() {
_switchWithContinue(0);
_switchWithContinue(1);
@@ -118,7 +118,7 @@
// the continue statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _switchWithoutContinue:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithoutContinue:Union([exact=JSString], [exact=JSUInt31])*/
_switchWithoutContinue(/*[exact=JSUInt31]*/ o) {
dynamic local;
switch (o) {
@@ -135,7 +135,7 @@
return local;
}
-/*element: switchWithoutContinue:[null]*/
+/*member: switchWithoutContinue:[null]*/
switchWithoutContinue() {
_switchWithoutContinue(0);
_switchWithoutContinue(1);
diff --git a/tests/compiler/dart2js/inference/data/switch1.dart b/tests/compiler/dart2js/inference/data/switch1.dart
index 036ccba..a9f9e32 100644
--- a/tests/compiler/dart2js/inference/data/switch1.dart
+++ b/tests/compiler/dart2js/inference/data/switch1.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.
-/*element: foo:[exact=JSString]*/
+/*member: foo:[exact=JSString]*/
foo(int /*[subclass=JSInt]*/ x) {
var a = "one";
switch (x) {
@@ -16,6 +16,6 @@
return a;
}
-/*element: main:[null]*/ main() {
+/*member: main:[null]*/ main() {
foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
}
diff --git a/tests/compiler/dart2js/inference/data/switch2.dart b/tests/compiler/dart2js/inference/data/switch2.dart
index ed9a38e..c2aaa71 100644
--- a/tests/compiler/dart2js/inference/data/switch2.dart
+++ b/tests/compiler/dart2js/inference/data/switch2.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.
-/*element: foo:Value([null|exact=JSString], value: "two")*/
+/*member: foo:Value([null|exact=JSString], value: "two")*/
foo(int /*[subclass=JSInt]*/ x) {
var a;
switch (x) {
@@ -16,7 +16,7 @@
return a;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
}
diff --git a/tests/compiler/dart2js/inference/data/switch5.dart b/tests/compiler/dart2js/inference/data/switch5.dart
index 1ce09a6..3263b55 100644
--- a/tests/compiler/dart2js/inference/data/switch5.dart
+++ b/tests/compiler/dart2js/inference/data/switch5.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.
-/*element: foo:[null|exact=JSUInt31]*/
+/*member: foo:[null|exact=JSUInt31]*/
foo(int /*[subclass=JSInt]*/ x) {
var a;
switch (x) {
@@ -18,7 +18,7 @@
return a;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
}
diff --git a/tests/compiler/dart2js/inference/data/switch6.dart b/tests/compiler/dart2js/inference/data/switch6.dart
index 8761199..2155d6f 100644
--- a/tests/compiler/dart2js/inference/data/switch6.dart
+++ b/tests/compiler/dart2js/inference/data/switch6.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.
-/*element: foo:[null|exact=JSUInt31]*/
+/*member: foo:[null|exact=JSUInt31]*/
foo(int /*[subclass=JSInt]*/ x) {
var a;
do {
@@ -20,7 +20,7 @@
return a;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
}
diff --git a/tests/compiler/dart2js/inference/data/throw.dart b/tests/compiler/dart2js/inference/data/throw.dart
index 679147c..e844463 100644
--- a/tests/compiler/dart2js/inference/data/throw.dart
+++ b/tests/compiler/dart2js/inference/data/throw.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
unconditionalThrow();
conditionalThrow();
@@ -14,19 +14,19 @@
/// Method that throws unconditionally.
////////////////////////////////////////////////////////////////////////////////
-/*element: unconditionalThrow:[empty]*/
+/*member: unconditionalThrow:[empty]*/
unconditionalThrow() => throw 'foo';
////////////////////////////////////////////////////////////////////////////////
/// Method that throws conditionally.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalThrow:[null]*/
+/*member: _conditionalThrow:[null]*/
_conditionalThrow(/*[exact=JSBool]*/ o) {
if (o) throw 'foo';
}
-/*element: conditionalThrow:[null]*/
+/*member: conditionalThrow:[null]*/
conditionalThrow() {
_conditionalThrow(true);
_conditionalThrow(false);
@@ -36,13 +36,13 @@
/// Method that throws conditionally and return 0.
////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalThrowReturn:[exact=JSUInt31]*/
+/*member: _conditionalThrowReturn:[exact=JSUInt31]*/
_conditionalThrowReturn(/*[exact=JSBool]*/ o) {
if (o) throw 'foo';
return 0;
}
-/*element: conditionalThrowReturn:[null]*/
+/*member: conditionalThrowReturn:[null]*/
conditionalThrowReturn() {
_conditionalThrowReturn(true);
_conditionalThrowReturn(false);
@@ -52,7 +52,7 @@
/// Method that rethrows unconditionally.
////////////////////////////////////////////////////////////////////////////////
-/*element: unconditionalRethrow:[null]*/
+/*member: unconditionalRethrow:[null]*/
unconditionalRethrow() {
try {
throw 'foo';
diff --git a/tests/compiler/dart2js/inference/data/try.dart b/tests/compiler/dart2js/inference/data/try.dart
index 340c852..ac0416f 100644
--- a/tests/compiler/dart2js/inference/data/try.dart
+++ b/tests/compiler/dart2js/inference/data/try.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
emptyTryCatch();
emptyTryFinally();
@@ -25,13 +25,13 @@
/// Parameter passed through an empty try-catch statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _emptyTryCatch:[exact=JSUInt31]*/
+/*member: _emptyTryCatch:[exact=JSUInt31]*/
_emptyTryCatch(/*[exact=JSUInt31]*/ o) {
try {} catch (e) {}
return o;
}
-/*element: emptyTryCatch:[null]*/
+/*member: emptyTryCatch:[null]*/
emptyTryCatch() {
_emptyTryCatch(0);
}
@@ -40,13 +40,13 @@
/// Parameter passed through an empty try-finally statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _emptyTryFinally:[exact=JSUInt31]*/
+/*member: _emptyTryFinally:[exact=JSUInt31]*/
_emptyTryFinally(/*[exact=JSUInt31]*/ o) {
try {} finally {}
return o;
}
-/*element: emptyTryFinally:[null]*/
+/*member: emptyTryFinally:[null]*/
emptyTryFinally() {
_emptyTryFinally(0);
}
@@ -55,13 +55,13 @@
/// Parameter passed through an empty try-catch-finally statement.
////////////////////////////////////////////////////////////////////////////////
-/*element: _emptyTryCatchFinally:[exact=JSUInt31]*/
+/*member: _emptyTryCatchFinally:[exact=JSUInt31]*/
_emptyTryCatchFinally(/*[exact=JSUInt31]*/ o) {
try {} catch (e) {} finally {}
return o;
}
-/*element: emptyTryCatchFinally:[null]*/
+/*member: emptyTryCatchFinally:[null]*/
emptyTryCatchFinally() {
_emptyTryCatchFinally(0);
}
@@ -70,7 +70,7 @@
/// A try-catch statement with an assignment in the try block.
////////////////////////////////////////////////////////////////////////////////
-/*element: tryCatchAssignmentInTry:[null|exact=JSUInt31]*/
+/*member: tryCatchAssignmentInTry:[null|exact=JSUInt31]*/
tryCatchAssignmentInTry() {
var o = 0;
try {
@@ -83,7 +83,7 @@
/// A try-catch statement with an assignment in the catch block.
////////////////////////////////////////////////////////////////////////////////
-/*element: tryCatchAssignmentInCatch:[null|exact=JSUInt31]*/
+/*member: tryCatchAssignmentInCatch:[null|exact=JSUInt31]*/
tryCatchAssignmentInCatch() {
var o = 0;
try {} catch (e) {
@@ -96,7 +96,7 @@
/// A try-finally statement with an assignment in the finally clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: tryFinallyAssignmentInFinally:[null]*/
+/*member: tryFinallyAssignmentInFinally:[null]*/
tryFinallyAssignmentInFinally() {
var o = 0;
try {} finally {
@@ -110,7 +110,7 @@
/// block.
////////////////////////////////////////////////////////////////////////////////
-/*element: tryCatchAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: tryCatchAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
tryCatchAssignmentInTryCatch() {
dynamic o = 0;
try {
@@ -126,7 +126,7 @@
/// finally block.
////////////////////////////////////////////////////////////////////////////////
-/*element: tryCatchAssignmentInTryFinally:[null]*/
+/*member: tryCatchAssignmentInTryFinally:[null]*/
tryCatchAssignmentInTryFinally() {
dynamic o = 0;
try {
@@ -142,7 +142,7 @@
/// catch clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryCatchParameterAssignmentInTry:[null|exact=JSUInt31]*/
+/*member: _tryCatchParameterAssignmentInTry:[null|exact=JSUInt31]*/
_tryCatchParameterAssignmentInTry(/*[exact=JSUInt31]*/ o) {
try {
o = null;
@@ -150,7 +150,7 @@
return o;
}
-/*element: tryCatchParameterAssignmentInTry:[null]*/
+/*member: tryCatchParameterAssignmentInTry:[null]*/
tryCatchParameterAssignmentInTry() {
_tryCatchParameterAssignmentInTry(0);
}
@@ -160,7 +160,7 @@
/// catch clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryCatchParameterAssignmentInCatch:[null|exact=JSUInt31]*/
+/*member: _tryCatchParameterAssignmentInCatch:[null|exact=JSUInt31]*/
_tryCatchParameterAssignmentInCatch(/*[exact=JSUInt31]*/ o) {
try {} catch (e) {
o = null;
@@ -168,7 +168,7 @@
return o;
}
-/*element: tryCatchParameterAssignmentInCatch:[null]*/
+/*member: tryCatchParameterAssignmentInCatch:[null]*/
tryCatchParameterAssignmentInCatch() {
_tryCatchParameterAssignmentInCatch(0);
}
@@ -178,7 +178,7 @@
/// finally clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryFinallyParameterAssignmentInFinally:[null]*/
+/*member: _tryFinallyParameterAssignmentInFinally:[null]*/
_tryFinallyParameterAssignmentInFinally(/*[exact=JSUInt31]*/ o) {
try {} finally {
o = null;
@@ -186,7 +186,7 @@
return o;
}
-/*element: tryFinallyParameterAssignmentInFinally:[null]*/
+/*member: tryFinallyParameterAssignmentInFinally:[null]*/
tryFinallyParameterAssignmentInFinally() {
_tryFinallyParameterAssignmentInFinally(0);
}
@@ -196,7 +196,7 @@
/// catch clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryCatchParameterAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: _tryCatchParameterAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
_tryCatchParameterAssignmentInTryCatch(/*[exact=JSUInt31]*/ o) {
try {
o = '';
@@ -206,7 +206,7 @@
return o;
}
-/*element: tryCatchParameterAssignmentInTryCatch:[null]*/
+/*member: tryCatchParameterAssignmentInTryCatch:[null]*/
tryCatchParameterAssignmentInTryCatch() {
_tryCatchParameterAssignmentInTryCatch(0);
}
@@ -216,7 +216,7 @@
/// finally clause.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryFinallyParameterAssignmentInTryFinally:[null]*/
+/*member: _tryFinallyParameterAssignmentInTryFinally:[null]*/
_tryFinallyParameterAssignmentInTryFinally(/*[exact=JSUInt31]*/ o) {
try {
o = '';
@@ -226,7 +226,7 @@
return o;
}
-/*element: tryFinallyParameterAssignmentInTryFinally:[null]*/
+/*member: tryFinallyParameterAssignmentInTryFinally:[null]*/
tryFinallyParameterAssignmentInTryFinally() {
_tryFinallyParameterAssignmentInTryFinally(0);
}
diff --git a/tests/compiler/dart2js/inference/data/try_catch.dart b/tests/compiler/dart2js/inference/data/try_catch.dart
index b4209bb..9dfe310 100644
--- a/tests/compiler/dart2js/inference/data/try_catch.dart
+++ b/tests/compiler/dart2js/inference/data/try_catch.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.
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
returnInt1() {
var a = 42;
try {
@@ -11,7 +11,7 @@
return a;
}
-/*element: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn1() {
dynamic a = 42;
try {
@@ -20,7 +20,7 @@
return a;
}
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
returnInt2() {
var a = 42;
try {
@@ -31,7 +31,7 @@
return a;
}
-/*element: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn2() {
dynamic a = 42;
try {
@@ -42,7 +42,7 @@
return a;
}
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
returnInt3() {
dynamic a = 42;
try {
@@ -55,7 +55,7 @@
return a;
}
-/*element: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn3() {
dynamic a = 42;
try {
@@ -70,7 +70,7 @@
return a;
}
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
returnInt4() {
var a = 42;
try {
@@ -85,7 +85,7 @@
return a;
}
-/*element: returnDyn4:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn4:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn4() {
dynamic a = 42;
if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -96,7 +96,7 @@
return a;
}
-/*element: returnInt5:[exact=JSUInt31]*/
+/*member: returnInt5:[exact=JSUInt31]*/
returnInt5() {
var a = 42;
if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -107,7 +107,7 @@
return a;
}
-/*element: returnDyn5:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn5:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn5() {
dynamic a = 42;
if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -120,7 +120,7 @@
return a;
}
-/*element: returnInt6:[subclass=JSInt]*/
+/*member: returnInt6:[subclass=JSInt]*/
returnInt6() {
try {
throw 42;
@@ -131,7 +131,7 @@
return 42;
}
-/*element: returnDyn6:[null|subclass=Object]*/
+/*member: returnDyn6:[null|subclass=Object]*/
returnDyn6() {
try {
throw 42;
@@ -140,7 +140,7 @@
}
}
-/*element: returnInt7:[exact=JSUInt31]*/
+/*member: returnInt7:[exact=JSUInt31]*/
returnInt7() {
dynamic a = 'foo';
try {
@@ -150,7 +150,7 @@
return 2;
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
returnInt1();
returnDyn1();
diff --git a/tests/compiler/dart2js/inference/data/type_literal.dart b/tests/compiler/dart2js/inference/data/type_literal.dart
index 46644d9..63ab341 100644
--- a/tests/compiler/dart2js/inference/data/type_literal.dart
+++ b/tests/compiler/dart2js/inference/data/type_literal.dart
@@ -2,20 +2,20 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
typeLiteral();
typeLiteralToString();
typeLiteralSubstring();
}
-/*element: typeLiteral:[exact=TypeImpl]*/
+/*member: typeLiteral:[exact=TypeImpl]*/
typeLiteral() => Object;
-/*element: typeLiteralToString:[exact=JSString]*/
+/*member: typeLiteralToString:[exact=JSString]*/
typeLiteralToString() => (Object). /*invoke: [exact=TypeImpl]*/ toString();
-/*element: typeLiteralSubstring:[exact=JSString]*/
+/*member: typeLiteralSubstring:[exact=JSString]*/
typeLiteralSubstring() {
String name = (List). /*invoke: [exact=TypeImpl]*/ toString();
name = name. /*invoke: [exact=JSString]*/ substring(
diff --git a/tests/compiler/dart2js/inference/data/unregister_call.dart b/tests/compiler/dart2js/inference/data/unregister_call.dart
index cfe5be7..b07989b 100644
--- a/tests/compiler/dart2js/inference/data/unregister_call.dart
+++ b/tests/compiler/dart2js/inference/data/unregister_call.dart
@@ -2,16 +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.
-/*element: a:Value([exact=JSString], value: "")*/
+/*member: a:Value([exact=JSString], value: "")*/
var a = '';
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {
- /*element: A.+:[exact=JSUInt31]*/
+ /*member: A.+:[exact=JSUInt31]*/
operator +(/*[exact=JSUInt31]*/ other) => other;
}
-/*element: foo:[exact=JSString]*/
+/*member: foo:[exact=JSString]*/
foo() {
// The following '+' call will first say that it may call A::+,
// String::+, or int::+. After all methods have been analyzed, we know
@@ -21,7 +21,7 @@
return a /*invoke: Value([exact=JSString], value: "")*/ + 'foo';
}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
new A() /*invoke: [exact=A]*/ + 42;
foo();
diff --git a/tests/compiler/dart2js/inference/data/use_static_types.dart b/tests/compiler/dart2js/inference/data/use_static_types.dart
index 1d59e90..f701b6d 100644
--- a/tests/compiler/dart2js/inference/data/use_static_types.dart
+++ b/tests/compiler/dart2js/inference/data/use_static_types.dart
@@ -2,77 +2,77 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
class A {}
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
class B extends A {}
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
class C {}
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
invokeFunctions();
invokeGenericClasses();
invokeGenericMethods();
}
-/*element: invokeFunction1:[null|subclass=A]*/
+/*member: invokeFunction1:[null|subclass=A]*/
invokeFunction1(A Function() /*[subclass=Closure]*/ f) {
return f();
}
-/*element: invokeFunction2:[null|exact=B]*/
+/*member: invokeFunction2:[null|exact=B]*/
invokeFunction2(B Function() /*[subclass=Closure]*/ f) {
return f();
}
-/*element: invokeFunction3:[null|exact=C]*/
+/*member: invokeFunction3:[null|exact=C]*/
invokeFunction3(C Function() /*[subclass=Closure]*/ f) {
return f();
}
-/*element: genericFunction:[null|subclass=Object]*/
+/*member: genericFunction:[null|subclass=Object]*/
T genericFunction<T>(T Function() /*[subclass=Closure]*/ f) => f();
-/*element: invokeGenericFunction1:[null|subclass=A]*/
+/*member: invokeGenericFunction1:[null|subclass=A]*/
invokeGenericFunction1() {
return genericFunction<A>(/*[exact=A]*/ () => new A());
}
-/*element: invokeGenericFunction2:[null|exact=B]*/
+/*member: invokeGenericFunction2:[null|exact=B]*/
invokeGenericFunction2() {
return genericFunction<B>(/*[exact=B]*/ () => new B());
}
-/*element: invokeGenericFunction3:[null|exact=C]*/
+/*member: invokeGenericFunction3:[null|exact=C]*/
invokeGenericFunction3() {
return genericFunction<C>(/*[exact=C]*/ () => new C());
}
-/*element: invokeGenericLocalFunction1:[null|subclass=A]*/
+/*member: invokeGenericLocalFunction1:[null|subclass=A]*/
invokeGenericLocalFunction1() {
/*[null|subclass=Object]*/
T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
return local<A>(/*[exact=A]*/ () => new A());
}
-/*element: invokeGenericLocalFunction2:[null|exact=B]*/
+/*member: invokeGenericLocalFunction2:[null|exact=B]*/
invokeGenericLocalFunction2() {
/*[null|subclass=Object]*/
T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
return local<B>(/*[exact=B]*/ () => new B());
}
-/*element: invokeGenericLocalFunction3:[null|exact=C]*/
+/*member: invokeGenericLocalFunction3:[null|exact=C]*/
invokeGenericLocalFunction3() {
/*[null|subclass=Object]*/
T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
return local<C>(/*[exact=C]*/ () => new C());
}
-/*element: invokeFunctions:[null]*/
+/*member: invokeFunctions:[null]*/
invokeFunctions() {
invokeFunction1(/*[exact=A]*/ () => new A());
invokeFunction2(/*[exact=B]*/ () => new B());
@@ -86,214 +86,214 @@
}
class GenericClass<T> {
- /*element: GenericClass.field:Union([exact=C], [subclass=A])*/
+ /*member: GenericClass.field:Union([exact=C], [subclass=A])*/
final T field;
- /*element: GenericClass.functionTypedField:[subclass=Closure]*/
+ /*member: GenericClass.functionTypedField:[subclass=Closure]*/
final T Function() functionTypedField;
- /*element: GenericClass.:[exact=GenericClass]*/
+ /*member: GenericClass.:[exact=GenericClass]*/
GenericClass(this. /*Union([exact=C], [subclass=A])*/ field)
: functionTypedField = (/*Union([exact=C], [subclass=A])*/ () => field);
- /*element: GenericClass.getter:Union([exact=C], [subclass=A])*/
+ /*member: GenericClass.getter:Union([exact=C], [subclass=A])*/
T get getter => /*[subclass=GenericClass]*/ field;
- /*element: GenericClass.functionTypedGetter:[subclass=Closure]*/
+ /*member: GenericClass.functionTypedGetter:[subclass=Closure]*/
T Function()
get functionTypedGetter => /*[subclass=GenericClass]*/ functionTypedField;
- /*element: GenericClass.method:Union([exact=C], [subclass=A])*/
+ /*member: GenericClass.method:Union([exact=C], [subclass=A])*/
T method() => /*[subclass=GenericClass]*/ field;
- /*element: GenericClass.functionTypedMethod:[subclass=Closure]*/
+ /*member: GenericClass.functionTypedMethod:[subclass=Closure]*/
T Function()
functionTypedMethod() => /*[subclass=GenericClass]*/ functionTypedField;
}
class GenericSubclass<T> extends GenericClass<T> {
- /*element: GenericSubclass.:[exact=GenericSubclass]*/
+ /*member: GenericSubclass.:[exact=GenericSubclass]*/
GenericSubclass(T /*Union([exact=C], [subclass=A])*/ field) : super(field);
- /*element: GenericSubclass.superField:Union([exact=C], [subclass=A])*/
+ /*member: GenericSubclass.superField:Union([exact=C], [subclass=A])*/
superField() => super.field;
- /*element: GenericSubclass.superGetter:Union([exact=C], [subclass=A])*/
+ /*member: GenericSubclass.superGetter:Union([exact=C], [subclass=A])*/
superGetter() => super.getter;
- /*element: GenericSubclass.superMethod:Union([exact=C], [subclass=A])*/
+ /*member: GenericSubclass.superMethod:Union([exact=C], [subclass=A])*/
superMethod() => super.method();
- /*element: GenericSubclass.superFieldInvoke:[null|subclass=Object]*/
+ /*member: GenericSubclass.superFieldInvoke:[null|subclass=Object]*/
superFieldInvoke() => super.functionTypedField();
- /*element: GenericSubclass.superGetterInvoke:[null|subclass=Object]*/
+ /*member: GenericSubclass.superGetterInvoke:[null|subclass=Object]*/
superGetterInvoke() => super.functionTypedGetter();
- /*element: GenericSubclass.superMethodInvoke:[null|subclass=Object]*/
+ /*member: GenericSubclass.superMethodInvoke:[null|subclass=Object]*/
superMethodInvoke() => super.functionTypedMethod()();
}
-/*element: invokeInstanceMethod1:[subclass=A]*/
+/*member: invokeInstanceMethod1:[subclass=A]*/
invokeInstanceMethod1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ method();
-/*element: invokeInstanceMethod2:[exact=B]*/
+/*member: invokeInstanceMethod2:[exact=B]*/
invokeInstanceMethod2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ method();
-/*element: invokeInstanceMethod3:[exact=C]*/
+/*member: invokeInstanceMethod3:[exact=C]*/
invokeInstanceMethod3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ method();
-/*element: invokeInstanceGetter1:[subclass=A]*/
+/*member: invokeInstanceGetter1:[subclass=A]*/
invokeInstanceGetter1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ getter;
-/*element: invokeInstanceGetter2:[exact=B]*/
+/*member: invokeInstanceGetter2:[exact=B]*/
invokeInstanceGetter2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ getter;
-/*element: invokeInstanceGetter3:[exact=C]*/
+/*member: invokeInstanceGetter3:[exact=C]*/
invokeInstanceGetter3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ getter;
-/*element: accessInstanceField1:[subclass=A]*/
+/*member: accessInstanceField1:[subclass=A]*/
accessInstanceField1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ field;
-/*element: accessInstanceField2:[exact=B]*/
+/*member: accessInstanceField2:[exact=B]*/
accessInstanceField2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ field;
-/*element: accessInstanceField3:[exact=C]*/
+/*member: accessInstanceField3:[exact=C]*/
accessInstanceField3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*[exact=GenericClass]*/ field;
-/*element: invokeSuperMethod1:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod1:Union([exact=C], [subclass=A])*/
invokeSuperMethod1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethod();
-/*element: invokeSuperMethod2:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod2:Union([exact=C], [subclass=A])*/
invokeSuperMethod2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethod();
-/*element: invokeSuperMethod3:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod3:Union([exact=C], [subclass=A])*/
invokeSuperMethod3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethod();
-/*element: invokeSuperGetter1:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter1:Union([exact=C], [subclass=A])*/
invokeSuperGetter1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetter();
-/*element: invokeSuperGetter2:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter2:Union([exact=C], [subclass=A])*/
invokeSuperGetter2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetter();
-/*element: invokeSuperGetter3:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter3:Union([exact=C], [subclass=A])*/
invokeSuperGetter3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetter();
-/*element: accessSuperField1:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField1:Union([exact=C], [subclass=A])*/
accessSuperField1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superField();
-/*element: accessSuperField2:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField2:Union([exact=C], [subclass=A])*/
accessSuperField2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superField();
-/*element: accessSuperField3:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField3:Union([exact=C], [subclass=A])*/
accessSuperField3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superField();
-/*element: invokeFunctionTypedInstanceMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceMethod1:[null|subclass=A]*/
invokeFunctionTypedInstanceMethod1(
GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
-/*element: invokeFunctionTypedInstanceMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceMethod2:[null|exact=B]*/
invokeFunctionTypedInstanceMethod2(
GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
-/*element: invokeFunctionTypedInstanceMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceMethod3:[null|exact=C]*/
invokeFunctionTypedInstanceMethod3(
GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
-/*element: invokeFunctionTypedInstanceGetter1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceGetter1:[null|subclass=A]*/
invokeFunctionTypedInstanceGetter1(
GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
-/*element: invokeFunctionTypedInstanceGetter2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceGetter2:[null|exact=B]*/
invokeFunctionTypedInstanceGetter2(
GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
-/*element: invokeFunctionTypedInstanceGetter3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceGetter3:[null|exact=C]*/
invokeFunctionTypedInstanceGetter3(
GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
-/*element: invokeFunctionTypedInstanceField1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceField1:[null|subclass=A]*/
invokeFunctionTypedInstanceField1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedField();
-/*element: invokeFunctionTypedInstanceField2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceField2:[null|exact=B]*/
invokeFunctionTypedInstanceField2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedField();
-/*element: invokeFunctionTypedInstanceField3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceField3:[null|exact=C]*/
invokeFunctionTypedInstanceField3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
c. /*invoke: [exact=GenericClass]*/ functionTypedField();
-/*element: invokeFunctionTypedSuperMethod1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod1:[null|subclass=Object]*/
invokeFunctionTypedSuperMethod1(
GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
-/*element: invokeFunctionTypedSuperMethod2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod2:[null|subclass=Object]*/
invokeFunctionTypedSuperMethod2(
GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
-/*element: invokeFunctionTypedSuperMethod3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod3:[null|subclass=Object]*/
invokeFunctionTypedSuperMethod3(
GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
-/*element: invokeFunctionTypedSuperGetter1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter1:[null|subclass=Object]*/
invokeFunctionTypedSuperGetter1(
GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
-/*element: invokeFunctionTypedSuperGetter2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter2:[null|subclass=Object]*/
invokeFunctionTypedSuperGetter2(
GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
-/*element: invokeFunctionTypedSuperGetter3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter3:[null|subclass=Object]*/
invokeFunctionTypedSuperGetter3(
GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
-/*element: invokeFunctionTypedSuperField1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField1:[null|subclass=Object]*/
invokeFunctionTypedSuperField1(
GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
-/*element: invokeFunctionTypedSuperField2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField2:[null|subclass=Object]*/
invokeFunctionTypedSuperField2(
GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
-/*element: invokeFunctionTypedSuperField3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField3:[null|subclass=Object]*/
invokeFunctionTypedSuperField3(
GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
-/*element: invokeGenericClasses:[null]*/
+/*member: invokeGenericClasses:[null]*/
invokeGenericClasses() {
invokeInstanceMethod1(new GenericClass<A>(new A()));
invokeInstanceMethod2(new GenericClass<B>(new B()));
@@ -336,128 +336,128 @@
invokeFunctionTypedSuperField3(new GenericSubclass<C>(new C()));
}
-/*element: genericMethod:Union([exact=C], [subclass=A])*/
+/*member: genericMethod:Union([exact=C], [subclass=A])*/
T genericMethod<T>(T /*Union([exact=C], [subclass=A])*/ t) => t;
-/*element: functionTypedGenericMethod:[subclass=Closure]*/
+/*member: functionTypedGenericMethod:[subclass=Closure]*/
T Function() functionTypedGenericMethod<T>(
T /*Union([exact=C], [subclass=A])*/ t) =>
/*Union([exact=C], [subclass=A])*/ () => t;
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
class Class {
- /*element: Class.genericMethod:Union([exact=C], [subclass=A])*/
+ /*member: Class.genericMethod:Union([exact=C], [subclass=A])*/
T genericMethod<T>(T /*Union([exact=C], [subclass=A])*/ t) => t;
- /*element: Class.functionTypedGenericMethod:[subclass=Closure]*/
+ /*member: Class.functionTypedGenericMethod:[subclass=Closure]*/
T Function() functionTypedGenericMethod<T>(
T /*Union([exact=C], [subclass=A])*/ t) =>
/*Union([exact=C], [subclass=A])*/ () => t;
}
-/*element: Subclass.:[exact=Subclass]*/
+/*member: Subclass.:[exact=Subclass]*/
class Subclass extends Class {
- /*element: Subclass.superMethod1:[subclass=A]*/
+ /*member: Subclass.superMethod1:[subclass=A]*/
superMethod1() {
return super.genericMethod<A>(new A());
}
- /*element: Subclass.superMethod2:[exact=B]*/
+ /*member: Subclass.superMethod2:[exact=B]*/
superMethod2() {
return super.genericMethod<B>(new B());
}
- /*element: Subclass.superMethod3:[exact=C]*/
+ /*member: Subclass.superMethod3:[exact=C]*/
superMethod3() {
return super.genericMethod<C>(new C());
}
- /*element: Subclass.functionTypedSuperMethod1:[null|subclass=A]*/
+ /*member: Subclass.functionTypedSuperMethod1:[null|subclass=A]*/
functionTypedSuperMethod1() {
return super.functionTypedGenericMethod<A>(new A())();
}
- /*element: Subclass.functionTypedSuperMethod2:[null|exact=B]*/
+ /*member: Subclass.functionTypedSuperMethod2:[null|exact=B]*/
functionTypedSuperMethod2() {
return super.functionTypedGenericMethod<B>(new B())();
}
- /*element: Subclass.functionTypedSuperMethod3:[null|exact=C]*/
+ /*member: Subclass.functionTypedSuperMethod3:[null|exact=C]*/
functionTypedSuperMethod3() {
return super.functionTypedGenericMethod<C>(new C())();
}
}
-/*element: invokeGenericMethod1:[subclass=A]*/
+/*member: invokeGenericMethod1:[subclass=A]*/
invokeGenericMethod1(A /*[exact=A]*/ a) => genericMethod<A>(a);
-/*element: invokeGenericMethod2:[exact=B]*/
+/*member: invokeGenericMethod2:[exact=B]*/
invokeGenericMethod2(B /*[exact=B]*/ b) => genericMethod<B>(b);
-/*element: invokeGenericMethod3:[exact=C]*/
+/*member: invokeGenericMethod3:[exact=C]*/
invokeGenericMethod3(C /*[exact=C]*/ c) => genericMethod<C>(c);
-/*element: invokeGenericInstanceMethod1:[subclass=A]*/
+/*member: invokeGenericInstanceMethod1:[subclass=A]*/
invokeGenericInstanceMethod1() =>
new Class(). /*invoke: [exact=Class]*/ genericMethod<A>(new A());
-/*element: invokeGenericInstanceMethod2:[exact=B]*/
+/*member: invokeGenericInstanceMethod2:[exact=B]*/
invokeGenericInstanceMethod2() =>
new Class(). /*invoke: [exact=Class]*/ genericMethod<B>(new B());
-/*element: invokeGenericInstanceMethod3:[exact=C]*/
+/*member: invokeGenericInstanceMethod3:[exact=C]*/
invokeGenericInstanceMethod3() =>
new Class(). /*invoke: [exact=Class]*/ genericMethod<C>(new C());
-/*element: invokeGenericSuperMethod1:[subclass=A]*/
+/*member: invokeGenericSuperMethod1:[subclass=A]*/
invokeGenericSuperMethod1() =>
new Subclass(). /*invoke: [exact=Subclass]*/ superMethod1();
-/*element: invokeGenericSuperMethod2:[exact=B]*/
+/*member: invokeGenericSuperMethod2:[exact=B]*/
invokeGenericSuperMethod2() =>
new Subclass(). /*invoke: [exact=Subclass]*/ superMethod2();
-/*element: invokeGenericSuperMethod3:[exact=C]*/
+/*member: invokeGenericSuperMethod3:[exact=C]*/
invokeGenericSuperMethod3() =>
new Subclass(). /*invoke: [exact=Subclass]*/ superMethod3();
-/*element: invokeFunctionTypedGenericMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericMethod1:[null|subclass=A]*/
invokeFunctionTypedGenericMethod1(A /*[exact=A]*/ a) =>
functionTypedGenericMethod<A>(a)();
-/*element: invokeFunctionTypedGenericMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericMethod2:[null|exact=B]*/
invokeFunctionTypedGenericMethod2(B /*[exact=B]*/ b) =>
functionTypedGenericMethod<B>(b)();
-/*element: invokeFunctionTypedGenericMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericMethod3:[null|exact=C]*/
invokeFunctionTypedGenericMethod3(C /*[exact=C]*/ c) =>
functionTypedGenericMethod<C>(c)();
-/*element: invokeFunctionTypedGenericInstanceMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericInstanceMethod1:[null|subclass=A]*/
invokeFunctionTypedGenericInstanceMethod1() => new Class()
. /*invoke: [exact=Class]*/ functionTypedGenericMethod<A>(new A())();
-/*element: invokeFunctionTypedGenericInstanceMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericInstanceMethod2:[null|exact=B]*/
invokeFunctionTypedGenericInstanceMethod2() => new Class()
. /*invoke: [exact=Class]*/ functionTypedGenericMethod<B>(new B())();
-/*element: invokeFunctionTypedGenericInstanceMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericInstanceMethod3:[null|exact=C]*/
invokeFunctionTypedGenericInstanceMethod3() => new Class()
. /*invoke: [exact=Class]*/ functionTypedGenericMethod<C>(new C())();
-/*element: invokeFunctionTypedGenericSuperMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericSuperMethod1:[null|subclass=A]*/
invokeFunctionTypedGenericSuperMethod1() =>
new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod1();
-/*element: invokeFunctionTypedGenericSuperMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericSuperMethod2:[null|exact=B]*/
invokeFunctionTypedGenericSuperMethod2() =>
new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod2();
-/*element: invokeFunctionTypedGenericSuperMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericSuperMethod3:[null|exact=C]*/
invokeFunctionTypedGenericSuperMethod3() =>
new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod3();
-/*element: invokeGenericMethods:[null]*/
+/*member: invokeGenericMethods:[null]*/
invokeGenericMethods() {
invokeGenericMethod1(new A());
invokeGenericMethod2(new B());
diff --git a/tests/compiler/dart2js/inference/data/while.dart b/tests/compiler/dart2js/inference/data/while.dart
index 1858bf4..a6f7373 100644
--- a/tests/compiler/dart2js/inference/data/while.dart
+++ b/tests/compiler/dart2js/inference/data/while.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
simpleWhile();
whileNull();
@@ -20,7 +20,7 @@
/// Simple int based while loop.
////////////////////////////////////////////////////////////////////////////////
-/*element: simpleWhile:[null]*/
+/*member: simpleWhile:[null]*/
simpleWhile() {
var i = 0;
while (i /*invoke: [subclass=JSPositiveInt]*/ < 10) {
@@ -33,7 +33,7 @@
/// While loop with null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: whileNull:Value([null|exact=JSString], value: "null")*/
+/*member: whileNull:Value([null|exact=JSString], value: "null")*/
whileNull() {
var o;
while (o == null) {
@@ -46,7 +46,7 @@
/// While loop with not-null test.
////////////////////////////////////////////////////////////////////////////////
-/*element: whileNotNull:[exact=JSString]*/
+/*member: whileNotNull:[exact=JSString]*/
whileNotNull() {
var o = '';
while (o != null) {
@@ -59,7 +59,7 @@
/// While loop with null test with an unreachable body.
////////////////////////////////////////////////////////////////////////////////
-/*element: whileNullUnreachable:[exact=JSString]*/
+/*member: whileNullUnreachable:[exact=JSString]*/
whileNullUnreachable() {
var o = '';
while (o == null) {
@@ -72,7 +72,7 @@
/// While loop with not-null test with an unreachable body.
////////////////////////////////////////////////////////////////////////////////
-/*element: whileNotNullUnreachable:[null]*/
+/*member: whileNotNullUnreachable:[null]*/
whileNotNullUnreachable() {
var o = null;
while (o != null) {
@@ -86,19 +86,19 @@
/// object to the [_whileUnion1] method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
class Class1 {
- /*element: Class1.field:[null|exact=Class2]*/
+ /*member: Class1.field:[null|exact=Class2]*/
var field;
}
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
class Class2 {
- /*element: Class2.field:[null|exact=Class1]*/
+ /*member: Class2.field:[null|exact=Class1]*/
var field;
}
-/*element: _whileUnion1:Union([exact=Class1], [null|exact=Class2])*/
+/*member: _whileUnion1:Union([exact=Class1], [null|exact=Class2])*/
_whileUnion1(/*[exact=Class1]*/ o) {
while (o != null) {
o = o. /*Union([exact=Class1], [exact=Class2])*/ field;
@@ -106,7 +106,7 @@
return o;
}
-/*element: whileUnion1:[null]*/
+/*member: whileUnion1:[null]*/
whileUnion1() {
var c1 = new Class1();
var c2 = new Class2();
@@ -120,19 +120,19 @@
/// object to the [_whileUnion2] method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
class Class3 {
- /*element: Class3.field:[null|exact=Class4]*/
+ /*member: Class3.field:[null|exact=Class4]*/
var field;
}
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
class Class4 {
- /*element: Class4.field:[null|exact=Class3]*/
+ /*member: Class4.field:[null|exact=Class3]*/
var field;
}
-/*element: _whileUnion2:Union([exact=Class4], [null|exact=Class3])*/
+/*member: _whileUnion2:Union([exact=Class4], [null|exact=Class3])*/
_whileUnion2(/*[exact=Class4]*/ o) {
while (o != null) {
o = o. /*Union([exact=Class3], [exact=Class4])*/ field;
@@ -140,7 +140,7 @@
return o;
}
-/*element: whileUnion2:[null]*/
+/*member: whileUnion2:[null]*/
whileUnion2() {
var c1 = new Class3();
var c2 = new Class4();
@@ -154,19 +154,19 @@
/// objects to the [_whileUnion3] method.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
class Class5 {
- /*element: Class5.field:[null|exact=Class6]*/
+ /*member: Class5.field:[null|exact=Class6]*/
var field;
}
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
class Class6 {
- /*element: Class6.field:[null|exact=Class5]*/
+ /*member: Class6.field:[null|exact=Class5]*/
var field;
}
-/*element: _whileUnion3:Union([null|exact=Class5], [null|exact=Class6])*/
+/*member: _whileUnion3:Union([null|exact=Class5], [null|exact=Class6])*/
_whileUnion3(/*Union([exact=Class5], [exact=Class6])*/ o) {
while (o != null) {
o = o. /*Union([exact=Class5], [exact=Class6])*/ field;
@@ -174,7 +174,7 @@
return o;
}
-/*element: whileUnion3:[null]*/
+/*member: whileUnion3:[null]*/
whileUnion3() {
var c1 = new Class5();
var c2 = new Class6();
@@ -188,19 +188,19 @@
/// While loop with is test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
class Class7 {
- /*element: Class7.field:[null|exact=Class8]*/
+ /*member: Class7.field:[null|exact=Class8]*/
var field;
}
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
class Class8 {
- /*element: Class8.field:[null|exact=Class7]*/
+ /*member: Class8.field:[null|exact=Class7]*/
var field;
}
-/*element: _whileIs:Union([exact=Class7], [null|exact=Class8])*/
+/*member: _whileIs:Union([exact=Class7], [null|exact=Class8])*/
_whileIs(/*[exact=Class7]*/ o) {
while (o is Class7) {
o = o. /*[exact=Class7]*/ field;
@@ -208,7 +208,7 @@
return o;
}
-/*element: whileIs:[null]*/
+/*member: whileIs:[null]*/
whileIs() {
var c1 = new Class7();
var c2 = new Class8();
@@ -221,19 +221,19 @@
/// While loop with is-not test that mixes field accesses.
////////////////////////////////////////////////////////////////////////////////
-/*element: Class9.:[exact=Class9]*/
+/*member: Class9.:[exact=Class9]*/
class Class9 {
- /*element: Class9.field:[null|exact=Class10]*/
+ /*member: Class9.field:[null|exact=Class10]*/
var field;
}
-/*element: Class10.:[exact=Class10]*/
+/*member: Class10.:[exact=Class10]*/
class Class10 {
- /*element: Class10.field:[null|exact=Class9]*/
+ /*member: Class10.field:[null|exact=Class9]*/
var field;
}
-/*element: _whileIsNot:Union([exact=Class9], [null|exact=Class10])*/
+/*member: _whileIsNot:Union([exact=Class9], [null|exact=Class10])*/
_whileIsNot(/*[exact=Class9]*/ o) {
while (o is! Class10) {
o = o. /*Union([exact=Class9], [null|exact=Class10])*/ field;
@@ -241,7 +241,7 @@
return o;
}
-/*element: whileIsNot:[null]*/
+/*member: whileIsNot:[null]*/
whileIsNot() {
var c1 = new Class9();
var c2 = new Class10();
diff --git a/tests/compiler/dart2js/inference/data/yield.dart b/tests/compiler/dart2js/inference/data/yield.dart
index 14b1d21..3f89f21 100644
--- a/tests/compiler/dart2js/inference/data/yield.dart
+++ b/tests/compiler/dart2js/inference/data/yield.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.
-/*element: main:[null]*/
+/*member: main:[null]*/
main() {
yieldZero();
yieldList();
@@ -15,7 +15,7 @@
// Yield a single integer.
////////////////////////////////////////////////////////////////////////////////
-/*element: yieldZero:[exact=_SyncStarIterable]*/
+/*member: yieldZero:[exact=_SyncStarIterable]*/
yieldZero() sync* {
yield 0;
}
@@ -24,7 +24,7 @@
// Yield a list of integers.
////////////////////////////////////////////////////////////////////////////////
-/*element: yieldList:[exact=_SyncStarIterable]*/
+/*member: yieldList:[exact=_SyncStarIterable]*/
yieldList() sync* {
yield [0, 1, 2, 3];
}
@@ -33,7 +33,7 @@
// Yield star of a list of integers.
////////////////////////////////////////////////////////////////////////////////
-/*element: yieldStarList:[exact=_SyncStarIterable]*/
+/*member: yieldStarList:[exact=_SyncStarIterable]*/
yieldStarList() sync* {
yield* [0, 1, 2, 3];
}
@@ -42,7 +42,7 @@
// Yield multiple integers.
////////////////////////////////////////////////////////////////////////////////
-/*element: yieldMany:[exact=_SyncStarIterable]*/
+/*member: yieldMany:[exact=_SyncStarIterable]*/
yieldMany() sync* {
yield 0;
yield 1;
@@ -54,7 +54,7 @@
// Yield an integer and a string.
////////////////////////////////////////////////////////////////////////////////
-/*element: yieldIntAndString:[exact=_SyncStarIterable]*/
+/*member: yieldIntAndString:[exact=_SyncStarIterable]*/
yieldIntAndString() sync* {
yield 0;
yield '';
diff --git a/tests/compiler/dart2js/inference/inference2_test.dart b/tests/compiler/dart2js/inference/inference2_test.dart
new file mode 100644
index 0000000..68b3c20
--- /dev/null
+++ b/tests/compiler/dart2js/inference/inference2_test.dart
@@ -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.
+
+import 'inference_test_helper.dart';
+
+main(List<String> args) {
+ runTests(args, 2);
+}
diff --git a/tests/compiler/dart2js/inference/inference3_test.dart b/tests/compiler/dart2js/inference/inference3_test.dart
new file mode 100644
index 0000000..6161412
--- /dev/null
+++ b/tests/compiler/dart2js/inference/inference3_test.dart
@@ -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.
+
+import 'inference_test_helper.dart';
+
+main(List<String> args) {
+ runTests(args, 3);
+}
diff --git a/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart b/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
index 8b629ec..d984418 100644
--- a/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
+++ b/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
@@ -11,13 +11,13 @@
staticCalledIndirectlyInForLoop();
}
-/*element: _staticCalledInForLoop:loop*/
+/*member: _staticCalledInForLoop:loop*/
_staticCalledInForLoop() {}
-/*element: _staticNotCalledInForLoop:*/
+/*member: _staticNotCalledInForLoop:*/
_staticNotCalledInForLoop() {}
-/*element: staticCalledInForLoop:*/
+/*member: staticCalledInForLoop:*/
staticCalledInForLoop() {
_staticNotCalledInForLoop();
for (int i = 0; i < 10; i++) {
@@ -26,13 +26,13 @@
_staticNotCalledInForLoop();
}
-/*element: _staticCalledInForInLoop:loop*/
+/*member: _staticCalledInForInLoop:loop*/
_staticCalledInForInLoop() {}
-/*element: _staticNotCalledInForInLoop:*/
+/*member: _staticNotCalledInForInLoop:*/
_staticNotCalledInForInLoop() {}
-/*element: staticCalledInForInLoop:*/
+/*member: staticCalledInForInLoop:*/
staticCalledInForInLoop() {
_staticNotCalledInForInLoop();
// ignore: unused_local_variable
@@ -42,13 +42,13 @@
_staticNotCalledInForInLoop();
}
-/*element: _staticCalledInWhileLoop:loop*/
+/*member: _staticCalledInWhileLoop:loop*/
_staticCalledInWhileLoop() {}
-/*element: _staticNotCalledInWhileLoop:*/
+/*member: _staticNotCalledInWhileLoop:*/
_staticNotCalledInWhileLoop() {}
-/*element: staticCalledInWhileLoop:*/
+/*member: staticCalledInWhileLoop:*/
staticCalledInWhileLoop() {
int i = 0;
_staticNotCalledInWhileLoop();
@@ -59,13 +59,13 @@
_staticNotCalledInWhileLoop();
}
-/*element: _staticCalledInDoLoop:loop*/
+/*member: _staticCalledInDoLoop:loop*/
_staticCalledInDoLoop() {}
-/*element: _staticNotCalledInDoLoop:*/
+/*member: _staticNotCalledInDoLoop:*/
_staticNotCalledInDoLoop() {}
-/*element: staticCalledInDoLoop:*/
+/*member: staticCalledInDoLoop:*/
staticCalledInDoLoop() {
int i = 0;
_staticNotCalledInDoLoop();
@@ -77,21 +77,21 @@
}
class Class {
- /*element: Class.constructorCalledInForLoop:loop*/
+ /*member: Class.constructorCalledInForLoop:loop*/
Class.constructorCalledInForLoop();
- /*element: Class.constructorNotCalledInForLoop:*/
+ /*member: Class.constructorNotCalledInForLoop:*/
Class.constructorNotCalledInForLoop();
// TODO(johnniwinther): Should we track instance calls in loops?
- /*element: Class.instanceCalledInForLoop:*/
+ /*member: Class.instanceCalledInForLoop:*/
instanceCalledInForLoop() {}
- /*element: Class.instanceNotCalledInForLoop:*/
+ /*member: Class.instanceNotCalledInForLoop:*/
instanceNotCalledInForLoop() {}
}
-/*element: instanceCalledInForLoop:*/
+/*member: instanceCalledInForLoop:*/
instanceCalledInForLoop() {
var c = new Class.constructorNotCalledInForLoop();
c.instanceNotCalledInForLoop();
@@ -103,13 +103,13 @@
}
// TODO(johnniwinther): Should we track indirect calls in loops?
-/*element: _staticCalledIndirectlyInForLoop:*/
+/*member: _staticCalledIndirectlyInForLoop:*/
_staticCalledIndirectlyInForLoop() {}
-/*element: _staticCalledIndirectlyInForLoopHelper:loop*/
+/*member: _staticCalledIndirectlyInForLoopHelper:loop*/
_staticCalledIndirectlyInForLoopHelper() => _staticCalledIndirectlyInForLoop();
-/*element: staticCalledIndirectlyInForLoop:*/
+/*member: staticCalledIndirectlyInForLoop:*/
staticCalledIndirectlyInForLoop() {
for (int i = 0; i < 10; i++) {
_staticCalledIndirectlyInForLoopHelper();
diff --git a/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart b/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
index b91c000..9c516ba 100644
--- a/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
+++ b/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
@@ -9,17 +9,17 @@
}
// We trust the annotation.
-/*element: noThrows:no-throw*/
+/*member: noThrows:no-throw*/
@pragma('dart2js:noThrows')
@pragma(
'dart2js:noInline') // Required for the @pragma('dart2js:noThrows') annotation.
noThrows() => throw '';
// Check that the @pragma('dart2js:noInline') annotation has no impact on its own.
-/*element: noInline:*/
+/*member: noInline:*/
@pragma('dart2js:noInline')
noInline() {}
// TODO(johnniwinther): Should we infer this?
-/*element: throws:*/
+/*member: throws:*/
throws() => 0;
diff --git a/tests/compiler/dart2js/inference/inference_data/function_apply.dart b/tests/compiler/dart2js/inference/inference_data/function_apply.dart
index b02d84a..a74ae06 100644
--- a/tests/compiler/dart2js/inference/inference_data/function_apply.dart
+++ b/tests/compiler/dart2js/inference/inference_data/function_apply.dart
@@ -10,35 +10,35 @@
instantiatedCall();
}
-/*element: _directCall:apply*/
+/*member: _directCall:apply*/
_directCall() {}
-/*element: directCall:*/
+/*member: directCall:*/
void directCall() {
Function.apply(_directCall, []);
}
-/*element: _indirectCall:apply*/
+/*member: _indirectCall:apply*/
_indirectCall() {}
-/*element: _indirectCallHelper:*/
+/*member: _indirectCallHelper:*/
_indirectCallHelper(f) => Function.apply(f, []);
-/*element: indirectCall:*/
+/*member: indirectCall:*/
void indirectCall() {
_indirectCallHelper(_indirectCall);
}
-/*element: Class.:*/
+/*member: Class.:*/
class Class {
- /*element: Class.instanceTearOff1:apply*/
+ /*member: Class.instanceTearOff1:apply*/
instanceTearOff1() {}
- /*element: Class.instanceTearOff2:*/
+ /*member: Class.instanceTearOff2:*/
instanceTearOff2() {}
}
-/*element: _instanceTearOffHelper:*/
+/*member: _instanceTearOffHelper:*/
_instanceTearOffHelper(f) => Function.apply(f, []);
instanceTearOff() {
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 9259adb..bd0eddb 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -38,7 +38,7 @@
testCFEConstants: true,
skipForStrong: skipForStrong,
shardIndex: shardIndex ?? 0,
- shards: shardIndex != null ? 2 : 1);
+ shards: shardIndex != null ? 4 : 1);
});
}
diff --git a/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart b/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
index 8ae50e9..f734696 100644
--- a/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
+++ b/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
@@ -3,33 +3,33 @@
// BSD-style license that can be found in the LICENSE file.
class _SECRET {
- /*element: _SECRET.:[exact=_SECRET]*/
+ /*member: _SECRET.:[exact=_SECRET]*/
const _SECRET();
- /*element: _SECRET.toString:Value([exact=JSString], value: "SECRET!")*/
+ /*member: _SECRET.toString:Value([exact=JSString], value: "SECRET!")*/
@override
String toString() => "SECRET!";
}
class C {
- /*element: C.x:[exact=JSUInt31]*/
+ /*member: C.x:[exact=JSUInt31]*/
final int x;
- /*element: C.y:Union([exact=JSString], [exact=_SECRET])*/
+ /*member: C.y:Union([exact=JSString], [exact=_SECRET])*/
final y;
- /*element: C.a:[exact=C]*/
+ /*member: C.a:[exact=C]*/
C.a(int /*[exact=JSUInt31]*/ x,
[var /*Union([exact=JSString], [exact=_SECRET])*/ b = const _SECRET()])
: this.x = x,
this.y = b;
- /*element: C.b:[exact=C]*/
+ /*member: C.b:[exact=C]*/
C.b(int /*[exact=JSUInt31]*/ x,
{var /*Union([exact=JSString], [exact=_SECRET])*/ b: const _SECRET()})
: this.x = x,
this.y = b;
- /*element: C.toString:[exact=JSString]*/
+ /*member: C.toString:[exact=JSString]*/
@override
String toString() => "C(${/*[exact=D]*/ x},${/*[exact=D]*/ y})";
}
diff --git a/tests/compiler/dart2js/inference/side_effects/annotations.dart b/tests/compiler/dart2js/inference/side_effects/annotations.dart
index 4337cf8..a7d5f65 100644
--- a/tests/compiler/dart2js/inference/side_effects/annotations.dart
+++ b/tests/compiler/dart2js/inference/side_effects/annotations.dart
@@ -7,18 +7,18 @@
/// Read a static field. This adds dependency of static properties to the
/// side effects of the method.
-/*element: readStaticField:SideEffects(reads static; writes nothing)*/
+/*member: readStaticField:SideEffects(reads static; writes nothing)*/
readStaticField() => field;
/// Read a static field. If not for the `@pragma('dart2js:noSideEffects')`
/// annotation this would add dependency of static properties to the side
/// effects of the method.
-/*element: readStaticFieldAnnotated:SideEffects(reads nothing; writes nothing)*/
+/*member: readStaticFieldAnnotated:SideEffects(reads nothing; writes nothing)*/
@pragma('dart2js:noInline')
@pragma('dart2js:noSideEffects')
readStaticFieldAnnotated() => field;
-/*element: main:SideEffects(reads static; writes nothing)*/
+/*member: main:SideEffects(reads static; writes nothing)*/
main() {
readStaticField();
readStaticFieldAnnotated();
diff --git a/tests/compiler/dart2js/inference/side_effects/foreign.dart b/tests/compiler/dart2js/inference/side_effects/foreign.dart
index 9c4e18a..dc8ad67 100644
--- a/tests/compiler/dart2js/inference/side_effects/foreign.dart
+++ b/tests/compiler/dart2js/inference/side_effects/foreign.dart
@@ -11,41 +11,41 @@
/// ignore: IMPORT_INTERNAL_LIBRARY, UNUSED_IMPORT
import 'dart:_interceptors';
-/*element: jsCallEmpty:SideEffects(reads nothing; writes nothing)*/
+/*member: jsCallEmpty:SideEffects(reads nothing; writes nothing)*/
jsCallEmpty() => JS('', '#', 0);
-/*element: jsCallInt:SideEffects(reads nothing; writes nothing)*/
+/*member: jsCallInt:SideEffects(reads nothing; writes nothing)*/
jsCallInt() => JS('int', '#', 0);
-/*element: jsCallEffectsAllDependsNoIndex:SideEffects(reads field, static; writes anything)*/
+/*member: jsCallEffectsAllDependsNoIndex:SideEffects(reads field, static; writes anything)*/
jsCallEffectsAllDependsNoIndex() => JS('effects:all;depends:no-index', '#', 0);
-/*element: jsCallEffectsNoInstanceDependsNoStatic:SideEffects(reads index, field; writes index, static)*/
+/*member: jsCallEffectsNoInstanceDependsNoStatic:SideEffects(reads index, field; writes index, static)*/
jsCallEffectsNoInstanceDependsNoStatic() =>
JS('effects:no-instance;depends:no-static', '#', 0);
-/*element: jsBuiltin_rawRtiToJsConstructorName:SideEffects(reads anything; writes anything)*/
+/*member: jsBuiltin_rawRtiToJsConstructorName:SideEffects(reads anything; writes anything)*/
jsBuiltin_rawRtiToJsConstructorName() {
return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
}
-/*element: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
+/*member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
jsEmbeddedGlobal_getTypeFromName() {
return JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
}
-/*element: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
+/*member: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
jsEmbeddedGlobal_libraries() {
return JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
}
-/*element: jsStringConcat:SideEffects(reads nothing; writes nothing)*/
+/*member: jsStringConcat:SideEffects(reads nothing; writes nothing)*/
jsStringConcat() => JS_STRING_CONCAT('a', 'b');
-/*element: jsGetStaticState:SideEffects(reads nothing; writes anything)*/
+/*member: jsGetStaticState:SideEffects(reads nothing; writes anything)*/
jsGetStaticState() => JS_GET_STATIC_STATE();
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
main() {
jsCallInt();
jsCallEmpty();
diff --git a/tests/compiler/dart2js/inference/side_effects/local_functions.dart b/tests/compiler/dart2js/inference/side_effects/local_functions.dart
index fdf569e..b6a53a0 100644
--- a/tests/compiler/dart2js/inference/side_effects/local_functions.dart
+++ b/tests/compiler/dart2js/inference/side_effects/local_functions.dart
@@ -4,31 +4,31 @@
var field;
-/*element: anonymousClosureUnused:SideEffects(reads nothing; writes nothing)*/
+/*member: anonymousClosureUnused:SideEffects(reads nothing; writes nothing)*/
anonymousClosureUnused() {
/*SideEffects(reads static; writes nothing)*/
() => field;
}
-/*element: anonymousClosureCalled:SideEffects(reads anything; writes anything)*/
+/*member: anonymousClosureCalled:SideEffects(reads anything; writes anything)*/
anonymousClosureCalled() {
var localFunction = /*SideEffects(reads static; writes nothing)*/ () => field;
return localFunction();
}
-/*element: localFunctionUnused:SideEffects(reads nothing; writes nothing)*/
+/*member: localFunctionUnused:SideEffects(reads nothing; writes nothing)*/
localFunctionUnused() {
// ignore: UNUSED_ELEMENT
/*SideEffects(reads static; writes nothing)*/ localFunction() => field;
}
-/*element: localFunctionCalled:SideEffects(reads static; writes nothing)*/
+/*member: localFunctionCalled:SideEffects(reads static; writes nothing)*/
localFunctionCalled() {
/*SideEffects(reads static; writes nothing)*/ localFunction() => field;
return localFunction();
}
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
main() {
anonymousClosureUnused();
anonymousClosureCalled();
diff --git a/tests/compiler/dart2js/inference/side_effects/methods.dart b/tests/compiler/dart2js/inference/side_effects/methods.dart
index 4774e55..99a0278 100644
--- a/tests/compiler/dart2js/inference/side_effects/methods.dart
+++ b/tests/compiler/dart2js/inference/side_effects/methods.dart
@@ -6,193 +6,193 @@
var field;
/// Static getter with no side effects. Used in tests below.
-/*element: emptyGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: emptyGetter:SideEffects(reads nothing; writes nothing)*/
get emptyGetter => null;
/// Static getter with a single side effect of reading a static. Used in tests
/// below.
-/*element: nonEmptyGetter:SideEffects(reads static; writes nothing)*/
+/*member: nonEmptyGetter:SideEffects(reads static; writes nothing)*/
get nonEmptyGetter => field;
/// Static method with no side effects. Used in tests below.
-/*element: emptyMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: emptyMethod:SideEffects(reads nothing; writes nothing)*/
emptyMethod() {}
/// Static method with a single side effect of reading a static. Used in tests
/// below.
-/*element: nonEmptyMethod:SideEffects(reads static; writes nothing)*/
+/*member: nonEmptyMethod:SideEffects(reads static; writes nothing)*/
nonEmptyMethod() => field;
-/*element: Class.:SideEffects(reads nothing; writes nothing)*/
+/*member: Class.:SideEffects(reads nothing; writes nothing)*/
class Class {
/// Instance field used in tests below.
var field;
/// Instance getter with no side effects. Used in tests below.
- /*element: Class.emptyGetter:SideEffects(reads nothing; writes nothing)*/
+ /*member: Class.emptyGetter:SideEffects(reads nothing; writes nothing)*/
get emptyGetter => null;
/// Instance getter with a single side effect of reading a static. Used in
/// tests below.
- /*element: Class.nonEmptyGetter:SideEffects(reads field; writes nothing)*/
+ /*member: Class.nonEmptyGetter:SideEffects(reads field; writes nothing)*/
get nonEmptyGetter => field;
/// Instance method with no side effects. Used in tests below.
- /*element: Class.emptyMethod:SideEffects(reads nothing; writes nothing)*/
+ /*member: Class.emptyMethod:SideEffects(reads nothing; writes nothing)*/
emptyMethod() {}
/// Instance method with a single side effect of reading a static. Used in
/// tests below.
- /*element: Class.nonEmptyMethod:SideEffects(reads field; writes nothing)*/
+ /*member: Class.nonEmptyMethod:SideEffects(reads field; writes nothing)*/
nonEmptyMethod() => field;
}
/// Call an empty instance method. This propagates the side effects of the
/// instance method; here none.
-/*element: callEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: callEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
callEmptyInstanceMethod(c) => c.emptyMethod();
/// Call an empty instance getter. This marks the method as having all side
/// effects.
-/*element: callEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
+/*member: callEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
callEmptyInstanceGetter(c) => c.emptyGetter();
/// Call a non-empty instance method. This propagates the side effects of the
/// instance method; here dependency of static properties.
-/*element: callNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
+/*member: callNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
callNonEmptyInstanceMethod(c) => c.nonEmptyMethod();
/// Call a non-empty instance getter. This marks the method as having all side
/// effects.
-/*element: callNonEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
+/*member: callNonEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
callNonEmptyInstanceGetter(c) => c.nonEmptyGetter();
/// Read an empty instance method. This propagates the side effects of the
/// instance method; here none.
-/*element: readEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
readEmptyInstanceMethod(c) => c.emptyMethod;
/// Read an empty instance getter. This propagates the side effects of the
/// instance getter; here none.
-/*element: readEmptyInstanceGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyInstanceGetter:SideEffects(reads nothing; writes nothing)*/
readEmptyInstanceGetter(c) => c.emptyGetter;
/// Read a non-empty instance method. This propagates the side effects of the
/// instance method; here dependency of static properties.
-/*element: readNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
+/*member: readNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
readNonEmptyInstanceMethod(c) => c.nonEmptyMethod;
/// Read a non-empty instance getter. This propagates the side effects of the
/// instance getter; here dependency of static properties.
-/*element: readNonEmptyInstanceGetter:SideEffects(reads field; writes nothing)*/
+/*member: readNonEmptyInstanceGetter:SideEffects(reads field; writes nothing)*/
readNonEmptyInstanceGetter(c) => c.nonEmptyGetter;
/// Read an instance field. This adds dependency of instance properties to the
/// side effects of the method.
-/*element: readInstanceField:SideEffects(reads field; writes nothing)*/
+/*member: readInstanceField:SideEffects(reads field; writes nothing)*/
readInstanceField(c) => c.field;
/// Write to an instance field. This adds change of instance properties to the
/// side effects of the method.
-/*element: writeInstanceField:SideEffects(reads nothing; writes field)*/
+/*member: writeInstanceField:SideEffects(reads nothing; writes field)*/
writeInstanceField(c) => c.field = 42;
/// Call an instance field. This marks the method as having all side effects.
-/*element: callInstanceField:SideEffects(reads anything; writes anything)*/
+/*member: callInstanceField:SideEffects(reads anything; writes anything)*/
callInstanceField(c) => c.field();
/// Read a static field. This adds dependency of static properties to the
/// side effects of the method.
-/*element: readStaticField:SideEffects(reads static; writes nothing)*/
+/*member: readStaticField:SideEffects(reads static; writes nothing)*/
readStaticField() => field;
/// Write to a static field. This adds change of static properties to the
/// side effects of the method.
-/*element: writeStaticField:SideEffects(reads nothing; writes static)*/
+/*member: writeStaticField:SideEffects(reads nothing; writes static)*/
writeStaticField() => field = 42;
/// Call a static field. This marks the method as having all side effects.
-/*element: callStaticField:SideEffects(reads anything; writes anything)*/
+/*member: callStaticField:SideEffects(reads anything; writes anything)*/
callStaticField() => field();
/// Read and write of a static field. This adds dependency of static properties
/// and change of static properties to the side effects of the method.
-/*element: readAndWriteStaticField:SideEffects(reads static; writes static)*/
+/*member: readAndWriteStaticField:SideEffects(reads static; writes static)*/
readAndWriteStaticField() {
field = field;
}
/// Call an empty static method. This propagates the side effects of the
/// instance method; here none.
-/*element: callEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: callEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
callEmptyStaticMethod() => emptyMethod();
/// Call an empty static getter. This marks the method as having all side
/// effects.
-/*element: callEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
+/*member: callEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
callEmptyStaticGetter() => emptyGetter();
/// Call a non-empty static method. This propagates the side effects of the
/// instance method; here dependency of static properties.
-/*element: callNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
+/*member: callNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
callNonEmptyStaticMethod() => nonEmptyMethod();
/// Call a non-empty static getter. This marks the method as having all side
/// effects.
-/*element: callNonEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
+/*member: callNonEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
callNonEmptyStaticGetter() => nonEmptyGetter();
/// Read an empty static method. This propagates the side effects of the
/// static method; here none.
-/*element: readEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
readEmptyStaticMethod() => emptyMethod;
/// Read an empty static getter. This propagates the side effects of the
/// static getter; here none.
-/*element: readEmptyStaticGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyStaticGetter:SideEffects(reads nothing; writes nothing)*/
readEmptyStaticGetter() => emptyGetter;
/// Read a non-empty static method. This propagates the side effects of the
/// static method; here dependency of static properties.
-/*element: readNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
+/*member: readNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
readNonEmptyStaticMethod() => nonEmptyMethod;
/// Read a non-empty static getter. This propagates the side effects of the
/// static getter; here dependency of static properties.
-/*element: readNonEmptyStaticGetter:SideEffects(reads static; writes nothing)*/
+/*member: readNonEmptyStaticGetter:SideEffects(reads static; writes nothing)*/
readNonEmptyStaticGetter() => nonEmptyGetter;
/// Call a static method that reads an instance field. This propagates the side
/// effects of the static method; here dependency of instance properties.
-/*element: callingReadInstanceField:SideEffects(reads field; writes nothing)*/
+/*member: callingReadInstanceField:SideEffects(reads field; writes nothing)*/
callingReadInstanceField(c) => readInstanceField(c);
/// Call a static method that writes to an instance field. This propagates the
/// side effects of the static method; here change of instance properties.
-/*element: callingWriteInstanceField:SideEffects(reads nothing; writes field)*/
+/*member: callingWriteInstanceField:SideEffects(reads nothing; writes field)*/
callingWriteInstanceField(c) => writeInstanceField(c);
/// Call a static method that calls an instance field. This propagates the side
/// effects of the static method; here all side-effects.
-/*element: callingCallInstanceField:SideEffects(reads anything; writes anything)*/
+/*member: callingCallInstanceField:SideEffects(reads anything; writes anything)*/
callingCallInstanceField(c) => callInstanceField(c);
/// Call a static method that reads a static field. This propagates the side
/// effects of the static method; here dependency of static properties.
-/*element: callingReadStaticField:SideEffects(reads static; writes nothing)*/
+/*member: callingReadStaticField:SideEffects(reads static; writes nothing)*/
callingReadStaticField() => readStaticField();
/// Call a static method that writes to a static field. This propagates the
/// side effects of the static method; here change of static properties.
-/*element: callingWriteStaticField:SideEffects(reads nothing; writes static)*/
+/*member: callingWriteStaticField:SideEffects(reads nothing; writes static)*/
callingWriteStaticField() => writeStaticField();
/// Call a static method that calls a static field. This propagates the side
/// effects of the static method; here all side-effects.
-/*element: callingCallStaticField:SideEffects(reads anything; writes anything)*/
+/*member: callingCallStaticField:SideEffects(reads anything; writes anything)*/
callingCallStaticField() => callStaticField();
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
main() {
var c = new Class();
diff --git a/tests/compiler/dart2js/inference/side_effects/out_of_order.dart b/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
index dd4cebb..c8501e3 100644
--- a/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
+++ b/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
@@ -14,21 +14,21 @@
// The new computation, based on [SideEffectsBuilder], computes the precise
// result regardless of computation order.
-/*element: _noSideEffects:SideEffects(reads nothing; writes nothing)*/
+/*member: _noSideEffects:SideEffects(reads nothing; writes nothing)*/
_noSideEffects() {}
-/*element: callCallNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
+/*member: callCallNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
callCallNoSideEffectsManyTimes() {
_callNoSideEffectsManyTimes();
}
-/*element: main:SideEffects(reads nothing; writes nothing)*/
+/*member: main:SideEffects(reads nothing; writes nothing)*/
main() {
callCallNoSideEffectsManyTimes();
callCallNoSideEffectsManyTimes();
}
-/*element: _callNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
+/*member: _callNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
_callNoSideEffectsManyTimes() {
_noSideEffects();
_noSideEffects();
diff --git a/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart b/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
index 50a15cc..e85be1f 100644
--- a/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
+++ b/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: stringInterpolation:SideEffects(reads nothing; writes anything)*/
+/*member: stringInterpolation:SideEffects(reads nothing; writes anything)*/
stringInterpolation() => '${null}';
-/*element: main:SideEffects(reads nothing; writes anything)*/
+/*member: main:SideEffects(reads nothing; writes anything)*/
main() {
stringInterpolation();
}
diff --git a/tests/compiler/dart2js/inlining/data/conditional.dart b/tests/compiler/dart2js/inlining/data/conditional.dart
index c8aa00f..c19404f 100644
--- a/tests/compiler/dart2js/inlining/data/conditional.dart
+++ b/tests/compiler/dart2js/inlining/data/conditional.dart
@@ -5,7 +5,7 @@
// Tests for the heuristics on conditional expression whose condition is a
// parameter for which the max, instead of the sum, of the branch sizes is used.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
conditionalField();
conditionalParameter();
@@ -16,19 +16,19 @@
// size of the condition is the sum of the nodes in the conditional expression.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[_conditionalField]*/
+/*member: _method1:[_conditionalField]*/
_method1() => 42;
bool _field1;
-/*element: _conditionalField:[]*/
+/*member: _conditionalField:[]*/
_conditionalField() {
return _field1
? _method1() + _method1() + _method1()
: _method1() + _method1() + _method1();
}
-/*element: conditionalField:[]*/
+/*member: conditionalField:[]*/
@pragma('dart2js:noInline')
conditionalField() {
_field1 = false;
@@ -42,17 +42,17 @@
// max of the branches + the condition itself.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method2:[conditionalParameter]*/
+/*member: _method2:[conditionalParameter]*/
_method2() => 42;
-/*element: _conditionalParameter:[conditionalParameter]*/
+/*member: _conditionalParameter:[conditionalParameter]*/
_conditionalParameter(bool o) {
return o
? _method2() + _method2() + _method2()
: _method2() + _method2() + _method2();
}
-/*element: conditionalParameter:[]*/
+/*member: conditionalParameter:[]*/
@pragma('dart2js:noInline')
conditionalParameter() {
_conditionalParameter(true);
diff --git a/tests/compiler/dart2js/inlining/data/constructor.dart b/tests/compiler/dart2js/inlining/data/constructor.dart
index bdd20c6..d60a569 100644
--- a/tests/compiler/dart2js/inlining/data/constructor.dart
+++ b/tests/compiler/dart2js/inlining/data/constructor.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
forceInlineConstructor();
forceInlineConstructorBody();
@@ -15,12 +15,12 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.:[forceInlineConstructor:Class1]*/
+ /*member: Class1.:[forceInlineConstructor:Class1]*/
@pragma('dart2js:tryInline')
Class1();
}
-/*element: forceInlineConstructor:[]*/
+/*member: forceInlineConstructor:[]*/
@pragma('dart2js:noInline')
forceInlineConstructor() {
new Class1();
@@ -31,14 +31,14 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.:[forceInlineConstructorBody+,forceInlineConstructorBody:Class2]*/
+ /*member: Class2.:[forceInlineConstructorBody+,forceInlineConstructorBody:Class2]*/
@pragma('dart2js:tryInline')
Class2() {
print('foo');
}
}
-/*element: forceInlineConstructorBody:[]*/
+/*member: forceInlineConstructorBody:[]*/
@pragma('dart2js:noInline')
forceInlineConstructorBody() {
new Class2();
@@ -49,12 +49,12 @@
////////////////////////////////////////////////////////////////////////////////
class Class3<T> {
- /*element: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+ /*member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
@pragma('dart2js:tryInline')
Class3();
}
-/*element: forceInlineGenericConstructor:[]*/
+/*member: forceInlineGenericConstructor:[]*/
@pragma('dart2js:noInline')
forceInlineGenericConstructor() {
new Class3<int>();
@@ -65,18 +65,18 @@
////////////////////////////////////////////////////////////////////////////////
class Class4a<T> implements Class4b<T> {
- /*element: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+ /*member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
@pragma('dart2js:tryInline')
Class4a();
}
class Class4b<T> {
- /*element: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+ /*member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
@pragma('dart2js:tryInline')
factory Class4b() => new Class4a<T>();
}
-/*element: forceInlineGenericFactory:[]*/
+/*member: forceInlineGenericFactory:[]*/
@pragma('dart2js:noInline')
forceInlineGenericFactory() {
new Class4b<int>();
diff --git a/tests/compiler/dart2js/inlining/data/dynamic.dart b/tests/compiler/dart2js/inlining/data/dynamic.dart
index 60bcb05..0810edd 100644
--- a/tests/compiler/dart2js/inlining/data/dynamic.dart
+++ b/tests/compiler/dart2js/inlining/data/dynamic.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
forceInlineDynamic();
forceInlineOptional();
@@ -13,16 +13,16 @@
////////////////////////////////////////////////////////////////////////////////
class Class1 {
- /*element: Class1.:[]*/
+ /*member: Class1.:[]*/
@pragma('dart2js:noInline')
Class1();
- /*element: Class1.method:[forceInlineDynamic]*/
+ /*member: Class1.method:[forceInlineDynamic]*/
@pragma('dart2js:tryInline')
method() {}
}
-/*element: forceInlineDynamic:[]*/
+/*member: forceInlineDynamic:[]*/
@pragma('dart2js:noInline')
forceInlineDynamic() {
new Class1().method();
@@ -33,16 +33,16 @@
////////////////////////////////////////////////////////////////////////////////
class Class2 {
- /*element: Class2.:[]*/
+ /*member: Class2.:[]*/
@pragma('dart2js:noInline')
Class2();
- /*element: Class2.method:[forceInlineOptional]*/
+ /*member: Class2.method:[forceInlineOptional]*/
@pragma('dart2js:tryInline')
method([x]) {}
}
-/*element: forceInlineOptional:[]*/
+/*member: forceInlineOptional:[]*/
@pragma('dart2js:noInline')
forceInlineOptional() {
new Class2().method();
diff --git a/tests/compiler/dart2js/inlining/data/external.dart b/tests/compiler/dart2js/inlining/data/external.dart
index b656ff4..e943165 100644
--- a/tests/compiler/dart2js/inlining/data/external.dart
+++ b/tests/compiler/dart2js/inlining/data/external.dart
@@ -7,17 +7,17 @@
import 'package:js/js.dart';
-/*element: main:[]*/
+/*member: main:[]*/
main() {
externalFunction();
}
-/*element: externalFunction:[]*/
+/*member: externalFunction:[]*/
@pragma('dart2js:noInline')
externalFunction() {
_externalFunction();
}
-/*element: _externalFunction:[]*/
+/*member: _externalFunction:[]*/
@JS('externalFunction')
external _externalFunction();
diff --git a/tests/compiler/dart2js/inlining/data/force_inline.dart b/tests/compiler/dart2js/inlining/data/force_inline.dart
index c7e0cf0..4bc1627 100644
--- a/tests/compiler/dart2js/inlining/data/force_inline.dart
+++ b/tests/compiler/dart2js/inlining/data/force_inline.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
forceInlineOnce();
forceInlineTwice1();
@@ -15,11 +15,11 @@
// Force inline a top level method once.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forceInlineOnce:[forceInlineOnce]*/
+/*member: _forceInlineOnce:[forceInlineOnce]*/
@pragma('dart2js:tryInline')
_forceInlineOnce() {}
-/*element: forceInlineOnce:[]*/
+/*member: forceInlineOnce:[]*/
@pragma('dart2js:noInline')
forceInlineOnce() {
_forceInlineOnce();
@@ -29,17 +29,17 @@
// Force inline a top level method twice.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forceInlineTwice:[forceInlineTwice1,forceInlineTwice2]*/
+/*member: _forceInlineTwice:[forceInlineTwice1,forceInlineTwice2]*/
@pragma('dart2js:tryInline')
_forceInlineTwice() {}
-/*element: forceInlineTwice1:[]*/
+/*member: forceInlineTwice1:[]*/
@pragma('dart2js:noInline')
forceInlineTwice1() {
_forceInlineTwice();
}
-/*element: forceInlineTwice2:[]*/
+/*member: forceInlineTwice2:[]*/
@pragma('dart2js:noInline')
forceInlineTwice2() {
_forceInlineTwice();
@@ -49,17 +49,17 @@
// Force inline nested top level methods.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forceInlineNested1:[forceInlineNested]*/
+/*member: _forceInlineNested1:[forceInlineNested]*/
@pragma('dart2js:tryInline')
_forceInlineNested1() {}
-/*element: _forceInlineNested2:[forceInlineNested]*/
+/*member: _forceInlineNested2:[forceInlineNested]*/
@pragma('dart2js:tryInline')
_forceInlineNested2() {
_forceInlineNested1();
}
-/*element: forceInlineNested:[]*/
+/*member: forceInlineNested:[]*/
@pragma('dart2js:noInline')
forceInlineNested() {
_forceInlineNested2();
@@ -69,11 +69,11 @@
// Force inline a top level method with optional argument.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forceInlineOptional:[forceInlineOptional]*/
+/*member: _forceInlineOptional:[forceInlineOptional]*/
@pragma('dart2js:tryInline')
_forceInlineOptional([x]) {}
-/*element: forceInlineOptional:[]*/
+/*member: forceInlineOptional:[]*/
@pragma('dart2js:noInline')
forceInlineOptional() {
_forceInlineOptional();
diff --git a/tests/compiler/dart2js/inlining/data/force_inline_loops.dart b/tests/compiler/dart2js/inlining/data/force_inline_loops.dart
index 7927b0e..c9c09a7 100644
--- a/tests/compiler/dart2js/inlining/data/force_inline_loops.dart
+++ b/tests/compiler/dart2js/inlining/data/force_inline_loops.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
forceInlineLoops();
}
@@ -10,7 +10,7 @@
// Force inline a top level method with loops.
////////////////////////////////////////////////////////////////////////////////
-/*element: _forLoop:loop,[forceInlineLoops]*/
+/*member: _forLoop:loop,[forceInlineLoops]*/
@pragma('dart2js:tryInline')
_forLoop() {
for (int i = 0; i < 10; i++) {
@@ -18,7 +18,7 @@
}
}
-/*element: _forInLoop:loop,[forceInlineLoops]*/
+/*member: _forInLoop:loop,[forceInlineLoops]*/
@pragma('dart2js:tryInline')
_forInLoop() {
for (var e in [0, 1, 2]) {
@@ -26,7 +26,7 @@
}
}
-/*element: _whileLoop:loop,[forceInlineLoops]*/
+/*member: _whileLoop:loop,[forceInlineLoops]*/
@pragma('dart2js:tryInline')
_whileLoop() {
int i = 0;
@@ -36,7 +36,7 @@
}
}
-/*element: _doLoop:loop,[forceInlineLoops]*/
+/*member: _doLoop:loop,[forceInlineLoops]*/
@pragma('dart2js:tryInline')
_doLoop() {
int i = 0;
@@ -46,7 +46,7 @@
} while (i < 10);
}
-/*element: _hardLoop:loop,(allowLoops)code after return*/
+/*member: _hardLoop:loop,(allowLoops)code after return*/
@pragma('dart2js:tryInline')
_hardLoop() {
for (int i = 0; i < 10; i++) {
@@ -56,7 +56,7 @@
return 1;
}
-/*element: forceInlineLoops:[]*/
+/*member: forceInlineLoops:[]*/
@pragma('dart2js:noInline')
forceInlineLoops() {
_forLoop();
diff --git a/tests/compiler/dart2js/inlining/data/heuristics.dart b/tests/compiler/dart2js/inlining/data/heuristics.dart
index cd0bae7..d9f0c2c 100644
--- a/tests/compiler/dart2js/inlining/data/heuristics.dart
+++ b/tests/compiler/dart2js/inlining/data/heuristics.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
outsideLoopNoArgsCalledOnce();
outsideLoopNoArgsCalledTwice();
@@ -19,10 +19,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method1:[outsideLoopNoArgsCalledOnce]*/
+/*member: _method1:[outsideLoopNoArgsCalledOnce]*/
_method1() {}
-/*element: _outsideLoopNoArgsCalledOnce:[outsideLoopNoArgsCalledOnce]*/
+/*member: _outsideLoopNoArgsCalledOnce:[outsideLoopNoArgsCalledOnce]*/
_outsideLoopNoArgsCalledOnce() {
_method1();
_method1();
@@ -32,7 +32,7 @@
_method1();
}
-/*element: outsideLoopNoArgsCalledOnce:[]*/
+/*member: outsideLoopNoArgsCalledOnce:[]*/
@pragma('dart2js:noInline')
outsideLoopNoArgsCalledOnce() {
_outsideLoopNoArgsCalledOnce();
@@ -43,10 +43,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method2:[_outsideLoopNoArgs2,outsideLoopNoArgsCalledTwice]*/
+/*member: _method2:[_outsideLoopNoArgs2,outsideLoopNoArgsCalledTwice]*/
_method2() {}
-/*element: _outsideLoopNoArgs1:[outsideLoopNoArgsCalledTwice]*/
+/*member: _outsideLoopNoArgs1:[outsideLoopNoArgsCalledTwice]*/
_outsideLoopNoArgs1() {
_method2();
_method2();
@@ -54,7 +54,7 @@
_method2();
}
-/*element: _outsideLoopNoArgs2:[]*/
+/*member: _outsideLoopNoArgs2:[]*/
_outsideLoopNoArgs2() {
_method2();
_method2();
@@ -64,7 +64,7 @@
_method2();
}
-/*element: outsideLoopNoArgsCalledTwice:[]*/
+/*member: outsideLoopNoArgsCalledTwice:[]*/
@pragma('dart2js:noInline')
outsideLoopNoArgsCalledTwice() {
_outsideLoopNoArgs1();
@@ -78,10 +78,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method3:[outsideLoopOneArgCalledOnce]*/
+/*member: _method3:[outsideLoopOneArgCalledOnce]*/
_method3() {}
-/*element: _outsideLoopOneArgCalledOnce:[outsideLoopOneArgCalledOnce]*/
+/*member: _outsideLoopOneArgCalledOnce:[outsideLoopOneArgCalledOnce]*/
_outsideLoopOneArgCalledOnce(arg) {
_method3();
_method3();
@@ -102,7 +102,7 @@
_method3();
}
-/*element: outsideLoopOneArgCalledOnce:[]*/
+/*member: outsideLoopOneArgCalledOnce:[]*/
@pragma('dart2js:noInline')
outsideLoopOneArgCalledOnce() {
_outsideLoopOneArgCalledOnce(0);
@@ -113,10 +113,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method4:[_outsideLoopOneArg2,outsideLoopOneArgCalledTwice]*/
+/*member: _method4:[_outsideLoopOneArg2,outsideLoopOneArgCalledTwice]*/
_method4() {}
-/*element: _outsideLoopOneArg1:[outsideLoopOneArgCalledTwice]*/
+/*member: _outsideLoopOneArg1:[outsideLoopOneArgCalledTwice]*/
_outsideLoopOneArg1(arg) {
_method4();
_method4();
@@ -126,7 +126,7 @@
_method4();
}
-/*element: _outsideLoopOneArg2:[]*/
+/*member: _outsideLoopOneArg2:[]*/
_outsideLoopOneArg2(arg) {
_method4();
_method4();
@@ -138,7 +138,7 @@
_method4();
}
-/*element: outsideLoopOneArgCalledTwice:[]*/
+/*member: outsideLoopOneArgCalledTwice:[]*/
@pragma('dart2js:noInline')
outsideLoopOneArgCalledTwice() {
_outsideLoopOneArg1(0);
@@ -152,10 +152,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method5:[insideLoopNoArgsCalledOnce]*/
+/*member: _method5:[insideLoopNoArgsCalledOnce]*/
_method5() {}
-/*element: _insideLoopNoArgsCalledOnce:[insideLoopNoArgsCalledOnce]*/
+/*member: _insideLoopNoArgsCalledOnce:[insideLoopNoArgsCalledOnce]*/
_insideLoopNoArgsCalledOnce() {
_method5();
_method5();
@@ -170,7 +170,7 @@
_method5();
}
-/*element: insideLoopNoArgsCalledOnce:loop*/
+/*member: insideLoopNoArgsCalledOnce:loop*/
@pragma('dart2js:noInline')
insideLoopNoArgsCalledOnce() {
// ignore: UNUSED_LOCAL_VARIABLE
@@ -184,10 +184,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method6:[_insideLoopNoArgs2,insideLoopNoArgsCalledTwice]*/
+/*member: _method6:[_insideLoopNoArgs2,insideLoopNoArgsCalledTwice]*/
_method6() {}
-/*element: _insideLoopNoArgs1:[insideLoopNoArgsCalledTwice]*/
+/*member: _insideLoopNoArgs1:[insideLoopNoArgsCalledTwice]*/
_insideLoopNoArgs1() {
_method6();
_method6();
@@ -201,7 +201,7 @@
_method6();
}
-/*element: _insideLoopNoArgs2:[]*/
+/*member: _insideLoopNoArgs2:[]*/
_insideLoopNoArgs2() {
_method6();
_method6();
@@ -219,7 +219,7 @@
_method6();
}
-/*element: insideLoopNoArgsCalledTwice:loop*/
+/*member: insideLoopNoArgsCalledTwice:loop*/
@pragma('dart2js:noInline')
insideLoopNoArgsCalledTwice() {
// ignore: UNUSED_LOCAL_VARIABLE
@@ -236,10 +236,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method7:[insideLoopOneArgCalledOnce]*/
+/*member: _method7:[insideLoopOneArgCalledOnce]*/
_method7() {}
-/*element: _insideLoopOneArgCalledOnce:[insideLoopOneArgCalledOnce]*/
+/*member: _insideLoopOneArgCalledOnce:[insideLoopOneArgCalledOnce]*/
_insideLoopOneArgCalledOnce(arg) {
_method7();
_method7();
@@ -260,7 +260,7 @@
_method7();
}
-/*element: insideLoopOneArgCalledOnce:loop*/
+/*member: insideLoopOneArgCalledOnce:loop*/
@pragma('dart2js:noInline')
insideLoopOneArgCalledOnce() {
for (var e in [1, 2, 3, 4]) {
@@ -273,10 +273,10 @@
// static no-arg calls in its body.
////////////////////////////////////////////////////////////////////////////////
-/*element: _method8:[_insideLoopOneArg2,insideLoopOneArgCalledTwice]*/
+/*member: _method8:[_insideLoopOneArg2,insideLoopOneArgCalledTwice]*/
_method8() {}
-/*element: _insideLoopOneArg1:[insideLoopOneArgCalledTwice]*/
+/*member: _insideLoopOneArg1:[insideLoopOneArgCalledTwice]*/
_insideLoopOneArg1(arg) {
_method8();
_method8();
@@ -292,7 +292,7 @@
_method8();
}
-/*element: _insideLoopOneArg2:[]*/
+/*member: _insideLoopOneArg2:[]*/
_insideLoopOneArg2(arg) {
_method8();
_method8();
@@ -310,7 +310,7 @@
_method8();
}
-/*element: insideLoopOneArgCalledTwice:loop*/
+/*member: insideLoopOneArgCalledTwice:loop*/
@pragma('dart2js:noInline')
insideLoopOneArgCalledTwice() {
for (var e in [1, 2, 3, 4]) {
diff --git a/tests/compiler/dart2js/inlining/data/map.dart b/tests/compiler/dart2js/inlining/data/map.dart
index 1d4589e..9063caa 100644
--- a/tests/compiler/dart2js/inlining/data/map.dart
+++ b/tests/compiler/dart2js/inlining/data/map.dart
@@ -2,17 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
passMapToNull();
}
-/*element: _passMapToNull:[passMapToNull]*/
+/*member: _passMapToNull:[passMapToNull]*/
_passMapToNull(f) {
f({});
}
-/*element: passMapToNull:[]*/
+/*member: passMapToNull:[]*/
@pragma('dart2js:noInline')
passMapToNull() {
_passMapToNull(null);
diff --git a/tests/compiler/dart2js/inlining/data/meta.dart b/tests/compiler/dart2js/inlining/data/meta.dart
index 6dc7f22..fe47d1d 100644
--- a/tests/compiler/dart2js/inlining/data/meta.dart
+++ b/tests/compiler/dart2js/inlining/data/meta.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
tryInlineOnce();
tryInlineTwice1();
@@ -13,11 +13,11 @@
// Use `tryInline` to inline a top level method once.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryInlineOnce:[tryInlineOnce]*/
+/*member: _tryInlineOnce:[tryInlineOnce]*/
@pragma('dart2js:tryInline')
_tryInlineOnce() {}
-/*element: tryInlineOnce:[]*/
+/*member: tryInlineOnce:[]*/
@pragma('dart2js:noInline')
tryInlineOnce() {
_tryInlineOnce();
@@ -27,17 +27,17 @@
// Use `tryInline`to inline a top level method twice.
////////////////////////////////////////////////////////////////////////////////
-/*element: _tryInlineTwice:[tryInlineTwice1,tryInlineTwice2]*/
+/*member: _tryInlineTwice:[tryInlineTwice1,tryInlineTwice2]*/
@pragma('dart2js:tryInline')
_tryInlineTwice() {}
-/*element: tryInlineTwice1:[]*/
+/*member: tryInlineTwice1:[]*/
@pragma('dart2js:noInline')
tryInlineTwice1() {
_tryInlineTwice();
}
-/*element: tryInlineTwice2:[]*/
+/*member: tryInlineTwice2:[]*/
@pragma('dart2js:noInline')
tryInlineTwice2() {
_tryInlineTwice();
diff --git a/tests/compiler/dart2js/inlining/data/native.dart b/tests/compiler/dart2js/inlining/data/native.dart
index 6492328..8b4c1cff 100644
--- a/tests/compiler/dart2js/inlining/data/native.dart
+++ b/tests/compiler/dart2js/inlining/data/native.dart
@@ -4,7 +4,7 @@
import 'dart:html';
-/*element: main:[]*/
+/*member: main:[]*/
main() {
document.createElement(CustomElement.tag);
newCustom();
@@ -18,13 +18,13 @@
// constructor isn't.
////////////////////////////////////////////////////////////////////////////////
-/*element: newCustom:[]*/
+/*member: newCustom:[]*/
@pragma('dart2js:noInline')
newCustom() {
new CustomElement();
}
-/*element: newCustomCreated:[]*/
+/*member: newCustomCreated:[]*/
@pragma('dart2js:noInline')
newCustomCreated() {
new CustomElement.created();
@@ -33,10 +33,10 @@
class CustomElement extends HtmlElement {
static final tag = 'x-foo';
- /*element: CustomElement.:[newCustom:CustomElement]*/
+ /*member: CustomElement.:[newCustom:CustomElement]*/
factory CustomElement() => new Element.tag(tag);
- /*element: CustomElement.created:[]*/
+ /*member: CustomElement.created:[]*/
CustomElement.created() : super.created() {
print('boo');
}
@@ -47,23 +47,23 @@
// the generative constructor are inlined.
////////////////////////////////////////////////////////////////////////////////
-/*element: newNormal:[]*/
+/*member: newNormal:[]*/
@pragma('dart2js:noInline')
newNormal() {
new NormalElement();
}
-/*element: newNormalCreated:[]*/
+/*member: newNormalCreated:[]*/
@pragma('dart2js:noInline')
newNormalCreated() {
new NormalElement.created();
}
class NormalElement {
- /*element: NormalElement.:[newNormal:NormalElement]*/
+ /*member: NormalElement.:[newNormal:NormalElement]*/
factory NormalElement() => null;
- /*element: NormalElement.created:[newNormalCreated+,newNormalCreated:NormalElement]*/
+ /*member: NormalElement.created:[newNormalCreated+,newNormalCreated:NormalElement]*/
NormalElement.created() {
print('foo');
}
diff --git a/tests/compiler/dart2js/inlining/data/nested.dart b/tests/compiler/dart2js/inlining/data/nested.dart
index e85ab5c..0c98ef2 100644
--- a/tests/compiler/dart2js/inlining/data/nested.dart
+++ b/tests/compiler/dart2js/inlining/data/nested.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
nestedGenericInlining();
nestedGenericFactoryInlining();
@@ -13,11 +13,11 @@
////////////////////////////////////////////////////////////////////////////////
class Class1<T> {
- /*element: Class1.:[nestedGenericInlining:Class1<int>]*/
+ /*member: Class1.:[nestedGenericInlining:Class1<int>]*/
@pragma('dart2js:tryInline')
Class1();
- /*element: Class1.method:[nestedGenericInlining]*/
+ /*member: Class1.method:[nestedGenericInlining]*/
@pragma('dart2js:tryInline')
method() {
new Class2<List<T>>().method();
@@ -27,16 +27,16 @@
class Class2<T> {
// TODO(johnniwinther): Should the type have been Class<List<int>>?
// Similarly below.
- /*element: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+ /*member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
@pragma('dart2js:tryInline')
Class2();
- /*element: Class2.method:[nestedGenericInlining]*/
+ /*member: Class2.method:[nestedGenericInlining]*/
@pragma('dart2js:tryInline')
method() {}
}
-/*element: nestedGenericInlining:[]*/
+/*member: nestedGenericInlining:[]*/
@pragma('dart2js:noInline')
nestedGenericInlining() {
new Class1<int>().method();
@@ -47,11 +47,11 @@
////////////////////////////////////////////////////////////////////////////////
class Class3a<T> implements Class3b<T> {
- /*element: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+ /*member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
@pragma('dart2js:tryInline')
Class3a();
- /*element: Class3a.method:[nestedGenericFactoryInlining]*/
+ /*member: Class3a.method:[nestedGenericFactoryInlining]*/
@pragma('dart2js:tryInline')
method() {
new Class4b<List<T>>().method();
@@ -59,7 +59,7 @@
}
abstract class Class3b<T> {
- /*element: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+ /*member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
@pragma('dart2js:tryInline')
factory Class3b() => new Class3a<T>();
@@ -67,24 +67,24 @@
}
class Class4a<T> implements Class4b<T> {
- /*element: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+ /*member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
@pragma('dart2js:tryInline')
Class4a();
- /*element: Class4a.method:[nestedGenericFactoryInlining]*/
+ /*member: Class4a.method:[nestedGenericFactoryInlining]*/
@pragma('dart2js:tryInline')
method() {}
}
abstract class Class4b<T> {
- /*element: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+ /*member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
@pragma('dart2js:tryInline')
factory Class4b() => new Class4a<T>();
method();
}
-/*element: nestedGenericFactoryInlining:[]*/
+/*member: nestedGenericFactoryInlining:[]*/
@pragma('dart2js:noInline')
nestedGenericFactoryInlining() {
new Class3b<int>().method();
diff --git a/tests/compiler/dart2js/inlining/data/setter.dart b/tests/compiler/dart2js/inlining/data/setter.dart
index 346568f..2c255fba 100644
--- a/tests/compiler/dart2js/inlining/data/setter.dart
+++ b/tests/compiler/dart2js/inlining/data/setter.dart
@@ -2,23 +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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
inlineSetter();
}
class Class1 {
var field;
-/*element: Class1.:[]*/
+/*member: Class1.:[]*/
@pragma('dart2js:noInline')
Class1();
- /*element: Class1.setter=:[inlineSetter]*/
+ /*member: Class1.setter=:[inlineSetter]*/
set setter(value) {
field = value;
}
}
-/*element: inlineSetter:[]*/
+/*member: inlineSetter:[]*/
@pragma('dart2js:noInline')
inlineSetter() {
Class1 c = new Class1();
diff --git a/tests/compiler/dart2js/inlining/data/static_initializer.dart b/tests/compiler/dart2js/inlining/data/static_initializer.dart
index 11838285..9c812c3 100644
--- a/tests/compiler/dart2js/inlining/data/static_initializer.dart
+++ b/tests/compiler/dart2js/inlining/data/static_initializer.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
_var1;
_var2;
@@ -12,11 +12,11 @@
var _var1 = <String>[_shortString(), _longStringMany()];
var _var2 = <String>[_shortString(), _longStringMany(), _longStringOnce()];
-/*element: _shortString:[_var1,_var2]*/
+/*member: _shortString:[_var1,_var2]*/
String _shortString() => r"""
hello""";
-/*element: _longStringMany:[]*/
+/*member: _longStringMany:[]*/
String _longStringMany() => r"""
I wandered lonely as a cloud
That floats on high o'er vales and hills,
@@ -26,7 +26,7 @@
Fluttering and dancing in the breeze.
""";
-/*element: _longStringOnce:[_var2]*/
+/*member: _longStringOnce:[_var2]*/
String _longStringOnce() => r"""
Continuous as the stars that shine
And twinkle on the milky way,
@@ -38,13 +38,13 @@
var _var3 = <int>[Foo().a, (Foo()..a).a];
-/*element: Foo.:[]*/
+/*member: Foo.:[]*/
class Foo {
int z = 99;
- /*element: Foo.a:[_var3]*/
+ /*member: Foo.a:[_var3]*/
get a => b;
- /*element: Foo.b:[_var3]*/
+ /*member: Foo.b:[_var3]*/
get b => c;
- /*element: Foo.c:[]*/
+ /*member: Foo.c:[]*/
get c => z++;
}
diff --git a/tests/compiler/dart2js/inlining/data/switch.dart b/tests/compiler/dart2js/inlining/data/switch.dart
index cf9d938..37a0c3d 100644
--- a/tests/compiler/dart2js/inlining/data/switch.dart
+++ b/tests/compiler/dart2js/inlining/data/switch.dart
@@ -2,12 +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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
switchThrowing();
}
-/*element: switchThrowing:[]*/
+/*member: switchThrowing:[]*/
@pragma('dart2js:noInline')
switchThrowing() {
switch (0) {
@@ -19,7 +19,7 @@
}
}
-/*element: _switchThrowing:[]*/
+/*member: _switchThrowing:[]*/
_switchThrowing() {
throw '';
}
diff --git a/tests/compiler/dart2js/inlining/data/too_difficult.dart b/tests/compiler/dart2js/inlining/data/too_difficult.dart
index 4a0b262..b545095 100644
--- a/tests/compiler/dart2js/inlining/data/too_difficult.dart
+++ b/tests/compiler/dart2js/inlining/data/too_difficult.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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
asyncMethod();
asyncStarMethod();
@@ -27,7 +27,7 @@
closureInInitializer();
}
-/*element: _multipleReturns:code after return*/
+/*member: _multipleReturns:code after return*/
_multipleReturns(c) {
if (c)
return;
@@ -35,27 +35,27 @@
return;
}
-/*element: multipleReturns:[]*/
+/*member: multipleReturns:[]*/
@pragma('dart2js:noInline')
multipleReturns() {
_multipleReturns(true);
_multipleReturns(false);
}
-/*element: _codeAfterReturn:code after return*/
+/*member: _codeAfterReturn:code after return*/
_codeAfterReturn(c) {
if (c) return;
print(c);
}
-/*element: codeAfterReturn:[]*/
+/*member: codeAfterReturn:[]*/
@pragma('dart2js:noInline')
codeAfterReturn() {
_codeAfterReturn(true);
_codeAfterReturn(false);
}
-/*element: _multipleThrows:[]*/
+/*member: _multipleThrows:[]*/
_multipleThrows(c) {
if (c)
throw '';
@@ -63,14 +63,14 @@
throw '';
}
-/*element: multipleThrows:[]*/
+/*member: multipleThrows:[]*/
@pragma('dart2js:noInline')
multipleThrows() {
_multipleThrows(true);
_multipleThrows(false);
}
-/*element: _returnAndThrow:code after return*/
+/*member: _returnAndThrow:code after return*/
_returnAndThrow(c) {
if (c)
return;
@@ -78,65 +78,65 @@
throw '';
}
-/*element: returnAndThrow:[]*/
+/*member: returnAndThrow:[]*/
@pragma('dart2js:noInline')
returnAndThrow() {
_returnAndThrow(true);
_returnAndThrow(false);
}
-/*element: asyncMethod:async/await*/
+/*member: asyncMethod:async/await*/
asyncMethod() async {}
-/*element: asyncStarMethod:async/await*/
+/*member: asyncStarMethod:async/await*/
asyncStarMethod() async* {}
-/*element: syncStarMethod:async/await*/
+/*member: syncStarMethod:async/await*/
syncStarMethod() sync* {}
-/*element: localFunction:closure*/
+/*member: localFunction:closure*/
localFunction() {
// ignore: UNUSED_ELEMENT
/*[]*/ local() {}
}
-/*element: anonymousFunction:closure*/
+/*member: anonymousFunction:closure*/
anonymousFunction() {
/*[]*/ () {};
}
-/*element: tryCatch:try*/
+/*member: tryCatch:try*/
tryCatch() {
try {} catch (e) {}
}
-/*element: tryFinally:try*/
+/*member: tryFinally:try*/
tryFinally() {
try {} finally {}
}
-/*element: tryWithRethrow:try*/
+/*member: tryWithRethrow:try*/
tryWithRethrow() {
try {} catch (e) {
rethrow;
}
}
-/*element: forLoop:loop*/
+/*member: forLoop:loop*/
forLoop() {
for (int i = 0; i < 10; i++) {
print(i);
}
}
-/*element: forInLoop:loop*/
+/*member: forInLoop:loop*/
forInLoop() {
for (var e in [0, 1, 2]) {
print(e);
}
}
-/*element: whileLoop:loop*/
+/*member: whileLoop:loop*/
whileLoop() {
int i = 0;
while (i < 10) {
@@ -145,7 +145,7 @@
}
}
-/*element: doLoop:loop*/
+/*member: doLoop:loop*/
doLoop() {
int i = 0;
do {
@@ -154,12 +154,12 @@
} while (i < 10);
}
-/*element: returnClosure:closure*/
+/*member: returnClosure:closure*/
returnClosure() {
return /*[]*/ () {};
}
-/*element: throwClosure:closure*/
+/*member: throwClosure:closure*/
throwClosure() {
throw /*[]*/ () {};
}
@@ -167,13 +167,13 @@
class Class1 {
var f;
- /*element: Class1.:closure*/
+ /*member: Class1.:closure*/
Class1() : f = (/*[]*/ () {}) {
print(f);
}
}
-/*element: closureInInitializer:[]*/
+/*member: closureInInitializer:[]*/
@pragma('dart2js:noInline')
closureInInitializer() {
new Class1();
diff --git a/tests/compiler/dart2js/inlining/data/type_variables.dart b/tests/compiler/dart2js/inlining/data/type_variables.dart
index 4641443..93c0c21 100644
--- a/tests/compiler/dart2js/inlining/data/type_variables.dart
+++ b/tests/compiler/dart2js/inlining/data/type_variables.dart
@@ -2,23 +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.
-/*element: main:[]*/
+/*member: main:[]*/
main() {
inlineTypeTests();
}
-/*element: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
class Mixin1<S> {
var field = /*[]*/ (S s) => null;
}
-/*element: Class1.:[inlineTypeTests:Class1<int>]*/
+/*member: Class1.:[inlineTypeTests:Class1<int>]*/
class Class1<T> extends Object with Mixin1<T> {}
-/*element: _inlineTypeTests:[inlineTypeTests]*/
+/*member: _inlineTypeTests:[inlineTypeTests]*/
_inlineTypeTests(o) => o.field is dynamic Function(int);
-/*element: inlineTypeTests:[]*/
+/*member: inlineTypeTests:[]*/
@pragma('dart2js:noInline')
void inlineTypeTests() {
_inlineTypeTests(new Mixin1<int>());
diff --git a/tests/compiler/dart2js/jumps/jump_test.dart b/tests/compiler/dart2js/jumps/jump_test.dart
index 5ea39a1..04d8988 100644
--- a/tests/compiler/dart2js/jumps/jump_test.dart
+++ b/tests/compiler/dart2js/jumps/jump_test.dart
@@ -102,7 +102,8 @@
needsComma = true;
}
String value = sb.toString();
- registerValue(data.sourceSpan, data.id, value, target);
+ registerValue(
+ data.sourceSpan.uri, data.sourceSpan.begin, data.id, value, target);
});
gotos.forEach((GotoData data) {
StringBuffer sb = new StringBuffer();
@@ -111,7 +112,8 @@
assert(targetData != null, "No TargetData for ${data.target}");
sb.write(targetData.index);
String value = sb.toString();
- registerValue(data.sourceSpan, data.id, value, data);
+ registerValue(
+ data.sourceSpan.uri, data.sourceSpan.begin, data.id, value, data);
});
}
diff --git a/tests/compiler/dart2js/member_usage/data/constant_folding.dart b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
index 0225146..195684c 100644
--- a/tests/compiler/dart2js/member_usage/data/constant_folding.dart
+++ b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
@@ -6,7 +6,7 @@
import "package:expect/expect.dart";
-/*element: main:invoke*/
+/*member: main:invoke*/
void main() {
const BitNot(42, 4294967253).check();
const BitNot(4294967253, 42).check();
@@ -17,7 +17,7 @@
const BitNot(0x12121212121212, 0xEDEDEDED).check();
}
-/*element: jsEquals:invoke*/
+/*member: jsEquals:invoke*/
void jsEquals(expected, actual, [String reason = null]) {
if (expected is num && actual is num) {
if (expected.isNaN && actual.isNaN) return;
@@ -36,16 +36,16 @@
}
abstract class TestOp {
- /*element: TestOp.expected:init,read*/
+ /*member: TestOp.expected:init,read*/
final expected;
- /*element: TestOp.result:init,read*/
+ /*member: TestOp.result:init,read*/
final result;
- /*strong.element: TestOp.:invoke*/
+ /*strong.member: TestOp.:invoke*/
const TestOp(this.expected, this.result);
- /*element: TestOp.checkAll:invoke*/
+ /*member: TestOp.checkAll:invoke*/
@pragma('dart2js:noInline')
checkAll(evalResult) {
jsEquals(expected, result,
@@ -59,17 +59,17 @@
}
class BitNot extends TestOp {
- /*element: BitNot.arg:init,read*/
+ /*member: BitNot.arg:init,read*/
final arg;
- /*strong.element: BitNot.:invoke*/
+ /*strong.member: BitNot.:invoke*/
const BitNot(this.arg, expected) : super(expected, ~arg);
- /*element: BitNot.check:invoke*/
+ /*member: BitNot.check:invoke*/
@pragma('dart2js:tryInline')
check() => checkAll(eval());
- /*element: BitNot.eval:invoke*/
+ /*member: BitNot.eval:invoke*/
@override
@pragma('dart2js:tryInline')
eval() => ~arg;
diff --git a/tests/compiler/dart2js/member_usage/data/constructors.dart b/tests/compiler/dart2js/member_usage/data/constructors.dart
index c53d93c..39d4566 100644
--- a/tests/compiler/dart2js/member_usage/data/constructors.dart
+++ b/tests/compiler/dart2js/member_usage/data/constructors.dart
@@ -3,73 +3,73 @@
// BSD-style license that can be found in the LICENSE file.
class Class {
- /*element: Class.constructor1:invoke*/
+ /*member: Class.constructor1:invoke*/
Class.constructor1() {}
- /*element: Class.constructor2a:invoke=(0)*/
+ /*member: Class.constructor2a:invoke=(0)*/
Class.constructor2a([a]) {}
- /*element: Class.constructor2b:invoke*/
+ /*member: Class.constructor2b:invoke*/
Class.constructor2b([a]) {}
- /*element: Class.constructor2c:invoke*/
+ /*member: Class.constructor2c:invoke*/
Class.constructor2c([a]) {}
- /*element: Class.constructor3a:invoke=(0)*/
+ /*member: Class.constructor3a:invoke=(0)*/
Class.constructor3a([a, b]) {}
- /*element: Class.constructor3b:invoke=(1)*/
+ /*member: Class.constructor3b:invoke=(1)*/
Class.constructor3b([a, b]) {}
- /*element: Class.constructor3c:invoke*/
+ /*member: Class.constructor3c:invoke*/
Class.constructor3c([a, b]) {}
- /*element: Class.constructor4a:invoke=(0)*/
+ /*member: Class.constructor4a:invoke=(0)*/
Class.constructor4a({a}) {}
- /*element: Class.constructor4b:invoke*/
+ /*member: Class.constructor4b:invoke*/
Class.constructor4b({a}) {}
- /*element: Class.constructor4c:invoke*/
+ /*member: Class.constructor4c:invoke*/
Class.constructor4c({a}) {}
- /*element: Class.constructor5a:invoke=(0)*/
+ /*member: Class.constructor5a:invoke=(0)*/
Class.constructor5a({a, b}) {}
- /*element: Class.constructor5b:invoke=(0,a)*/
+ /*member: Class.constructor5b:invoke=(0,a)*/
Class.constructor5b({a, b}) {}
- /*element: Class.constructor5c:invoke=(0,b)*/
+ /*member: Class.constructor5c:invoke=(0,b)*/
Class.constructor5c({a, b}) {}
- /*element: Class.constructor6a:invoke=(1)*/
+ /*member: Class.constructor6a:invoke=(1)*/
Class.constructor6a(a, [b, c]) {}
- /*element: Class.constructor6b:invoke=(2)*/
+ /*member: Class.constructor6b:invoke=(2)*/
Class.constructor6b(a, [b, c]) {}
- /*element: Class.constructor6c:invoke*/
+ /*member: Class.constructor6c:invoke*/
Class.constructor6c(a, [b, c]) {}
- /*element: Class.constructor7a:invoke=(1)*/
+ /*member: Class.constructor7a:invoke=(1)*/
Class.constructor7a(a, {b, c}) {}
- /*element: Class.constructor7b:invoke=(1,b)*/
+ /*member: Class.constructor7b:invoke=(1,b)*/
Class.constructor7b(a, {b, c}) {}
- /*element: Class.constructor7c:invoke=(1,c)*/
+ /*member: Class.constructor7c:invoke=(1,c)*/
Class.constructor7c(a, {b, c}) {}
- /*element: Class.constructor8a:invoke=(0)*/
+ /*member: Class.constructor8a:invoke=(0)*/
@pragma('dart2js:noElision')
Class.constructor8a([a, b]) {}
- /*element: Class.constructor8b:invoke=(0)*/
+ /*member: Class.constructor8b:invoke=(0)*/
@pragma('dart2js:noElision')
Class.constructor8b({a, b}) {}
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
new Class.constructor1();
diff --git a/tests/compiler/dart2js/member_usage/data/fields.dart b/tests/compiler/dart2js/member_usage/data/fields.dart
index 6b40661..9bdacad 100644
--- a/tests/compiler/dart2js/member_usage/data/fields.dart
+++ b/tests/compiler/dart2js/member_usage/data/fields.dart
@@ -2,89 +2,89 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: field1a:init,read*/
+/*member: field1a:init,read*/
var field1a;
-/*element: field1b:init,write*/
+/*member: field1b:init,write*/
var field1b;
-/*element: field1c:init,read,write*/
+/*member: field1c:init,read,write*/
var field1c;
// Invocations of static/top level fields are converted into 'field1d.call(...)`
// so we don't have an invocation of the field but instead an additional dynamic
// call to 'call'.
-/*element: field1d:init,read*/
+/*member: field1d:init,read*/
var field1d;
-/*element: field2a:read*/
+/*member: field2a:read*/
get field2a => 42;
set field2a(_) {}
get field2b => 42;
-/*element: field2b=:write*/
+/*member: field2b=:write*/
set field2b(_) {}
-/*element: field2c:read*/
+/*member: field2c:read*/
get field2c => 42;
-/*element: field2c=:write*/
+/*member: field2c=:write*/
set field2c(_) {}
// Invocations of static/top level getters are converted into
// 'field2d.call(...)` so we don't have an invocation of the field but instead
// an additional dynamic call to 'call'.
-/*element: field2d:read*/
+/*member: field2d:read*/
get field2d => 42;
set field2d(_) {}
class Class {
- /*element: Class.field1a:init,read*/
+ /*member: Class.field1a:init,read*/
var field1a;
- /*element: Class.field1b:init,write*/
+ /*member: Class.field1b:init,write*/
var field1b;
- /*element: Class.field1c:init,read,write*/
+ /*member: Class.field1c:init,read,write*/
var field1c;
- /*element: Class.field1d:init,invoke,read=static*/
+ /*member: Class.field1d:init,invoke,read=static*/
var field1d;
- /*element: Class.field2a:read*/
+ /*member: Class.field2a:read*/
get field2a => 42;
set field2a(_) {}
get field2b => 42;
- /*element: Class.field2b=:write*/
+ /*member: Class.field2b=:write*/
set field2b(_) {}
- /*element: Class.field2c:read*/
+ /*member: Class.field2c:read*/
get field2c => 42;
- /*element: Class.field2c=:write*/
+ /*member: Class.field2c=:write*/
set field2c(_) {}
- /*element: Class.field2d:invoke,read=static*/
+ /*member: Class.field2d:invoke,read=static*/
get field2d => null;
set field2d(_) {}
- /*element: Class.field3a:init*/
+ /*member: Class.field3a:init*/
var field3a = 0;
- /*element: Class.field3b:init*/
+ /*member: Class.field3b:init*/
var field3b;
- /*element: Class.:invoke=(0)*/
+ /*member: Class.:invoke=(0)*/
Class([this.field3b]);
- /*element: Class.test:invoke*/
+ /*member: Class.test:invoke*/
test() {
field1a;
field1b = 42;
@@ -98,7 +98,7 @@
}
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
field1a;
field1b = 42;
diff --git a/tests/compiler/dart2js/member_usage/data/general.dart b/tests/compiler/dart2js/member_usage/data/general.dart
index 9954b67..8e86d99 100644
--- a/tests/compiler/dart2js/member_usage/data/general.dart
+++ b/tests/compiler/dart2js/member_usage/data/general.dart
@@ -2,49 +2,49 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: A.:invoke*/
+/*member: A.:invoke*/
class A {
- /*element: A.method1:invoke*/
+ /*member: A.method1:invoke*/
method1() {}
method2() {}
- /*element: A.method4:invoke*/
+ /*member: A.method4:invoke*/
method4() {}
- /*element: A.getter:read*/
+ /*member: A.getter:read*/
get getter => 42;
set setter(_) {}
}
-/*element: B.:invoke*/
+/*member: B.:invoke*/
class B {
method1() {}
method2() {}
- /*element: B.method5:invoke*/
+ /*member: B.method5:invoke*/
method5() {}
get getter => 42;
- /*element: B.setter=:write*/
+ /*member: B.setter=:write*/
set setter(_) {}
}
-/*element: C.:invoke*/
+/*member: C.:invoke*/
class C extends A {
- /*element: C.method1:invoke*/
+ /*member: C.method1:invoke*/
@override
method1() {}
- /*element: B.method2:invoke*/
+ /*member: B.method2:invoke*/
@override
method2() {}
@override
method4() {}
- /*element: C.getter:read*/
+ /*member: C.getter:read*/
@override
get getter => 42;
@@ -52,12 +52,12 @@
set setter(_) {}
}
-/*element: D.:invoke*/
+/*member: D.:invoke*/
class D implements B {
@override
method1() {}
- /*element: D.method2:invoke*/
+ /*member: D.method2:invoke*/
@override
method2() {}
@@ -67,7 +67,7 @@
@override
get getter => 42;
- /*element: D.setter=:write*/
+ /*member: D.setter=:write*/
@override
set setter(_) {}
}
@@ -107,40 +107,40 @@
}
class G {
- /*element: G.method1:invoke*/
+ /*member: G.method1:invoke*/
method1() {}
method2() {}
method4() {}
- /*element: G.getter:read*/
+ /*member: G.getter:read*/
get getter => 42;
set setter(_) {}
}
-/*element: H.:invoke*/
+/*member: H.:invoke*/
class H extends Object with G implements A {}
-/*element: I.:invoke*/
+/*member: I.:invoke*/
class I {
- /*element: I.method1:invoke*/
+ /*member: I.method1:invoke*/
method1() {}
method2() {}
method4() {}
- /*element: I.getter:read*/
+ /*member: I.getter:read*/
get getter => 42;
set setter(_) {}
}
-/*element: J.:invoke*/
+/*member: J.:invoke*/
class J extends I implements A {}
class K {
- /*element: K.method1:invoke*/
+ /*member: K.method1:invoke*/
method1() {}
method2() {}
- /*element: K.getter:read*/
+ /*member: K.getter:read*/
get getter => 42;
set setter(_) {}
}
@@ -148,13 +148,13 @@
class L = Object with K;
class L2 = Object with L;
-/*element: M.:invoke*/
+/*member: M.:invoke*/
class M extends L {}
-/*element: M2.:invoke*/
+/*member: M2.:invoke*/
class M2 extends L2 {}
-/*element: N.:invoke*/
+/*member: N.:invoke*/
class N {
method1() {}
get getter => 42;
@@ -163,54 +163,54 @@
abstract class O extends N {}
-/*element: P.:invoke*/
+/*member: P.:invoke*/
class P implements O {
- /*element: P.method1:invoke*/
+ /*member: P.method1:invoke*/
@override
method1() {}
- /*element: P.getter:read*/
+ /*member: P.getter:read*/
@override
get getter => 42;
- /*element: P.setter=:write*/
+ /*member: P.setter=:write*/
@override
set setter(_) {}
}
-/*element: Q.:invoke*/
+/*member: Q.:invoke*/
class Q {
- /*element: Q.method3:invoke*/
+ /*member: Q.method3:invoke*/
method3() {}
}
-/*element: R.:invoke*/
+/*member: R.:invoke*/
class R extends Q {}
-/*element: Class1a.:invoke*/
+/*member: Class1a.:invoke*/
class Class1a {
- /*element: Class1a.call:invoke*/
+ /*member: Class1a.call:invoke*/
call(a, b, c) {} // Call structure only used in Class1a and Class2b.
}
-/*element: Class1b.:invoke*/
+/*member: Class1b.:invoke*/
class Class1b {
call(a, b, c) {}
}
-/*element: Class2.:invoke*/
+/*member: Class2.:invoke*/
class Class2 {
- /*element: Class2.c:init,invoke,read=static*/
+ /*member: Class2.c:init,invoke,read=static*/
Class1a c;
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
method1();
method2();
}
-/*element: method1:invoke*/
+/*member: method1:invoke*/
@pragma('dart2js:disableFinal')
method1() {
A a = new A();
@@ -238,7 +238,7 @@
new Class2().c(0, 1, 2);
}
-/*element: method2:invoke*/
+/*member: method2:invoke*/
method2() {
A a = new A();
B b = new B();
diff --git a/tests/compiler/dart2js/member_usage/data/generic.dart b/tests/compiler/dart2js/member_usage/data/generic.dart
index 9cf10de..7ae48a3 100644
--- a/tests/compiler/dart2js/member_usage/data/generic.dart
+++ b/tests/compiler/dart2js/member_usage/data/generic.dart
@@ -2,29 +2,29 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: Class.:invoke*/
+/*member: Class.:invoke*/
class Class {
// The type parameter is never provided but needed nonetheless.
- /*element: Class.method1:invoke=(0)*/
+ /*member: Class.method1:invoke=(0)*/
method1<S>([a]) => S;
- /*element: Class.method2:invoke=<1>(0)*/
+ /*member: Class.method2:invoke=<1>(0)*/
method2<S>([a]) => S;
- /*element: Class.method3:invoke=<1>(0)*/
+ /*member: Class.method3:invoke=<1>(0)*/
method3<S>([a]) => S;
- /*element: Class.method4:invoke=(1)*/
+ /*member: Class.method4:invoke=(1)*/
method4<S>([a]) => S;
- /*element: Class.method5:invoke*/
+ /*member: Class.method5:invoke*/
method5<S>([a]) => S;
- /*element: Class.method6:invoke*/
+ /*member: Class.method6:invoke*/
method6<S>([a]) => S;
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
dynamic c = new Class();
c.method1();
diff --git a/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
index 44aa24e..0e9ad65 100644
--- a/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
+++ b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
@@ -2,98 +2,98 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: Class.:invoke*/
+/*member: Class.:invoke*/
class Class {
- /*element: Class.method1:invoke*/
+ /*member: Class.method1:invoke*/
method1() {}
- /*element: Class.method2a:invoke=(0)*/
+ /*member: Class.method2a:invoke=(0)*/
method2a([a]) {}
- /*element: Class.method2b:invoke*/
+ /*member: Class.method2b:invoke*/
method2b([a]) {}
- /*element: Class.method2c:invoke*/
+ /*member: Class.method2c:invoke*/
method2c([a]) {}
- /*element: Class.method2d:invoke,read*/
+ /*member: Class.method2d:invoke,read*/
method2d([a]) {}
- /*element: Class.method3a:invoke=(0)*/
+ /*member: Class.method3a:invoke=(0)*/
method3a([a, b]) {}
- /*element: Class.method3b:invoke=(1)*/
+ /*member: Class.method3b:invoke=(1)*/
method3b([a, b]) {}
- /*element: Class.method3c:invoke*/
+ /*member: Class.method3c:invoke*/
method3c([a, b]) {}
- /*element: Class.method3d:invoke,read*/
+ /*member: Class.method3d:invoke,read*/
method3d([a, b]) {}
- /*element: Class.method4a:invoke=(0)*/
+ /*member: Class.method4a:invoke=(0)*/
method4a({a}) {}
- /*element: Class.method4b:invoke*/
+ /*member: Class.method4b:invoke*/
method4b({a}) {}
- /*element: Class.method4c:invoke*/
+ /*member: Class.method4c:invoke*/
method4c({a}) {}
- /*element: Class.method4d:invoke,read*/
+ /*member: Class.method4d:invoke,read*/
method4d({a}) {}
- /*element: Class.method5a:invoke=(0)*/
+ /*member: Class.method5a:invoke=(0)*/
method5a({a, b}) {}
- /*element: Class.method5b:invoke=(0,a)*/
+ /*member: Class.method5b:invoke=(0,a)*/
method5b({a, b}) {}
- /*element: Class.method5c:invoke=(0,b)*/
+ /*member: Class.method5c:invoke=(0,b)*/
method5c({a, b}) {}
- /*element: Class.method5d:invoke,read*/
+ /*member: Class.method5d:invoke,read*/
method5d({a, b}) {}
- /*element: Class.method6a:invoke*/
+ /*member: Class.method6a:invoke*/
method6a<T>() {}
- /*element: Class.method6b:invoke,read*/
+ /*member: Class.method6b:invoke,read*/
method6b<T>() {}
- /*element: Class.method7a:invoke=(1)*/
+ /*member: Class.method7a:invoke=(1)*/
method7a(a, [b, c]) {}
- /*element: Class.method7b:invoke=(2)*/
+ /*member: Class.method7b:invoke=(2)*/
method7b(a, [b, c]) {}
- /*element: Class.method7c:invoke*/
+ /*member: Class.method7c:invoke*/
method7c(a, [b, c]) {}
- /*element: Class.method7d:invoke,read*/
+ /*member: Class.method7d:invoke,read*/
method7d(a, [b, c]) {}
- /*element: Class.method8a:invoke=(1)*/
+ /*member: Class.method8a:invoke=(1)*/
method8a(a, {b, c}) {}
- /*element: Class.method8b:invoke=(1,b)*/
+ /*member: Class.method8b:invoke=(1,b)*/
method8b(a, {b, c}) {}
- /*element: Class.method8c:invoke=(1,c)*/
+ /*member: Class.method8c:invoke=(1,c)*/
method8c(a, {b, c}) {}
- /*element: Class.method8d:invoke,read*/
+ /*member: Class.method8d:invoke,read*/
method8d(a, {b, c}) {}
- /*element: Class.method9a:invoke=(0)*/
+ /*member: Class.method9a:invoke=(0)*/
@pragma('dart2js:noElision')
method9a([a, b]) {}
- /*element: Class.method9b:invoke=(0)*/
+ /*member: Class.method9b:invoke=(0)*/
@pragma('dart2js:noElision')
method9b({a, b}) {}
- /*element: Class.test:invoke*/
+ /*member: Class.test:invoke*/
test() {
method1();
@@ -139,7 +139,7 @@
}
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
new Class().test();
}
diff --git a/tests/compiler/dart2js/member_usage/data/native.dart b/tests/compiler/dart2js/member_usage/data/native.dart
index a787af4..691562b 100644
--- a/tests/compiler/dart2js/member_usage/data/native.dart
+++ b/tests/compiler/dart2js/member_usage/data/native.dart
@@ -5,7 +5,7 @@
// ignore: import_internal_library
import 'dart:_js_helper';
-/*element: field2a:read*/
+/*member: field2a:read*/
@JSName('field2a')
get field2a => 42;
@@ -15,54 +15,54 @@
@JSName('field2b')
get field2b => 42;
-/*element: field2b=:write*/
+/*member: field2b=:write*/
@JSName('field2b')
set field2b(_) {}
-/*element: field2c:read*/
+/*member: field2c:read*/
@JSName('field2c')
get field2c => 42;
-/*element: field2c=:write*/
+/*member: field2c=:write*/
@JSName('field2c')
set field2c(_) {}
@Native('Class')
class Class {
- /*element: Class.field1a:read*/
+ /*member: Class.field1a:read*/
var field1a;
- /*element: Class.field1b:write*/
+ /*member: Class.field1b:write*/
var field1b;
- /*element: Class.field1c:read,write*/
+ /*member: Class.field1c:read,write*/
var field1c;
- /*element: Class.field2a:read*/
+ /*member: Class.field2a:read*/
get field2a => 42;
set field2a(_) {}
get field2b => 42;
- /*element: Class.field2b=:write*/
+ /*member: Class.field2b=:write*/
set field2b(_) {}
- /*element: Class.field2c:read*/
+ /*member: Class.field2c:read*/
get field2c => 42;
- /*element: Class.field2c=:write*/
+ /*member: Class.field2c=:write*/
set field2c(_) {}
var field3a = 0;
- /*element: Class.field3b:init*/
+ /*member: Class.field3b:init*/
var field3b;
- /*element: Class.:invoke=(0)*/
+ /*member: Class.:invoke=(0)*/
Class([this.field3b]);
- /*element: Class.test:invoke*/
+ /*member: Class.test:invoke*/
test() {
field1a;
field1b = 42;
@@ -74,7 +74,7 @@
}
}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
field2a;
field2b = 42;
diff --git a/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
index 936c819..5548810 100644
--- a/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
+++ b/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
@@ -2,96 +2,96 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: method1:invoke*/
+/*member: method1:invoke*/
method1() {}
-/*element: method2a:invoke=(0)*/
+/*member: method2a:invoke=(0)*/
method2a([a]) {}
-/*element: method2b:invoke*/
+/*member: method2b:invoke*/
method2b([a]) {}
-/*element: method2c:invoke*/
+/*member: method2c:invoke*/
method2c([a]) {}
-/*element: method2d:invoke,read*/
+/*member: method2d:invoke,read*/
method2d([a]) {}
-/*element: method3a:invoke=(0)*/
+/*member: method3a:invoke=(0)*/
method3a([a, b]) {}
-/*element: method3b:invoke=(1)*/
+/*member: method3b:invoke=(1)*/
method3b([a, b]) {}
-/*element: method3c:invoke*/
+/*member: method3c:invoke*/
method3c([a, b]) {}
-/*element: method3d:invoke,read*/
+/*member: method3d:invoke,read*/
method3d([a, b]) {}
-/*element: method4a:invoke=(0)*/
+/*member: method4a:invoke=(0)*/
method4a({a}) {}
-/*element: method4b:invoke*/
+/*member: method4b:invoke*/
method4b({a}) {}
-/*element: method4c:invoke*/
+/*member: method4c:invoke*/
method4c({a}) {}
-/*element: method4d:invoke,read*/
+/*member: method4d:invoke,read*/
method4d({a}) {}
-/*element: method5a:invoke=(0)*/
+/*member: method5a:invoke=(0)*/
method5a({a, b}) {}
-/*element: method5b:invoke=(0,a)*/
+/*member: method5b:invoke=(0,a)*/
method5b({a, b}) {}
-/*element: method5c:invoke=(0,b)*/
+/*member: method5c:invoke=(0,b)*/
method5c({a, b}) {}
-/*element: method5d:invoke,read*/
+/*member: method5d:invoke,read*/
method5d({a, b}) {}
-/*element: method6a:invoke*/
+/*member: method6a:invoke*/
method6a<T>() {}
-/*element: method6b:invoke,read*/
+/*member: method6b:invoke,read*/
method6b<T>() {}
-/*element: method7a:invoke=(1)*/
+/*member: method7a:invoke=(1)*/
method7a(a, [b, c]) {}
-/*element: method7b:invoke=(2)*/
+/*member: method7b:invoke=(2)*/
method7b(a, [b, c]) {}
-/*element: method7c:invoke*/
+/*member: method7c:invoke*/
method7c(a, [b, c]) {}
-/*element: method7d:invoke,read*/
+/*member: method7d:invoke,read*/
method7d(a, [b, c]) {}
-/*element: method8a:invoke=(1)*/
+/*member: method8a:invoke=(1)*/
method8a(a, {b, c}) {}
-/*element: method8b:invoke=(1,b)*/
+/*member: method8b:invoke=(1,b)*/
method8b(a, {b, c}) {}
-/*element: method8c:invoke=(1,c)*/
+/*member: method8c:invoke=(1,c)*/
method8c(a, {b, c}) {}
-/*element: method8d:invoke,read*/
+/*member: method8d:invoke,read*/
method8d(a, {b, c}) {}
-/*element: method9a:invoke=(0)*/
+/*member: method9a:invoke=(0)*/
@pragma('dart2js:noElision')
method9a([a, b]) {}
-/*element: method9b:invoke=(0)*/
+/*member: method9b:invoke=(0)*/
@pragma('dart2js:noElision')
method9b({a, b}) {}
-/*element: main:invoke*/
+/*member: main:invoke*/
main() {
method1();
diff --git a/tests/compiler/dart2js/member_usage/data/super.dart b/tests/compiler/dart2js/member_usage/data/super.dart
index 5b3b775..50e3547 100644
--- a/tests/compiler/dart2js/member_usage/data/super.dart
+++ b/tests/compiler/dart2js/member_usage/data/super.dart
@@ -3,108 +3,108 @@
// BSD-style license that can be found in the LICENSE file.
class Super {
- /*element: Super.field1:init,read=super*/
+ /*member: Super.field1:init,read=super*/
var field1;
- /*element: Super.field2:init,write=super*/
+ /*member: Super.field2:init,write=super*/
var field2;
- /*element: Super.field3:init,read=super*/
+ /*member: Super.field3:init,read=super*/
var field3;
- /*element: Super.field4:init,read=super*/
+ /*member: Super.field4:init,read=super*/
final field4;
- /*element: Super.field5:init,read=super*/
+ /*member: Super.field5:init,read=super*/
final field5;
- /*element: Super.constructor1:invoke*/
+ /*member: Super.constructor1:invoke*/
Super.constructor1(this.field4, this.field5);
- /*element: Super.constructor2:invoke=(0)*/
+ /*member: Super.constructor2:invoke=(0)*/
Super.constructor2([this.field4, this.field5]);
- /*element: Super.constructor3:invoke=(1)*/
+ /*member: Super.constructor3:invoke=(1)*/
Super.constructor3([this.field4, this.field5]);
- /*element: Super.method1:invoke=(1):super*/
+ /*member: Super.method1:invoke=(1):super*/
method1([a, b]) {}
- /*element: Super.method2:invoke,read=super*/
+ /*member: Super.method2:invoke,read=super*/
method2([a, b]) {}
- /*element: Super.getter1:read=super*/
+ /*member: Super.getter1:read=super*/
get getter1 => null;
- /*element: Super.getter2:read=super*/
+ /*member: Super.getter2:read=super*/
get getter2 => null;
- /*element: Super.setter1=:write=super*/
+ /*member: Super.setter1=:write=super*/
set setter1(_) {}
- /*element: Super.call:invoke=(0,a,b,c)*/
+ /*member: Super.call:invoke=(0,a,b,c)*/
void call({a, b, c, d}) {}
}
class Sub extends Super {
- /*element: Sub.constructor1:invoke=(1)*/
+ /*member: Sub.constructor1:invoke=(1)*/
Sub.constructor1([field4, field5]) : super.constructor1(field4, field5);
- /*element: Sub.constructor2:invoke*/
+ /*member: Sub.constructor2:invoke*/
Sub.constructor2() : super.constructor2();
- /*element: Sub.readSuperField:invoke*/
+ /*member: Sub.readSuperField:invoke*/
readSuperField() {
return super.field1;
}
- /*element: Sub.writeSuperField:invoke*/
+ /*member: Sub.writeSuperField:invoke*/
writeSuperField() {
super.field2 = null;
}
- /*element: Sub.invokeSuperField:invoke*/
+ /*member: Sub.invokeSuperField:invoke*/
invokeSuperField() {
super.field3(a: 0);
}
- /*element: Sub.readSuperFinalField:invoke*/
+ /*member: Sub.readSuperFinalField:invoke*/
readSuperFinalField() {
return super.field4;
}
- /*element: Sub.invokeSuperFinalField:invoke*/
+ /*member: Sub.invokeSuperFinalField:invoke*/
invokeSuperFinalField() {
super.field5(b: 0);
}
- /*element: Sub.invokeSuperMethod:invoke*/
+ /*member: Sub.invokeSuperMethod:invoke*/
invokeSuperMethod() {
super.method1(0);
}
- /*element: Sub.readSuperMethod:invoke*/
+ /*member: Sub.readSuperMethod:invoke*/
readSuperMethod() {
return super.method2;
}
- /*element: Sub.readSuperGetter:invoke*/
+ /*member: Sub.readSuperGetter:invoke*/
readSuperGetter() {
return super.getter1;
}
- /*element: Sub.invokeSuperGetter:invoke*/
+ /*member: Sub.invokeSuperGetter:invoke*/
invokeSuperGetter() {
return super.getter2(c: 0);
}
- /*element: Sub.writeSuperSetter:invoke*/
+ /*member: Sub.writeSuperSetter:invoke*/
writeSuperSetter() {
super.setter1 = null;
}
}
-/*element: main:invoke*/
+/*member: main:invoke*/
void main() {
new Super.constructor3(null);
new Sub.constructor1(null);
diff --git a/tests/compiler/dart2js/member_usage/member_usage_test.dart b/tests/compiler/dart2js/member_usage/member_usage_test.dart
index 1a5dd51..fdccf53 100644
--- a/tests/compiler/dart2js/member_usage/member_usage_test.dart
+++ b/tests/compiler/dart2js/member_usage/member_usage_test.dart
@@ -7,7 +7,6 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/universe/member_usage.dart';
import 'package:compiler/src/universe/resolution_world_builder.dart';
@@ -108,8 +107,9 @@
}
}
Id id = computeEntityId(node);
- actualMap[id] = new ActualData<Features>(
- id, features, computeSourceSpanFromTreeNode(node), member);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ actualMap[id] = new ActualData<Features>(id, features,
+ nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
}
@override
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
index 1ed2501..8eb6746 100644
--- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -493,7 +493,47 @@
'const C2<A>(id)',
'ConstructedConstant(C2<A>(a='
'InstantiationConstant([A],FunctionConstant(id))))'),
- ])
+ ]),
+ const TestData('unused-arguments', '''
+class A {
+ const A();
+
+ A operator -() => this;
+}
+class B implements A {
+ const B();
+
+ B operator -() => this;
+}
+class C implements A {
+ const C();
+
+ C operator -() => this;
+}
+class Class<T extends A> {
+ const Class(T t);
+ const Class.redirect(dynamic t) : this(t);
+ const Class.method(T t) : this(-t);
+}
+class Subclass<T extends A> extends Class<T> {
+ const Subclass(dynamic t) : super(t);
+}
+''', const <ConstantData>[
+ const ConstantData(
+ 'const Class<A>(const A())', 'ConstructedConstant(Class<A>())'),
+ const ConstantData('const Class<B>.redirect(const B())',
+ 'ConstructedConstant(Class<B>())'),
+ const ConstantData('const Class<B>.redirect(const C())', 'NonConstant',
+ expectedErrors: 'ConstEvalInvalidType'),
+ const ConstantData('const Class<A>.method(const A())', 'NonConstant',
+ expectedErrors: 'ConstEvalInvalidMethodInvocation'),
+ const ConstantData(
+ 'const Subclass<A>(const A())', 'ConstructedConstant(Subclass<A>())'),
+ const ConstantData(
+ 'const Subclass<B>(const B())', 'ConstructedConstant(Subclass<B>())'),
+ const ConstantData('const Subclass<B>(const C())', 'NonConstant',
+ expectedErrors: 'ConstEvalInvalidType'),
+ ]),
];
main(List<String> args) {
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic.dart b/tests/compiler/dart2js/optimization/data/arithmetic.dart
index 3ec5b39..cd984e6 100644
--- a/tests/compiler/dart2js/optimization/data/arithmetic.dart
+++ b/tests/compiler/dart2js/optimization/data/arithmetic.dart
@@ -118,25 +118,25 @@
// Negation
////////////////////////////////////////////////////////////////////////////////
-/*element: negate:Specializer=[Negate],PrimitiveCheck=[]*/
+/*member: negate:Specializer=[Negate],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
negate(o) {
return -o;
}
-/*element: negateNum:Specializer=[Negate],PrimitiveCheck=[]*/
+/*member: negateNum:Specializer=[Negate],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
negateNum(o) {
return -o;
}
-/*element: negateNull:Specializer=[Negate],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: negateNull:Specializer=[Negate],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
negateNull(o) {
return -o;
}
-/*element: negateString:Specializer=[!Negate]*/
+/*member: negateString:Specializer=[!Negate]*/
@pragma('dart2js:noInline')
negateString(o) {
return -o;
@@ -146,49 +146,49 @@
// Addition
////////////////////////////////////////////////////////////////////////////////
-/*element: add:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: add:Specializer=[Add],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
add(a, b) {
return a + b;
}
-/*element: addNumInt:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addNumInt:Specializer=[Add],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
addNumInt(a, b) {
return a + b;
}
-/*element: addIntNum:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addIntNum:Specializer=[Add],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
addIntNum(a, b) {
return a + b;
}
-/*element: addNumNum:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addNumNum:Specializer=[Add],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
addNumNum(a, b) {
return a + b;
}
-/*element: addNullInt:Specializer=[Add],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: addNullInt:Specializer=[Add],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
addNullInt(a, b) {
return a + b;
}
-/*element: addIntNull:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: addIntNull:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
addIntNull(a, b) {
return a + b;
}
-/*element: addStringInt:Specializer=[!Add]*/
+/*member: addStringInt:Specializer=[!Add]*/
@pragma('dart2js:noInline')
addStringInt(a, b) {
return a + b;
}
-/*element: addIntString:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: addIntString:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
addIntString(a, b) {
return a + b;
@@ -198,49 +198,49 @@
// Subtraction
////////////////////////////////////////////////////////////////////////////////
-/*element: subtract:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtract:Specializer=[Subtract],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
subtract(a, b) {
return a - b;
}
-/*element: subtractNumInt:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractNumInt:Specializer=[Subtract],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
subtractNumInt(a, b) {
return a - b;
}
-/*element: subtractIntNum:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractIntNum:Specializer=[Subtract],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
subtractIntNum(a, b) {
return a - b;
}
-/*element: subtractNumNum:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractNumNum:Specializer=[Subtract],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
subtractNumNum(a, b) {
return a - b;
}
-/*element: subtractNullInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: subtractNullInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
subtractNullInt(a, b) {
return a - b;
}
-/*element: subtractIntNull:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: subtractIntNull:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
subtractIntNull(a, b) {
return a - b;
}
-/*element: subtractStringInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: subtractStringInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
subtractStringInt(a, b) {
return a - b;
}
-/*element: subtractIntString:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: subtractIntString:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
subtractIntString(a, b) {
return a - b;
@@ -250,49 +250,49 @@
// Multiplication
////////////////////////////////////////////////////////////////////////////////
-/*element: multiply:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiply:Specializer=[Multiply],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
multiply(a, b) {
return a * b;
}
-/*element: multiplyNumInt:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyNumInt:Specializer=[Multiply],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
multiplyNumInt(a, b) {
return a * b;
}
-/*element: multiplyIntNum:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyIntNum:Specializer=[Multiply],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
multiplyIntNum(a, b) {
return a * b;
}
-/*element: multiplyNumNum:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyNumNum:Specializer=[Multiply],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
multiplyNumNum(a, b) {
return a * b;
}
-/*element: multiplyNullInt:Specializer=[Multiply],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: multiplyNullInt:Specializer=[Multiply],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
multiplyNullInt(a, b) {
return a * b;
}
-/*element: multiplyIntNull:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: multiplyIntNull:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
multiplyIntNull(a, b) {
return a * b;
}
-/*element: multiplyStringInt:Specializer=[!Multiply]*/
+/*member: multiplyStringInt:Specializer=[!Multiply]*/
@pragma('dart2js:noInline')
multiplyStringInt(a, b) {
return a * b;
}
-/*element: multiplyIntString:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: multiplyIntString:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
multiplyIntString(a, b) {
return a * b;
@@ -302,55 +302,55 @@
// Division
////////////////////////////////////////////////////////////////////////////////
-/*element: divide:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divide:Specializer=[Divide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
divide(a, b) {
return a / b;
}
-/*element: divideZero:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideZero:Specializer=[Divide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
divideZero(a) {
return a / 0;
}
-/*element: divideNumInt:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideNumInt:Specializer=[Divide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
divideNumInt(a, b) {
return a / b;
}
-/*element: divideIntNum:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideIntNum:Specializer=[Divide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
divideIntNum(a, b) {
return a / b;
}
-/*element: divideNumNum:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideNumNum:Specializer=[Divide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
divideNumNum(a, b) {
return a / b;
}
-/*element: divideNullInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: divideNullInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
divideNullInt(a, b) {
return a / b;
}
-/*element: divideIntNull:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: divideIntNull:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
divideIntNull(a, b) {
return a / b;
}
-/*element: divideStringInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: divideStringInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
divideStringInt(a, b) {
return a / b;
}
-/*element: divideIntString:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: divideIntString:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
divideIntString(a, b) {
return a / b;
@@ -360,73 +360,73 @@
// Truncating division
////////////////////////////////////////////////////////////////////////////////
-/*element: truncatingDivide:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivide:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
truncatingDivide(a, b) {
return a ~/ 2;
}
-/*element: truncatingDivideZero:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideZero:Specializer=[!TruncatingDivide]*/
@pragma('dart2js:noInline')
truncatingDivideZero(a) {
return a ~/ 0;
}
-/*element: truncatingDivideIntNonZero1:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivideIntNonZero1:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
truncatingDivideIntNonZero1(a) {
return a ~/ 1;
}
-/*element: truncatingDivideIntNonZero2:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivideIntNonZero2:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
truncatingDivideIntNonZero2(a) {
return a ~/ 2;
}
-/*element: truncatingDivideNumInt:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideNumInt:Specializer=[!TruncatingDivide]*/
@pragma('dart2js:noInline')
truncatingDivideNumInt(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideNumNonZero:Specializer=[TruncatingDivide._tdivFast],PrimitiveCheck=[]*/
+/*member: truncatingDivideNumNonZero:Specializer=[TruncatingDivide._tdivFast],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
truncatingDivideNumNonZero(a) {
return a ~/ 2;
}
-/*element: truncatingDivideIntNum:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideIntNum:Specializer=[!TruncatingDivide]*/
@pragma('dart2js:noInline')
truncatingDivideIntNum(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideNumNum:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideNumNum:Specializer=[!TruncatingDivide]*/
@pragma('dart2js:noInline')
truncatingDivideNumNum(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideNullInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: truncatingDivideNullInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
truncatingDivideNullInt(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideIntNull:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: truncatingDivideIntNull:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
truncatingDivideIntNull(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideStringInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: truncatingDivideStringInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
truncatingDivideStringInt(a, b) {
return a ~/ b;
}
-/*element: truncatingDivideIntString:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: truncatingDivideIntString:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
truncatingDivideIntString(a, b) {
return a ~/ b;
@@ -436,25 +436,25 @@
// .abs()
////////////////////////////////////////////////////////////////////////////////
-/*element: abs:Specializer=[Abs]*/
+/*member: abs:Specializer=[Abs]*/
@pragma('dart2js:noInline')
abs(o) {
return o.abs();
}
-/*element: absNum:Specializer=[Abs]*/
+/*member: absNum:Specializer=[Abs]*/
@pragma('dart2js:noInline')
absNum(o) {
return o.abs();
}
-/*element: absNull:Specializer=[Abs]*/
+/*member: absNull:Specializer=[Abs]*/
@pragma('dart2js:noInline')
absNull(o) {
return o.abs();
}
-/*element: absString:Specializer=[!Abs]*/
+/*member: absString:Specializer=[!Abs]*/
@pragma('dart2js:noInline')
absString(o) {
return o.abs();
@@ -464,25 +464,25 @@
// .round()
////////////////////////////////////////////////////////////////////////////////
-/*element: round:Specializer=[Round]*/
+/*member: round:Specializer=[Round]*/
@pragma('dart2js:noInline')
round(o) {
return o.round();
}
-/*element: roundNum:Specializer=[Round]*/
+/*member: roundNum:Specializer=[Round]*/
@pragma('dart2js:noInline')
roundNum(o) {
return o.round();
}
-/*element: roundNull:Specializer=[Round]*/
+/*member: roundNull:Specializer=[Round]*/
@pragma('dart2js:noInline')
roundNull(o) {
return o.round();
}
-/*element: roundString:Specializer=[!Round]*/
+/*member: roundString:Specializer=[!Round]*/
@pragma('dart2js:noInline')
roundString(o) {
return o.round();
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
index 6d5ccef..dad0dcc 100644
--- a/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
+++ b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
@@ -8,56 +8,56 @@
@pragma('dart2js:noInline')
int confuse(int x) => x;
-/*element: intPlusZero:Specializer=[Add,BitAnd]*/
+/*member: intPlusZero:Specializer=[Add,BitAnd]*/
@pragma('dart2js:noInline')
intPlusZero() {
int x = confuse(0);
return (x & 1) + 0;
}
-/*element: zeroPlusInt:Specializer=[Add,BitAnd]*/
+/*member: zeroPlusInt:Specializer=[Add,BitAnd]*/
@pragma('dart2js:noInline')
zeroPlusInt() {
int x = confuse(0);
return 0 + (x & 1);
}
-/*element: numPlusZero:Specializer=[Add]*/
+/*member: numPlusZero:Specializer=[Add]*/
@pragma('dart2js:noInline')
numPlusZero() {
num x = confuse(0);
return x + 0;
}
-/*element: zeroPlusNum:Specializer=[Add]*/
+/*member: zeroPlusNum:Specializer=[Add]*/
@pragma('dart2js:noInline')
zeroPlusNum() {
num x = confuse(0);
return 0 + x;
}
-/*element: intTimesOne:Specializer=[BitAnd,Multiply]*/
+/*member: intTimesOne:Specializer=[BitAnd,Multiply]*/
@pragma('dart2js:noInline')
intTimesOne() {
int x = confuse(0);
return (x & 1) * 1;
}
-/*element: oneTimesInt:Specializer=[BitAnd,Multiply]*/
+/*member: oneTimesInt:Specializer=[BitAnd,Multiply]*/
@pragma('dart2js:noInline')
oneTimesInt() {
int x = confuse(0);
return 1 * (x & 1);
}
-/*element: numTimesOne:Specializer=[Multiply]*/
+/*member: numTimesOne:Specializer=[Multiply]*/
@pragma('dart2js:noInline')
numTimesOne() {
num x = confuse(0);
return x * 1;
}
-/*element: oneTimesNum:Specializer=[Multiply]*/
+/*member: oneTimesNum:Specializer=[Multiply]*/
@pragma('dart2js:noInline')
oneTimesNum() {
num x = confuse(0);
diff --git a/tests/compiler/dart2js/optimization/data/bit.dart b/tests/compiler/dart2js/optimization/data/bit.dart
index 543a87d..49364cf 100644
--- a/tests/compiler/dart2js/optimization/data/bit.dart
+++ b/tests/compiler/dart2js/optimization/data/bit.dart
@@ -64,25 +64,25 @@
// Bitwise not
////////////////////////////////////////////////////////////////////////////////
-/*element: bitNot:Specializer=[BitNot]*/
+/*member: bitNot:Specializer=[BitNot]*/
@pragma('dart2js:noInline')
bitNot(o) {
return ~o;
}
-/*element: bitNotNum:Specializer=[BitNot]*/
+/*member: bitNotNum:Specializer=[BitNot]*/
@pragma('dart2js:noInline')
bitNotNum(o) {
return ~o;
}
-/*element: bitNotNull:Specializer=[BitNot]*/
+/*member: bitNotNull:Specializer=[BitNot]*/
@pragma('dart2js:noInline')
bitNotNull(o) {
return ~o;
}
-/*element: bitNotString:Specializer=[!BitNot]*/
+/*member: bitNotString:Specializer=[!BitNot]*/
@pragma('dart2js:noInline')
bitNotString(o) {
return ~o;
@@ -92,49 +92,49 @@
// Bitwise and
////////////////////////////////////////////////////////////////////////////////
-/*element: bitAnd:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAnd:Specializer=[BitAnd],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitAnd(a, b) {
return a & b;
}
-/*element: bitAndNumInt:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndNumInt:Specializer=[BitAnd],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitAndNumInt(a, b) {
return a & b;
}
-/*element: bitAndIntNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndIntNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitAndIntNum(a, b) {
return a & b;
}
-/*element: bitAndNumNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndNumNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitAndNumNum(a, b) {
return a & b;
}
-/*element: bitAndNullInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitAndNullInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitAndNullInt(a, b) {
return a & b;
}
-/*element: bitAndIntNull:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitAndIntNull:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitAndIntNull(a, b) {
return a & b;
}
-/*element: bitAndStringInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitAndStringInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitAndStringInt(a, b) {
return a & b;
}
-/*element: bitAndIntString:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitAndIntString:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitAndIntString(a, b) {
return a & b;
@@ -144,49 +144,49 @@
// Bitwise or
////////////////////////////////////////////////////////////////////////////////
-/*element: bitOr:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOr:Specializer=[BitOr],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitOr(a, b) {
return a | b;
}
-/*element: bitOrNumInt:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrNumInt:Specializer=[BitOr],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitOrNumInt(a, b) {
return a | b;
}
-/*element: bitOrIntNum:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrIntNum:Specializer=[BitOr],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitOrIntNum(a, b) {
return a | b;
}
-/*element: bitOrNumNum:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrNumNum:Specializer=[BitOr],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitOrNumNum(a, b) {
return a | b;
}
-/*element: bitOrNullInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitOrNullInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitOrNullInt(a, b) {
return a | b;
}
-/*element: bitOrIntNull:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitOrIntNull:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitOrIntNull(a, b) {
return a | b;
}
-/*element: bitOrStringInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitOrStringInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitOrStringInt(a, b) {
return a | b;
}
-/*element: bitOrIntString:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitOrIntString:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitOrIntString(a, b) {
return a | b;
@@ -196,49 +196,49 @@
// Bitwise xor
////////////////////////////////////////////////////////////////////////////////
-/*element: bitXor:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXor:Specializer=[BitXor],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitXor(a, b) {
return a ^ b;
}
-/*element: bitXorNumInt:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorNumInt:Specializer=[BitXor],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitXorNumInt(a, b) {
return a ^ b;
}
-/*element: bitXorIntNum:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorIntNum:Specializer=[BitXor],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitXorIntNum(a, b) {
return a ^ b;
}
-/*element: bitXorNumNum:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorNumNum:Specializer=[BitXor],PrimitiveCheck=[]*/
@pragma('dart2js:noInline')
bitXorNumNum(a, b) {
return a ^ b;
}
-/*element: bitXorNullInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitXorNullInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitXorNullInt(a, b) {
return a ^ b;
}
-/*element: bitXorIntNull:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitXorIntNull:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitXorIntNull(a, b) {
return a ^ b;
}
-/*element: bitXorStringInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitXorStringInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
@pragma('dart2js:noInline')
bitXorStringInt(a, b) {
return a ^ b;
}
-/*element: bitXorIntString:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitXorIntString:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
@pragma('dart2js:noInline')
bitXorIntString(a, b) {
return a ^ b;
diff --git a/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart b/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
index 70578fc..fc11e74 100644
--- a/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
+++ b/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
@@ -13,7 +13,7 @@
var field3 = 0;
}
-/*element: method1:
+/*member: method1:
ConstantFieldGet=[name=Class1.field1&value=IntConstant(0)],
FieldGet=[]
*/
@@ -22,7 +22,7 @@
return c.field1;
}
-/*element: method2:FieldGet=[name=Class1.field2]*/
+/*member: method2:FieldGet=[name=Class1.field2]*/
@pragma('dart2js:noInline')
method2(Class1 c) {
return c.field2;
@@ -43,7 +43,7 @@
int Function() field4 = _field4;
}
-/*element: method4:
+/*member: method4:
ConstantFieldCall=[name=Class3.field4&value=FunctionConstant(_field4)],
FieldCall=[]
*/
@@ -52,7 +52,7 @@
return c.field4();
}
-/*element: method6:
+/*member: method6:
ConstantFieldGet=[name=Class1.field1&value=IntConstant(0)],
FieldGet=[name=<null-guard>]
*/
@@ -61,7 +61,7 @@
return c.field1;
}
-/*element: method7:
+/*member: method7:
ConstantFieldCall=[name=Class3.field4&value=FunctionConstant(_field4)],
FieldCall=[name=<null-guard>]
*/
diff --git a/tests/compiler/dart2js/optimization/data/field_get.dart b/tests/compiler/dart2js/optimization/data/field_get.dart
index e9101e5..301efeb 100644
--- a/tests/compiler/dart2js/optimization/data/field_get.dart
+++ b/tests/compiler/dart2js/optimization/data/field_get.dart
@@ -18,7 +18,7 @@
int field1;
}
-/*element: method1:FieldGet=[name=Class1a.field1]*/
+/*member: method1:FieldGet=[name=Class1a.field1]*/
@pragma('dart2js:noInline')
method1(Class1a c) {
return c.field1;
@@ -31,7 +31,7 @@
class Class2b extends Class2a {}
-/*element: method2:FieldGet=[name=Class2a.field2]*/
+/*member: method2:FieldGet=[name=Class2a.field2]*/
@pragma('dart2js:noInline')
method2(Class2a c) {
return c.field2;
@@ -69,7 +69,7 @@
int Function() field5;
}
-/*element: method5:FieldCall=[name=Class5a.field5]*/
+/*member: method5:FieldCall=[name=Class5a.field5]*/
@pragma('dart2js:noInline')
method5(Class5a c) {
return c.field5();
diff --git a/tests/compiler/dart2js/optimization/data/field_set.dart b/tests/compiler/dart2js/optimization/data/field_set.dart
index 3c19021..a7e1cbb 100644
--- a/tests/compiler/dart2js/optimization/data/field_set.dart
+++ b/tests/compiler/dart2js/optimization/data/field_set.dart
@@ -20,7 +20,7 @@
int field1;
}
-/*element: method1:FieldSet=[name=Class1a.field1]*/
+/*member: method1:FieldSet=[name=Class1a.field1]*/
@pragma('dart2js:noInline')
method1(Class1a c) {
c.field1 = 42;
@@ -33,7 +33,7 @@
class Class2b extends Class2a {}
-/*element: method2:FieldSet=[name=Class2a.field2]*/
+/*member: method2:FieldSet=[name=Class2a.field2]*/
@pragma('dart2js:noInline')
method2(Class2a c) {
c.field2 = 42;
@@ -70,7 +70,7 @@
int field5;
}
-/*element: method5:FieldSet=[removed=field5]*/
+/*member: method5:FieldSet=[removed=field5]*/
@pragma('dart2js:noInline')
method5(Class5a c) {
c.field5 = 42;
@@ -82,7 +82,7 @@
class Class6b extends Class6a {}
-/*element: method6:FieldSet=[removed=field6]*/
+/*member: method6:FieldSet=[removed=field6]*/
@pragma('dart2js:noInline')
method6(Class6a c) {
c.field6 = 42;
diff --git a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
index 6411114..9b64132 100644
--- a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
@@ -11,7 +11,7 @@
}
class ViewCardComponent extends AppView<CardComponent> {
- /*element: ViewCardComponent.method1:
+ /*member: ViewCardComponent.method1:
FieldGet=[name=AppView.ctx],
FieldSet=[name=CardComponent.title]
*/
@@ -20,7 +20,7 @@
ctx.title = value;
}
- /*element: ViewCardComponent.method2:
+ /*member: ViewCardComponent.method2:
FieldGet=[name=AppView.ctx,name=CardComponent.title]
*/
@pragma('dart2js:noInline')
@@ -34,7 +34,7 @@
}
class ViewCardComponent2 extends AppView<CardComponent2> {
- /*element: ViewCardComponent2.method1:
+ /*member: ViewCardComponent2.method1:
FieldGet=[name=AppView.ctx],
FieldSet=[name=CardComponent2.title]
*/
@@ -43,7 +43,7 @@
ctx.title = value;
}
- /*element: ViewCardComponent2.method2:
+ /*member: ViewCardComponent2.method2:
FieldGet=[name=AppView.ctx,name=CardComponent2.title]
*/
@pragma('dart2js:noInline')
@@ -52,8 +52,8 @@
}
}
-/*strong.element: main:*/
-/*omit.element: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
+/*strong.member: main:*/
+/*omit.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
main() {
var c1 = new ViewCardComponent();
c1.ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/optimization/data/index.dart b/tests/compiler/dart2js/optimization/data/index.dart
index b6dd480..a38b22c 100644
--- a/tests/compiler/dart2js/optimization/data/index.dart
+++ b/tests/compiler/dart2js/optimization/data/index.dart
@@ -4,41 +4,41 @@
import 'dart:collection';
-/*element: dynamicIndex:Specializer=[!Index]*/
+/*member: dynamicIndex:Specializer=[!Index]*/
@pragma('dart2js:noInline')
dynamicIndex(var list) {
return list[0]; // This not known to be an indexable primitive.
}
-/*element: unknownListIndex:Specializer=[!Index]*/
+/*member: unknownListIndex:Specializer=[!Index]*/
@pragma('dart2js:noInline')
unknownListIndex(List list) {
return list[0]; // This not known to be an indexable primitive.
}
-/*element: possiblyNullMutableListIndex:Specializer=[Index]*/
+/*member: possiblyNullMutableListIndex:Specializer=[Index]*/
@pragma('dart2js:noInline')
possiblyNullMutableListIndex(bool b) {
var list = b ? [0] : null;
return list[0];
}
-/*element: mutableListIndex:Specializer=[Index]*/
+/*member: mutableListIndex:Specializer=[Index]*/
@pragma('dart2js:noInline')
mutableListIndex() {
var list = [0];
return list[0];
}
-/*element: mutableListDynamicIndex:Specializer=[Index]*/
+/*member: mutableListDynamicIndex:Specializer=[Index]*/
@pragma('dart2js:noInline')
mutableListDynamicIndex(dynamic index) {
var list = [0];
return list[index]; // CFE inserts an implicit cast of the index.
}
-/*strong.element: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
-/*omit.element: mutableDynamicListDynamicIndex:Specializer=[Index]*/
+/*strong.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
+/*omit.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
@pragma('dart2js:noInline')
@pragma('dart2js:disableFinal')
mutableDynamicListDynamicIndex(dynamic index) {
diff --git a/tests/compiler/dart2js/optimization/data/index_assign.dart b/tests/compiler/dart2js/optimization/data/index_assign.dart
index 35c03ff..d2ac26d 100644
--- a/tests/compiler/dart2js/optimization/data/index_assign.dart
+++ b/tests/compiler/dart2js/optimization/data/index_assign.dart
@@ -2,52 +2,52 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: dynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*member: dynamicIndexAssign:Specializer=[!IndexAssign]*/
@pragma('dart2js:noInline')
dynamicIndexAssign(var list) {
list[0] = 1;
}
-/*strong.element: unknownListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: unknownListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
unknownListIndexAssign(List list) {
list[0] = 1;
}
-/*strong.element: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
possiblyNullMutableListIndexAssign(bool b) {
var list = b ? [0] : null;
list[0] = 1;
}
-/*strong.element: mutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListIndexAssign() {
var list = [0];
list[0] = 1;
}
-/*strong.element: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListDynamicIndexAssign(dynamic index) {
var list = [0];
list[index] = 1;
}
-/*strong.element: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
@pragma('dart2js:noInline')
mutableListDynamicValueIndexAssign(dynamic value) {
var list = [0];
list[0] = value;
}
-/*element: immutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*member: immutableListIndexAssign:Specializer=[!IndexAssign]*/
@pragma('dart2js:noInline')
immutableListIndexAssign() {
var list = const [0];
diff --git a/tests/compiler/dart2js/optimization/data/modulo_remainder.dart b/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
index 9139d26..d2d909cc 100644
--- a/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
+++ b/tests/compiler/dart2js/optimization/data/modulo_remainder.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.
-/*element: mod1:Specializer=[Modulo]*/
+/*member: mod1:Specializer=[Modulo]*/
@pragma('dart2js:noInline')
mod1(param) {
var a = param ? 0xFFFFFFFF : 1;
@@ -11,7 +11,7 @@
// absent: '$mod'
}
-/*element: mod2:Specializer=[!Modulo]*/
+/*member: mod2:Specializer=[!Modulo]*/
@pragma('dart2js:noInline')
mod2(param) {
var a = param ? 0xFFFFFFFF : -0.0;
@@ -21,7 +21,7 @@
// absent: ' % 2'
}
-/*element: mod3:Specializer=[Modulo]*/
+/*member: mod3:Specializer=[Modulo]*/
@pragma('dart2js:noInline')
mod3(param) {
var a = param ? 0xFFFFFFFF : -0.0;
@@ -31,7 +31,7 @@
// absent: '$mod'
}
-/*element: rem1:Specializer=[Remainder]*/
+/*member: rem1:Specializer=[Remainder]*/
@pragma('dart2js:noInline')
rem1(param) {
var a = param ? 0xFFFFFFFF : 1;
@@ -41,7 +41,7 @@
// absent: 'remainder'
}
-/*element: rem2:Specializer=[Remainder]*/
+/*member: rem2:Specializer=[Remainder]*/
@pragma('dart2js:noInline')
rem2(param) {
var a = param ? 123.4 : -1;
@@ -51,7 +51,7 @@
// absent: 'remainder'
}
-/*element: rem3:Specializer=[!Remainder]*/
+/*member: rem3:Specializer=[!Remainder]*/
@pragma('dart2js:noInline')
rem3(param) {
var a = param ? 123 : null;
diff --git a/tests/compiler/dart2js/rti/data/call_typed_generic.dart b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
index 972f65f..6e7e075 100644
--- a/tests/compiler/dart2js/rti/data/call_typed_generic.dart
+++ b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
@@ -7,8 +7,8 @@
/*strong.class: A:direct,explicit=[A.T],needsArgs*/
/*omit.class: A:*/
class A<T> {
- /*strong.element: A.call:*/
- /*omit.element: A.call:*/
+ /*strong.member: A.call:*/
+ /*omit.member: A.call:*/
call(T t) {}
}
diff --git a/tests/compiler/dart2js/rti/data/closure.dart b/tests/compiler/dart2js/rti/data/closure.dart
index a77b268..aeb2742 100644
--- a/tests/compiler/dart2js/rti/data/closure.dart
+++ b/tests/compiler/dart2js/rti/data/closure.dart
@@ -9,7 +9,7 @@
return /*needsSignature*/ (T t) {};
}
- /*element: A.f:*/
+ /*member: A.f:*/
f() {
// TODO(johnniwinther): Optimize local function type signature need.
return
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is.dart b/tests/compiler/dart2js/rti/data/dynamic_is.dart
index d644fe8..3918c53 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is2.dart b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
index d9574d0..b9c6996 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
@@ -5,12 +5,12 @@
/*omit.class: A:*/
/*strong.class: A:explicit=[A]*/
class A {
- /*element: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
}
class B {
- /*element: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
+ /*member: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
instanceMethod<T>(A a, t) => a.instanceMethod<T>(t);
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart b/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
index 4100762..100e0b6 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart b/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
index 0d2153a..95b4516 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:deps=[local],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: A.instanceMethod:deps=[local],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not.dart b/tests/compiler/dart2js/rti/data/dynamic_not.dart
index 9a5b7d3..15e708a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:*/
+ /*member: A.instanceMethod:*/
instanceMethod<T>(t) => t;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not2.dart b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
index 10a4018..aa043a6 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
@@ -4,12 +4,12 @@
/*strong.class: A:explicit=[A]*/
class A {
- /*element: A.instanceMethod:deps=[B.instanceMethod]*/
+ /*member: A.instanceMethod:deps=[B.instanceMethod]*/
instanceMethod<T>(t) => t;
}
class B {
- /*element: B.instanceMethod:*/
+ /*member: B.instanceMethod:*/
instanceMethod<T>(A a, t) => a.instanceMethod<T>(t);
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart b/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
index 03451cd..9049c26 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:*/
+ /*member: A.instanceMethod:*/
instanceMethod<T>(t) => t;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart b/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
index f98d095..d06c360 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:deps=[local]*/
+ /*member: A.instanceMethod:deps=[local]*/
instanceMethod<T>(t) => t;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart
index 55a024b..191ab7a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off.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.
-/*element: staticMethod:direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod:direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
staticMethod<T>(t) => t is T;
main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
index 28102d4..b018072 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
@@ -2,11 +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.
-/*element: staticMethod:deps=[B.instanceMethod],direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod:deps=[B.instanceMethod],direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
staticMethod<T>(t) => t is T;
class B {
- /*element: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
+ /*member: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
instanceMethod<T>(a, t) => a<T>(t);
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
index f620594..807f356 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
@@ -5,11 +5,11 @@
/*omit.class: A:*/
/*strong.class: A:explicit=[A]*/
class A {
- /*element: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(t) => t is T;
}
-/*element: staticMethod:implicit=[staticMethod.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
+/*member: staticMethod:implicit=[staticMethod.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
staticMethod<T>(A a, t) => a.instanceMethod<T>(t);
main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
index b37ff25..2f04620 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: staticMethod1:deps=[staticMethod2],direct,explicit=[staticMethod1.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod1:deps=[staticMethod2],direct,explicit=[staticMethod1.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
staticMethod1<T>(t) => t is T;
-/*element: staticMethod2:implicit=[staticMethod2.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
+/*member: staticMethod2:implicit=[staticMethod2.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
staticMethod2<T>(a, t) => a<T>(t);
main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
index 35506c8..b13dccd 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class A {
- /*element: A.instanceMethod:exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
+ /*member: A.instanceMethod:exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
instanceMethod<T>() => T;
}
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
index 975f814..2f0ab7a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
@@ -4,12 +4,12 @@
/*strong.class: A:explicit=[A]*/
class A {
- /*element: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
+ /*member: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
instanceMethod<T>() => T;
}
class B {
- /*element: B.instanceMethod:needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+ /*member: B.instanceMethod:needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
instanceMethod<T>(A a) => a.instanceMethod<T>();
}
diff --git a/tests/compiler/dart2js/rti/data/generic_bounds.dart b/tests/compiler/dart2js/rti/data/generic_bounds.dart
index d045fa7..2d694aa 100644
--- a/tests/compiler/dart2js/rti/data/generic_bounds.dart
+++ b/tests/compiler/dart2js/rti/data/generic_bounds.dart
@@ -14,19 +14,19 @@
class Class2b<T> extends Class2a<T> {}
-/*strong.element: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*strong.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
method1<T extends Class1a>() => null;
-/*strong.element: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*strong.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
method2<T extends Class2a<num>>() => null;
method3<T>() => null;
class Class3 {
- /*strong.element: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*strong.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T extends Class1a>() => null;
- /*strong.element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ /*strong.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
method5<T extends Class2a<num>>() => null;
method6<T>() => null;
@@ -35,7 +35,7 @@
/*strong.class: Class4:explicit=[Class4]*/
class Class4 {}
-/*strong.element: method10:needsArgs*/
+/*strong.member: method10:needsArgs*/
method10<T extends Class4>() => null;
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_creation.dart b/tests/compiler/dart2js/rti/data/generic_creation.dart
index cdae93c..b46fc2f 100644
--- a/tests/compiler/dart2js/rti/data/generic_creation.dart
+++ b/tests/compiler/dart2js/rti/data/generic_creation.dart
@@ -6,44 +6,44 @@
/*class: A:needsArgs*/
-/*strong.element: A.:*/
-/*omit.element: A.:*/
+/*strong.member: A.:*/
+/*omit.member: A.:*/
class A<X, Y, Z> {
- /*strong.element: A.shift:*/
- /*omit.element: A.shift:*/
+ /*strong.member: A.shift:*/
+ /*omit.member: A.shift:*/
shift() => new A<Z, X, Y>();
- /*strong.element: A.swap:*/
- /*omit.element: A.swap:*/
+ /*strong.member: A.swap:*/
+ /*omit.member: A.swap:*/
swap() => new A<Z, Y, X>();
- /*strong.element: A.first:*/
- /*omit.element: A.first:*/
+ /*strong.member: A.first:*/
+ /*omit.member: A.first:*/
first() => new A<X, X, X>();
- /*strong.element: A.last:*/
- /*omit.element: A.last:*/
+ /*strong.member: A.last:*/
+ /*omit.member: A.last:*/
last() => new A<Z, Z, Z>();
- /*strong.element: A.wrap:*/
- /*omit.element: A.wrap:*/
+ /*strong.member: A.wrap:*/
+ /*omit.member: A.wrap:*/
wrap() => new A<A<X, X, X>, A<Y, Y, Y>, A<Z, Z, Z>>();
}
-/*strong.element: B.:*/
-/*omit.element: B.:*/
+/*strong.member: B.:*/
+/*omit.member: B.:*/
class B extends A<U, V, W> {}
/*class: C:needsArgs*/
-/*strong.element: C.:*/
-/*omit.element: C.:*/
+/*strong.member: C.:*/
+/*omit.member: C.:*/
class C<T> extends A<U, T, W> {}
/*class: D:needsArgs*/
-/*strong.element: D.:*/
-/*omit.element: D.:*/
+/*strong.member: D.:*/
+/*omit.member: D.:*/
class D<X, Y, Z> extends A<Y, Z, X> {}
class U {}
@@ -52,12 +52,12 @@
class W {}
-/*strong.element: sameType:*/
-/*omit.element: sameType:*/
+/*strong.member: sameType:*/
+/*omit.member: sameType:*/
sameType(a, b) => Expect.equals(a.runtimeType, b.runtimeType);
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
A a = new A<U, V, W>();
sameType(new A<W, U, V>(), a.shift());
diff --git a/tests/compiler/dart2js/rti/data/generic_method1.dart b/tests/compiler/dart2js/rti/data/generic_method1.dart
index da2373a..bad6514 100644
--- a/tests/compiler/dart2js/rti/data/generic_method1.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method1.dart
@@ -15,7 +15,7 @@
/*class: BB:implicit=[BB]*/
class BB {}
-/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
+/*member: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
@pragma('dart2js:noInline')
method2<T>() => new A<T>();
@@ -27,7 +27,7 @@
}
}
-/*element: method1:implicit=[method1.T],indirect,needsArgs*/
+/*member: method1:implicit=[method1.T],indirect,needsArgs*/
@pragma('dart2js:noInline')
method1<T>() {
return new B<T>().foo();
diff --git a/tests/compiler/dart2js/rti/data/generic_method2.dart b/tests/compiler/dart2js/rti/data/generic_method2.dart
index 6ddb5c0..bfa88fd 100644
--- a/tests/compiler/dart2js/rti/data/generic_method2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method2.dart
@@ -23,7 +23,7 @@
}
}
-/*element: method1:implicit=[method1.T],indirect,needsArgs*/
+/*member: method1:implicit=[method1.T],indirect,needsArgs*/
@pragma('dart2js:noInline')
method1<T>() {
return new B<T>().foo();
diff --git a/tests/compiler/dart2js/rti/data/generic_method3.dart b/tests/compiler/dart2js/rti/data/generic_method3.dart
index a00bee3..8fceecc 100644
--- a/tests/compiler/dart2js/rti/data/generic_method3.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method3.dart
@@ -15,7 +15,7 @@
/*class: BB:implicit=[BB]*/
class BB {}
-/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
+/*member: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
@pragma('dart2js:noInline')
method2<T>() => new A<T>();
diff --git a/tests/compiler/dart2js/rti/data/generic_method4.dart b/tests/compiler/dart2js/rti/data/generic_method4.dart
index 342fcdd..7c7fa24 100644
--- a/tests/compiler/dart2js/rti/data/generic_method4.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method4.dart
@@ -24,13 +24,13 @@
}
class C {
- /*element: C.method1:implicit=[method1.T],indirect,needsArgs,selectors=[Selector(call, method1, arity=0, types=1)]*/
+ /*member: C.method1:implicit=[method1.T],indirect,needsArgs,selectors=[Selector(call, method1, arity=0, types=1)]*/
@pragma('dart2js:noInline')
method1<T>() {
return new B<T>().foo(this);
}
- /*element: C.method2:deps=[B],implicit=[method2.T],indirect,needsArgs,selectors=[Selector(call, method2, arity=0, types=1)]*/
+ /*member: C.method2:deps=[B],implicit=[method2.T],indirect,needsArgs,selectors=[Selector(call, method2, arity=0, types=1)]*/
@pragma('dart2js:noInline')
method2<T>() => new A<T>();
}
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
index 04ef2e4..8404071 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
@@ -8,8 +8,8 @@
/*class: B:deps=[method],explicit=[B<A>],needsArgs*/
class B<T> {}
-/*strong.element: method:needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:needsArgs*/
+/*omit.member: method:needsArgs*/
method<T>() => new B<T>();
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is.dart b/tests/compiler/dart2js/rti/data/generic_method_is.dart
index 972f756..2012cdf 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is.dart
@@ -2,8 +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.
-/*strong.element: method:direct,explicit=[method.T],needsArgs*/
-/*omit.element: method:direct,explicit=[method.T],needsArgs*/
+/*strong.member: method:direct,explicit=[method.T],needsArgs*/
+/*omit.member: method:direct,explicit=[method.T],needsArgs*/
method<T>(T t) => t is T;
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is2.dart b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
index 4caa1c3..a415e06 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
@@ -44,20 +44,20 @@
/*class: F3:implicit=[F3]*/
class F3 {}
-/*element: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a1], types=1)]*/
+/*member: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a1], types=1)]*/
// Calls to this imply a check of the passed type arguments.
bool topLevelMethod1<T>(T t, {a1}) => t is T;
-/*strong.element: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
+/*strong.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
// Calls to this does _not_ imply a check of the passed type arguments.
T topLevelMethod2<T>(T t, {a2}) => t;
class Class {
- /*element: Class.instanceMethod1:direct,explicit=[instanceMethod1.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b1], types=1),Selector(call, instanceMethod1, arity=2, named=[b1], types=1)]*/
+ /*member: Class.instanceMethod1:direct,explicit=[instanceMethod1.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b1], types=1),Selector(call, instanceMethod1, arity=2, named=[b1], types=1)]*/
// Calls to this imply a check of the passed type arguments.
bool instanceMethod1<S>(S s, {b1}) => s is S;
- /*strong.element: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
+ /*strong.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
// Calls to this does _not_ imply a check of the passed type arguments.
S instanceMethod2<S>(S s, {b2}) => s;
}
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
index 142ac30..c1b9be7 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
@@ -19,8 +19,8 @@
class B {}
class C {
- /*omit.element: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
- /*strong.element: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*strong.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
List<T> bar<T>(Iterable<T> t) => <T>[t.first];
}
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
index 2959bc1..ea8041b 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
@@ -19,8 +19,8 @@
class B {}
class C {
- /*omit.element: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
- /*strong.element: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+ /*strong.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
A<T> bar<T>(A<T> t) => new A<T>(t.field);
}
diff --git a/tests/compiler/dart2js/rti/data/indirect_through_static.dart b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
index e548a31..95fb0c3 100644
--- a/tests/compiler/dart2js/rti/data/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
@@ -26,8 +26,8 @@
map['x'] = new C<B>();
}
-/*strong.element: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
-/*omit.element: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*strong.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*omit.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
C<T> lookup<T>(String key) {
final value = map[key];
if (value != null && value is C<T>) {
diff --git a/tests/compiler/dart2js/rti/data/instantiation1.dart b/tests/compiler/dart2js/rti/data/instantiation1.dart
index 1b8e7cd..930c1ff 100644
--- a/tests/compiler/dart2js/rti/data/instantiation1.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation1.dart
@@ -2,8 +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.
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation2.dart b/tests/compiler/dart2js/rti/data/instantiation2.dart
index 48c7b6c..777fcc0 100644
--- a/tests/compiler/dart2js/rti/data/instantiation2.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation2.dart
@@ -2,8 +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.
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation3.dart b/tests/compiler/dart2js/rti/data/instantiation3.dart
index 7d3df34..f426821 100644
--- a/tests/compiler/dart2js/rti/data/instantiation3.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation3.dart
@@ -2,8 +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.
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation4.dart b/tests/compiler/dart2js/rti/data/instantiation4.dart
index 1fcdac2..34948b9 100644
--- a/tests/compiler/dart2js/rti/data/instantiation4.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation4.dart
@@ -2,8 +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.
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation5.dart b/tests/compiler/dart2js/rti/data/instantiation5.dart
index c69f333..5cde8c6 100644
--- a/tests/compiler/dart2js/rti/data/instantiation5.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation5.dart
@@ -2,13 +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.
-/*strong.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.element: f:deps=[method]*/
+/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*omit.member: f:deps=[method]*/
int f<T>(T a) => null;
typedef int F<R>(R a);
-/*strong.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
method<S>() {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation6.dart b/tests/compiler/dart2js/rti/data/instantiation6.dart
index 672e987..3ce71b5 100644
--- a/tests/compiler/dart2js/rti/data/instantiation6.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation6.dart
@@ -2,14 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*strong.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*omit.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
bool f<T>(T a) => a is T;
typedef bool F<R>(R a);
-/*strong.element: method:indirect,needsArgs*/
-/*omit.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
+/*omit.member: method:indirect,needsArgs*/
method<S>() {
F<S> c;
diff --git a/tests/compiler/dart2js/rti/data/instantiation7.dart b/tests/compiler/dart2js/rti/data/instantiation7.dart
index d8af322..87aabd6 100644
--- a/tests/compiler/dart2js/rti/data/instantiation7.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation7.dart
@@ -2,23 +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.
-/*strong.element: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
-/*omit.element: f1:deps=[method]*/
+/*strong.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
+/*omit.member: f1:deps=[method]*/
int f1<T>(T a, T b, T c) => null;
-/*strong.element: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
-/*omit.element: f2:deps=[method]*/
+/*strong.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
+/*omit.member: f2:deps=[method]*/
int f2<T, S>(T a, S b, S c) => null;
-/*strong.element: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
-/*omit.element: f3:deps=[method]*/
+/*strong.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
+/*omit.member: f3:deps=[method]*/
int f3<T, S, U>(T a, S b, U c) => null;
typedef int F1<R>(R a, R b, R c);
typedef int F2<R, P>(R a, P b, P c);
typedef int F3<R, P, Q>(R a, P b, Q c);
-/*strong.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
method<X, Y, Z>() {
F1<X> c1;
F2<X, Y> c2;
diff --git a/tests/compiler/dart2js/rti/data/list_literal.dart b/tests/compiler/dart2js/rti/data/list_literal.dart
index a6d181f..1b2d499 100644
--- a/tests/compiler/dart2js/rti/data/list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal.dart
@@ -16,7 +16,7 @@
}
class Class {
- /*element: Class.m:implicit=[m.T],indirect,needsArgs,selectors=[Selector(call, m, arity=0, types=1)]*/
+ /*member: Class.m:implicit=[m.T],indirect,needsArgs,selectors=[Selector(call, m, arity=0, types=1)]*/
m<T>() {
return <T>[];
}
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
index aa06e82..d3894cd 100644
--- a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
@@ -7,8 +7,8 @@
/*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
/*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
-/*strong.element: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
+/*omit.member: method:needsArgs*/
@pragma('dart2js:noInline')
method<T>() {
return () => <T>[];
diff --git a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
index 4084c3c..6edee72 100644
--- a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
@@ -7,8 +7,8 @@
/*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
/*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
-/*strong.element: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
+/*omit.member: method:needsArgs*/
@pragma('dart2js:noInline')
method<T>() {
return () => <T, int>{};
diff --git a/tests/compiler/dart2js/rti/data/local_function_signature2.dart b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
index ce0306e..dd0c838 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signature2.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
@@ -25,8 +25,8 @@
}
class Class2 {
- /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
- /*omit.element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -35,7 +35,7 @@
}
class Class3 {
- /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ /*member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
method5<T>() {
/*needsSignature*/
T local(num n) => null;
@@ -44,8 +44,8 @@
}
class Class4 {
- /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
- /*omit.element: Class4.method6:*/
+ /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+ /*omit.member: Class4.method6:*/
method6<T>() {
/**/
num local(num n, T t) => null;
@@ -53,23 +53,23 @@
}
}
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.element: method7:needsArgs*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*omit.member: method7:needsArgs*/
method7<T>() {
/*needsSignature*/
num local(T n) => null;
return local;
}
-/*element: method8:needsArgs*/
+/*member: method8:needsArgs*/
method8<T>() {
/*needsSignature*/
T local(num n) => null;
return local;
}
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*omit.member: method9:*/
method9<T>() {
/**/
num local(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
index 92252a3..80eed74 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
@@ -25,8 +25,8 @@
}
class Class2 {
- /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
- /*omit.element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
method4<T>() {
/*needsSignature*/
num local(T n) => null;
@@ -35,7 +35,7 @@
}
class Class3 {
- /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ /*member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
method5<T>() {
/*needsSignature*/
T local(num n) => null;
@@ -44,8 +44,8 @@
}
class Class4 {
- /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
- /*omit.element: Class4.method6:*/
+ /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+ /*omit.member: Class4.method6:*/
method6<T>() {
/**/
num local(num n, T t) => null;
@@ -53,23 +53,23 @@
}
}
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.element: method7:needsArgs*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*omit.member: method7:needsArgs*/
method7<T>() {
/*needsSignature*/
num local(T n) => null;
return local;
}
-/*element: method8:needsArgs*/
+/*member: method8:needsArgs*/
method8<T>() {
/*needsSignature*/
T local(num n) => null;
return local;
}
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*omit.member: method9:*/
method9<T>() {
/**/
num local(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/method_signatures.dart b/tests/compiler/dart2js/rti/data/method_signatures.dart
index 5a4b083..e393181 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures.dart
@@ -5,44 +5,44 @@
import 'package:expect/expect.dart';
class Class1 {
- /*element: Class1.method1:*/
+ /*member: Class1.method1:*/
num method1(num n) => null;
- /*element: Class1.method2:*/
+ /*member: Class1.method2:*/
num method2(int n) => null;
- /*element: Class1.method3:*/
+ /*member: Class1.method3:*/
Object method3(num n) => null;
}
/*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.method4:*/
- /*omit.element: Class2.method4:*/
+ /*strong.member: Class2.method4:*/
+ /*omit.member: Class2.method4:*/
num method4(T n) => null;
}
/*class: Class3:needsArgs*/
class Class3<T> {
- /*element: Class3.method5:needsSignature*/
+ /*member: Class3.method5:needsSignature*/
T method5(num n) => null;
}
/*omit.class: Class4:*/
/*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
class Class4<T> {
- /*element: Class4.method6:*/
+ /*member: Class4.method6:*/
num method6(num n, T t) => null;
}
-/*element: method7:*/
+/*member: method7:*/
num method7(num n) => null;
-/*element: method8:*/
+/*member: method8:*/
num method8(int n) => null;
-/*element: method9:*/
+/*member: method9:*/
Object method9(num n) => null;
@pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
index 1c1cb02..9f33a9f 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
@@ -5,42 +5,42 @@
import 'package:expect/expect.dart';
class Class1 {
- /*element: Class1.method1:*/
+ /*member: Class1.method1:*/
num method1<T>(num n) => null;
- /*element: Class1.method2:*/
+ /*member: Class1.method2:*/
num method2<T>(int n) => null;
- /*element: Class1.method3:*/
+ /*member: Class1.method3:*/
int method3<T>(num n) => null;
}
class Class2 {
- /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>]*/
- /*omit.element: Class2.method4:*/
+ /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>]*/
+ /*omit.member: Class2.method4:*/
num method4<T>(T n) => null;
}
class Class3 {
- /*element: Class3.method5:*/
+ /*member: Class3.method5:*/
T method5<T>(num n) => null;
}
class Class4 {
- /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>]*/
- /*omit.element: Class4.method6:*/
+ /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>]*/
+ /*omit.member: Class4.method6:*/
num method6<T>(num n, T t) => null;
}
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>]*/
-/*omit.element: method7:*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>]*/
+/*omit.member: method7:*/
num method7<T>(T n) => null;
-/*element: method8:*/
+/*member: method8:*/
T method8<T>(num n) => null;
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>]*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>]*/
+/*omit.member: method9:*/
num method9<T>(num n, T t) => null;
@pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/no_such_method1.dart b/tests/compiler/dart2js/rti/data/no_such_method1.dart
index f2e93f1..da65384 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method1.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class C {
- /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+ /*member: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
noSuchMethod(i) => i.typeArguments;
}
diff --git a/tests/compiler/dart2js/rti/data/no_such_method2.dart b/tests/compiler/dart2js/rti/data/no_such_method2.dart
index 55434cd..8b27c38 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method2.dart
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
class C {
- /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+ /*member: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
noSuchMethod(i) => i.typeArguments;
}
class D {
- /*element: D.foo:exp,needsArgs,selectors=[Selector(call, foo, arity=0, types=2)]*/
+ /*member: D.foo:exp,needsArgs,selectors=[Selector(call, foo, arity=0, types=2)]*/
foo<U, V>() => [U, V];
}
diff --git a/tests/compiler/dart2js/rti/data/no_such_method3.dart b/tests/compiler/dart2js/rti/data/no_such_method3.dart
index d10adf2..a6ba3c7 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method3.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class C {
- /*element: C.noSuchMethod:*/
+ /*member: C.noSuchMethod:*/
noSuchMethod(i) => null;
}
diff --git a/tests/compiler/dart2js/rti/data/private_dynamic.dart b/tests/compiler/dart2js/rti/data/private_dynamic.dart
index 275d6c2..fb5ca94 100644
--- a/tests/compiler/dart2js/rti/data/private_dynamic.dart
+++ b/tests/compiler/dart2js/rti/data/private_dynamic.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
class C {
- /*element: C._private:direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
+ /*member: C._private:direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
_private<T>(t) => t is T;
}
diff --git a/tests/compiler/dart2js/rti/data/private_dynamic2.dart b/tests/compiler/dart2js/rti/data/private_dynamic2.dart
index 0a82cf2..5612fbf 100644
--- a/tests/compiler/dart2js/rti/data/private_dynamic2.dart
+++ b/tests/compiler/dart2js/rti/data/private_dynamic2.dart
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
class C {
- /*element: C._private:deps=[D._private2],direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
+ /*member: C._private:deps=[D._private2],direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
_private<T>(t) => t is T;
}
class D {
- /*element: D._private2:implicit=[_private2.T],indirect,needsArgs,selectors=[Selector(call, _private2, arity=2, types=1)]*/
+ /*member: D._private2:implicit=[_private2.T],indirect,needsArgs,selectors=[Selector(call, _private2, arity=2, types=1)]*/
_private2<T>(c, t) => c._private<T>(t);
}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
index 69a3f14..08cc7bf 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
@@ -7,13 +7,13 @@
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
/*needsSignature*/
local1a() {}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
index 2757f5a..c7cc1f4 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
@@ -7,13 +7,13 @@
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
/*strong.needsArgs,needsSignature*/
/*omit.needsArgs,needsSignature*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
index d650fb6..e586484 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
@@ -9,12 +9,12 @@
/*omit.class: Class1:needsArgs*/
/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
- /*strong.element: Class1.method:*/
- /*omit.element: Class1.method:*/
+ /*strong.member: Class1.method:*/
+ /*omit.member: Class1.method:*/
method() {
/*needsSignature*/
T local1a() => null;
@@ -34,13 +34,13 @@
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
new Class1<int>().method();
new Class2<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
index 33973ff..d219396 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
@@ -7,37 +7,37 @@
/*strong.class: Class1:*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
// TODO(johnniwinther): Currently only methods that use class type variables
// in their signature are marked as 'needs signature'. Change this to mark
// all methods that need to support access to their function type at runtime.
- /*strong.element: Class1.method1a:*/
- /*omit.element: Class1.method1a:*/
+ /*strong.member: Class1.method1a:*/
+ /*omit.member: Class1.method1a:*/
method1a() => null;
- /*strong.element: Class1.method1b:*/
- /*omit.element: Class1.method1b:*/
+ /*strong.member: Class1.method1b:*/
+ /*omit.member: Class1.method1b:*/
method1b() => null;
- /*strong.element: Class1.method2:*/
- /*omit.element: Class1.method2:*/
+ /*strong.member: Class1.method2:*/
+ /*omit.member: Class1.method2:*/
method2(t, s) => t;
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
index 82ed29c..62858b0 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
@@ -7,33 +7,33 @@
/*omit.class: Class1:needsArgs*/
/*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
- /*strong.element: Class1.method1a:needsSignature*/
- /*omit.element: Class1.method1a:needsSignature*/
+ /*strong.member: Class1.method1a:needsSignature*/
+ /*omit.member: Class1.method1a:needsSignature*/
T method1a() => null;
- /*strong.element: Class1.method1b:needsSignature*/
- /*omit.element: Class1.method1b:needsSignature*/
+ /*strong.member: Class1.method1b:needsSignature*/
+ /*omit.member: Class1.method1b:needsSignature*/
T method1b() => null;
- /*strong.element: Class1.method2:needsSignature*/
- /*omit.element: Class1.method2:needsSignature*/
+ /*strong.member: Class1.method2:needsSignature*/
+ /*omit.member: Class1.method2:needsSignature*/
T method2(T t, String s) => t;
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
index 219ee28..f469a25 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
@@ -4,28 +4,28 @@
import 'package:expect/expect.dart';
-/*strong.element: method1a:*/
-/*omit.element: method1a:*/
+/*strong.member: method1a:*/
+/*omit.member: method1a:*/
method1a() => null;
-/*strong.element: method1b:*/
-/*omit.element: method1b:*/
+/*strong.member: method1b:*/
+/*omit.member: method1b:*/
method1b() => null;
-/*strong.element: method2:*/
-/*omit.element: method2:*/
+/*strong.member: method2:*/
+/*omit.member: method2:*/
method2(t, s) => t;
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
index ac7d406..db76621 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
@@ -4,26 +4,26 @@
import 'package:expect/expect.dart';
-/*element: method1a:*/
+/*member: method1a:*/
T method1a<T>() => null;
-/*element: method1b:*/
+/*member: method1b:*/
T method1b<T>() => null;
-/*strong.element: method2:direct,explicit=[method2.T],needsArgs*/
-/*omit.element: method2:*/
+/*strong.member: method2:direct,explicit=[method2.T],needsArgs*/
+/*omit.member: method2:*/
T method2<T>(T t, String s) => t;
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
index d597301..a7b639a 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
@@ -7,31 +7,31 @@
/*strong.class: Class1:*/
/*omit.class: Class1:*/
class Class1<S> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
- /*element: Class1.method1a:*/
+ /*member: Class1.method1a:*/
T method1a<T>() => null;
- /*element: Class1.method1b:*/
+ /*member: Class1.method1b:*/
T method1b<T>() => null;
- /*strong.element: Class1.method2:direct,explicit=[method2.T],needsArgs*/
- /*omit.element: Class1.method2:*/
+ /*strong.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
+ /*omit.member: Class1.method2:*/
T method2<T>(T t, String s) => t;
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
var c = new Class1<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
index 53f3285..a1acdd3 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
@@ -5,13 +5,13 @@
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
/*strong.needsSignature*/
/*omit.*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
index 209cf08..041b311 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
@@ -5,13 +5,13 @@
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
/*strong.needsArgs,needsSignature*/
/*omit.*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
index 0496521..9d80812 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
@@ -5,25 +5,25 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
- /*strong.element: Class1.method:needsSignature*/
- /*omit.element: Class1.method:*/
+ /*strong.member: Class1.method:needsSignature*/
+ /*omit.member: Class1.method:*/
T method() => null;
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
index 907e515..f4511ea 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
@@ -4,20 +4,20 @@
/*class: Class1:*/
class Class1 {
- /*element: Class1.:*/
+ /*member: Class1.:*/
Class1();
- /*element: Class1.method:*/
+ /*member: Class1.method:*/
T method<T>() => null;
}
/*class: Class2:*/
class Class2<T> {
- /*element: Class2.:*/
+ /*member: Class2.:*/
Class2();
}
-/*element: main:*/
+/*member: main:*/
main() {
Class1 cls1 = new Class1();
print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
index 810ca7a..20026ba 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
@@ -5,21 +5,21 @@
/*strong.class: Class:*/
/*omit.class: Class:*/
class Class<T> {
- /*strong.element: Class.:*/
- /*omit.element: Class.:*/
+ /*strong.member: Class.:*/
+ /*omit.member: Class.:*/
Class();
}
-/*strong.element: method1:*/
-/*omit.element: method1:*/
+/*strong.member: method1:*/
+/*omit.member: method1:*/
method1() {}
-/*strong.element: method2:*/
-/*omit.element: method2:*/
+/*strong.member: method2:*/
+/*omit.member: method2:*/
method2(int i, String s) => i;
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
print('${method1.runtimeType}');
method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
index b684856..fa6db4d 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
@@ -4,17 +4,17 @@
/*class: Class:*/
class Class<T> {
- /*element: Class.:*/
+ /*member: Class.:*/
Class();
}
-/*element: method1:*/
+/*member: method1:*/
method1<T>() {}
-/*element: method2:*/
+/*member: method2:*/
method2<T>(t, s) => t;
-/*element: main:*/
+/*member: main:*/
main() {
print('${method1.runtimeType}');
method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
index 0f6cce7..bf0d3e2 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
@@ -6,12 +6,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.element: Class1a.:*/
- /*omit.element: Class1a.:*/
+ /*strong.member: Class1a.:*/
+ /*omit.member: Class1a.:*/
Class1a();
- /*strong.element: Class1a.==:*/
- /*omit.element: Class1a.==:*/
+ /*strong.member: Class1a.==:*/
+ /*omit.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return runtimeType == other.runtimeType;
@@ -20,8 +20,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.element: Class1b.:*/
- /*omit.element: Class1b.:*/
+ /*strong.member: Class1b.:*/
+ /*omit.member: Class1b.:*/
Class1b();
}
@@ -29,21 +29,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.element: Class1c.:*/
- /*omit.element: Class1c.:*/
+ /*strong.member: Class1c.:*/
+ /*omit.member: Class1c.:*/
Class1c();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
index eb04620..77b9099 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
@@ -6,12 +6,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.element: Class1a.:*/
- /*omit.element: Class1a.:*/
+ /*strong.member: Class1a.:*/
+ /*omit.member: Class1a.:*/
Class1a();
- /*strong.element: Class1a.==:*/
- /*omit.element: Class1a.==:*/
+ /*strong.member: Class1a.==:*/
+ /*omit.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return other.runtimeType == runtimeType;
@@ -20,8 +20,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.element: Class1b.:*/
- /*omit.element: Class1b.:*/
+ /*strong.member: Class1b.:*/
+ /*omit.member: Class1b.:*/
Class1b();
}
@@ -29,21 +29,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.element: Class1c.:*/
- /*omit.element: Class1c.:*/
+ /*strong.member: Class1c.:*/
+ /*omit.member: Class1c.:*/
Class1c();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
index e83b5cf..c290ac6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
@@ -6,12 +6,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.element: Class1a.:*/
- /*omit.element: Class1a.:*/
+ /*strong.member: Class1a.:*/
+ /*omit.member: Class1a.:*/
Class1a();
- /*strong.element: Class1a.==:*/
- /*omit.element: Class1a.==:*/
+ /*strong.member: Class1a.==:*/
+ /*omit.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return runtimeType == other?.runtimeType;
@@ -20,8 +20,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.element: Class1b.:*/
- /*omit.element: Class1b.:*/
+ /*strong.member: Class1b.:*/
+ /*omit.member: Class1b.:*/
Class1b();
}
@@ -29,21 +29,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.element: Class1c.:*/
- /*omit.element: Class1c.:*/
+ /*strong.member: Class1c.:*/
+ /*omit.member: Class1c.:*/
Class1c();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
index f3f3b67..5e77f79 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
@@ -6,12 +6,12 @@
/*class: Class1a:needsArgs*/
class Class1a<T> {
- /*strong.element: Class1a.:*/
- /*omit.element: Class1a.:*/
+ /*strong.member: Class1a.:*/
+ /*omit.member: Class1a.:*/
Class1a();
- /*strong.element: Class1a.==:*/
- /*omit.element: Class1a.==:*/
+ /*strong.member: Class1a.==:*/
+ /*omit.member: Class1a.==:*/
bool operator ==(other) {
if (identical(this, other)) return true;
return other?.runtimeType == runtimeType;
@@ -20,8 +20,8 @@
/*class: Class1b:needsArgs*/
class Class1b<T> extends Class1a<T> {
- /*strong.element: Class1b.:*/
- /*omit.element: Class1b.:*/
+ /*strong.member: Class1b.:*/
+ /*omit.member: Class1b.:*/
Class1b();
}
@@ -29,21 +29,21 @@
// this class.
/*class: Class1c:needsArgs*/
class Class1c<T> implements Class1a<T> {
- /*strong.element: Class1c.:*/
- /*omit.element: Class1c.:*/
+ /*strong.member: Class1c.:*/
+ /*omit.member: Class1c.:*/
Class1c();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1a<int> cls1a = new Class1a<int>();
Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
index 56285d2..c1db9ed 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
@@ -27,14 +27,14 @@
Class2();
}
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
test(Class1a c, Type type) {
return c.runtimeType == type;
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Expect.isTrue(test(new Class1a(), Class1a));
Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
index 2aff7c1..f0cca27 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
@@ -28,14 +28,14 @@
Class2();
}
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
test(Class1a c, Type type) {
return c.runtimeType == type;
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Expect.isTrue(test(new Class1a(), Class1a));
Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
index a1748f4..8639733 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
@@ -35,14 +35,14 @@
Class3(this.field);
}
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
test(Class3 c, Type type) {
return c.field.runtimeType == type;
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Expect.isTrue(test(new Class3<int>(new Class1a()), Class1a));
Expect.isFalse(test(new Class3<int>(new Class1b<int>()), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
index 657513e..282d501 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.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.
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
main() {
/*strong.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
index 2db3273..22ddfb3 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
@@ -2,9 +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.
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
-/*strong.element: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+/*strong.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
T id<T>(T t, String s) => t;
main() {
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
index cb51e1b..222eb2b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
class Class {
- /*strong.element: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+ /*strong.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
T id<T>(T t, String s) => t;
}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
index ae67754..70f0f95 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
@@ -5,29 +5,29 @@
/*strong.class: Class1:*/
/*omit.class: Class1:*/
class Class1 {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
/*strong.class: Class3:needsArgs*/
/*omit.class: Class3:*/
class Class3<T> implements Class1 {
- /*strong.element: Class3.:*/
- /*omit.element: Class3.:*/
+ /*strong.member: Class3.:*/
+ /*omit.member: Class3.:*/
Class3();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1 cls1 = new Class1();
print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
index 3c36e34..d8efa16 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
@@ -5,21 +5,21 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
index 91058ce..baf98d4 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
@@ -5,21 +5,21 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
index 2b9902a..77babb9 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
@@ -5,21 +5,21 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print(cls1?.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
index 22f8349..235b8be 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
@@ -5,21 +5,21 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1<int> cls1 = new Class1<int>();
print('${cls1?.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
index eeb633c..b312960 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
@@ -5,21 +5,21 @@
/*strong.class: Class1:needsArgs*/
/*omit.class: Class1:*/
class Class1<T> {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:needsArgs*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
dynamic cls1 = new Class1<int>();
print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
index ae67754..70f0f95 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
@@ -5,29 +5,29 @@
/*strong.class: Class1:*/
/*omit.class: Class1:*/
class Class1 {
- /*strong.element: Class1.:*/
- /*omit.element: Class1.:*/
+ /*strong.member: Class1.:*/
+ /*omit.member: Class1.:*/
Class1();
}
/*strong.class: Class2:*/
/*omit.class: Class2:*/
class Class2<T> {
- /*strong.element: Class2.:*/
- /*omit.element: Class2.:*/
+ /*strong.member: Class2.:*/
+ /*omit.member: Class2.:*/
Class2();
}
/*strong.class: Class3:needsArgs*/
/*omit.class: Class3:*/
class Class3<T> implements Class1 {
- /*strong.element: Class3.:*/
- /*omit.element: Class3.:*/
+ /*strong.member: Class3.:*/
+ /*omit.member: Class3.:*/
Class3();
}
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
main() {
Class1 cls1 = new Class1();
print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/tear_off.dart b/tests/compiler/dart2js/rti/data/tear_off.dart
index 421d480..f2c56b1 100644
--- a/tests/compiler/dart2js/rti/data/tear_off.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off.dart
@@ -4,10 +4,10 @@
/*class: A:*/
class A<T> {
- /*element: A.m:*/
+ /*member: A.m:*/
void m(String t) {}
- /*element: A.f:*/
+ /*member: A.f:*/
void f(int t) {}
}
diff --git a/tests/compiler/dart2js/rti/data/tear_off_generic.dart b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
index 24cc2ee..b3689bb 100644
--- a/tests/compiler/dart2js/rti/data/tear_off_generic.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
@@ -5,11 +5,11 @@
/*strong.class: A:direct,explicit=[A.T],needsArgs*/
/*omit.class: A:*/
class A<T> {
- /*strong.element: A.m:*/
- /*omit.element: A.m:*/
+ /*strong.member: A.m:*/
+ /*omit.member: A.m:*/
void m(T t) {}
- /*element: A.f:*/
+ /*member: A.f:*/
void f(int t) {}
}
diff --git a/tests/compiler/dart2js/rti/data/type_literal_generic.dart b/tests/compiler/dart2js/rti/data/type_literal_generic.dart
index 098d700..dde4860 100644
--- a/tests/compiler/dart2js/rti/data/type_literal_generic.dart
+++ b/tests/compiler/dart2js/rti/data/type_literal_generic.dart
@@ -6,19 +6,19 @@
class A<T> {
instanceMethod() => T;
- /*element: A.staticMethod:exp,needsArgs*/
+ /*member: A.staticMethod:exp,needsArgs*/
static staticMethod<S>() => S;
- /*element: A.staticMethodNested:exp,needsArgs*/
+ /*member: A.staticMethodNested:exp,needsArgs*/
static staticMethodNested<S>() {
var inner = () => S;
return inner();
}
- /*element: A.genericMethod:exp,needsArgs,selectors=[Selector(call, genericMethod, arity=0, types=1)]*/
+ /*member: A.genericMethod:exp,needsArgs,selectors=[Selector(call, genericMethod, arity=0, types=1)]*/
genericMethod<S>() => S;
- /*element: A.genericMethodNested:exp,needsArgs,selectors=[Selector(call, genericMethodNested, arity=0, types=1)]*/
+ /*member: A.genericMethodNested:exp,needsArgs,selectors=[Selector(call, genericMethodNested, arity=0, types=1)]*/
genericMethodNested<S>() {
var inner = () => S;
return inner();
@@ -42,10 +42,10 @@
}
}
-/*element: topLevelMethod:exp,needsArgs*/
+/*member: topLevelMethod:exp,needsArgs*/
topLevelMethod<S>() => S;
-/*element: topLevelMethodNested:exp,needsArgs*/
+/*member: topLevelMethodNested:exp,needsArgs*/
topLevelMethodNested<S>() {
var inner = () => S;
return inner();
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index fd96ed8..a6fc1c2 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -9,7 +9,6 @@
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/js_backend/runtime_types.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js_model/element_map.dart';
@@ -127,7 +126,7 @@
}
class RtiClassEmissionIrComputer extends DataRegistry<String>
- with ComputeValueMixin {
+ with ComputeValueMixin, IrDataRegistryMixin<String> {
@override
final Compiler compiler;
final JsToElementMap _elementMap;
@@ -142,8 +141,9 @@
void computeClassValue(ClassEntity cls) {
Id id = new ClassId(cls.name);
ir.TreeNode node = _elementMap.getClassDefinition(cls).node;
- registerValue(
- computeSourceSpanFromTreeNode(node), id, getClassValue(cls), cls);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+ id, getClassValue(cls), cls);
}
}
diff --git a/tests/compiler/dart2js/rti/rti_need_test_helper.dart b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
index d5c4e49..bbdd2c2 100644
--- a/tests/compiler/dart2js/rti/rti_need_test_helper.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
@@ -11,7 +11,6 @@
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/ir/util.dart';
import 'package:compiler/src/js_backend/runtime_types.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:compiler/src/js_model/element_map.dart';
@@ -318,7 +317,7 @@
}
class RtiClassNeedIrComputer extends DataRegistry<String>
- with ComputeValueMixin, IrMixin {
+ with ComputeValueMixin, IrMixin, IrDataRegistryMixin<String> {
@override
final Compiler compiler;
final JsToElementMap _elementMap;
@@ -333,8 +332,9 @@
void computeClassValue(ClassEntity cls) {
Id id = new ClassId(cls.name);
ir.TreeNode node = _elementMap.getClassDefinition(cls).node;
- registerValue(
- computeSourceSpanFromTreeNode(node), id, getClassValue(cls), cls);
+ ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+ id, getClassValue(cls), cls);
}
}
diff --git a/tests/compiler/dart2js/sourcemaps/mapping_test.dart b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
index 6c933ee..a534142 100644
--- a/tests/compiler/dart2js/sourcemaps/mapping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
@@ -9,7 +9,7 @@
import 'package:compiler/compiler_new.dart';
import 'package:expect/expect.dart';
import 'package:source_maps/source_maps.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import '../helpers/memory_compiler.dart';
@@ -72,7 +72,7 @@
} else if (arg == '--write-js') {
writeJs = true;
} else {
- int index = int.parse(arg, onError: (_) => null);
+ int index = int.tryParse(arg);
if (index != null) {
indices ??= <int>[];
if (index < 0 || index >= TESTS.length) {
diff --git a/tests/compiler/dart2js/sourcemaps/stepping_test.dart b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
index c8610e0..e37bf06 100644
--- a/tests/compiler/dart2js/sourcemaps/stepping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
@@ -11,7 +11,7 @@
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/dart2js.dart' as entry;
import 'package:expect/expect.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
import 'package:sourcemap_testing/src/stepping_helper.dart';
void main(List<String> args) {
diff --git a/tests/compiler/dart2js_extra/22776_test.dart b/tests/compiler/dart2js_extra/22776_test.dart
index 80dbffd1..135f505 100644
--- a/tests/compiler/dart2js_extra/22776_test.dart
+++ b/tests/compiler/dart2js_extra/22776_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.
-// Regression test for http://dartbug.com/22776/
+// Regression test for http://dartbug.com/22776
import "package:expect/expect.dart";
diff --git a/tests/compiler/dart2js_extra/22868_test.dart b/tests/compiler/dart2js_extra/22868_test.dart
index 0d83b955..71907def 100644
--- a/tests/compiler/dart2js_extra/22868_test.dart
+++ b/tests/compiler/dart2js_extra/22868_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.
-// Regression test for http://dartbug.com/22868/ and http://dartbug.com/22895/.
+// Regression test for http://dartbug.com/22868 and http://dartbug.com/22895
// Ensure that the closure tracer properly handles await.
main() async {
diff --git a/tests/compiler/dart2js_extra/23264_test.dart b/tests/compiler/dart2js_extra/23264_test.dart
deleted file mode 100644
index a834426..0000000
--- a/tests/compiler/dart2js_extra/23264_test.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:expect/expect.dart';
-
-class A {
- A(ignore);
-}
-
-main() => Expect.throws(() => A(const [])); // oops, `new` is missing!
diff --git a/tests/compiler/dart2js_extra/23404_test.dart b/tests/compiler/dart2js_extra/23404_test.dart
index d3b9f46..699e63d 100644
--- a/tests/compiler/dart2js_extra/23404_test.dart
+++ b/tests/compiler/dart2js_extra/23404_test.dart
@@ -2,12 +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.
-// Regression test for http://dartbug.com/23404/
-import 'package:expect/expect.dart';
-
+// Regression test for http://dartbug.com/23404
+//
// Dart2js crashed when the global metadata had escaped characters. That
// happens, for example, when tearing off a function that uses a default
// argument containing escape characters.
+import 'package:expect/expect.dart';
+
foo([a = '\u00a0']) => a;
bar() => '';
diff --git a/tests/compiler/dart2js_extra/23486_test.dart b/tests/compiler/dart2js_extra/23486_test.dart
index b628cf7..1d41e26 100644
--- a/tests/compiler/dart2js_extra/23486_test.dart
+++ b/tests/compiler/dart2js_extra/23486_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.
-// Regression test for http://dartbug.com/23486/
+// Regression test for http://dartbug.com/23486
//
// Dart2js used to crash when using `super` and prefixes inside parenthesized
// expressions.
diff --git a/tests/compiler/dart2js_extra/23804_test.dart b/tests/compiler/dart2js_extra/23804_test.dart
index fbcf965..32bb00b 100644
--- a/tests/compiler/dart2js_extra/23804_test.dart
+++ b/tests/compiler/dart2js_extra/23804_test.dart
@@ -2,7 +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.
-// Regression test for http://dartbug.com/23804/
+// Regression test for http://dartbug.com/23804
+//
// Inference incorrectly assumed that `any` and `every` didn't escape the values
// in the collections.
diff --git a/tests/compiler/dart2js_extra/23828_test.dart b/tests/compiler/dart2js_extra/23828_test.dart
index be5edd5..e2fbf7d 100644
--- a/tests/compiler/dart2js_extra/23828_test.dart
+++ b/tests/compiler/dart2js_extra/23828_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.
-// Regression test for http://dartbug.com/23828/
+// Regression test for http://dartbug.com/23828
// Used to fail when methods contain a name starting with `get`
import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js_extra/invalid_annotation_test.dart b/tests/compiler/dart2js_extra/invalid_annotation_test.dart
index ac7689a..fe68503 100644
--- a/tests/compiler/dart2js_extra/invalid_annotation_test.dart
+++ b/tests/compiler/dart2js_extra/invalid_annotation_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.
-// Regression test for http://dartbug.com/23893/
+// Regression test for http://dartbug.com/23893
//
// Because annotations are parsed lazily, dart2js used to crash when an
// annotation had a syntax error.
diff --git a/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart b/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
index ad09aef..d16c31c 100644
--- a/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
+++ b/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
@@ -5,7 +5,7 @@
// dart2jsOptions=--strong
// Regression test checking that nsm-forwarders do not get installed for private
-// members of other libraries. See https://dartbug.com/33665
+// members of other libraries. See http://dartbug.com/33665
import 'package:expect/expect.dart';
import 'no_such_method_strong11_lib.dart';
diff --git a/tests/compiler/dart2js_extra/round_constant_folding_test.dart b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
index 9c0a1fe..2c786dd 100644
--- a/tests/compiler/dart2js_extra/round_constant_folding_test.dart
+++ b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
@@ -53,8 +53,9 @@
const int PI3 = 0x1234;
const int PI4 = 0x12345678;
const int PI5 = 0x123456789AB;
-const int PI6 = 0x123456789ABCDEF;
-const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
+const int PI6 = 0x123456789ABCD00 + 0xEF;
+const int PI7 = 0x123456789ABCD * 0x1234567 * 0x1234567 * 0x1234567;
+//const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
const int NI1 = 0 - PI1;
const int NI2 = -PI2;
diff --git a/tests/compiler/dart2js_extra/rti/canonical_recipe_test.dart b/tests/compiler/dart2js_extra/rti/canonical_recipe_test.dart
new file mode 100644
index 0000000..856ca7a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/canonical_recipe_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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+final universe = rti.testingCreateUniverse();
+
+main() {
+ test('@', '@');
+ test('~', '~');
+ test('0&', '0&');
+ test('1&', '1&');
+ test('int', 'int');
+ test('int/', 'int/');
+ test('List<int>', 'List<int>');
+ test('Foo<bool,Bar<int,double>>', 'Foo<bool,Bar<int,double>>');
+ test('@;<int,bool>', '@<int><bool>');
+}
+
+String canonicalize(String recipe) {
+ var t = rti.testingUniverseEval(universe, recipe);
+ return rti.testingCanonicalRecipe(t);
+}
+
+void test(String expected, String recipe) =>
+ Expect.equals(expected, canonicalize(recipe));
diff --git a/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart b/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart
new file mode 100644
index 0000000..7d4be33
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart
@@ -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.
+
+import 'dart:_recipe_syntax';
+
+main() {
+ Recipe.testEquivalence();
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_1_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_1_test.dart
new file mode 100644
index 0000000..1eb67ab
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_1_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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class GenericThingy<A, B> {
+ toString() => 'GenericThingy<$A, $B>';
+}
+
+main() {
+ var rti1 = rti.instanceType(1);
+ Expect.equals('JSInt', rti.testingRtiToString(rti1));
+
+ var rti2 = rti.instanceType('Hello');
+ Expect.equals('JSString', rti.testingRtiToString(rti2));
+
+ var rti3 = rti.instanceType(Thingy());
+ Expect.equals('Thingy', rti.testingRtiToString(rti3));
+
+ var rti4 = rti.instanceType(GenericThingy<String, int>());
+ Expect.equals('GenericThingy<String, int>', rti.testingRtiToString(rti4));
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart
new file mode 100644
index 0000000..69b352a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart
@@ -0,0 +1,33 @@
+// 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+Type grab<T>() => T;
+
+@pragma('dart2js:noInline')
+Type grabList<T>() => grab<List<T>>();
+
+main() {
+ Expect.equals('int', grab<int>().toString());
+
+ Expect.identical(int, grab<int>());
+ Expect.identical(dynamic, grab<dynamic>());
+ Expect.identical(Object, grab<Object>());
+ Expect.identical(Null, grab<Null>());
+
+ Expect.equals('List<int>', grabList<int>().toString());
+ Expect.equals('List<Null>', grabList<Null>().toString());
+
+ Expect.equals('List<dynamic>', (List).toString());
+
+ Expect.equals('dynamic', (dynamic).toString());
+ Expect.equals('Object', (Object).toString());
+ Expect.equals('Null', (Null).toString());
+
+ Expect.equals(List, grabList<dynamic>());
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart
new file mode 100644
index 0000000..7d8d51e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart
@@ -0,0 +1,15 @@
+// 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+import "dart:_foreign_helper" show JS;
+
+main() {
+ Expect.equals('JSArray<int>', <int>[].runtimeType.toString());
+
+ // TODO(35084): An 'any' type would make JS-interop easier to use.
+ Expect.equals('JSArray<dynamic>', JS('', '[]').runtimeType.toString());
+}
diff --git a/tests/compiler/dart2js_extra/rti/simple_is_test.dart b/tests/compiler/dart2js_extra/rti/simple_is_test.dart
new file mode 100644
index 0000000..7c7aafa
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/simple_is_test.dart
@@ -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 file.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class Generic<AA> {
+ checkMethod(o) => o is AA;
+}
+
+@pragma('dart2js:noInline')
+void check<T>(o) {
+ Expect.isTrue(o is T);
+ Expect.isFalse(o is! T);
+}
+
+main() {
+ check<Thingy>(Thingy());
+
+ check<Generic<int>>(Generic<int>());
+
+ check<Generic<dynamic>>(Generic<dynamic>());
+ check<Generic<Object>>(Generic<Object>());
+ check<Generic<Object>>(Generic<dynamic>());
+ check<Generic<dynamic>>(Generic<Object>());
+
+ Expect.isTrue(Generic<Thingy>().checkMethod(Thingy()));
+ Expect.isTrue(Generic<Object>().checkMethod(Object()));
+ Expect.isTrue(Generic<Object>().checkMethod(Thingy()));
+ Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+ Expect.isTrue(Generic<dynamic>().checkMethod(Object()));
+
+ Expect.isFalse(Generic<Thingy>().checkMethod(123));
+ Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+}
diff --git a/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart b/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart
new file mode 100644
index 0000000..064327f
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart
@@ -0,0 +1,43 @@
+// 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.
+//
+// dart2jsOptions=--experiment-new-rti
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+dynamic makeFunction(x) {
+ // Return a local function since that does not require any tear-off code.
+ dynamic foo<U extends V, V extends num>() {
+ // Returning x ensures this is a local function and will not be optimized to
+ // a static tear-off.
+ return x;
+ }
+
+ return foo;
+}
+
+@pragma('dart2js:noInline')
+void test(dynamic action, bool expectThrows) {
+ // Don't use Expect.throws because it is hard to call without implicit type
+ // checks.
+ try {
+ // There is no type check here, just a dynamic 'call' selector.
+ action();
+ } catch (e, st) {
+ if (expectThrows) return;
+ Expect.fail('Should throw');
+ return;
+ }
+ if (expectThrows) {
+ Expect.fail('Did not throw');
+ }
+}
+
+main() {
+ dynamic f = makeFunction(123);
+
+ test(() => f<String, int>(), true);
+ test(() => f<num, num>(), false);
+}
diff --git a/tests/compiler/dart2js_extra/rti/subtype_test.dart b/tests/compiler/dart2js_extra/rti/subtype_test.dart
index 91fb5b5..c90f0f7 100644
--- a/tests/compiler/dart2js_extra/rti/subtype_test.dart
+++ b/tests/compiler/dart2js_extra/rti/subtype_test.dart
@@ -2,32 +2,106 @@
// for 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:_foreign_helper' show JS, JS_GET_NAME;
+import 'dart:_js_embedded_names' show JsGetName;
import 'dart:_rti' as rti;
import "package:expect/expect.dart";
+final String objectName = JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
+final String futureName = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+final String nullName = JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+const typeRulesJson = r'''
+{
+ "int": {"num": []},
+ "List": {"Iterable": ["1"]},
+ "CodeUnits": {
+ "List": ["int"],
+ "Iterable": ["int"]
+ }
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+final universe = rti.testingCreateUniverse();
+
main() {
- testCodeUnits();
+ rti.testingAddRules(universe, typeRules);
+ runTests();
+ runTests(); // Ensure caching didn't change anything.
}
-void testCodeUnits() {
- var universe = rti.testingCreateUniverse();
+void runTests() {
+ testInterfaces();
+ testTopTypes();
+ testNull();
+ testFutureOr();
+}
- var intRule = rti.testingCreateRule();
- rti.testingAddSupertype(intRule, 'num', []);
+void testInterfaces() {
+ strictSubtype('List<CodeUnits>', 'Iterable<List<int>>');
+ strictSubtype('CodeUnits', 'Iterable<num>');
+ strictSubtype('Iterable<int>', 'Iterable<num>');
+ unrelated('int', 'CodeUnits');
+ equivalent('double', 'double');
+ equivalent('List<int>', 'List<int>');
+}
- var listRule = rti.testingCreateRule();
- rti.testingAddSupertype(listRule, 'Iterable', ['1']);
+void testTopTypes() {
+ strictSubtype('List<int>', objectName);
+ equivalent(objectName, objectName);
+ equivalent('@', '@');
+ equivalent('~', '~');
+ equivalent('1&', '1&');
+ equivalent(objectName, '@');
+ equivalent(objectName, '~');
+ equivalent(objectName, '1&');
+ equivalent('@', '~');
+ equivalent('@', '1&');
+ equivalent('~', '1&');
+ equivalent('List<$objectName>', 'List<@>');
+ equivalent('List<$objectName>', 'List<~>');
+ equivalent('List<$objectName>', 'List<1&>');
+ equivalent('List<@>', 'List<~>');
+ equivalent('List<@>', 'List<1&>');
+ equivalent('List<~>', 'List<1&>');
+}
- var codeUnitsRule = rti.testingCreateRule();
- rti.testingAddSupertype(codeUnitsRule, 'List', ['int']);
+void testNull() {
+ strictSubtype(nullName, 'int');
+ strictSubtype(nullName, 'Iterable<CodeUnits>');
+ strictSubtype(nullName, objectName);
+ equivalent(nullName, nullName);
+}
- rti.testingAddRule(universe, 'int', intRule);
- rti.testingAddRule(universe, 'List', listRule);
- rti.testingAddRule(universe, 'CodeUnits', codeUnitsRule);
+void testFutureOr() {
+ strictSubtype('$futureName<int>', '$futureName<num>');
+ strictSubtype('int', 'int/');
+ strictSubtype('$futureName<int>', 'int/');
+ strictSubtype('int/', 'num/');
+ strictSubtype('int', 'num/');
+ strictSubtype('$futureName<int>', 'num/');
+ equivalent('@/', '~/');
+}
- var rti1 = rti.testingUniverseEval(universe, 'List<CodeUnits>');
- var rti2 = rti.testingUniverseEval(universe, 'Iterable<List<int>>');
+String reason(String s, String t) => "$s <: $t";
- Expect.isTrue(rti.testingIsSubtype(universe, rti1, rti2));
- Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+void strictSubtype(String s, String t) {
+ var sRti = rti.testingUniverseEval(universe, s);
+ var tRti = rti.testingUniverseEval(universe, t);
+ Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+ Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void unrelated(String s, String t) {
+ var sRti = rti.testingUniverseEval(universe, s);
+ var tRti = rti.testingUniverseEval(universe, t);
+ Expect.isFalse(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+ Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void equivalent(String s, String t) {
+ var sRti = rti.testingUniverseEval(universe, s);
+ var tRti = rti.testingUniverseEval(universe, t);
+ Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+ Expect.isTrue(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
}
diff --git a/tests/compiler/dart2js_extra/type_argument_optimization_test.dart b/tests/compiler/dart2js_extra/type_argument_optimization_test.dart
new file mode 100644
index 0000000..21b41c5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/type_argument_optimization_test.dart
@@ -0,0 +1,121 @@
+// 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 issue 37267.
+
+typedef UpdateShouldNotify<T> = bool Function(T previous, T current);
+
+typedef ValueWidgetBuilder<T> = Widget Function(
+ BuildContext context, T value, Widget child);
+
+class BuildContext {}
+
+class Widget {}
+
+abstract class ProxyWidget extends Widget {
+ final Widget child;
+
+ ProxyWidget({this.child});
+}
+
+abstract class InheritedWidget extends ProxyWidget {
+ InheritedWidget({Widget child}) : super(child: child);
+}
+
+class InheritedProvider<T> extends InheritedWidget {
+ final T _value;
+ final UpdateShouldNotify<T> _updateShouldNotify;
+
+ InheritedProvider(
+ {T value, UpdateShouldNotify<T> updateShouldNotify, Widget child})
+ : _value = value,
+ _updateShouldNotify = updateShouldNotify,
+ super(child: child);
+}
+
+class StateDelegate {}
+
+abstract class ValueStateDelegate<T> extends StateDelegate {
+ T get value;
+}
+
+class ValueStateDelegateImpl<T> implements ValueStateDelegate<T> {
+ final T value;
+
+ ValueStateDelegateImpl(this.value);
+}
+
+class DelegateWidget {
+ final StateDelegate delegate;
+
+ DelegateWidget(this.delegate);
+}
+
+abstract class Listenable {}
+
+abstract class ValueListenable<T> extends Listenable {
+ T get value;
+}
+
+class ValueListenableImpl<T> implements ValueListenable<T> {
+ final T value;
+
+ ValueListenableImpl(this.value);
+}
+
+class ValueDelegateWidget<T> extends DelegateWidget {
+ ValueDelegateWidget(ValueStateDelegate<T> delegate) : super(delegate);
+
+ @pragma('dart2js:tryInline')
+ ValueStateDelegate<T> get delegate => super.delegate as ValueStateDelegate<T>;
+}
+
+class ValueListenableProvider<T>
+ extends ValueDelegateWidget<ValueListenable<T>> {
+ final Widget child;
+
+ final UpdateShouldNotify<T> updateShouldNotify;
+
+ ValueListenableProvider(ValueStateDelegate<ValueListenable<T>> delegate,
+ this.updateShouldNotify, this.child)
+ : super(delegate);
+
+ Widget build() {
+ return ValueListenableBuilder<T>(
+ valueListenable: delegate.value,
+ builder: (_, value, child) {
+ return InheritedProvider<T>(
+ value: value,
+ updateShouldNotify: updateShouldNotify,
+ child: child,
+ );
+ },
+ child: child,
+ );
+ }
+}
+
+class ValueListenableBuilder<T> extends Widget {
+ final ValueListenable<T> valueListenable;
+ final ValueWidgetBuilder<T> builder;
+ final Widget child;
+
+ ValueListenableBuilder({this.valueListenable, this.builder, this.child});
+}
+
+void main() {
+ print(create(42).valueListenable.value);
+ print(create('foo').valueListenable.value);
+}
+
+ValueListenableBuilder<T> create<T>(T value) {
+ ValueListenableImpl<T> valueListenable = new ValueListenableImpl<T>(value);
+ ValueStateDelegateImpl<ValueListenable<T>> valueStateDelegate =
+ new ValueStateDelegateImpl<ValueListenable<T>>(valueListenable);
+ ValueListenableProvider<T> valueListenableProvider =
+ new ValueListenableProvider<T>(valueStateDelegate, null, null);
+ Widget widget = valueListenableProvider.build();
+ print(value);
+ return widget;
+}
diff --git a/tests/compiler/dart2js_extra/typed_locals_test.dart b/tests/compiler/dart2js_extra/typed_locals_test.dart
deleted file mode 100644
index 86ba926..0000000
--- a/tests/compiler/dart2js_extra/typed_locals_test.dart
+++ /dev/null
@@ -1,9 +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.
-
-void main() {
- String s = 3;
- int i = 'hestfisk';
- void v;
-}
diff --git a/tests/compiler/dart2js_extra/unused_local_const_test.dart b/tests/compiler/dart2js_extra/unused_local_const_test.dart
new file mode 100644
index 0000000..acd2076
--- /dev/null
+++ b/tests/compiler/dart2js_extra/unused_local_const_test.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.
+
+// dart2jsOptions=--enable-experiment=constant-update-2018
+
+class A {
+ const A();
+
+ A operator -() => this;
+}
+
+main() {
+ const a = const A();
+ const c = //# 01: compile-time error
+ const bool.fromEnvironment('foo') ? null : -a; //# 01: continued
+}
diff --git a/tests/compiler/dartdevc_native/subtype_test.dart b/tests/compiler/dartdevc_native/subtype_test.dart
new file mode 100644
index 0000000..4a14499
--- /dev/null
+++ b/tests/compiler/dartdevc_native/subtype_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:expect/expect.dart";
+import 'dart:_foreign_helper' show JS;
+import 'dart:_runtime' as dart;
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D<T extends B> {}
+
+// Returns sWrapped<tWrapped> as a wrapped type.
+Object generic1(Type sWrapped, Type tWrapped) {
+ var s = dart.unwrapType(sWrapped);
+ var t = dart.unwrapType(tWrapped);
+ var sGeneric = dart.getGenericClass(s);
+ return dart.wrapType(JS('', '#(#)', sGeneric, t));
+}
+
+void checkSubtype(Type sWrapped, Type tWrapped) {
+ var s = dart.unwrapType(sWrapped);
+ var t = dart.unwrapType(tWrapped);
+ Expect.isTrue(dart.isSubtypeOf(s, t));
+}
+
+void checkProperSubtype(Type sWrapped, Type tWrapped) {
+ var s = dart.unwrapType(sWrapped);
+ var t = dart.unwrapType(tWrapped);
+ Expect.isTrue(dart.isSubtypeOf(s, t));
+ Expect.isFalse(dart.isSubtypeOf(t, s));
+}
+
+void main() {
+ checkProperSubtype(B, A);
+ checkProperSubtype(C, B);
+ checkProperSubtype(C, A);
+
+ checkSubtype(D, generic1(D, B));
+ checkSubtype(generic1(D, B), D);
+ checkProperSubtype(generic1(D, C), generic1(D, B));
+}
diff --git a/tests/corelib_2/bigint_test.dart b/tests/corelib_2/bigint_test.dart
index 89b361b..bffa4c9 100644
--- a/tests/corelib_2/bigint_test.dart
+++ b/tests/corelib_2/bigint_test.dart
@@ -771,11 +771,13 @@
Expect.equals(BigInt.zero, BigInt.zero >> 1234567890);
Expect.equals(BigInt.two.pow(999), BigInt.one << 999);
Expect.equals(BigInt.one, BigInt.two.pow(999) >> 999);
- Expect.equals(BigInt.zero, new BigInt.from(12) >> 0x7FFFFFFFFFFFFFFF);
- Expect.equals(-BigInt.one, -new BigInt.from(12) >> 0x7FFFFFFFFFFFFFFF);
+ // 0x7FFFFFFFFFFFFFFF on VM, slightly rounded up on web platform.
+ const int maxInt64 = 0x7FFFFFFFFFFFF000 + 0xFFF;
+ Expect.equals(BigInt.zero, new BigInt.from(12) >> maxInt64);
+ Expect.equals(-BigInt.one, -new BigInt.from(12) >> maxInt64);
bool exceptionCaught = false;
try {
- var a = BigInt.one << 0x7FFFFFFFFFFFFFFF;
+ var a = BigInt.one << maxInt64;
} on OutOfMemoryError catch (e) {
exceptionCaught = true;
} catch (e) {
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index b196c6f..c58a56d 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -16,33 +16,20 @@
[ $compiler == dart2js ]
bigint_from_test: RuntimeError # Issue 32589
-bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
core_runtime_types_test: RuntimeError # Issue 34147
date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
-date_time_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
double_floor_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
error_stack_trace1_test: RuntimeError # Issue 12399
-growable_list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-growable_list_test: RuntimeError # Concurrent modifications test always runs
-int_ceil_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_ceil_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_parse_radix_int64_test/02: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_parse_radix_test/01: RuntimeError
-int_round_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_round_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_to_int_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
integer_to_radix_string_test/01: RuntimeError
@@ -54,7 +41,6 @@
list_unmodifiable_test: Pass, RuntimeError # Issue 28712
num_parse_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
num_parse_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-num_sign_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
[ $compiler != dartdevc ]
error_stack_trace_test/static: MissingCompileTimeError
@@ -70,11 +56,21 @@
bool_from_environment2_test/03: MissingCompileTimeError
string_from_environment3_test/03: MissingCompileTimeError
-[ $compiler == precompiler ]
-bigint_test: Pass, Timeout # --no_intrinsify
-int_parse_radix_test: Pass, Timeout # --no_intrinsify
-integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
-regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
+[ $compiler == none ]
+int_parse_radix_bad_handler_test: MissingCompileTimeError
+symbol_operator_test/03: Fail # Issue 11669
+symbol_reserved_word_test/02: CompileTimeError # Issue 20191
+symbol_reserved_word_test/04: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/06: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_reserved_word_test/07: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/09: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_reserved_word_test/10: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/12: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_test/01: Fail, Pass # Issue 11669
+symbol_test/02: MissingCompileTimeError # Issue 11669
+symbol_test/03: MissingCompileTimeError # Issue 11669
+symbol_test/none: Fail # Issue 11669
+unicode_test: Fail # Issue 6706
[ $mode == debug ]
regexp/pcre_test: Pass, Slow # Issue 22008
@@ -184,7 +180,6 @@
[ $compiler == dart2js && $minified ]
dynamic_nosuchmethod_test: RuntimeError
error_stack_trace1_test: RuntimeError # Issue 12399
-growable_list_test: RuntimeError # Concurrent modifications test always runs
hash_set_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(_CustomHashSet.#x), local(_CustomHashSet.#)) for j:closure_call(_CustomHashSet__CustomHashSet_closure.call).
integer_to_radix_string_test/01: RuntimeError
integer_to_radix_string_test/02: RuntimeError
@@ -235,9 +230,11 @@
iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
string_base_vm_static_test: MissingCompileTimeError
-[ $compiler == precompiler && $runtime == dart_precompiled && !$checked ]
-iterable_generate_test/01: RuntimeError
-splay_tree_from_iterable_test: RuntimeError
+# We no longer expect Dart2 tests to run with the standalone VM without the new
+# common front end, but for now we get better coverage by still running them in
+# checked mode, which is mostly Dart2-compatible.
+[ $compiler == none && !$checked && ($runtime == dart_precompiled || $runtime == vm) ]
+*: SkipByDesign
[ $mode == release && $hot_reload && ($compiler == dartk || $compiler == dartkb) ]
bigint_parse_radix_test: Crash
@@ -271,12 +268,6 @@
symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
unicode_test: RuntimeError # Issue 18061: German double S.
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign
-
[ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
*: SkipByDesign # Deprecating all Dart1 modes of execution
@@ -290,52 +281,10 @@
[ $arch == simdbc || $arch == simdbc64 ]
regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
-[ $compiler == app_jit || $compiler == none || $compiler == precompiler ]
-int_parse_radix_bad_handler_test: MissingCompileTimeError
-symbol_operator_test/03: Fail # Issue 11669
-symbol_reserved_word_test/02: CompileTimeError # Issue 20191
-symbol_reserved_word_test/04: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/06: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/07: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/09: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/10: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/12: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_test/01: Fail, Pass # Issue 11669
-symbol_test/02: MissingCompileTimeError # Issue 11669
-symbol_test/03: MissingCompileTimeError # Issue 11669
-symbol_test/none: Fail # Issue 11669
-unicode_test: Fail # Issue 6706
-
-[ $compiler == app_jit || $compiler == precompiler ]
-from_environment_const_type_test/02: MissingCompileTimeError
-from_environment_const_type_test/03: MissingCompileTimeError
-from_environment_const_type_test/04: MissingCompileTimeError
-from_environment_const_type_test/06: MissingCompileTimeError
-from_environment_const_type_test/07: MissingCompileTimeError
-from_environment_const_type_test/08: MissingCompileTimeError
-from_environment_const_type_test/09: MissingCompileTimeError
-from_environment_const_type_test/11: MissingCompileTimeError
-from_environment_const_type_test/12: MissingCompileTimeError
-from_environment_const_type_test/13: MissingCompileTimeError
-from_environment_const_type_test/14: MissingCompileTimeError
-from_environment_const_type_test/16: MissingCompileTimeError
-from_environment_const_type_undefined_test/02: MissingCompileTimeError
-from_environment_const_type_undefined_test/03: MissingCompileTimeError
-from_environment_const_type_undefined_test/04: MissingCompileTimeError
-from_environment_const_type_undefined_test/06: MissingCompileTimeError
-from_environment_const_type_undefined_test/07: MissingCompileTimeError
-from_environment_const_type_undefined_test/08: MissingCompileTimeError
-from_environment_const_type_undefined_test/09: MissingCompileTimeError
-from_environment_const_type_undefined_test/11: MissingCompileTimeError
-from_environment_const_type_undefined_test/12: MissingCompileTimeError
-from_environment_const_type_undefined_test/13: MissingCompileTimeError
-from_environment_const_type_undefined_test/14: MissingCompileTimeError
-from_environment_const_type_undefined_test/16: MissingCompileTimeError
-iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
-
[ $compiler == dartdevc || $compiler == dartdevk ]
bigint_from_test: RuntimeError # Issue 32589
-bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+bigint_test/03: SkipSlow # modPow is very slow
+bigint_test/15: SkipSlow # modPow is very slow
bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
compare_to2_test: RuntimeError # Issue 30170
compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -346,12 +295,7 @@
double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
error_stack_trace_test/nullThrown: RuntimeError # .stackTrace not present for exception caught from 'throw null;'
-growable_list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
hash_set_test/01: RuntimeError # Issue 29921
-int_ceil_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_ceil_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_modulo_arith_test/none: RuntimeError # Issue 29921
int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -360,11 +304,6 @@
int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
int_parse_radix_test/01: RuntimeError # Issue 29921
int_parse_with_limited_ints_test: Skip # Requires fixed-size int64 support.
-int_round_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_round_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_to_int_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
integer_arith_vm_test/modPow: RuntimeError # Issue 30170
integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -379,7 +318,6 @@
nan_infinity_test/01: RuntimeError # Issue 29921
num_parse_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
num_parse_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-num_sign_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
regexp/alternative-length-miscalculation_test: RuntimeError # Issue 29921
regexp/ascii-regexp-subject_test: RuntimeError # Issue 29921
regexp/bol-with-multiline_test: RuntimeError # Issue 29921
diff --git a/tests/corelib_2/date_time_extremes_test.dart b/tests/corelib_2/date_time_extremes_test.dart
new file mode 100644
index 0000000..05563d1
--- /dev/null
+++ b/tests/corelib_2/date_time_extremes_test.dart
@@ -0,0 +1,99 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Dart test program for DateTime, extreme values.
+
+bool get supportsMicroseconds =>
+ new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+// Identical to _maxMillisecondsSinceEpoch in date_time.dart
+const int _MAX_MILLISECONDS = 8640000000000000;
+
+void testExtremes() {
+ var dt =
+ new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+ Expect.equals(275760, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(13, dt.day);
+ Expect.equals(0, dt.hour);
+ Expect.equals(0, dt.minute);
+ Expect.equals(0, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+ Expect.equals(-271821, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(20, dt.day);
+ Expect.equals(0, dt.hour);
+ Expect.equals(0, dt.minute);
+ Expect.equals(0, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+ // Make sure that we can build the extreme dates in local too.
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(-_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
+ Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
+ _MAX_MILLISECONDS + 1,
+ isUtc: true));
+ Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
+ -_MAX_MILLISECONDS - 1,
+ isUtc: true));
+ Expect.throws(
+ () => new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS + 1));
+ Expect.throws(
+ () => new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS - 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+ Expect.throws(
+ () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() =>
+ new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+ Expect.throws(
+ () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() =>
+ new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
+
+ if (!supportsMicroseconds) return;
+
+ dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
+ dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+ Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ _MAX_MILLISECONDS * 1000 + 1,
+ isUtc: true));
+ Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+ -_MAX_MILLISECONDS * 1000 - 1,
+ isUtc: true));
+ Expect.throws(() =>
+ new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000 + 1));
+ Expect.throws(() =>
+ new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000 - 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+ Expect.throws(() =>
+ new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() =>
+ new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+ Expect.throws(() =>
+ new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
+ dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+ Expect.throws(() => new DateTime.utc(
+ dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
+}
+
+void main() {
+ testExtremes();
+}
diff --git a/tests/corelib_2/date_time_far_away_dates_test.dart b/tests/corelib_2/date_time_far_away_dates_test.dart
new file mode 100644
index 0000000..ba7104f
--- /dev/null
+++ b/tests/corelib_2/date_time_far_away_dates_test.dart
@@ -0,0 +1,107 @@
+// 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";
+
+// Dart test program for DateTime, far away dates.
+
+// TODO(37442): Find far-away dates with milliseconds-since-epoch values that
+// are 'web' integers.
+
+bool get supportsMicroseconds =>
+ new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+void testFarAwayDates() {
+ DateTime dt =
+ new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(27, dt.day);
+ Expect.equals(1, dt.hour);
+ Expect.equals(46, dt.minute);
+ Expect.equals(40, dt.second);
+ Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+ dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(5, dt.day);
+ Expect.equals(22, dt.hour);
+ Expect.equals(13, dt.minute);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+ // Same with local zone.
+ dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(true, dt.day == 27 || dt.day == 26);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 46 % 15);
+ Expect.equals(40, dt.second);
+ Expect.equals(1, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+ dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(true, 5 == dt.day || 6 == dt.day);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 13);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(0, dt.microsecond);
+
+ if (!supportsMicroseconds) return;
+ dt =
+ new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(27, dt.day);
+ Expect.equals(1, dt.hour);
+ Expect.equals(46, dt.minute);
+ Expect.equals(40, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001,
+ isUtc: true);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(5, dt.day);
+ Expect.equals(22, dt.hour);
+ Expect.equals(13, dt.minute);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(999, dt.microsecond);
+ // Same with local zone.
+ dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
+ Expect.equals(33658, dt.year);
+ Expect.equals(9, dt.month);
+ Expect.equals(true, dt.day == 27 || dt.day == 26);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 46 % 15);
+ Expect.equals(40, dt.second);
+ Expect.equals(0, dt.millisecond);
+ Expect.equals(1, dt.microsecond);
+ dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
+ Expect.equals(-29719, dt.year);
+ Expect.equals(4, dt.month);
+ Expect.equals(true, 5 == dt.day || 6 == dt.day);
+ // Not much we can test for local hour.
+ Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+ // Timezones can have offsets down to 15 minute.
+ Expect.equals(true, dt.minute % 15 == 13);
+ Expect.equals(19, dt.second);
+ Expect.equals(999, dt.millisecond);
+ Expect.equals(999, dt.microsecond);
+}
+
+void main() {
+ testFarAwayDates();
+}
diff --git a/tests/corelib_2/date_time_test.dart b/tests/corelib_2/date_time_test.dart
index 07a920d..e782ca5 100644
--- a/tests/corelib_2/date_time_test.dart
+++ b/tests/corelib_2/date_time_test.dart
@@ -49,96 +49,6 @@
Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
}
-void testFarAwayDates() {
- DateTime dt =
- new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
- Expect.equals(33658, dt.year);
- Expect.equals(9, dt.month);
- Expect.equals(27, dt.day);
- Expect.equals(1, dt.hour);
- Expect.equals(46, dt.minute);
- Expect.equals(40, dt.second);
- Expect.equals(1, dt.millisecond);
- Expect.equals(0, dt.microsecond);
- dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
- Expect.equals(-29719, dt.year);
- Expect.equals(4, dt.month);
- Expect.equals(5, dt.day);
- Expect.equals(22, dt.hour);
- Expect.equals(13, dt.minute);
- Expect.equals(19, dt.second);
- Expect.equals(999, dt.millisecond);
- Expect.equals(0, dt.microsecond);
- // Same with local zone.
- dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
- Expect.equals(33658, dt.year);
- Expect.equals(9, dt.month);
- Expect.equals(true, dt.day == 27 || dt.day == 26);
- // Not much we can test for local hour.
- Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
- // Timezones can have offsets down to 15 minute.
- Expect.equals(true, dt.minute % 15 == 46 % 15);
- Expect.equals(40, dt.second);
- Expect.equals(1, dt.millisecond);
- Expect.equals(0, dt.microsecond);
- dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
- Expect.equals(-29719, dt.year);
- Expect.equals(4, dt.month);
- Expect.equals(true, 5 == dt.day || 6 == dt.day);
- // Not much we can test for local hour.
- Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
- // Timezones can have offsets down to 15 minute.
- Expect.equals(true, dt.minute % 15 == 13);
- Expect.equals(19, dt.second);
- Expect.equals(999, dt.millisecond);
- Expect.equals(0, dt.microsecond);
-
- if (!supportsMicroseconds) return;
- dt =
- new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
- Expect.equals(33658, dt.year);
- Expect.equals(9, dt.month);
- Expect.equals(27, dt.day);
- Expect.equals(1, dt.hour);
- Expect.equals(46, dt.minute);
- Expect.equals(40, dt.second);
- Expect.equals(0, dt.millisecond);
- Expect.equals(1, dt.microsecond);
- dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001,
- isUtc: true);
- Expect.equals(-29719, dt.year);
- Expect.equals(4, dt.month);
- Expect.equals(5, dt.day);
- Expect.equals(22, dt.hour);
- Expect.equals(13, dt.minute);
- Expect.equals(19, dt.second);
- Expect.equals(999, dt.millisecond);
- Expect.equals(999, dt.microsecond);
- // Same with local zone.
- dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
- Expect.equals(33658, dt.year);
- Expect.equals(9, dt.month);
- Expect.equals(true, dt.day == 27 || dt.day == 26);
- // Not much we can test for local hour.
- Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
- // Timezones can have offsets down to 15 minute.
- Expect.equals(true, dt.minute % 15 == 46 % 15);
- Expect.equals(40, dt.second);
- Expect.equals(0, dt.millisecond);
- Expect.equals(1, dt.microsecond);
- dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
- Expect.equals(-29719, dt.year);
- Expect.equals(4, dt.month);
- Expect.equals(true, 5 == dt.day || 6 == dt.day);
- // Not much we can test for local hour.
- Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
- // Timezones can have offsets down to 15 minute.
- Expect.equals(true, dt.minute % 15 == 13);
- Expect.equals(19, dt.second);
- Expect.equals(999, dt.millisecond);
- Expect.equals(999, dt.microsecond);
-}
-
void testEquivalentYears() {
// All hardcoded values come from V8. This means that the values are not
// necessarily correct (see limitations of DateTime object in
@@ -363,88 +273,6 @@
Expect.equals(0, dt.microsecond);
}
-void testExtremes() {
- var dt =
- new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
- Expect.equals(275760, dt.year);
- Expect.equals(9, dt.month);
- Expect.equals(13, dt.day);
- Expect.equals(0, dt.hour);
- Expect.equals(0, dt.minute);
- Expect.equals(0, dt.second);
- Expect.equals(0, dt.millisecond);
- Expect.equals(0, dt.microsecond);
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
- Expect.equals(-271821, dt.year);
- Expect.equals(4, dt.month);
- Expect.equals(20, dt.day);
- Expect.equals(0, dt.hour);
- Expect.equals(0, dt.minute);
- Expect.equals(0, dt.second);
- Expect.equals(0, dt.millisecond);
- Expect.equals(0, dt.microsecond);
- // Make sure that we can build the extreme dates in local too.
- dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
- dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
- Expect.equals(_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
- dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
- Expect.equals(-_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
- Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
- _MAX_MILLISECONDS + 1,
- isUtc: true));
- Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
- -_MAX_MILLISECONDS - 1,
- isUtc: true));
- Expect.throws(
- () => new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS + 1));
- Expect.throws(
- () => new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS - 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
- Expect.throws(
- () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
- Expect.throws(() =>
- new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
- Expect.throws(
- () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
- Expect.throws(() =>
- new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
-
- if (!supportsMicroseconds) return;
-
- dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
- dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
- Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
- dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
- dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
- Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
- Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
- _MAX_MILLISECONDS * 1000 + 1,
- isUtc: true));
- Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
- -_MAX_MILLISECONDS * 1000 - 1,
- isUtc: true));
- Expect.throws(() =>
- new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000 + 1));
- Expect.throws(() =>
- new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000 - 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
- Expect.throws(() =>
- new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
- Expect.throws(() =>
- new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
- Expect.throws(() =>
- new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
- dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
- Expect.throws(() => new DateTime.utc(
- dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
-}
-
void testUTCGetters() {
var dt = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
Expect.equals(2011, dt.year);
@@ -1372,8 +1200,6 @@
testUnderflowAndOverflow();
testDateStrings();
testEquivalentYears();
- testExtremes();
- testFarAwayDates();
testWeekday();
testToStrings();
testIsoString();
diff --git a/tests/corelib_2/growable_list_test.dart b/tests/corelib_2/growable_list_test.dart
index 8c3443ae..2172710 100644
--- a/tests/corelib_2/growable_list_test.dart
+++ b/tests/corelib_2/growable_list_test.dart
@@ -90,8 +90,8 @@
testGrowable(new List<int>()..length = 5);
testGrowable(new List<int>.filled(5, null, growable: true));
Expect.throwsArgumentError(() => new List<int>(-1), "-1");
- // There must be limits. Fix this test if we ever allow 10^30 elements.
- Expect.throwsArgumentError(() => new List<int>(0x7fffffffffffffff), "bignum");
+ // There must be limits. Fix this test if we ever allow 2^63 elements.
+ Expect.throwsArgumentError(() => new List<int>(0x7ffffffffffff000), "bignum");
Expect.throwsArgumentError(() => new List<int>(null), "null");
testThrowsOrTypeError(
() => new List([] as Object), // Cast to avoid warning.
diff --git a/tests/corelib_2/int_ceil_test.dart b/tests/corelib_2/int_ceil_test.dart
index 9b50dbd..731e15a 100644
--- a/tests/corelib_2/int_ceil_test.dart
+++ b/tests/corelib_2/int_ceil_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0, 0.ceil());
Expect.equals(1, 1.ceil());
Expect.equals(0x1234, 0x1234.ceil());
Expect.equals(0x12345678, 0x12345678.ceil());
Expect.equals(0x123456789AB, 0x123456789AB.ceil());
- Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.ceil());
- Expect.equals(-1, -1.ceil());
- Expect.equals(-0x1234, -0x1234.ceil());
- Expect.equals(-0x12345678, -0x12345678.ceil());
- Expect.equals(-0x123456789AB, -0x123456789AB.ceil());
- Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.ceil());
+ Expect.equals(big, big.ceil());
+ Expect.equals(-1, (-1).ceil());
+ Expect.equals(-0x1234, (-0x1234).ceil());
+ Expect.equals(-0x12345678, (-0x12345678).ceil());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).ceil());
+ Expect.equals(-big, (-big).ceil());
Expect.isTrue(0.ceil() is int);
Expect.isTrue(1.ceil() is int);
Expect.isTrue(0x1234.ceil() is int);
Expect.isTrue(0x12345678.ceil() is int);
Expect.isTrue(0x123456789AB.ceil() is int);
- Expect.isTrue(0x123456789ABCDEF.ceil() is int);
- Expect.isTrue(-1.ceil() is int);
- Expect.isTrue(-0x1234.ceil() is int);
- Expect.isTrue(-0x12345678.ceil() is int);
- Expect.isTrue(-0x123456789AB.ceil() is int);
- Expect.isTrue(-0x123456789ABCDEF.ceil() is int);
+ Expect.isTrue(big.ceil() is int);
+ Expect.isTrue((-1).ceil() is int);
+ Expect.isTrue((-0x1234).ceil() is int);
+ Expect.isTrue((-0x12345678).ceil() is int);
+ Expect.isTrue((-0x123456789AB).ceil() is int);
+ Expect.isTrue((-big).ceil() is int);
}
diff --git a/tests/corelib_2/int_ceil_to_double_test.dart b/tests/corelib_2/int_ceil_to_double_test.dart
index e31d298..0a35acb 100644
--- a/tests/corelib_2/int_ceil_to_double_test.dart
+++ b/tests/corelib_2/int_ceil_to_double_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0.0, 0.ceilToDouble());
Expect.equals(1.0, 1.ceilToDouble());
Expect.equals(0x1234, 0x1234.ceilToDouble());
Expect.equals(0x12345678, 0x12345678.ceilToDouble());
Expect.equals(0x123456789AB, 0x123456789AB.ceilToDouble());
- Expect.equals(81985529216486900.0, 0x123456789ABCDEF.ceilToDouble());
- Expect.equals(-1.0, -1.ceilToDouble());
- Expect.equals(-0x1234, -0x1234.ceilToDouble());
- Expect.equals(-0x12345678, -0x12345678.ceilToDouble());
- Expect.equals(-0x123456789AB, -0x123456789AB.ceilToDouble());
- Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.ceilToDouble());
+ Expect.equals(81985529216486900.0, big.ceilToDouble());
+ Expect.equals(-1.0, (-1).ceilToDouble());
+ Expect.equals(-0x1234, (-0x1234).ceilToDouble());
+ Expect.equals(-0x12345678, (-0x12345678).ceilToDouble());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).ceilToDouble());
+ Expect.equals(-81985529216486900.0, (-big).ceilToDouble());
Expect.isTrue(0.ceilToDouble() is double);
Expect.isTrue(1.ceilToDouble() is double);
Expect.isTrue(0x1234.ceilToDouble() is double);
Expect.isTrue(0x12345678.ceilToDouble() is double);
Expect.isTrue(0x123456789AB.ceilToDouble() is double);
- Expect.isTrue(0x123456789ABCDEF.ceilToDouble() is double);
- Expect.isTrue(-1.ceilToDouble() is double);
- Expect.isTrue(-0x1234.ceilToDouble() is double);
- Expect.isTrue(-0x12345678.ceilToDouble() is double);
- Expect.isTrue(-0x123456789AB.ceilToDouble() is double);
- Expect.isTrue(-0x123456789ABCDEF.ceilToDouble() is double);
+ Expect.isTrue(big.ceilToDouble() is double);
+ Expect.isTrue((-1).ceilToDouble() is double);
+ Expect.isTrue((-0x1234).ceilToDouble() is double);
+ Expect.isTrue((-0x12345678).ceilToDouble() is double);
+ Expect.isTrue((-0x123456789AB).ceilToDouble() is double);
+ Expect.isTrue((-big).ceilToDouble() is double);
}
diff --git a/tests/corelib_2/int_floor_test.dart b/tests/corelib_2/int_floor_test.dart
index 6588824..e85d5df 100644
--- a/tests/corelib_2/int_floor_test.dart
+++ b/tests/corelib_2/int_floor_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0, 0.floor());
Expect.equals(1, 1.floor());
Expect.equals(0x1234, 0x1234.floor());
Expect.equals(0x12345678, 0x12345678.floor());
Expect.equals(0x123456789AB, 0x123456789AB.floor());
- Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.floor());
- Expect.equals(-1, -1.floor());
- Expect.equals(-0x1234, -0x1234.floor());
- Expect.equals(-0x12345678, -0x12345678.floor());
- Expect.equals(-0x123456789AB, -0x123456789AB.floor());
- Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.floor());
+ Expect.equals(big, big.floor());
+ Expect.equals(-1, (-1).floor());
+ Expect.equals(-0x1234, (-0x1234).floor());
+ Expect.equals(-0x12345678, (-0x12345678).floor());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).floor());
+ Expect.equals(-big, (-big).floor());
Expect.isTrue(0.floor() is int);
Expect.isTrue(1.floor() is int);
Expect.isTrue(0x1234.floor() is int);
Expect.isTrue(0x12345678.floor() is int);
Expect.isTrue(0x123456789AB.floor() is int);
- Expect.isTrue(0x123456789ABCDEF.floor() is int);
- Expect.isTrue(-1.floor() is int);
- Expect.isTrue(-0x1234.floor() is int);
- Expect.isTrue(-0x12345678.floor() is int);
- Expect.isTrue(-0x123456789AB.floor() is int);
- Expect.isTrue(-0x123456789ABCDEF.floor() is int);
+ Expect.isTrue(big.floor() is int);
+ Expect.isTrue((-1).floor() is int);
+ Expect.isTrue((-0x1234).floor() is int);
+ Expect.isTrue((-0x12345678).floor() is int);
+ Expect.isTrue((-0x123456789AB).floor() is int);
+ Expect.isTrue((-big).floor() is int);
}
diff --git a/tests/corelib_2/int_floor_to_double_test.dart b/tests/corelib_2/int_floor_to_double_test.dart
index 7510849..659b295 100644
--- a/tests/corelib_2/int_floor_to_double_test.dart
+++ b/tests/corelib_2/int_floor_to_double_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0.0, 0.floorToDouble());
Expect.equals(1.0, 1.floorToDouble());
Expect.equals(0x1234, 0x1234.floorToDouble());
Expect.equals(0x12345678, 0x12345678.floorToDouble());
Expect.equals(0x123456789AB, 0x123456789AB.floorToDouble());
- Expect.equals(81985529216486900.0, 0x123456789ABCDEF.floorToDouble());
- Expect.equals(-1.0, -1.floorToDouble());
- Expect.equals(-0x1234, -0x1234.floorToDouble());
- Expect.equals(-0x12345678, -0x12345678.floorToDouble());
- Expect.equals(-0x123456789AB, -0x123456789AB.floorToDouble());
- Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.floorToDouble());
+ Expect.equals(81985529216486900.0, big.floorToDouble());
+ Expect.equals(-1.0, (-1).floorToDouble());
+ Expect.equals(-0x1234, (-0x1234).floorToDouble());
+ Expect.equals(-0x12345678, (-0x12345678).floorToDouble());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).floorToDouble());
+ Expect.equals(-81985529216486900.0, (-big).floorToDouble());
Expect.isTrue(0.floorToDouble() is double);
Expect.isTrue(1.floorToDouble() is double);
Expect.isTrue(0x1234.floorToDouble() is double);
Expect.isTrue(0x12345678.floorToDouble() is double);
Expect.isTrue(0x123456789AB.floorToDouble() is double);
- Expect.isTrue(0x123456789ABCDEF.floorToDouble() is double);
- Expect.isTrue(-1.floorToDouble() is double);
- Expect.isTrue(-0x1234.floorToDouble() is double);
- Expect.isTrue(-0x12345678.floorToDouble() is double);
- Expect.isTrue(-0x123456789AB.floorToDouble() is double);
- Expect.isTrue(-0x123456789ABCDEF.floorToDouble() is double);
+ Expect.isTrue(big.floorToDouble() is double);
+ Expect.isTrue((-1).floorToDouble() is double);
+ Expect.isTrue((-0x1234).floorToDouble() is double);
+ Expect.isTrue((-0x12345678).floorToDouble() is double);
+ Expect.isTrue((-0x123456789AB).floorToDouble() is double);
+ Expect.isTrue((-big).floorToDouble() is double);
}
diff --git a/tests/corelib_2/int_round_test.dart b/tests/corelib_2/int_round_test.dart
index 21b1f7c..3e9a8ae 100644
--- a/tests/corelib_2/int_round_test.dart
+++ b/tests/corelib_2/int_round_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // truncating arithmetic on web.
+
Expect.equals(0, 0.round());
Expect.equals(1, 1.round());
Expect.equals(0x1234, 0x1234.round());
Expect.equals(0x12345678, 0x12345678.round());
Expect.equals(0x123456789AB, 0x123456789AB.round());
- Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.round());
- Expect.equals(-1, -1.round());
- Expect.equals(-0x1234, -0x1234.round());
- Expect.equals(-0x12345678, -0x12345678.round());
- Expect.equals(-0x123456789AB, -0x123456789AB.round());
- Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.round());
+ Expect.equals(big, big.round());
+ Expect.equals(-1, (-1).round());
+ Expect.equals(-0x1234, (-0x1234).round());
+ Expect.equals(-0x12345678, (-0x12345678).round());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).round());
+ Expect.equals(-big, (-big).round());
Expect.isTrue(0.round() is int);
Expect.isTrue(1.round() is int);
Expect.isTrue(0x1234.round() is int);
Expect.isTrue(0x12345678.round() is int);
Expect.isTrue(0x123456789AB.round() is int);
- Expect.isTrue(0x123456789ABCDEF.round() is int);
- Expect.isTrue(-1.round() is int);
- Expect.isTrue(-0x1234.round() is int);
- Expect.isTrue(-0x12345678.round() is int);
- Expect.isTrue(-0x123456789AB.round() is int);
- Expect.isTrue(-0x123456789ABCDEF.round() is int);
+ Expect.isTrue(big.round() is int);
+ Expect.isTrue((-1).round() is int);
+ Expect.isTrue((-0x1234).round() is int);
+ Expect.isTrue((-0x12345678).round() is int);
+ Expect.isTrue((-0x123456789AB).round() is int);
+ Expect.isTrue((-big).round() is int);
}
diff --git a/tests/corelib_2/int_round_to_double_test.dart b/tests/corelib_2/int_round_to_double_test.dart
index fdc6c94..b49cd94 100644
--- a/tests/corelib_2/int_round_to_double_test.dart
+++ b/tests/corelib_2/int_round_to_double_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0.0, 0.roundToDouble());
Expect.equals(1.0, 1.roundToDouble());
Expect.equals(0x1234, 0x1234.roundToDouble());
Expect.equals(0x12345678, 0x12345678.roundToDouble());
Expect.equals(0x123456789AB, 0x123456789AB.roundToDouble());
- Expect.equals(81985529216486900.0, 0x123456789ABCDEF.roundToDouble());
- Expect.equals(-1.0, -1.roundToDouble());
- Expect.equals(-0x1234, -0x1234.roundToDouble());
- Expect.equals(-0x12345678, -0x12345678.roundToDouble());
- Expect.equals(-0x123456789AB, -0x123456789AB.roundToDouble());
- Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.roundToDouble());
+ Expect.equals(81985529216486900.0, big.roundToDouble());
+ Expect.equals(-1.0, (-1).roundToDouble());
+ Expect.equals(-0x1234, (-0x1234).roundToDouble());
+ Expect.equals(-0x12345678, (-0x12345678).roundToDouble());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).roundToDouble());
+ Expect.equals(-81985529216486900.0, (-big).roundToDouble());
Expect.isTrue(0.roundToDouble() is double);
Expect.isTrue(1.roundToDouble() is double);
Expect.isTrue(0x1234.roundToDouble() is double);
Expect.isTrue(0x12345678.roundToDouble() is double);
Expect.isTrue(0x123456789AB.roundToDouble() is double);
- Expect.isTrue(0x123456789ABCDEF.roundToDouble() is double);
- Expect.isTrue(-1.roundToDouble() is double);
- Expect.isTrue(-0x1234.roundToDouble() is double);
- Expect.isTrue(-0x12345678.roundToDouble() is double);
- Expect.isTrue(-0x123456789AB.roundToDouble() is double);
- Expect.isTrue(-0x123456789ABCDEF.roundToDouble() is double);
+ Expect.isTrue(big.roundToDouble() is double);
+ Expect.isTrue((-1).roundToDouble() is double);
+ Expect.isTrue((-0x1234).roundToDouble() is double);
+ Expect.isTrue((-0x12345678).roundToDouble() is double);
+ Expect.isTrue((-0x123456789AB).roundToDouble() is double);
+ Expect.isTrue((-big).roundToDouble() is double);
}
diff --git a/tests/corelib_2/int_to_int_test.dart b/tests/corelib_2/int_to_int_test.dart
index ea3de36..065d357 100644
--- a/tests/corelib_2/int_to_int_test.dart
+++ b/tests/corelib_2/int_to_int_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0, 0.toInt());
Expect.equals(1, 1.toInt());
Expect.equals(0x1234, 0x1234.toInt());
Expect.equals(0x12345678, 0x12345678.toInt());
Expect.equals(0x123456789AB, 0x123456789AB.toInt());
- Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.toInt());
- Expect.equals(-1, -1.toInt());
- Expect.equals(-0x1234, -0x1234.toInt());
- Expect.equals(-0x12345678, -0x12345678.toInt());
- Expect.equals(-0x123456789AB, -0x123456789AB.toInt());
- Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.toInt());
+ Expect.equals(big, big.toInt());
+ Expect.equals(-1, (-1).toInt());
+ Expect.equals(-0x1234, (-0x1234).toInt());
+ Expect.equals(-0x12345678, (-0x12345678).toInt());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).toInt());
+ Expect.equals(-big, (-big).toInt());
Expect.isTrue(0.toInt() is int);
Expect.isTrue(1.toInt() is int);
Expect.isTrue(0x1234.toInt() is int);
Expect.isTrue(0x12345678.toInt() is int);
Expect.isTrue(0x123456789AB.toInt() is int);
- Expect.isTrue(0x123456789ABCDEF.toInt() is int);
- Expect.isTrue(-1.toInt() is int);
- Expect.isTrue(-0x1234.toInt() is int);
- Expect.isTrue(-0x12345678.toInt() is int);
- Expect.isTrue(-0x123456789AB.toInt() is int);
- Expect.isTrue(-0x123456789ABCDEF.toInt() is int);
+ Expect.isTrue(big.toInt() is int);
+ Expect.isTrue((-1).toInt() is int);
+ Expect.isTrue((-0x1234).toInt() is int);
+ Expect.isTrue((-0x12345678).toInt() is int);
+ Expect.isTrue((-0x123456789AB).toInt() is int);
+ Expect.isTrue((-big).toInt() is int);
}
diff --git a/tests/corelib_2/int_truncate_test.dart b/tests/corelib_2/int_truncate_test.dart
index 605241d..f26a856 100644
--- a/tests/corelib_2/int_truncate_test.dart
+++ b/tests/corelib_2/int_truncate_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0, 0.truncate());
Expect.equals(1, 1.truncate());
Expect.equals(0x1234, 0x1234.truncate());
Expect.equals(0x12345678, 0x12345678.truncate());
Expect.equals(0x123456789AB, 0x123456789AB.truncate());
- Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.truncate());
- Expect.equals(-1, -1.truncate());
- Expect.equals(-0x1234, -0x1234.truncate());
- Expect.equals(-0x12345678, -0x12345678.truncate());
- Expect.equals(-0x123456789AB, -0x123456789AB.truncate());
- Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.truncate());
+ Expect.equals(big, big.truncate());
+ Expect.equals(-1, (-1).truncate());
+ Expect.equals(-0x1234, (-0x1234).truncate());
+ Expect.equals(-0x12345678, (-0x12345678).truncate());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).truncate());
+ Expect.equals(-big, (-big).truncate());
Expect.isTrue(0.truncate() is int);
Expect.isTrue(1.truncate() is int);
Expect.isTrue(0x1234.truncate() is int);
Expect.isTrue(0x12345678.truncate() is int);
Expect.isTrue(0x123456789AB.truncate() is int);
- Expect.isTrue(0x123456789ABCDEF.truncate() is int);
- Expect.isTrue(-1.truncate() is int);
- Expect.isTrue(-0x1234.truncate() is int);
- Expect.isTrue(-0x12345678.truncate() is int);
- Expect.isTrue(-0x123456789AB.truncate() is int);
- Expect.isTrue(-0x123456789ABCDEF.truncate() is int);
+ Expect.isTrue(big.truncate() is int);
+ Expect.isTrue((-1).truncate() is int);
+ Expect.isTrue((-0x1234).truncate() is int);
+ Expect.isTrue((-0x12345678).truncate() is int);
+ Expect.isTrue((-0x123456789AB).truncate() is int);
+ Expect.isTrue((-big).truncate() is int);
}
diff --git a/tests/corelib_2/int_truncate_to_double_test.dart b/tests/corelib_2/int_truncate_to_double_test.dart
index c2b7cc7..20b27d3 100644
--- a/tests/corelib_2/int_truncate_to_double_test.dart
+++ b/tests/corelib_2/int_truncate_to_double_test.dart
@@ -5,27 +5,29 @@
import 'package:expect/expect.dart';
main() {
+ const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
Expect.equals(0.0, 0.truncateToDouble());
Expect.equals(1.0, 1.truncateToDouble());
Expect.equals(0x1234, 0x1234.truncateToDouble());
Expect.equals(0x12345678, 0x12345678.truncateToDouble());
Expect.equals(0x123456789AB, 0x123456789AB.truncateToDouble());
- Expect.equals(81985529216486900.0, 0x123456789ABCDEF.truncateToDouble());
- Expect.equals(-1.0, -1.truncateToDouble());
- Expect.equals(-0x1234, -0x1234.truncateToDouble());
- Expect.equals(-0x12345678, -0x12345678.truncateToDouble());
- Expect.equals(-0x123456789AB, -0x123456789AB.truncateToDouble());
- Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.truncateToDouble());
+ Expect.equals(81985529216486900.0, big.truncateToDouble());
+ Expect.equals(-1.0, (-1).truncateToDouble());
+ Expect.equals(-0x1234, (-0x1234).truncateToDouble());
+ Expect.equals(-0x12345678, (-0x12345678).truncateToDouble());
+ Expect.equals(-0x123456789AB, (-0x123456789AB).truncateToDouble());
+ Expect.equals(-81985529216486900.0, (-big).truncateToDouble());
Expect.isTrue(0.truncateToDouble() is double);
Expect.isTrue(1.truncateToDouble() is double);
Expect.isTrue(0x1234.truncateToDouble() is double);
Expect.isTrue(0x12345678.truncateToDouble() is double);
Expect.isTrue(0x123456789AB.truncateToDouble() is double);
- Expect.isTrue(0x123456789ABCDEF.truncateToDouble() is double);
- Expect.isTrue(-1.truncateToDouble() is double);
- Expect.isTrue(-0x1234.truncateToDouble() is double);
- Expect.isTrue(-0x12345678.truncateToDouble() is double);
- Expect.isTrue(-0x123456789AB.truncateToDouble() is double);
- Expect.isTrue(-0x123456789ABCDEF.truncateToDouble() is double);
+ Expect.isTrue(big.truncateToDouble() is double);
+ Expect.isTrue((-1).truncateToDouble() is double);
+ Expect.isTrue((-0x1234).truncateToDouble() is double);
+ Expect.isTrue((-0x12345678).truncateToDouble() is double);
+ Expect.isTrue((-0x123456789AB).truncateToDouble() is double);
+ Expect.isTrue((-big).truncateToDouble() is double);
}
diff --git a/tests/corelib_2/num_sign_test.dart b/tests/corelib_2/num_sign_test.dart
index d7913bb..db5f497 100644
--- a/tests/corelib_2/num_sign_test.dart
+++ b/tests/corelib_2/num_sign_test.dart
@@ -25,51 +25,54 @@
0,
1,
2,
- 0x7f, // ~7 bits
+ 0x7f, // ~7 bits
0x80,
- 0xff, // ~8 bits
+ 0xff, // ~8 bits
0x100,
- 0xffff, // ~16 bits
+ 0xffff, // ~16 bits
0x10000,
- 0x3fffffff, // ~30 bits (max positive 32-bit tagged smi)
+ 0x3fffffff, // ~30 bits (max positive 32-bit tagged smi)
0x40000000,
0x40000001,
- 0x7fffffff, // ~31 bits
+ 0x7fffffff, // ~31 bits
0x80000000,
0x80000001,
- 0xfffffffff, // ~32 bits
+ 0xfffffffff, // ~32 bits
0x100000000,
0x100000001,
- 0x10000000000000, // ~53 bits
+ 0x10000000000000, // ~53 bits
0x10000000000001,
0x1fffffffffffff,
0x20000000000000,
- 0x20000000000001, // first integer not representable as double.
- 0x20000000000002,
- 0x7fffffffffffffff, // ~63 bits
+ // Use arithmetic to construct values below since they are not valid 'web
+ // integers'. On platforms that use doubles to represent integers, there will
+ // be some rounding in the arithmetic, testing a nearby value instead.
+ 0x20000000000000 + 1, // first integer not representable as double.
+ 0x20000000000000 + 2,
+ 0x7ffffffffffff000 + 0xfff, // ~63 bits
0x8000000000000000,
- 0x8000000000000001,
- 0xffffffffffffffff, // ~64 bits
+ 0x8000000000000000 + 1,
+ 0xfffffffffffff000 + 0xfff, // ~64 bits
// Doubles.
0.0,
- 5e-324, // min positive
- 2.225073858507201e-308, // max denormal
- 2.2250738585072014e-308, // min normal
- 0.49999999999999994, // ~0.5
+ 5e-324, // min positive
+ 2.225073858507201e-308, // max denormal
+ 2.2250738585072014e-308, // min normal
+ 0.49999999999999994, // ~0.5
0.5,
0.5000000000000001,
- 0.9999999999999999, // ~1.0
+ 0.9999999999999999, // ~1.0
1.0,
1.0000000000000002,
- 4294967295.0, // ~32 bits
+ 4294967295.0, // ~32 bits
4294967296.0,
- 4503599627370495.5, // max fractional
+ 4503599627370495.5, // max fractional
4503599627370497.0,
9007199254740991.0,
- 9007199254740992.0, // max exact (+1 is not a double)
- 1.7976931348623157e+308, // max finite double
- 1.0 / 0.0, // Infinity
- 0.0 / 0.0, // NaN
+ 9007199254740992.0, // max exact (+1 is not a double)
+ 1.7976931348623157e+308, // max finite double
+ 1.0 / 0.0, // Infinity
+ 0.0 / 0.0, // NaN
];
main() {
diff --git a/tests/ffi/aliasing_test.dart b/tests/ffi/aliasing_test.dart
new file mode 100644
index 0000000..34a32fe
--- /dev/null
+++ b/tests/ffi/aliasing_test.dart
@@ -0,0 +1,218 @@
+// 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 programing for testing that optimizations do wrongly assume loads
+// from and stores to C memory are not aliased.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=--deterministic --optimization-counter-threshold=50 --enable-inlining-annotations
+
+library FfiTest;
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() {
+ for (int i = 0; i < 100; ++i) {
+ testNonAlias();
+ testAliasCast();
+ testAliasCast2();
+ testAliasOffsetBy();
+ testAliasOffsetBy2();
+ testAliasElementAt();
+ testAliasElementAt2();
+ testAliasFromAddress();
+ testAliasFromAddress2();
+ testAliasFromAddressViaMemory();
+ testAliasFromAddressViaMemory2();
+ testAliasFromAddressViaNativeFunction();
+ testAliasFromAddressViaNativeFunction2();
+ testPartialOverlap();
+ }
+}
+
+void testNonAlias() {
+ final source = Pointer<Int64>.allocate();
+ source.store(42);
+ final int a = source.load();
+ source.store(1984);
+ // alias.load() should be re-executed, as we wrote to alias.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasCast() {
+ final source = Pointer<Int64>.allocate();
+ final alias = source.cast<Int8>().cast<Int64>();
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasCast2() {
+ final source = Pointer<Int64>.allocate();
+ final alias = source.cast<Int16>().cast<Int64>();
+ final alias2 = source.cast<Int8>().cast<Int64>();
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ source.free();
+}
+
+void testAliasOffsetBy() {
+ final source = Pointer<Int64>.allocate(count: 2);
+ final alias = source.offsetBy(8).offsetBy(-8);
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasOffsetBy2() {
+ final source = Pointer<Int64>.allocate(count: 3);
+ final alias = source.offsetBy(16).offsetBy(-16);
+ final alias2 = source.offsetBy(8).offsetBy(-8);
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ source.free();
+}
+
+void testAliasElementAt() {
+ final source = Pointer<Int64>.allocate(count: 2);
+ final alias = source.elementAt(1).elementAt(-1);
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasElementAt2() {
+ final source = Pointer<Int64>.allocate(count: 3);
+ final alias = source.elementAt(2).elementAt(-2);
+ final alias2 = source.elementAt(1).elementAt(-1);
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ source.free();
+}
+
+void testAliasFromAddress() {
+ final source = Pointer<Int64>.allocate();
+ final alias = Pointer<Int64>.fromAddress(source.address);
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasFromAddress2() {
+ final source = Pointer<Int64>.allocate();
+ final alias = Pointer<Int64>.fromAddress(source.address);
+ final alias2 = Pointer<Int64>.fromAddress(source.address);
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ source.free();
+}
+
+void testAliasFromAddressViaMemory() {
+ final helper = Pointer<IntPtr>.allocate();
+ final source = Pointer<Int64>.allocate();
+ helper.store(source.address);
+ final alias = Pointer<Int64>.fromAddress(helper.load());
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ helper.free();
+ source.free();
+}
+
+void testAliasFromAddressViaMemory2() {
+ final helper = Pointer<IntPtr>.allocate();
+ final source = Pointer<Int64>.allocate();
+ helper.store(source.address);
+ final alias = Pointer<Int64>.fromAddress(helper.load());
+ final alias2 = Pointer<Int64>.fromAddress(helper.load());
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ helper.free();
+ source.free();
+}
+
+typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
+typedef QuadOp = int Function(int, int, int, int);
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+QuadOp intComputation = ffiTestFunctions
+ .lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
+
+void testAliasFromAddressViaNativeFunction() {
+ final source = Pointer<Int64>.allocate();
+ final alias =
+ Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+ source.store(42);
+ final int a = source.load();
+ alias.store(1984);
+ // source.load() should be re-executed, we wrote alias which aliases source.
+ Expect.notEquals(a, source.load<int>());
+ source.free();
+}
+
+void testAliasFromAddressViaNativeFunction2() {
+ final source = Pointer<Int64>.allocate();
+ final alias =
+ Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+ final alias2 =
+ Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+ alias.store(42);
+ final int a = alias.load();
+ alias2.store(1984);
+ // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+ Expect.notEquals(a, alias.load<int>());
+ source.free();
+}
+
+// TODO(dacoharkes): Replace with @pragma annotations once available.
+const NeverInline = 'NeverInline';
+
+@NeverInline
+Pointer<Int8> makeDerived(Pointer<Int64> source) =>
+ source.offsetBy(7).cast<Int8>();
+
+testPartialOverlap() {
+ final source = Pointer<Int64>.allocate(count: 2);
+ final derived = makeDerived(source);
+ source.store(0x1122334455667788);
+ final int value = source.load();
+ derived.store(0xaa);
+ Expect.notEquals(value, source.load<int>());
+ source.free();
+}
diff --git a/tests/ffi/coordinate.dart b/tests/ffi/coordinate.dart
index fbca952..8c8b4d4 100644
--- a/tests/ffi/coordinate.dart
+++ b/tests/ffi/coordinate.dart
@@ -4,37 +4,23 @@
library FfiTest;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
/// Sample struct for dart:ffi library.
-@ffi.struct
-class Coordinate extends ffi.Pointer<ffi.Void> {
- @ffi.Double()
+class Coordinate extends Struct<Coordinate> {
+ @Double()
double x;
- @ffi.Double()
+ @Double()
double y;
- @ffi.Pointer()
- Coordinate next;
+ @Pointer()
+ Pointer<Coordinate> next;
- /// generated by @ffi.struct annotation
- external static int sizeOf();
-
- Coordinate offsetBy(int offsetInBytes) =>
- super.offsetBy(offsetInBytes).cast();
-
- Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
-
- static Coordinate allocate({int count: 1}) =>
- ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
-
- /// Allocate a new [Coordinate] in C memory and populate its fields.
- factory Coordinate(double x, double y, Coordinate next) {
- Coordinate result = Coordinate.allocate()
+ factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
+ return Pointer<Coordinate>.allocate().load<Coordinate>()
..x = x
..y = y
..next = next;
- return result;
}
}
diff --git a/tests/ffi/coordinate_bare.dart b/tests/ffi/coordinate_bare.dart
index 764cb9f..7858882 100644
--- a/tests/ffi/coordinate_bare.dart
+++ b/tests/ffi/coordinate_bare.dart
@@ -4,17 +4,16 @@
library FfiTestCoordinateBare;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
/// Stripped down sample struct for dart:ffi library.
-@ffi.struct
-class Coordinate extends ffi.Pointer<ffi.Void> {
- @ffi.Double()
+class Coordinate extends Struct<Coordinate> {
+ @Double()
double x;
- @ffi.Double()
+ @Double()
double y;
- @ffi.Pointer()
- Coordinate next;
+ @Pointer()
+ Pointer<Coordinate> next;
}
diff --git a/tests/ffi/coordinate_manual.dart b/tests/ffi/coordinate_manual.dart
deleted file mode 100644
index d4d1aca..0000000
--- a/tests/ffi/coordinate_manual.dart
+++ /dev/null
@@ -1,44 +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.
-
-library FfiTestCoordinateManual;
-
-import 'dart:ffi' as ffi;
-
-/// Sample struct for dart:ffi library without use of ffi annotations.
-class Coordinate extends ffi.Pointer<ffi.Void> {
- ffi.Pointer<ffi.Double> get _xPtr => cast();
- set x(double v) => _xPtr.store(v);
- double get x => _xPtr.load();
-
- ffi.Pointer<ffi.Double> get _yPtr =>
- offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
- set y(double v) => _yPtr.store(v);
- double get y => _yPtr.load();
-
- ffi.Pointer<Coordinate> get _nextPtr =>
- offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
- set next(Coordinate v) => _nextPtr.store(v);
- Coordinate get next => _nextPtr.load();
-
- static int sizeOf() =>
- ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
-
- Coordinate offsetBy(int offsetInBytes) =>
- super.offsetBy(offsetInBytes).cast();
-
- Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
-
- static Coordinate allocate({int count: 1}) =>
- ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
-
- /// Allocate a new [Coordinate] in C memory and populate its fields.
- factory Coordinate(double x, double y, Coordinate next) {
- Coordinate result = Coordinate.allocate()
- ..x = x
- ..y = y
- ..next = next;
- return result;
- }
-}
diff --git a/tests/ffi/cstring.dart b/tests/ffi/cstring.dart
index b976007..b0bfdae 100644
--- a/tests/ffi/cstring.dart
+++ b/tests/ffi/cstring.dart
@@ -6,27 +6,31 @@
import 'dart:convert';
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
-/// Sample non-struct subtype of Pointer for dart:ffi library.
-class CString extends ffi.Pointer<ffi.Uint8> {
- CString elementAt(int index) => super.elementAt(index).cast();
+/// Sample non-struct Pointer wrapper for dart:ffi library.
+class Utf8 extends ffi.Struct<Utf8> {
+ @ffi.Int8()
+ int char;
- String fromUtf8() {
+ static String fromUtf8(Pointer<Utf8> str) {
List<int> units = [];
int len = 0;
while (true) {
- int char = elementAt(len++).load<int>();
+ int char = str.elementAt(len++).load<Utf8>().char;
if (char == 0) break;
units.add(char);
}
return Utf8Decoder().convert(units);
}
- factory CString.toUtf8(String s) {
- CString result = ffi.allocate<ffi.Uint8>(count: s.length + 1).cast();
+ static Pointer<Utf8> toUtf8(String s) {
+ Pointer<Utf8> result = Pointer<Utf8>.allocate(count: s.length + 1).cast();
List<int> units = Utf8Encoder().convert(s);
- for (int i = 0; i < s.length; i++) result.elementAt(i).store(units[i]);
- result.elementAt(s.length).store(0);
+ for (int i = 0; i < s.length; i++) {
+ result.elementAt(i).load<Utf8>().char = units[i];
+ }
+ result.elementAt(s.length).load<Utf8>().char = 0;
return result;
}
}
diff --git a/tests/ffi/data_not_asan_test.dart b/tests/ffi/data_not_asan_test.dart
index 2be8598..308c458 100644
--- a/tests/ffi/data_not_asan_test.dart
+++ b/tests/ffi/data_not_asan_test.dart
@@ -3,27 +3,35 @@
// BSD-style license that can be found in the LICENSE file.
//
// Dart test program for testing dart:ffi primitive data pointers.
-// This test tries to allocate too much memory on purpose to test the Exception
-// thrown on malloc failing.
-// This malloc also triggers an asan alarm, so this test is in a separate file
+//
+// These mallocs trigger an asan alarm, so these tests are in a separate file
// which is excluded in asan mode.
library FfiTest;
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
import "package:expect/expect.dart";
void main() {
testPointerAllocateTooLarge();
+ testPointerAllocateNegative();
}
-/// This test is skipped in asan mode.
void testPointerAllocateTooLarge() {
+ // Try to allocate something that doesn't fit in 64 bit address space.
int maxInt = 9223372036854775807; // 2^63 - 1
- Expect.throws(
- () => ffi.allocate<ffi.Int64>(count: maxInt)); // does not fit in range
+ Expect.throws(() => Pointer<ffi.Int64>.allocate(count: maxInt));
+
+ // Try to allocate almost the full 64 bit address space.
int maxInt1_8 = 1152921504606846975; // 2^60 -1
- Expect.throws(
- () => ffi.allocate<ffi.Int64>(count: maxInt1_8)); // not enough memory
+ Expect.throws(() => Pointer<ffi.Int64>.allocate(count: maxInt1_8));
+}
+
+void testPointerAllocateNegative() {
+ // Passing in -1 will be converted into an unsigned integer. So, it will try
+ // to allocate SIZE_MAX - 1 + 1 bytes. This will fail as it is the max amount
+ // of addressable memory on the system.
+ Expect.throws(() => Pointer<ffi.Int8>.allocate(count: -1));
}
diff --git a/tests/ffi/data_test.dart b/tests/ffi/data_test.dart
index 4cdc79b..a86f9af 100644
--- a/tests/ffi/data_test.dart
+++ b/tests/ffi/data_test.dart
@@ -7,6 +7,7 @@
library FfiTest;
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
import "package:expect/expect.dart";
@@ -15,7 +16,7 @@
testPointerFromPointer();
testPointerPointerArithmetic();
testPointerPointerArithmeticSizes();
- testPointerAllocateNonPositive();
+ testPointerAllocateZero();
testPointerCast();
testCastGeneric();
testCastGeneric2();
@@ -54,85 +55,96 @@
}
void testPointerBasic() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate();
+ Pointer<ffi.Int64> p = Pointer.allocate();
p.store(42);
Expect.equals(42, p.load<int>());
p.free();
}
void testPointerFromPointer() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate();
+ Pointer<ffi.Int64> p = Pointer.allocate();
p.store(1337);
int ptr = p.address;
- ffi.Pointer<ffi.Int64> p2 = ffi.fromAddress(ptr);
+ Pointer<ffi.Int64> p2 = Pointer.fromAddress(ptr);
Expect.equals(1337, p2.load<int>());
p.free();
}
void testPointerPointerArithmetic() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
- ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+ Pointer<ffi.Int64> p = Pointer.allocate(count: 2);
+ Pointer<ffi.Int64> p2 = p.elementAt(1);
p2.store(100);
- ffi.Pointer<ffi.Int64> p3 = p.offsetBy(8);
+ Pointer<ffi.Int64> p3 = p.offsetBy(8);
Expect.equals(100, p3.load<int>());
p.free();
}
void testPointerPointerArithmeticSizes() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
- ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+ Pointer<ffi.Int64> p = Pointer.allocate(count: 2);
+ Pointer<ffi.Int64> p2 = p.elementAt(1);
int addr = p.address;
Expect.equals(addr + 8, p2.address);
p.free();
- ffi.Pointer<ffi.Int32> p3 = ffi.allocate(count: 2);
- ffi.Pointer<ffi.Int32> p4 = p3.elementAt(1);
+ Pointer<ffi.Int32> p3 = Pointer.allocate(count: 2);
+ Pointer<ffi.Int32> p4 = p3.elementAt(1);
addr = p3.address;
Expect.equals(addr + 4, p4.address);
p3.free();
}
-void testPointerAllocateNonPositive() {
- Expect.throws(() => ffi.allocate<ffi.Int8>(count: 0));
- Expect.throws(() => ffi.allocate<ffi.Int8>(count: -1));
+void testPointerAllocateZero() {
+ // > If size is 0, either a null pointer or a unique pointer that can be
+ // > successfully passed to free() shall be returned.
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
+ //
+ // Null pointer throws a Dart exception.
+ bool returnedNullPointer = false;
+ ffi.Pointer<ffi.Int8> p;
+ try {
+ p = Pointer<ffi.Int8>.allocate(count: 0);
+ } on Exception {
+ returnedNullPointer = true;
+ }
+ if (!returnedNullPointer) {
+ p.free();
+ }
}
void testPointerCast() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate();
- ffi.Pointer<ffi.Int32> p2 = p.cast(); // gets the correct type args back
+ Pointer<ffi.Int64> p = Pointer.allocate();
+ Pointer<ffi.Int32> p2 = p.cast(); // gets the correct type args back
p.free();
}
void testCastGeneric() {
- ffi.Pointer<T> generic<T extends ffi.NativeType>(ffi.Pointer<ffi.Int16> p) {
+ Pointer<T> generic<T extends ffi.NativeType>(Pointer<ffi.Int16> p) {
return p.cast();
}
- ffi.Pointer<ffi.Int16> p = ffi.allocate();
- ffi.Pointer<ffi.Int64> p2 = generic(p);
+ Pointer<ffi.Int16> p = Pointer.allocate();
+ Pointer<ffi.Int64> p2 = generic(p);
p.free();
}
void testCastGeneric2() {
- ffi.Pointer<ffi.Int64> generic<T extends ffi.NativeType>(ffi.Pointer<T> p) {
+ Pointer<ffi.Int64> generic<T extends ffi.NativeType>(Pointer<T> p) {
return p.cast();
}
- ffi.Pointer<ffi.Int16> p = ffi.allocate();
- ffi.Pointer<ffi.Int64> p2 = generic(p);
+ Pointer<ffi.Int16> p = Pointer.allocate();
+ Pointer<ffi.Int64> p2 = generic(p);
p.free();
}
void testCastNativeType() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate();
- Expect.throws(() {
- p.cast<ffi.Pointer>();
- });
+ ffi.Pointer<ffi.Int64> p = Pointer.allocate();
+ p.cast<ffi.Pointer>();
p.free();
}
void testCondensedNumbersInt8() {
- ffi.Pointer<ffi.Int8> p = ffi.allocate(count: 8);
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate(count: 8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p.elementAt(i).store(i * 3);
}
@@ -143,7 +155,7 @@
}
void testCondensedNumbersFloat() {
- ffi.Pointer<ffi.Float> p = ffi.allocate(count: 8);
+ ffi.Pointer<ffi.Float> p = Pointer.allocate(count: 8);
for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
p.elementAt(i).store(1.511366173271439e-13);
}
@@ -154,7 +166,7 @@
}
void testRangeInt8() {
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
p.store(127);
Expect.equals(127, p.load<int>());
p.store(-128);
@@ -173,7 +185,7 @@
}
void testRangeUint8() {
- ffi.Pointer<ffi.Uint8> p = ffi.allocate();
+ ffi.Pointer<ffi.Uint8> p = Pointer.allocate();
p.store(255);
Expect.equals(255, p.load<int>());
p.store(0);
@@ -192,7 +204,7 @@
}
void testRangeInt16() {
- ffi.Pointer<ffi.Int16> p = ffi.allocate();
+ ffi.Pointer<ffi.Int16> p = Pointer.allocate();
p.store(0x7FFF);
Expect.equals(0x7FFF, p.load<int>());
p.store(-0x8000);
@@ -206,7 +218,7 @@
}
void testRangeUint16() {
- ffi.Pointer<ffi.Uint16> p = ffi.allocate();
+ ffi.Pointer<ffi.Uint16> p = Pointer.allocate();
p.store(0xFFFF);
Expect.equals(0xFFFF, p.load<int>());
p.store(0);
@@ -219,7 +231,7 @@
}
void testRangeInt32() {
- ffi.Pointer<ffi.Int32> p = ffi.allocate();
+ ffi.Pointer<ffi.Int32> p = Pointer.allocate();
p.store(0x7FFFFFFF);
Expect.equals(0x7FFFFFFF, p.load<int>());
p.store(-0x80000000);
@@ -233,7 +245,7 @@
}
void testRangeUint32() {
- ffi.Pointer<ffi.Uint32> p = ffi.allocate();
+ ffi.Pointer<ffi.Uint32> p = Pointer.allocate();
p.store(0xFFFFFFFF);
Expect.equals(0xFFFFFFFF, p.load<int>());
p.store(0);
@@ -246,7 +258,7 @@
}
void testRangeInt64() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate();
+ ffi.Pointer<ffi.Int64> p = Pointer.allocate();
p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
p.store(-0x8000000000000000); // -2 ^ 63
@@ -255,7 +267,7 @@
}
void testRangeUint64() {
- ffi.Pointer<ffi.Uint64> p = ffi.allocate();
+ ffi.Pointer<ffi.Uint64> p = Pointer.allocate();
p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
p.store(-0x8000000000000000); // -2 ^ 63 interpreted as 2 ^ 63
@@ -270,7 +282,7 @@
}
void testRangeIntPtr() {
- ffi.Pointer<ffi.IntPtr> p = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> p = Pointer.allocate();
int pAddr = p.address;
p.store(pAddr); // its own address should fit
p.store(0x7FFFFFFF); // and 32 bit addresses should fit
@@ -281,7 +293,7 @@
}
void testFloat() {
- ffi.Pointer<ffi.Float> p = ffi.allocate();
+ ffi.Pointer<ffi.Float> p = Pointer.allocate();
p.store(1.511366173271439e-13);
Expect.equals(1.511366173271439e-13, p.load<double>());
p.store(1.4260258159703532e-105); // float does not have enough precision
@@ -290,23 +302,23 @@
}
void testDouble() {
- ffi.Pointer<ffi.Double> p = ffi.allocate();
+ ffi.Pointer<ffi.Double> p = Pointer.allocate();
p.store(1.4260258159703532e-105);
Expect.equals(1.4260258159703532e-105, p.load<double>());
p.free();
}
void testVoid() {
- ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
ffi.Pointer<ffi.Void> p2 = p1.cast(); // make this dart pointer opaque
p2.address; // we can print the address
p2.free();
}
void testPointerPointer() {
- ffi.Pointer<ffi.Int16> p = ffi.allocate();
+ ffi.Pointer<ffi.Int16> p = Pointer.allocate();
p.store(17);
- ffi.Pointer<ffi.Pointer<ffi.Int16>> p2 = ffi.allocate();
+ ffi.Pointer<ffi.Pointer<ffi.Int16>> p2 = Pointer.allocate();
p2.store(p);
Expect.equals(17, p2.load<ffi.Pointer<ffi.Int16>>().load<int>());
p2.free();
@@ -314,32 +326,36 @@
}
void testPointerPointerNull() {
- ffi.Pointer<ffi.Pointer<ffi.Int8>> pointerToPointer = ffi.allocate();
- ffi.Pointer<ffi.Int8> value = null;
+ Pointer<Pointer<ffi.Int8>> pointerToPointer = Pointer.allocate();
+ Pointer<ffi.Int8> value = ffi.nullptr.cast();
pointerToPointer.store(value);
value = pointerToPointer.load();
- Expect.isNull(value);
- value = ffi.allocate();
+ Expect.equals(value, ffi.nullptr);
+ value = Pointer.allocate();
pointerToPointer.store(value);
value = pointerToPointer.load();
Expect.isNotNull(value);
value.free();
- value = null;
+ value = ffi.nullptr.cast();
pointerToPointer.store(value);
value = pointerToPointer.load();
- Expect.isNull(value);
+ Expect.equals(value, ffi.nullptr);
pointerToPointer.free();
}
void testPointerStoreNull() {
int i = null;
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
Expect.throws(() => p.store(i));
p.free();
double d = null;
- ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+ ffi.Pointer<ffi.Float> p2 = Pointer.allocate();
Expect.throws(() => p2.store(d));
p2.free();
+ Pointer<ffi.Void> x = null;
+ ffi.Pointer<ffi.Pointer<ffi.Void>> p3 = Pointer.allocate();
+ Expect.throws(() => p3.store(x));
+ p3.free();
}
void testSizeOf() {
@@ -364,7 +380,7 @@
head.store(value);
return;
}
- ffi.Pointer<ffi.IntPtr> next = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> next = Pointer.allocate();
head.store(next.address);
createChain(next, length - 1, value);
}
@@ -373,12 +389,12 @@
if (length == 0) {
return head.load();
}
- ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+ ffi.Pointer<ffi.IntPtr> next = Pointer.fromAddress(head.load());
return getChainValue(next, length - 1);
}
void freeChain(ffi.Pointer<ffi.IntPtr> head, int length) {
- ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+ ffi.Pointer<ffi.IntPtr> next = Pointer.fromAddress(head.load());
head.free();
if (length == 0) {
return;
@@ -386,7 +402,7 @@
freeChain(next, length - 1);
}
- ffi.Pointer<ffi.IntPtr> head = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> head = Pointer.allocate();
createChain(head, length, 512);
int tailValue = getChainValue(head, length);
Expect.equals(512, tailValue);
@@ -394,23 +410,23 @@
}
void testTypeTest() {
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
Expect.isTrue(p is ffi.Pointer);
p.free();
}
void testToString() {
- ffi.Pointer<ffi.Int16> p = ffi.allocate();
+ ffi.Pointer<ffi.Int16> p = Pointer.allocate();
Expect.stringEquals(
"Pointer<Int16>: address=0x", p.toString().substring(0, 26));
p.free();
- ffi.Pointer<ffi.Int64> p2 = ffi.fromAddress(0x123abc);
+ ffi.Pointer<ffi.Int64> p2 = Pointer.fromAddress(0x123abc);
Expect.stringEquals("Pointer<Int64>: address=0x123abc", p2.toString());
}
void testEquality() {
- ffi.Pointer<ffi.Int8> p = ffi.fromAddress(12345678);
- ffi.Pointer<ffi.Int8> p2 = ffi.fromAddress(12345678);
+ ffi.Pointer<ffi.Int8> p = Pointer.fromAddress(12345678);
+ ffi.Pointer<ffi.Int8> p2 = Pointer.fromAddress(12345678);
Expect.equals(p, p2);
Expect.equals(p.hashCode, p2.hashCode);
ffi.Pointer<ffi.Int16> p3 = p.cast();
@@ -427,7 +443,7 @@
void testAllocateGeneric() {
ffi.Pointer<T> generic<T extends ffi.NativeType>() {
ffi.Pointer<T> pointer;
- pointer = ffi.allocate();
+ pointer = Pointer.allocate();
return pointer;
}
@@ -437,19 +453,19 @@
void testAllocateVoid() {
Expect.throws(() {
- ffi.Pointer<ffi.Void> p = ffi.allocate();
+ ffi.Pointer<ffi.Void> p = Pointer.allocate();
});
}
void testAllocateNativeFunction() {
Expect.throws(() {
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.allocate();
+ ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.allocate();
});
}
void testAllocateNativeType() {
Expect.throws(() {
- ffi.allocate();
+ Pointer.allocate();
});
}
@@ -484,8 +500,8 @@
void testFreeZeroOut() {
// at least one of these pointers should have address != 0 on all platforms
- ffi.Pointer<ffi.Int8> p1 = ffi.allocate();
- ffi.Pointer<ffi.Int8> p2 = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p1 = Pointer.allocate();
+ ffi.Pointer<ffi.Int8> p2 = Pointer.allocate();
Expect.notEquals(0, p1.address & p2.address);
p1.free();
p2.free();
diff --git a/tests/ffi/dynamic_library_test.dart b/tests/ffi/dynamic_library_test.dart
index 3282f4c..7b29a18 100644
--- a/tests/ffi/dynamic_library_test.dart
+++ b/tests/ffi/dynamic_library_test.dart
@@ -8,7 +8,7 @@
library FfiTest;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
import 'dylib_utils.dart';
@@ -21,10 +21,11 @@
testLookupError();
testToString();
testEquality();
+ testHandle();
}
void testOpen() {
- ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.notEquals(null, l);
}
@@ -33,35 +34,46 @@
() => dlopenPlatformSpecific("doesnotexistforsurelibrary123409876"));
}
-typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
+typedef NativeDoubleUnOp = Double Function(Double);
typedef DoubleUnOp = double Function(double);
void testLookup() {
- ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
Expect.approxEquals(12.0, timesFour(3));
}
void testLookupError() {
- ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.throws(() => l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>(
"functionnamethatdoesnotexistforsure749237593845"));
}
void testToString() {
- ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.stringEquals(
"DynamicLibrary: handle=0x", l.toString().substring(0, 25));
}
void testEquality() {
- ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
- ffi.DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.equals(l, l2);
Expect.equals(l.hashCode, l2.hashCode);
Expect.notEquals(l, null);
Expect.notEquals(null, l);
- ffi.DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
+ DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
Expect.notEquals(l, l3);
}
+
+void testHandle() {
+ DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
+ Pointer<Void> h = l.handle;
+ Pointer<Void> h2 = l2.handle;
+ Expect.equals(h, h2);
+ DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
+ Pointer<Void> h3 = l3.handle;
+ Expect.notEquals(h, h3);
+}
diff --git a/tests/ffi/enable_structs_test.dart b/tests/ffi/enable_structs_test.dart
index ed8655b..21f48d0 100644
--- a/tests/ffi/enable_structs_test.dart
+++ b/tests/ffi/enable_structs_test.dart
@@ -6,20 +6,17 @@
library FfiTest;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
import "package:expect/expect.dart";
-@ffi.struct
-class C extends ffi.Pointer<ffi.Void> {
- @ffi.IntPtr()
+class C extends Struct<C> {
+ @IntPtr()
int x;
- external static int sizeOf();
}
void main() {
- final C c = ffi.fromAddress<C>(1);
+ final C c = nullptr.cast<C>().load();
Expect.throws<UnimplementedError>(() => c.x);
Expect.throws<UnimplementedError>(() => c.x = 0);
- Expect.throws<UnimplementedError>(() => C.sizeOf());
}
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 1fa9e5b..de333a5 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -19,12 +19,12 @@
function_callbacks_test/03: Skip
[ $runtime == dart_precompiled ]
-*: Skip # AOT is not yet supported: dartbug.com/35765
+function_callbacks_test: Skip # Issue dartbug.com/37295
[ $arch == arm && $system != android ]
*: Skip # "hardfp" calling convention is not yet supported (iOS is also supported but not tested): dartbug.com/36309
-[ $arch == simdbc64 && $system != linux && $system != macos ]
+[ $arch == simdbc64 && $system != android && $system != linux && $system != macos ]
*: Skip # FFI not yet supported outside x64 Linux: dartbug.com/36809
[ $runtime != dart_precompiled && $runtime != vm ]
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart
index b3ddc9a..1b25dc1 100644
--- a/tests/ffi/function_callbacks_test.dart
+++ b/tests/ffi/function_callbacks_test.dart
@@ -139,45 +139,73 @@
Pointer<Int64> store(Pointer<Int64> ptr) => ptr.elementAt(1)..store(1337);
typedef NullPointersType = Pointer<Int64> Function(Pointer<Int64>);
-Pointer<Int64> nullPointers(Pointer<Int64> ptr) => ptr?.elementAt(1);
+Pointer<Int64> nullPointers(Pointer<Int64> ptr) => ptr.elementAt(1);
typedef ReturnNullType = Int32 Function();
int returnNull() {
- print('Expect "unhandled exception" error message to follow.');
return null;
}
typedef ReturnVoid = Void Function();
void returnVoid() {}
+void throwException() {
+ throw "Exception.";
+}
+
+typedef ThrowExceptionInt = IntPtr Function();
+int throwExceptionInt() {
+ throw "Exception.";
+}
+
+typedef ThrowExceptionDouble = Double Function();
+double throwExceptionDouble() {
+ throw "Exception.";
+}
+
+typedef ThrowExceptionPointer = Pointer<Void> Function();
+Pointer<Void> throwExceptionPointer() {
+ throw "Exception.";
+}
+
void testGC() {
triggerGc();
}
final List<Test> testcases = [
- Test("SimpleAddition", fromFunction<SimpleAdditionType>(simpleAddition)),
- Test("IntComputation", fromFunction<IntComputationType>(intComputation)),
- Test("UintComputation", fromFunction<UintComputationType>(uintComputation)),
- Test("SimpleMultiply", fromFunction<SimpleMultiplyType>(simpleMultiply)),
+ Test("SimpleAddition", Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
+ Test("IntComputation", Pointer.fromFunction<IntComputationType>(intComputation, 0)),
+ Test(
+ "UintComputation", Pointer.fromFunction<UintComputationType>(uintComputation, 0)),
+ Test("SimpleMultiply", Pointer.fromFunction<SimpleMultiplyType>(simpleMultiply, 0.0)),
Test("SimpleMultiplyFloat",
- fromFunction<SimpleMultiplyFloatType>(simpleMultiplyFloat)),
- Test("ManyInts", fromFunction<ManyIntsType>(manyInts)),
- Test("ManyDoubles", fromFunction<ManyDoublesType>(manyDoubles)),
- Test("ManyArgs", fromFunction<ManyArgsType>(manyArgs)),
- Test("Store", fromFunction<StoreType>(store)),
- Test("NullPointers", fromFunction<NullPointersType>(nullPointers)),
- Test("ReturnNull", fromFunction<ReturnNullType>(returnNull)),
- Test("GC", fromFunction<ReturnVoid>(testGC)),
+ Pointer.fromFunction<SimpleMultiplyFloatType>(simpleMultiplyFloat, 0.0)),
+ Test("ManyInts", Pointer.fromFunction<ManyIntsType>(manyInts, 0)),
+ Test("ManyDoubles", Pointer.fromFunction<ManyDoublesType>(manyDoubles, 0.0)),
+ Test("ManyArgs", Pointer.fromFunction<ManyArgsType>(manyArgs, 0.0)),
+ Test("Store", Pointer.fromFunction<StoreType>(store, null)),
+ Test("NullPointers", Pointer.fromFunction<NullPointersType>(nullPointers, null)),
+ Test("ReturnNull", Pointer.fromFunction<ReturnNullType>(returnNull, 42)),
+ Test("ReturnVoid", Pointer.fromFunction<ReturnVoid>(returnVoid, null)),
+ Test("ThrowExceptionDouble",
+ Pointer.fromFunction<ThrowExceptionDouble>(throwExceptionDouble, 42.0)),
+ Test(
+ "ThrowExceptionPointer",
+ Pointer.fromFunction<ThrowExceptionPointer>(
+ throwExceptionPointer, Pointer<Void>.fromAddress(42))),
+ Test("ThrowException", Pointer.fromFunction<ThrowExceptionInt>(throwExceptionInt, 42)),
+ Test("GC", Pointer.fromFunction<ReturnVoid>(testGC, null)),
];
testCallbackWrongThread() =>
- Test("CallbackWrongThread", fromFunction<ReturnVoid>(returnVoid)).run();
+ Test("CallbackWrongThread", Pointer.fromFunction<ReturnVoid>(returnVoid, null)).run();
testCallbackOutsideIsolate() =>
- Test("CallbackOutsideIsolate", fromFunction<ReturnVoid>(returnVoid)).run();
+ Test("CallbackOutsideIsolate", Pointer.fromFunction<ReturnVoid>(returnVoid, null))
+ .run();
isolateHelper(int callbackPointer) {
- final Pointer<Void> ptr = fromAddress(callbackPointer);
+ final Pointer<Void> ptr = Pointer.fromAddress(callbackPointer);
final NativeCallbackTestFn tester =
testLibrary.lookupFunction<NativeCallbackTest, NativeCallbackTestFn>(
"TestCallbackWrongIsolate");
@@ -185,15 +213,27 @@
}
testCallbackWrongIsolate() async {
- final int callbackPointer = fromFunction<ReturnVoid>(returnVoid).address;
+ final int callbackPointer = Pointer.fromFunction<ReturnVoid>(returnVoid, null).address;
final ReceivePort exitPort = ReceivePort();
await Isolate.spawn(isolateHelper, callbackPointer,
errorsAreFatal: true, onExit: exitPort.sendPort);
await exitPort.first;
}
+// Correct type of exceptionalReturn argument to Pointer.fromFunction.
+double testExceptionalReturn() {
+ Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0.0);
+ Expect.throwsArgumentError(() => Pointer.fromFunction<Void Function()>(returnVoid, 0));
+ Pointer.fromFunction<Void Function()>(returnVoid, null);
+ Expect.throwsArgumentError(() => Pointer.fromFunction<Double Function()>(returnVoid, null));
+
+ Pointer.fromFunction<Double Function()>(testExceptionalReturn, "abc"); //# 61: compile-time error
+ Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0); //# 62: compile-time error
+}
+
void main() async {
testcases.forEach((t) => t.run()); //# 00: ok
+ testExceptionalReturn(); //# 00: ok
// These tests terminate the process after successful completion, so we have
// to run them separately.
diff --git a/tests/ffi/function_structs_test.dart b/tests/ffi/function_structs_test.dart
index 6f1f906..875f621 100644
--- a/tests/ffi/function_structs_test.dart
+++ b/tests/ffi/function_structs_test.dart
@@ -10,6 +10,7 @@
library FfiTest;
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
import 'dylib_utils.dart';
@@ -18,7 +19,7 @@
import 'coordinate.dart';
import 'very_large_struct.dart';
-typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
void main() {
testFunctionWithStruct();
@@ -35,14 +36,15 @@
ffiTestFunctions.lookup("TransposeCoordinate");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = Coordinate(10.0, 20.0, null);
- Coordinate c2 = Coordinate(42.0, 84.0, c1);
- c1.next = c2;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(10.0, 20.0, ffi.nullptr.cast<Coordinate>()).addressOf;
+ Pointer<Coordinate> c2 = Coordinate.allocate(42.0, 84.0, c1).addressOf;
+ c1.load<Coordinate>().next = c2;
- Coordinate result = f1(c1);
+ Coordinate result = f1(c1).load();
- Expect.approxEquals(20.0, c1.x);
- Expect.approxEquals(30.0, c1.y);
+ Expect.approxEquals(20.0, c1.load<Coordinate>().x);
+ Expect.approxEquals(30.0, c1.load<Coordinate>().y);
Expect.approxEquals(42.0, result.x);
Expect.approxEquals(84.0, result.y);
@@ -57,36 +59,36 @@
ffiTestFunctions.lookup("CoordinateElemAt1");
NativeCoordinateOp f1 = p1.asFunction();
- Coordinate c1 = Coordinate.allocate(count: 3);
- Coordinate c2 = c1.elementAt(1);
- Coordinate c3 = c1.elementAt(2);
+ Coordinate c1 = Pointer<Coordinate>.allocate(count: 3).load();
+ Coordinate c2 = c1.addressOf.elementAt(1).load();
+ Coordinate c3 = c1.addressOf.elementAt(2).load();
c1.x = 10.0;
c1.y = 10.0;
- c1.next = c3;
+ c1.next = c3.addressOf;
c2.x = 20.0;
c2.y = 20.0;
- c2.next = c1;
+ c2.next = c1.addressOf;
c3.x = 30.0;
c3.y = 30.0;
- c3.next = c2;
+ c3.next = c2.addressOf;
- Coordinate result = f1(c1);
+ Coordinate result = f1(c1.addressOf).load();
Expect.approxEquals(20.0, result.x);
Expect.approxEquals(20.0, result.y);
- c1.free();
+ c1.addressOf.free();
}
-typedef VeryLargeStructSum = int Function(VeryLargeStruct);
-typedef NativeVeryLargeStructSum = ffi.Int64 Function(VeryLargeStruct);
+typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
+typedef NativeVeryLargeStructSum = ffi.Int64 Function(Pointer<VeryLargeStruct>);
void testFunctionWithVeryLargeStruct() {
ffi.Pointer<ffi.NativeFunction<NativeVeryLargeStructSum>> p1 =
ffiTestFunctions.lookup("SumVeryLargeStruct");
VeryLargeStructSum f = p1.asFunction();
- VeryLargeStruct vls1 = VeryLargeStruct.allocate(count: 2);
- VeryLargeStruct vls2 = vls1.elementAt(1);
+ VeryLargeStruct vls1 = Pointer<VeryLargeStruct>.allocate(count: 2).load();
+ VeryLargeStruct vls2 = vls1.addressOf.elementAt(1).load();
List<VeryLargeStruct> structs = [vls1, vls2];
for (VeryLargeStruct struct in structs) {
struct.a = 1;
@@ -102,19 +104,19 @@
struct.k = 1024;
struct.smallLastField = 1;
}
- vls1.parent = vls2;
+ vls1.parent = vls2.addressOf;
vls1.numChidlren = 2;
- vls1.children = vls1;
- vls2.parent = vls2;
- vls2.parent = null;
+ vls1.children = vls1.addressOf;
+ vls2.parent = vls2.addressOf;
+ vls2.parent = ffi.nullptr.cast();
vls2.numChidlren = 0;
- vls2.children = null;
+ vls2.children = ffi.nullptr.cast();
- int result = f(vls1);
+ int result = f(vls1.addressOf);
Expect.equals(2051, result);
- result = f(vls2);
+ result = f(vls2.addressOf);
Expect.equals(2048, result);
- vls1.free();
+ vls1.addressOf.free();
}
diff --git a/tests/ffi/function_test.dart b/tests/ffi/function_test.dart
index 2865d30..f31a470 100644
--- a/tests/ffi/function_test.dart
+++ b/tests/ffi/function_test.dart
@@ -12,6 +12,7 @@
library FfiTest;
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
import 'dylib_utils.dart';
@@ -38,6 +39,7 @@
testFloatRounding();
testVoidReturn();
testNoArgs();
+ testException();
}
}
@@ -50,7 +52,7 @@
typedef GenericBinaryOp<T> = int Function(int, T);
void testNativeFunctionFromCast() {
- ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
ffi.Pointer<ffi.NativeFunction<NativeBinaryOp>> p2 = p1.cast();
p2.asFunction<BinaryOp>();
p2.asFunction<GenericBinaryOp<int>>();
@@ -83,73 +85,73 @@
typedef NativeReturnMaxUint8 = ffi.Uint8 Function();
int Function() returnMaxUint8 = ffiTestFunctions
.lookup("ReturnMaxUint8")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint8>>>()
+ .cast<ffi.NativeFunction<NativeReturnMaxUint8>>()
.asFunction();
typedef NativeReturnMaxUint16 = ffi.Uint16 Function();
int Function() returnMaxUint16 = ffiTestFunctions
.lookup("ReturnMaxUint16")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint16>>>()
+ .cast<ffi.NativeFunction<NativeReturnMaxUint16>>()
.asFunction();
typedef NativeReturnMaxUint32 = ffi.Uint32 Function();
int Function() returnMaxUint32 = ffiTestFunctions
.lookup("ReturnMaxUint32")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint32>>>()
+ .cast<ffi.NativeFunction<NativeReturnMaxUint32>>()
.asFunction();
typedef NativeReturnMinInt8 = ffi.Int8 Function();
int Function() returnMinInt8 = ffiTestFunctions
.lookup("ReturnMinInt8")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt8>>>()
+ .cast<ffi.NativeFunction<NativeReturnMinInt8>>()
.asFunction();
typedef NativeReturnMinInt16 = ffi.Int16 Function();
int Function() returnMinInt16 = ffiTestFunctions
.lookup("ReturnMinInt16")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt16>>>()
+ .cast<ffi.NativeFunction<NativeReturnMinInt16>>()
.asFunction();
typedef NativeReturnMinInt32 = ffi.Int32 Function();
int Function() returnMinInt32 = ffiTestFunctions
.lookup("ReturnMinInt32")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt32>>>()
+ .cast<ffi.NativeFunction<NativeReturnMinInt32>>()
.asFunction();
typedef NativeTakeMaxUint8 = ffi.IntPtr Function(ffi.Uint8);
int Function(int) takeMaxUint8 = ffiTestFunctions
.lookup("TakeMaxUint8")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint8>>>()
+ .cast<ffi.NativeFunction<NativeTakeMaxUint8>>()
.asFunction();
typedef NativeTakeMaxUint16 = ffi.IntPtr Function(ffi.Uint16);
int Function(int) takeMaxUint16 = ffiTestFunctions
.lookup("TakeMaxUint16")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint16>>>()
+ .cast<ffi.NativeFunction<NativeTakeMaxUint16>>()
.asFunction();
typedef NativeTakeMaxUint32 = ffi.IntPtr Function(ffi.Uint32);
int Function(int) takeMaxUint32 = ffiTestFunctions
.lookup("TakeMaxUint32")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint32>>>()
+ .cast<ffi.NativeFunction<NativeTakeMaxUint32>>()
.asFunction();
typedef NativeTakeMinInt8 = ffi.IntPtr Function(ffi.Int8);
int Function(int) takeMinInt8 = ffiTestFunctions
.lookup("TakeMinInt8")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt8>>>()
+ .cast<ffi.NativeFunction<NativeTakeMinInt8>>()
.asFunction();
typedef NativeTakeMinInt16 = ffi.IntPtr Function(ffi.Int16);
int Function(int) takeMinInt16 = ffiTestFunctions
.lookup("TakeMinInt16")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt16>>>()
+ .cast<ffi.NativeFunction<NativeTakeMinInt16>>()
.asFunction();
typedef NativeTakeMinInt32 = ffi.IntPtr Function(ffi.Int32);
int Function(int) takeMinInt32 = ffiTestFunctions
.lookup("TakeMinInt32")
- .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt32>>>()
+ .cast<ffi.NativeFunction<NativeTakeMinInt32>>()
.asFunction();
void testExtension() {
@@ -351,7 +353,7 @@
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
void testNativeFunctionPointer() {
- ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+ ffi.Pointer<ffi.Int64> p2 = Pointer.allocate(count: 2);
p2.store(42);
p2.elementAt(1).store(1000);
ffi.Pointer<ffi.Int64> result = assign1337Index1(p2);
@@ -381,12 +383,12 @@
.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("NullableInt64ElemAt1");
void testNullPointers() {
- ffi.Pointer<ffi.Int64> result = nullableInt64ElemAt1(null);
- Expect.isNull(result);
+ Pointer<ffi.Int64> result = nullableInt64ElemAt1(ffi.nullptr.cast());
+ Expect.equals(result, ffi.nullptr);
- ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+ Pointer<ffi.Int64> p2 = Pointer.allocate(count: 2);
result = nullableInt64ElemAt1(p2);
- Expect.isNotNull(result);
+ Expect.notEquals(result, ffi.nullptr);
p2.free();
}
@@ -397,7 +399,7 @@
NativeFloatPointerToBool, FloatPointerToBool>("IsRoughly1337");
void testFloatRounding() {
- ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+ Pointer<ffi.Float> p2 = Pointer.allocate();
p2.store(1337.0);
int result = isRoughly1337(p2);
@@ -430,3 +432,15 @@
double result = inventFloatValue();
Expect.approxEquals(1337.0, result);
}
+
+// Throw an exception from within the trampoline and collect a stacktrace
+// include its frame.
+void testException() {
+ try {
+ sumPlus42(null, null);
+ } catch (e, s) {
+ print("$e, $s");
+ return;
+ }
+ throw "Didn't throw!";
+}
diff --git a/tests/ffi/negative_function_test.dart b/tests/ffi/negative_function_test.dart
index f851728..d96c17c 100644
--- a/tests/ffi/negative_function_test.dart
+++ b/tests/ffi/negative_function_test.dart
@@ -13,6 +13,8 @@
main() {
testWrongArity();
testWrongTypes();
+ testDynamicAsFunction();
+ testDynamicLookupFunction();
}
ffi.DynamicLibrary ffiTestFunctions =
@@ -61,3 +63,21 @@
Expect.throwsTypeError(() => pointerOp(0));
}
}
+
+// Test that invoking 'Pointer.asFunction' with a dynamic receiver type throws
+// an exception.
+void testDynamicAsFunction() {
+ dynamic x = ffi.nullptr.cast<ffi.NativeFunction<ffi.Void Function()>>();
+ Expect.throwsUnsupportedError(() {
+ x.asFunction<void Function()>();
+ });
+}
+
+// Test that invoking 'DynamicLibrary.lookupFunction' with a dynamic receiver
+// type throws an exception.
+void testDynamicLookupFunction() {
+ dynamic lib = ffiTestFunctions;
+ Expect.throwsUnsupportedError(() {
+ lib.lookupFunction<ffi.Void Function(), void Function()>("_");
+ });
+}
diff --git a/tests/ffi/object_gc_test.dart b/tests/ffi/object_gc_test.dart
new file mode 100644
index 0000000..deecb10
--- /dev/null
+++ b/tests/ffi/object_gc_test.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.
+//
+// Tests GC of Pointer objects.
+//
+// SharedObjects=ffi_test_functions
+
+library FfiTest;
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'cstring.dart';
+import 'dylib_utils.dart';
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final triggerGc = ffiTestFunctions
+ .lookupFunction<Void Function(), void Function()>("TriggerGC");
+
+void main() async {
+ testSizeOf();
+ testGC();
+}
+
+dynamic bar;
+
+Future<void> testGC() async {
+ bar = Pointer<Int8>.fromAddress(11);
+ // Verify that the objects manufactured by 'fromAddress' can be scanned by the
+ // GC.
+ triggerGc();
+}
+
+void testSizeOf() {
+ Expect.equals(true, 4 == sizeOf<Pointer>() || 8 == sizeOf<Pointer>());
+}
diff --git a/tests/ffi/regress_37100_test.dart b/tests/ffi/regress_37100_test.dart
index 7281042..19af367 100644
--- a/tests/ffi/regress_37100_test.dart
+++ b/tests/ffi/regress_37100_test.dart
@@ -10,12 +10,12 @@
import 'dylib_utils.dart';
-class EVP_MD extends Pointer<Void> {}
+class EVP_MD extends Struct<EVP_MD> {}
DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
-final EVP_sha1 = ffiTestFunctions
- .lookupFunction<EVP_MD Function(), EVP_MD Function()>('LargePointer');
+final EVP_sha1 = ffiTestFunctions.lookupFunction<Pointer<EVP_MD> Function(),
+ Pointer<EVP_MD> Function()>('LargePointer');
main() {
int result = EVP_sha1().address;
diff --git a/tests/ffi/regress_37254_test.dart b/tests/ffi/regress_37254_test.dart
new file mode 100644
index 0000000..faf9897
--- /dev/null
+++ b/tests/ffi/regress_37254_test.dart
@@ -0,0 +1,263 @@
+// 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.
+//
+// This program tests interaction with generic Pointers.
+//
+// Notation used in following tables:
+// * static_type//dynamic_type
+// * P = Pointer
+// * I = Int8
+// * NT = NativeType
+//
+// Note #1: When NNBD is landed, implicit downcasts will be static errors.
+//
+// Note #2: When we switch to extension methods we will _only_ use the static
+// type of the container.
+//
+// ===== a.store(b) ======
+// Does a.store(b), where a and b have specific static and dynamic types: run
+// fine, fail at compile time, or fail at runtime?
+// =======================
+// b P<I>//P<I> P<NT>//P<I> P<NT>//P<NT>
+// a
+// P<P<I>>//P<P<I>> 1 ok 2 implicit downcast 3 implicit downcast
+// of argument: ok of argument: fail
+// at runtime
+//
+// P<P<NT>>//P<P<I>> 4 ok 5 ok 6 fail at runtime
+//
+// P<P<NT>>//P<P<NT>> 7 ok 8 ok 9 ok
+//
+// ====== final c = a.load() ======
+// What is the (inferred) static type and runtime type of `a.load()`. Note that
+// we assume extension method here: on Pointer<PointerT>> { Pointer<T> load(); }
+// ================================
+// a a.load()
+// inferred static type*//runtime type
+// P<P<I>>//P<P<I>> P<I>//P<I>
+//
+// P<P<NT>>//P<P<I>> P<NT>//P<I>
+//
+// P<P<NT>>//P<P<NT>> P<NT>//P<NT>
+//
+// * The inferred static type when we get extension methods.
+//
+// ====== b = a.load() ======
+// What happens when we try to assign the result of a.load() to variable b with
+// a specific static type: runs fine, fails at compile time, or fails at runtime.
+// ==========================
+// b P<I> P<NT>
+// a
+// P<P<I>>//P<P<I>> 1 ok 2 ok
+//
+// P<P<NT>>//P<P<I>> 3 implicit downcast 4 ok
+// of returnvalue: ok
+//
+// P<P<NT>>//P<P<NT>> 5 implicit downcast 6 ok
+// of returnvalue: fail
+// at runtime
+//
+// These are the normal Dart assignment rules.
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+// ===== a.store(b) ======
+// The tests follow table cells left to right, top to bottom.
+void store1() {
+ final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+ final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store2() {
+ final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+ final Pointer<NativeType> b =
+ Pointer<Int8>.allocate(); // Reified Pointer<Int8> at runtime.
+
+ // Successful implicit downcast of argument at runtime.
+ // Should succeed now, should statically be rejected when NNBD lands.
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store3() {
+ final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+ final Pointer<NativeType> b =
+ Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+ // Failing implicit downcast of argument at runtime.
+ // Should fail now at runtime, should statically be rejected when NNBD lands.
+ Expect.throws(() {
+ a.store(b);
+ });
+
+ a.free();
+ b.free();
+}
+
+void store4() {
+ // Reified as Pointer<Pointer<Int8>> at runtime.
+ final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+ final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store5() {
+ // Reified as Pointer<Pointer<Int8>> at runtime.
+ final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+ final Pointer<NativeType> b =
+ Pointer<Int8>.allocate(); // Reified as Pointer<Int8> at runtime.
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store6() {
+ // Reified as Pointer<Pointer<Int8>> at runtime.
+ final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+ final Pointer<NativeType> b =
+ Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+ // Fails on type check of argument.
+ Expect.throws(() {
+ a.store(b);
+ });
+
+ a.free();
+ b.free();
+}
+
+void store7() {
+ final Pointer<Pointer<NativeType>> a =
+ Pointer<Pointer<NativeType>>.allocate();
+ final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store8() {
+ final Pointer<Pointer<NativeType>> a =
+ Pointer<Pointer<NativeType>>.allocate();
+
+ // Reified as Pointer<Int8> at runtime.
+ final Pointer<NativeType> b = Pointer<Int8>.allocate();
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+void store9() {
+ final Pointer<Pointer<NativeType>> a =
+ Pointer<Pointer<NativeType>>.allocate();
+ final Pointer<NativeType> b =
+ Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+ a.store(b);
+
+ a.free();
+ b.free();
+}
+
+// ====== b = a.load() ======
+// The tests follow table cells left to right, top to bottom.
+void load1() {
+ final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+
+ Pointer<Int8> b = a.load();
+ Expect.type<Pointer<Int8>>(b);
+
+ a.free();
+}
+
+void load2() {
+ final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+
+ Pointer<NativeType> b = a.load<Pointer<Int8>>();
+ Expect.type<Pointer<Int8>>(b);
+
+ a.free();
+}
+
+void load3() {
+ // Reified as Pointer<Pointer<Int8>> at runtime.
+ final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+ Pointer<Int8> b = a.load<Pointer<NativeType>>();
+ Expect.type<Pointer<Int8>>(b);
+
+ a.free();
+}
+
+void load4() {
+ // Reified as Pointer<Pointer<Int8>> at runtime.
+ final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+ // Return value runtime type is Pointer<Int8>.
+ Pointer<NativeType> b = a.load();
+ Expect.type<Pointer<Int8>>(b);
+
+ a.free();
+}
+
+void load5() {
+ final Pointer<Pointer<NativeType>> a =
+ Pointer<Pointer<NativeType>>.allocate();
+
+ // Failing implicit downcast of return value at runtime.
+ // Should fail now at runtime, should statically be rejected when NNBD lands.
+ Expect.throws(() {
+ Pointer<Int8> b = a.load<Pointer<NativeType>>();
+ });
+
+ a.free();
+}
+
+void load6() {
+ final Pointer<Pointer<NativeType>> a =
+ Pointer<Pointer<NativeType>>.allocate();
+
+ Pointer<NativeType> b = a.load();
+ Expect.type<Pointer<NativeType>>(b);
+
+ a.free();
+}
+
+void main() {
+ store1();
+ store2();
+ store3();
+ store4();
+ store5();
+ store6();
+ store7();
+ store8();
+ store9();
+ load1();
+ load2();
+ load3();
+ load4();
+ load5();
+ load6();
+}
diff --git a/tests/ffi/snapshot_test.dart b/tests/ffi/snapshot_test.dart
index 02b4cc4..a3b7d22 100644
--- a/tests/ffi/snapshot_test.dart
+++ b/tests/ffi/snapshot_test.dart
@@ -14,7 +14,7 @@
main(args) async {
try {
- await Isolate.spawn(print, fromAddress<Pointer<Void>>(1));
+ await Isolate.spawn(print, Pointer<Void>.fromAddress(1));
} catch (e) {
Expect.type<ArgumentError>(e);
return;
diff --git a/tests/ffi/static_checks_test.dart b/tests/ffi/static_checks_test.dart
index e0ab94c..7b8cdfb 100644
--- a/tests/ffi/static_checks_test.dart
+++ b/tests/ffi/static_checks_test.dart
@@ -9,6 +9,7 @@
library FfiTest;
import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
import 'dylib_utils.dart';
@@ -55,7 +56,7 @@
return result;
}
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
p.store(123);
ffi.Pointer loseType = p;
generic(loseType);
@@ -64,7 +65,7 @@
void testGetGeneric2() {
T generic<T extends Object>() {
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ Pointer<ffi.Int8> p = Pointer.allocate();
p.store(123);
T result;
result = p.load<T>(); //# 21: compile-time error
@@ -76,7 +77,7 @@
}
void testGetVoid() {
- ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
ffi.Pointer<ffi.Void> p2 = p1.cast();
p2.load<int>(); //# 22: compile-time error
@@ -85,7 +86,7 @@
}
void testGetNativeFunction() {
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+ Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntUnOp f = p.load(); //# 23: compile-time error
}
@@ -94,8 +95,8 @@
}
void testGetTypeMismatch() {
- ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
- ffi.Pointer<ffi.Int16> typedNull = null;
+ ffi.Pointer<ffi.Pointer<ffi.Int16>> p = Pointer.allocate();
+ ffi.Pointer<ffi.Int16> typedNull = ffi.nullptr.cast();
p.store(typedNull);
// this fails to compile due to type mismatch
@@ -109,7 +110,7 @@
p.store(123); //# 26: compile-time error
}
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
p.store(123);
ffi.Pointer loseType = p;
generic(loseType);
@@ -118,7 +119,7 @@
void testSetGeneric2() {
void generic<T extends Object>(T arg) {
- ffi.Pointer<ffi.Int8> p = ffi.allocate();
+ ffi.Pointer<ffi.Int8> p = Pointer.allocate();
p.store(arg); //# 27: compile-time error
p.free();
}
@@ -127,7 +128,7 @@
}
void testSetVoid() {
- ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+ ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
ffi.Pointer<ffi.Void> p2 = p1.cast();
p2.store(1234); //# 28: compile-time error
@@ -136,7 +137,7 @@
}
void testSetNativeFunction() {
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+ Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntUnOp f = (a) => a + 1;
p.store(f); //# 29: compile-time error
}
@@ -147,10 +148,10 @@
void testSetTypeMismatch() {
// the pointer to pointer types must match up
- ffi.Pointer<ffi.Int8> pHelper = ffi.allocate();
+ ffi.Pointer<ffi.Int8> pHelper = Pointer.allocate();
pHelper.store(123);
- ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+ ffi.Pointer<ffi.Pointer<ffi.Int16>> p = Pointer.allocate();
// this fails to compile due to type mismatch
p.store(pHelper); //# 40: compile-time error
@@ -161,7 +162,7 @@
void testAsFunctionGeneric() {
T generic<T extends Function>() {
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+ ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
Function f;
f = p.asFunction<T>(); //# 11: compile-time error
return f;
@@ -177,7 +178,7 @@
return f;
}
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+ ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
generic(p);
}
@@ -189,7 +190,7 @@
typedef IntBinOp = int Function(int, int);
void testAsFunctionTypeMismatch() {
- ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+ ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
IntBinOp f = p.asFunction(); //# 14: compile-time error
}
@@ -303,67 +304,132 @@
}
// error on missing field annotation
-@ffi.struct
-class TestStruct extends ffi.Pointer<ffi.Void> {
+class TestStruct extends ffi.Struct<TestStruct> {
@ffi.Double()
double x;
double y; //# 50: compile-time error
}
-// error on missing struct annotation
-class TestStruct2 extends ffi.Pointer<ffi.Void> {
- @ffi.Double() //# 51: compile-time error
- double x; //# 51: compile-time error
-}
-
-// error on missing annotation on subtype
-@ffi.struct
-class TestStruct3 extends TestStruct {
- double z; //# 52: compile-time error
-}
+// Cannot extend structs.
+class TestStruct3 extends TestStruct {} //# 52: compile-time error
// error on double annotation
-@ffi.struct
-class TestStruct4 extends ffi.Pointer<ffi.Void> {
+class TestStruct4 extends ffi.Struct<TestStruct4> {
@ffi.Double()
@ffi.Double() //# 53: compile-time error
double z;
}
// error on annotation not matching up
-@ffi.struct
-class TestStruct5 extends ffi.Pointer<ffi.Void> {
+class TestStruct5 extends ffi.Struct<TestStruct5> {
@ffi.Int64() //# 54: compile-time error
double z; //# 54: compile-time error
}
// error on annotation not matching up
-@ffi.struct
-class TestStruct6 extends ffi.Pointer<ffi.Void> {
+class TestStruct6 extends ffi.Struct<TestStruct6> {
@ffi.Void() //# 55: compile-time error
double z; //# 55: compile-time error
}
// error on annotation not matching up
-@ffi.struct
-class TestStruct7 extends ffi.Pointer<ffi.Void> {
+class TestStruct7 extends ffi.Struct<TestStruct7> {
@ffi.NativeType() //# 56: compile-time error
double z; //# 56: compile-time error
}
// error on field initializer on field
-@ffi.struct
-class TestStruct8 extends ffi.Pointer<ffi.Void> {
+class TestStruct8 extends ffi.Struct<TestStruct8> {
@ffi.Double() //# 57: compile-time error
double z = 10.0; //# 57: compile-time error
}
// error on field initializer in constructor
-@ffi.struct
-class TestStruct9 extends ffi.Pointer<ffi.Void> {
+class TestStruct9 extends ffi.Struct<TestStruct9> {
@ffi.Double()
double z;
TestStruct9() : z = 0.0 {} //# 58: compile-time error
}
+
+// A struct "C" must extend "Struct<C>", not "Struct<AnythingElse>".
+class TestStruct10 extends ffi.Struct<ffi.Int8> {} //# 59: compile-time error
+
+// Struct classes may not be generic.
+class TestStruct11<T> extends ffi.Struct<TestStruct11<dynamic>> {} //# 60: compile-time error
+
+// Structs may not appear inside structs (currently, there is no suitable
+// annotation).
+class TestStruct12 extends ffi.Struct<TestStruct12> {
+ @ffi.Pointer //# 61: compile-time error
+ TestStruct9 struct; //# 61: compile-time error
+}
+
+// Cannot extend native types.
+
+class ENativeType extends ffi.NativeType {} //# 90: compile-time error
+
+class EInt8 extends ffi.Int8 {} //# 91: compile-time error
+
+class EInt16 extends ffi.Int16 {} //# 92: compile-time error
+
+class EInt32 extends ffi.Int32 {} //# 93: compile-time error
+
+class EInt64 extends ffi.Int64 {} //# 94: compile-time error
+
+class EUint8 extends ffi.Uint8 {} //# 95: compile-time error
+
+class EUint16 extends ffi.Uint16 {} //# 96: compile-time error
+
+class EUint32 extends ffi.Uint32 {} //# 97: compile-time error
+
+class EUint64 extends ffi.Uint64 {} //# 98: compile-time error
+
+class EIntPtr extends ffi.IntPtr {} //# 99: compile-time error
+
+class EFloat extends ffi.Float {} //# 910: compile-time error
+
+class EDouble extends ffi.Double {} //# 911: compile-time error
+
+class EVoid extends ffi.Void {} //# 912: compile-time error
+
+class ENativeFunction extends ffi.NativeFunction {} //# 913: compile-time error
+
+class EPointer extends ffi.Pointer {} //# 914: compile-time error
+
+// Cannot implement native natives or Struct.
+
+// Cannot extend native types.
+
+class INativeType implements ffi.NativeType {} //# 80: compile-time error
+
+class IInt8 implements ffi.Int8 {} //# 81: compile-time error
+
+class IInt16 implements ffi.Int16 {} //# 82: compile-time error
+
+class IInt32 implements ffi.Int32 {} //# 83: compile-time error
+
+class IInt64 implements ffi.Int64 {} //# 84: compile-time error
+
+class IUint8 implements ffi.Uint8 {} //# 85: compile-time error
+
+class IUint16 implements ffi.Uint16 {} //# 86: compile-time error
+
+class IUint32 implements ffi.Uint32 {} //# 87: compile-time error
+
+class IUint64 implements ffi.Uint64 {} //# 88: compile-time error
+
+class IIntPtr implements ffi.IntPtr {} //# 88: compile-time error
+
+class IFloat implements ffi.Float {} //# 810: compile-time error
+
+class IDouble implements ffi.Double {} //# 811: compile-time error
+
+class IVoid implements ffi.Void {} //# 812: compile-time error
+
+class INativeFunction implements ffi.NativeFunction {} //# 813: compile-time error
+
+class IPointer implements ffi.Pointer {} //# 814: compile-time error
+
+class IStruct implements ffi.Struct {} //# 815: compile-time error
diff --git a/tests/ffi/structs_test.dart b/tests/ffi/structs_test.dart
index cbb2eab..a2ed758 100644
--- a/tests/ffi/structs_test.dart
+++ b/tests/ffi/structs_test.dart
@@ -6,12 +6,11 @@
library FfiTest;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
import "package:expect/expect.dart";
import 'coordinate_bare.dart' as bare;
-import 'coordinate_manual.dart' as manual;
import 'coordinate.dart';
void main() {
@@ -19,24 +18,24 @@
testStructFromAddress();
testStructWithNulls();
testBareStruct();
- testManualStruct();
testTypeTest();
}
/// allocates each coordinate separately in c memory
void testStructAllocate() {
- Coordinate c1 = Coordinate(10.0, 10.0, null);
- Coordinate c2 = Coordinate(20.0, 20.0, c1);
- Coordinate c3 = Coordinate(30.0, 30.0, c2);
- c1.next = c3;
+ Pointer<Coordinate> c1 =
+ Coordinate.allocate(10.0, 10.0, nullptr.cast()).addressOf;
+ Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
+ Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
+ c1.load<Coordinate>().next = c3;
- Coordinate currentCoordinate = c1;
+ Coordinate currentCoordinate = c1.load();
Expect.equals(10.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(30.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(20.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(10.0, currentCoordinate.x);
c1.free();
@@ -46,91 +45,76 @@
/// allocates coordinates consecutively in c memory
void testStructFromAddress() {
- Coordinate c1 = Coordinate.allocate(count: 3);
- Coordinate c2 = c1.elementAt(1);
- Coordinate c3 = c1.elementAt(2);
- c1.x = 10.0;
- c1.y = 10.0;
- c1.next = c3;
- c2.x = 20.0;
- c2.y = 20.0;
- c2.next = c1;
- c3.x = 30.0;
- c3.y = 30.0;
- c3.next = c2;
+ Pointer<Coordinate> c1 = Pointer.allocate(count: 3);
+ Pointer<Coordinate> c2 = c1.elementAt(1);
+ Pointer<Coordinate> c3 = c1.elementAt(2);
+ c1.load<Coordinate>().x = 10.0;
+ c1.load<Coordinate>().y = 10.0;
+ c1.load<Coordinate>().next = c3;
+ c2.load<Coordinate>().x = 20.0;
+ c2.load<Coordinate>().y = 20.0;
+ c2.load<Coordinate>().next = c1;
+ c3.load<Coordinate>().x = 30.0;
+ c3.load<Coordinate>().y = 30.0;
+ c3.load<Coordinate>().next = c2;
- Coordinate currentCoordinate = c1;
+ Coordinate currentCoordinate = c1.load();
Expect.equals(10.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(30.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(20.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(10.0, currentCoordinate.x);
c1.free();
}
void testStructWithNulls() {
- Coordinate coordinate = Coordinate(10.0, 10.0, null);
- Expect.isNull(coordinate.next);
- coordinate.next = coordinate;
- Expect.isNotNull(coordinate.next);
- coordinate.next = null;
- Expect.isNull(coordinate.next);
+ Pointer<Coordinate> coordinate =
+ Coordinate.allocate(10.0, 10.0, nullptr.cast<Coordinate>()).addressOf;
+ Expect.equals(coordinate.load<Coordinate>().next, nullptr);
+ coordinate.load<Coordinate>().next = coordinate;
+ Expect.notEquals(coordinate.load<Coordinate>().next, nullptr);
+ coordinate.load<Coordinate>().next = nullptr.cast();
+ Expect.equals(coordinate.load<Coordinate>().next, nullptr);
coordinate.free();
}
void testBareStruct() {
- int structSize = ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
- bare.Coordinate c1 = ffi.allocate<ffi.Uint8>(count: structSize * 3).cast();
- bare.Coordinate c2 = c1.offsetBy(structSize).cast();
- bare.Coordinate c3 = c1.offsetBy(structSize * 2).cast();
+ int structSize = sizeOf<Double>() * 2 + sizeOf<IntPtr>();
+ bare.Coordinate c1 = Pointer<Uint8>.allocate(count: structSize * 3)
+ .cast<bare.Coordinate>()
+ .load();
+ bare.Coordinate c2 =
+ c1.addressOf.offsetBy(structSize).cast<bare.Coordinate>().load();
+ bare.Coordinate c3 =
+ c1.addressOf.offsetBy(structSize * 2).cast<bare.Coordinate>().load();
c1.x = 10.0;
c1.y = 10.0;
- c1.next = c3;
+ c1.next = c3.addressOf;
c2.x = 20.0;
c2.y = 20.0;
- c2.next = c1;
+ c2.next = c1.addressOf;
c3.x = 30.0;
c3.y = 30.0;
- c3.next = c2;
+ c3.next = c2.addressOf;
bare.Coordinate currentCoordinate = c1;
Expect.equals(10.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(30.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(20.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
+ currentCoordinate = currentCoordinate.next.load();
Expect.equals(10.0, currentCoordinate.x);
- c1.free();
-}
-
-void testManualStruct() {
- manual.Coordinate c1 = manual.Coordinate(10.0, 10.0, null);
- manual.Coordinate c2 = manual.Coordinate(20.0, 20.0, c1);
- manual.Coordinate c3 = manual.Coordinate(30.0, 30.0, c2);
- c1.next = c3;
-
- manual.Coordinate currentCoordinate = c1;
- Expect.equals(10.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
- Expect.equals(30.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
- Expect.equals(20.0, currentCoordinate.x);
- currentCoordinate = currentCoordinate.next;
- Expect.equals(10.0, currentCoordinate.x);
-
- c1.free();
- c2.free();
- c3.free();
+ c1.addressOf.free();
}
void testTypeTest() {
- Coordinate c = Coordinate(10, 10, null);
- Expect.isTrue(c is ffi.Pointer);
- Expect.isTrue(c is ffi.Pointer<ffi.Void>);
- c.free();
+ Coordinate c = Coordinate.allocate(10, 10, nullptr.cast<Coordinate>());
+ Expect.isTrue(c is Struct);
+ Expect.isTrue(c is Struct<Coordinate>);
+ c.addressOf.free();
}
diff --git a/tests/ffi/subtype_test.dart b/tests/ffi/subtype_test.dart
deleted file mode 100644
index 54977b5..0000000
--- a/tests/ffi/subtype_test.dart
+++ /dev/null
@@ -1,48 +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.
-//
-// Dart test program for testing dart:ffi Pointer subtypes.
-//
-// SharedObjects=ffi_test_functions
-// VMOptions=--verbose-gc
-
-library FfiTest;
-
-import 'dart:ffi' as ffi;
-
-import "package:expect/expect.dart";
-
-import 'cstring.dart';
-import 'dylib_utils.dart';
-
-ffi.DynamicLibrary ffiTestFunctions =
- dlopenPlatformSpecific("ffi_test_functions");
-
-final triggerGc = ffiTestFunctions
- .lookupFunction<ffi.Void Function(), void Function()>("TriggerGC");
-
-void main() async {
- testAllocate();
- testSizeOf();
- testGC();
-}
-
-dynamic bar;
-
-void testAllocate() {
- CString cs = CString.toUtf8("hello world!");
- Expect.equals("hello world!", cs.fromUtf8());
- cs.free();
-}
-
-Future<void> testGC() async {
- bar = ffi.fromAddress<CString>(11);
- // Verify that the objects manufactured by 'fromAddress' can be scanned by the
- // GC.
- triggerGc();
-}
-
-void testSizeOf() {
- Expect.equals(true, 4 == ffi.sizeOf<CString>() || 8 == ffi.sizeOf<CString>());
-}
diff --git a/tests/ffi/very_large_struct.dart b/tests/ffi/very_large_struct.dart
index 283cb57..06cbac6 100644
--- a/tests/ffi/very_large_struct.dart
+++ b/tests/ffi/very_large_struct.dart
@@ -4,64 +4,52 @@
library FfiTestCoordinateBare;
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
/// Large sample struct for dart:ffi library.
-@ffi.struct
-class VeryLargeStruct extends ffi.Pointer<ffi.Void> {
- @ffi.Int8()
+class VeryLargeStruct extends Struct<VeryLargeStruct> {
+ @Int8()
int a;
- @ffi.Int16()
+ @Int16()
int b;
- @ffi.Int32()
+ @Int32()
int c;
- @ffi.Int64()
+ @Int64()
int d;
- @ffi.Uint8()
+ @Uint8()
int e;
- @ffi.Uint16()
+ @Uint16()
int f;
- @ffi.Uint32()
+ @Uint32()
int g;
- @ffi.Uint64()
+ @Uint64()
int h;
- @ffi.IntPtr()
+ @IntPtr()
int i;
- @ffi.Float()
+ @Float()
double j;
- @ffi.Double()
+ @Double()
double k;
- @ffi.Pointer()
- VeryLargeStruct parent;
+ @Pointer()
+ Pointer<VeryLargeStruct> parent;
- @ffi.IntPtr()
+ @IntPtr()
int numChidlren;
- @ffi.Pointer()
- VeryLargeStruct children;
+ @Pointer()
+ Pointer<VeryLargeStruct> children;
- @ffi.Int8()
+ @Int8()
int smallLastField;
-
- // generated by @ffi.struct annotation
- external static int sizeOf();
-
- VeryLargeStruct offsetBy(int offsetInBytes) =>
- super.offsetBy(offsetInBytes).cast();
-
- VeryLargeStruct elementAt(int index) => offsetBy(sizeOf() * index);
-
- static VeryLargeStruct allocate({int count: 1}) =>
- ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
}
diff --git a/tests/language_2/branch_canonicalization_test.dart b/tests/language_2/branch_canonicalization_test.dart
index dfb35f6..49990cd 100644
--- a/tests/language_2/branch_canonicalization_test.dart
+++ b/tests/language_2/branch_canonicalization_test.dart
@@ -47,7 +47,7 @@
main() {
final a = 1.0;
- final b = 1 << 62;
+ final b = 0x4000000000000000; // 1 << 62
final x = new A(), y = new B(), z = new C();
for (var i = 0; i < 20; i++) {
Expect.equals(1, fooDouble(a, a));
diff --git a/tests/language_2/const_map4_test.dart b/tests/language_2/const_map4_test.dart
index 2d759b9..397672c 100644
--- a/tests/language_2/const_map4_test.dart
+++ b/tests/language_2/const_map4_test.dart
@@ -13,11 +13,15 @@
b = const {1: 'a', 2: 'b', 3: 'c'};
Expect.equals(true, a == b);
+ a = const <int, String>{1: 'a', 2: 'b', 3: 'c'};
+ b = const {1: 'a', 2: 'b', 3: 'c'};
+ Expect.equals(true, a == b);
+
a = const <num, String>{1: 'a', 2: 'b', 3: 'c'};
b = const {1: 'a', 2: 'b', 3: 'c'};
Expect.equals(false, a == b);
a = const <dynamic, dynamic>{1: 'a', 2: 'b', 3: 'c'};
b = const {1: 'a', 2: 'b', 3: 'c'};
- Expect.equals(true, a == b);
+ Expect.equals(false, a == b);
}
diff --git a/tests/language_2/fannkuch_test.dart b/tests/language_2/fannkuch_test.dart
index 4aac0f5..a08a0cf 100644
--- a/tests/language_2/fannkuch_test.dart
+++ b/tests/language_2/fannkuch_test.dart
@@ -1,8 +1,8 @@
// 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.
-// The Great Computer Language Shootout
-// http://shootout.alioth.debian.org/
+// The Computer Language Benchmarks Game
+// https://benchmarksgame-team.pages.debian.net/benchmarksgame/
// Ported from JavaScript contributed by Isaac Gouy.
// Description: Repeatedly access a tiny integer-sequence.
diff --git a/tests/language_2/implicit_creation/implicit_const_context_not_test.dart b/tests/language_2/implicit_creation/implicit_const_context_not_test.dart
new file mode 100644
index 0000000..7d69c0a
--- /dev/null
+++ b/tests/language_2/implicit_creation/implicit_const_context_not_test.dart
@@ -0,0 +1,78 @@
+// 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";
+
+// Check places that are *not* supposed to be constant contexts,
+// but which do require constant values, do not introduce an implicit const.
+// Nested expressions still do.
+// (Also acts as regression test for http:/dartbug.com/36533)
+
+class C {
+ final v;
+
+ // Initializer of final field in class with const constructor.
+ // Can't use `const C()`, it's a cyclic constant dependency.
+ final i1 = []; //# 1: compile-time error
+ final i2 = const [];
+ final i3 = const [[]];
+
+ const C([this.v]);
+
+ // Initializer expression in generative const constructor.
+ const C.c1() : v = C(); //# 2: compile-time error
+ const C.c2() : v = const C();
+ const C.c3() : v = const C(C());
+
+ // Expression in redirecting generative const constuctor.
+ const C.r1() : this(C()); //# 3: compile-time error
+ const C.r2() : this(const C());
+ const C.r3() : this(const C(C()));
+
+ // Default value of positional optional parameter.
+ static List<C> foo([
+ p1 = C(), //# 4: compile-time error
+ p2 = const C(),
+ p3 = const C(C()),
+ ]) =>
+ [p2, p3];
+
+ // Default value of named optional parameter.
+ static List<C> bar({
+ p1 = C(), //# 5: compile-time error
+ p2 = const C(),
+ p3 = const C(C()),
+ }) =>
+ [p2, p3];
+}
+
+void main() {
+ var c = const C();
+ var cc = const C(C());
+
+ // Check that const constructors can be invoked without `const`,
+ // creating new instances every time.
+ var nc1 = C();
+ var nc2 = C.c2();
+ var nc3 = C.c3();
+ var nc4 = C.r2();
+ var nc5 = C.r3();
+ Expect.allDistinct([nc1, nc2, nc3, nc4, nc5, c, cc]);
+
+ // Check that const invocations create identical objects.
+ Expect.identical(c, C.c2().v);
+ Expect.identical(cc, C.c3().v);
+
+ Expect.identical(c, C.r2().v);
+ Expect.identical(cc, C.r3().v);
+
+ Expect.identical(const [], C().i2);
+ Expect.identical(const [[]], C().i3);
+
+ Expect.identical(c, C.foo()[0]);
+ Expect.identical(cc, C.foo()[1]);
+
+ Expect.identical(c, C.bar()[0]);
+ Expect.identical(cc, C.bar()[1]);
+}
diff --git a/tests/language_2/issue32353_2_test.dart b/tests/language_2/issue32353_2_test.dart
index c959089..19aff61 100644
--- a/tests/language_2/issue32353_2_test.dart
+++ b/tests/language_2/issue32353_2_test.dart
@@ -7,7 +7,7 @@
// Error: 'D' can't implement both '#lib1::B<#lib1::D::X, #lib1::D::Y>' and
// '#lib1::B<#lib1::D::X, #lib1::A>'
// class D<X, Y> extends B<X, Y> with C<X> {}
-// ^
+// ~
class A {}
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 3741571..4daa9a6 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -2,9 +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.
-[ $compiler == app_jit ]
-deferred_inheritance_constraints_test/redirecting_constructor: Crash
-
[ $compiler == compare_analyzer_cfe ]
const_native_factory_test: Fail # Issue 29763
deferred_global_test: Fail # Issue 34503
@@ -24,6 +21,11 @@
[ $compiler != dart2analyzer ]
switch_case_warn_test: Skip # Analyzer only, see language_analyzer2.status
+[ $compiler == none ]
+invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34013
+library_env_test/has_no_mirror_support: RuntimeError, OK
+void/*: Skip # https://github.com/dart-lang/sdk/issues/34013
+
[ $compiler == spec_parser ]
double_literals/*: Skip # https://github.com/dart-lang/sdk/issues/34355
invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34015
@@ -58,9 +60,6 @@
partial_instantiation_static_bounds_check_test/02: MissingCompileTimeError # Issue 34327
partial_instantiation_static_bounds_check_test/03: MissingCompileTimeError # Issue 34327
-[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
-built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
-
[ $compiler != compare_analyzer_cfe && $compiler != dart2js && $compiler != spec_parser && !$fasta ]
compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
@@ -93,14 +92,12 @@
[ $compiler != dart2js && $compiler != dartdevc && !$checked ]
function_type/*: Skip # Needs checked mode.
+[ $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
+built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
+
[ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
*: SkipByDesign # Deprecating all Dart1 modes of execution
-[ $compiler == app_jit || $compiler == none ]
-invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34013
-library_env_test/has_no_mirror_support: RuntimeError, OK
-void/*: Skip # https://github.com/dart-lang/sdk/issues/34013
-
[ $hot_reload || $hot_reload_rollback ]
cha_deopt1_test: Crash # Requires deferred libraries
cha_deopt2_test: Crash # Requires deferred libraries
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index d6403c5..8f1b289 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -17,7 +17,6 @@
bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-branch_canonicalization_test: RuntimeError
call_method_as_cast_test/06: RuntimeError
call_method_implicit_tear_off_implements_function_test/05: RuntimeError
call_method_implicit_tear_off_implements_function_test/06: RuntimeError
@@ -37,10 +36,8 @@
const_constructor_nonconst_param_test/01: MissingCompileTimeError
const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
const_evaluation_test/01: RuntimeError
-const_list_test: RuntimeError
const_map2_test/00: MissingCompileTimeError
const_map3_test/00: MissingCompileTimeError
-const_map4_test: RuntimeError
const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
constructor12_test: RuntimeError
@@ -118,7 +115,6 @@
library_env_test/has_mirror_support: Fail # mirrors not supported on web
library_env_test/has_no_html_support: RuntimeError, OK
library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
-list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
local_function2_test/none: RuntimeError
local_function3_test/none: RuntimeError
local_function_test/none: RuntimeError
@@ -168,7 +164,6 @@
modulo_test: RuntimeError # non JS number semantics
named_parameters_default_eq_test/none: RuntimeError
nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: RuntimeError
no_main_test/01: CompileTimeError
no_such_method_mock_test: RuntimeError
null_no_such_method_test: CompileTimeError
@@ -198,10 +193,10 @@
super_call4_test/01: MissingCompileTimeError
super_test: RuntimeError
tearoff_dynamic_test: RuntimeError
-truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
+truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
type_constants_test/none: RuntimeError # Issue 35052
type_error_test: RuntimeError
-type_literal_test: RuntimeError
+type_literal_canonicalization_test: RuntimeError
type_promotion_more_specific_test/04: CompileTimeError
vm/*: SkipByDesign # Tests for the VM.
@@ -269,7 +264,6 @@
bit_operations_test/03: RuntimeError
bit_operations_test/04: RuntimeError
bit_operations_test/none: RuntimeError
-branch_canonicalization_test: RuntimeError
canonical_const2_test: RuntimeError, OK # non JS number semantics
checked_method_error_order_test: RuntimeError
class_cycle_test/02: MissingCompileTimeError
@@ -464,7 +458,6 @@
mock_writable_final_private_field_test: RuntimeError # Issue 17526, 30847
modulo_test: RuntimeError # non JS number semantics
nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: Crash # Unsupported operation: Unsupported type parameter type node F.
no_main_test/01: CompileTimeError
not_enough_positional_arguments_test/00: MissingCompileTimeError
not_enough_positional_arguments_test/01: MissingCompileTimeError
@@ -496,9 +489,9 @@
stacktrace_test: RuntimeError # Issue 12698
symbol_literal_test/01: MissingCompileTimeError
tearoff_dynamic_test: RuntimeError
-truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
+truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
type_check_const_function_typedef2_test: MissingCompileTimeError
-type_literal_test: RuntimeError
+type_literal_canonicalization_test: RuntimeError
type_parameter_test/06: Crash # Internal Error: Unexpected type variable in static context.
type_parameter_test/09: Crash # Internal Error: Unexpected type variable in static context.
type_variable_scope_test/03: Crash # Internal Error: Unexpected type variable in static context.
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 26643dc..b2b9294 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -298,7 +298,6 @@
bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-branch_canonicalization_test: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <1>) fails.
built_in_identifier_prefix_test: CompileTimeError
canonical_const2_test: RuntimeError # Ints and doubles are unified.; Expect.isFalse(true) fails.
closure_call_wrong_argument_count_negative_test: Fail
@@ -307,7 +306,6 @@
config_import_corelib_test: CompileTimeError
const_evaluation_test/01: RuntimeError # dart:mirrors not supported in DDC
const_list_test: RuntimeError # Expect.equals(expected: <false>, actual: <true>) fails.
-const_map4_test: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
const_switch_test/02: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <0.0>) fails.
const_switch_test/04: RuntimeError # Ints and doubles are unified.; Expect.equals(expected: <1>, actual: <1.0>) fails.
constructor12_test: RuntimeError # Issue 29920; ReferenceError: JSArrayOfT is not defined
@@ -357,7 +355,6 @@
library_env_test/has_io_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
library_env_test/has_mirror_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
library_env_test/has_no_html_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
-list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
local_function2_test/none: RuntimeError # ReferenceError: TToNull is not defined
local_function3_test/none: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
local_function_test/none: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 5953301..d17264f9 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -33,7 +33,6 @@
config_import_test: RuntimeError
const_list_test: RuntimeError
const_locals_test: RuntimeError
-const_map4_test: RuntimeError
const_nested_test: RuntimeError
const_string_test: RuntimeError
constructor12_test: RuntimeError
@@ -135,7 +134,6 @@
web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
[ $compiler == dartdevk ]
-mixin_method_override_test/G5: Skip # Issue 34354
private_method_tearoff_test: RuntimeError
[ $compiler == dartkp ]
@@ -236,7 +234,6 @@
mixin_illegal_superclass_test/28: MissingCompileTimeError
mixin_illegal_superclass_test/29: MissingCompileTimeError
mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
multiline_newline_test/04: MissingCompileTimeError
multiline_newline_test/04r: MissingCompileTimeError
multiline_newline_test/05: MissingCompileTimeError
@@ -275,21 +272,13 @@
f_bounded_quantification4_test: CompileTimeError # Issue 34583
issue31596_super_test/02: MissingCompileTimeError # Issue 31596
issue31596_super_test/04: MissingCompileTimeError # Issue 31596
-issue34488_test/01: MissingCompileTimeError # Issue 34488
-issue34488_test/02: MissingCompileTimeError # Issue 34488
-issue34488_test/03: MissingCompileTimeError # Issue 34488
-issue34488_test/04: MissingCompileTimeError # Issue 34488
-issue34488_test/05: MissingCompileTimeError # Issue 34488
-issue34488_test/06: MissingCompileTimeError # Issue 34488
mixin_declaration/mixin_declaration_invalid_override_test/08: MissingCompileTimeError
mixin_declaration/mixin_declaration_superinvocation_application_test/04: MissingCompileTimeError
mixin_declaration/mixin_declaration_superinvocation_application_test/05: MissingCompileTimeError
mixin_declaration/mixin_declaration_superinvocation_application_test/06: MissingCompileTimeError
mixin_declaration/mixin_declaration_superinvocation_application_test/07: MissingCompileTimeError
mixin_declaration/mixin_declaration_superinvocation_application_test/08: MissingCompileTimeError
-mixin_method_override_test/G5: Crash # Issue 34354
nnbd/*: Skip
-override_inheritance_field_test/42: MissingCompileTimeError
regress_22976_test/*: CompileTimeError # Issue 31935
set_literals/invalid_set_literal_test/08: MissingCompileTimeError # Requires constant evaluation
set_literals/invalid_set_literal_test/09: MissingCompileTimeError # Requires constant evaluation
@@ -600,7 +589,6 @@
config_import_test: RuntimeError # KernelVM bug: Configurable imports.
const_evaluation_test: SkipByDesign
const_list_test: RuntimeError
-const_map4_test: RuntimeError
constructor12_test: RuntimeError
constructor3_test: Fail, OK, Pass
ct_const2_test: Skip # Incompatible flag: --compile_all
@@ -925,7 +913,6 @@
const_dynamic_type_literal_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
const_list_test: RuntimeError
const_locals_test: RuntimeError
-const_map4_test: RuntimeError
const_nested_test: RuntimeError # KernelVM bug: Constant evaluation.
const_string_test: RuntimeError
constructor12_test: RuntimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 7416230..4149ec3 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -18,15 +18,6 @@
async_star/async_star_cancel_test: RuntimeError
async_star/async_star_test: RuntimeError
-[ $compiler == precompiler && $runtime == dart_precompiled ]
-async_star/async_star_await_for_test: RuntimeError
-async_star/async_star_cancel_test: RuntimeError
-async_star/async_star_invalid_test/01: MissingCompileTimeError
-async_star/async_star_invalid_test/02: MissingCompileTimeError
-async_star/async_star_invalid_test/04: MissingCompileTimeError
-async_star/async_star_invalid_test/none: RuntimeError
-async_star/async_star_test: RuntimeError
-
[ $runtime == dart_precompiled && $minified ]
cyclic_type_test/*: Skip
enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language_2/list_test.dart b/tests/language_2/list_test.dart
index 9108409..e5475c4 100644
--- a/tests/language_2/list_test.dart
+++ b/tests/language_2/list_test.dart
@@ -118,7 +118,7 @@
Expect.equals(9, element);
Expect.throws(() => new List(-1));
- Expect.throws(() => new List(0x7fffffffffffffff));
+ Expect.throws(() => new List(0x7ffffffffffff000));
List list = new List();
Expect.throwsRangeError(list.removeLast);
diff --git a/tests/language_2/nested_generic_closure_test.dart b/tests/language_2/nested_generic_closure_test.dart
index 57a3f6d..1c5925c 100644
--- a/tests/language_2/nested_generic_closure_test.dart
+++ b/tests/language_2/nested_generic_closure_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=--reify-generic-functions
+// TODO(37452): Avoid using unspecified 'toString' behaviour in language test.
import 'package:expect/expect.dart';
@@ -25,11 +25,34 @@
}
main() {
- Expect.equals("(<F>(F) => F) => void", foo.runtimeType.toString());
- Expect.equals("<B>(<F>(F) => B) => B", bar.runtimeType.toString());
- Expect.equals("<F>(F) => int", baz<int>().runtimeType.toString());
+ expectOne(
+ foo.runtimeType.toString(),
+ ["(<F>(F) => F) => void", "(<T1>(T1) => T1) => void"],
+ );
+ expectOne(
+ bar.runtimeType.toString(),
+ ["<B>(<F>(F) => B) => B", "<T1>(<T2>(T2) => T1) => T1"],
+ );
+ expectOne(
+ baz<int>().runtimeType.toString(),
+ ["<F>(F) => int", "<T1>(T1) => int"],
+ );
+
var c = new C<bool>();
- Expect.equals("(<F>(bool, F) => F) => void", c.foo.runtimeType.toString());
- Expect.equals("<B>(<F>(bool, F) => B) => B", c.bar.runtimeType.toString());
- Expect.equals("<F>(bool, F) => int", c.baz<int>().runtimeType.toString());
+ expectOne(
+ c.foo.runtimeType.toString(),
+ ["(<F>(bool, F) => F) => void", "(<T1>(bool, T1) => T1) => void"],
+ );
+ expectOne(
+ c.bar.runtimeType.toString(),
+ ["<B>(<F>(bool, F) => B) => B", "<T1>(<T2>(bool, T2) => T1) => T1"],
+ );
+ expectOne(
+ c.baz<int>().runtimeType.toString(),
+ ["<F>(bool, F) => int", "<T1>(bool, T1) => int"],
+ );
+}
+
+expectOne(String name, Iterable<String> names) {
+ Expect.isTrue(names.contains(name), '"$name" should be one of: ${names}');
}
diff --git a/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart b/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
index 9757f79..2d6c7a6 100644
--- a/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
+++ b/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
@@ -27,7 +27,7 @@
// Caveat: it is NOT that the argument is promoted to non-null. Otherwise,
// types which we can't cleanly promote, such as FutureOr<int?>, would not be
// assignable in comparisons.
- FutureOr<int?> foInt = Future.value(0);
+ FutureOr<int?> foInt;
// Valid comparison.
o == foInt;
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart
new file mode 100644
index 0000000..2043828
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v; //# none: compile-time error
+ if (b) {
+ // not assigned
+ } else {
+ v = 1;
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart
new file mode 100644
index 0000000..5eb19ce
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v;
+ if (b) {
+ v = 0;
+ } else {
+ v = 1;
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart
new file mode 100644
index 0000000..2b9496c
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v; //# none: compile-time error
+ if (b) {
+ v = 0;
+ } else {
+ // not assigned
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_test.dart
new file mode 100644
index 0000000..7c65fb5
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v; //# none: compile-time error
+ if (b) {
+ v = 0;
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
new file mode 100644
index 0000000..ba9f896
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+// This test check cases when the variable is only initialized (or not)
+// at its declaration, and there are no other assignments.
+
+void main() {
+ int v; v; //# 01: compile-time error
+ int v; //# 02: ok
+ int v = 0; v; //# 03: ok
+ late int v; v; //# 04: ok
+ late int v = 0; v; //# 05: ok
+ int? v; v; //# 06: ok
+ int? v = 0; v; //# 07: ok
+
+}
+
+f<T>(T a) {
+ T v; v; //# 08: compile-time error
+ T v; //# 09: ok
+ T v = a; v; //# 10: ok
+ late T v; v; //# 11: ok
+ late T v = a; v; //# 12: ok
+ T? v; v; //# 13: ok
+ T? v = a; v; //# 14: ok
+}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart
new file mode 100644
index 0000000..94968d3
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+void main() {
+ int v;
+ try {
+ g();
+ v = 0;
+ } catch (_) {
+ v = 1;
+ }
+ v;
+}
+
+void g() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart
new file mode 100644
index 0000000..05a8676
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+void main() {
+ int v; //# none: compile-time error
+ try {
+ g();
+ v = 0;
+ } catch (_) {
+ // not assigned
+ }
+ v;
+}
+
+void g() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_test.dart
new file mode 100644
index 0000000..8c9a408
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v;
+ while (true) {
+ v = 0;
+ if (b) break;
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_test.dart
new file mode 100644
index 0000000..d0443ad
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+ int v; //# none: compile-time error
+ while (true) {
+ if (b) break;
+ v = 0;
+ }
+ v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_test.dart
new file mode 100644
index 0000000..a70142e
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that it is an error if a static field non-nullable type has no
+// initializer expression.
+void main() {}
+
+class A {
+ static int v; //# 01: compile-time error
+ static int v = 0; //# 02: ok
+ static int? v; //# 03: ok
+ static int? v = 0; //# 04: ok
+ static dynamic v; //# 05: ok
+ static var v; //# 06: ok
+ static void v; //# 07: ok
+ static Never v; //# 08: compile-time error
+}
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
deleted file mode 100644
index d4b2207..0000000
--- a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
+++ /dev/null
@@ -1,29 +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.
-
-// SharedOptions=--enable-experiment=non-nullable
-
-// It is an error if a potentially non-nullable local variable which has no
-// initializer expression and is not marked `late` is used before it is
-// definitely assigned.
-// TODO(scheglov) Update once we implement definite assignment analysis.
-
-void main() {
- int v; //# 01: compile-time error
- int v = 0; //# 02: ok
- late int v; //# 03: ok
- late int v = 0; //# 04: ok
- int? v; //# 05: ok
- int? v = 0; //# 06: ok
-
-}
-
-f<T>(T a) {
- T v; //# 07: compile-time error
- T v = a; //# 08: ok
- late T v; //# 09: ok
- late T v = a; //# 10: ok
- T? v; //# 11: ok
- T? v = a; //# 12: ok
-}
diff --git a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
index b8265e3..059b2d5 100644
--- a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
+++ b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
@@ -29,12 +29,9 @@
// Out of order modifiers
class C2 {
void m({
- covariant
- required //# 07: compile-time error
- int i2,
- final
- required //# 08: compile-time error
- int i3,
+ required int i1,
+ covariant required int i2, //# 07: compile-time error
+ final required int i3, //# 08: compile-time error
}) {
}
}
diff --git a/tests/language_2/nnbd/type_promotion/assignment_test.dart b/tests/language_2/nnbd/type_promotion/assignment_test.dart
new file mode 100644
index 0000000..ab93abb
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/assignment_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is String) {
+ x = 42;
+ x.length; //# none: compile-time error
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/conditional_both_test.dart b/tests/language_2/nnbd/type_promotion/conditional_both_test.dart
new file mode 100644
index 0000000..a663af58
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/conditional_both_test.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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+ b ? ((x is String) || (throw 1)) : ((x is String) || (throw 2));
+ x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart b/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart
new file mode 100644
index 0000000..c5b7420
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ do {
+ x.length; //# 01: compile-time error
+ } while (x is! String);
+ x.length; //# 02: ok
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart b/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart
new file mode 100644
index 0000000..83572cd
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ do {
+ x.length; //# 01: compile-time error
+ } while (x is String);
+ x.length; //# 02: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart
new file mode 100644
index 0000000..06f0653
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+ if (x is String) {
+ do {
+ x.length;
+ } while (b);
+ x.length;
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart
new file mode 100644
index 0000000..3aaed04
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+ if (x is String) {
+ for (; b;) {
+ x.length;
+ }
+ x.length;
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
new file mode 100644
index 0000000..5f67881
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f() {
+ void g(Object x) {
+ if (x is String) {
+ x.length; //# none: compile-time error
+ }
+
+ void h() {
+ x = 42;
+ }
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart
new file mode 100644
index 0000000..83200a7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f() {
+ void g(Object x) {
+ if (x is String) {
+ x.length;
+ }
+ x = 42;
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
new file mode 100644
index 0000000..a9a546f
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ void Function() g;
+
+ if (x is String) {
+ x.length;
+
+ g = () {
+ x.length; //# 01: compile-time error
+ };
+ }
+
+ x = 42;
+ x.length; //# 02: compile-time error
+ g();
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart b/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart
new file mode 100644
index 0000000..4fb31b7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is! String) {
+ x.length; //# 01: compile-time error
+ } else {
+ x.length; //# 02: ok
+ }
+ x.length; //# 03: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/if_is_type_test.dart b/tests/language_2/nnbd/type_promotion/if_is_type_test.dart
new file mode 100644
index 0000000..dc97344
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/if_is_type_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is String) {
+ x.length; //# 01: ok
+ } else {
+ x.length; //# 02: compile-time error
+ }
+ x.length; //# 03: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/logical_or_throw_test.dart b/tests/language_2/nnbd/type_promotion/logical_or_throw_test.dart
new file mode 100644
index 0000000..e8c7e8b
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/logical_or_throw_test.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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ x is String || (throw 42);
+ x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart
new file mode 100644
index 0000000..4a3bef4
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is! String) return;
+ x.length;
+ try {
+ x = 42;
+ g(); // might throw
+ if (x is! String) return;
+ x.length;
+ } catch (_) {}
+ x.length; //# 01: compile-time error
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_test.dart
new file mode 100644
index 0000000..41449de
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is String) {
+ try {
+ x.length;
+ } catch (_) {
+ x.length;
+ } finally {
+ x.length;
+ }
+ x.length;
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_test.dart
new file mode 100644
index 0000000..9b2462c
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ try {
+ if (x is! String) return;
+ x.length;
+ } catch (_) {
+ if (x is! String) return;
+ x.length;
+ }
+ x.length;
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.dart
new file mode 100644
index 0000000..3d8ca81
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ try {
+ if (x is! String) return;
+ x.length;
+ } catch (_) {}
+ x.length; //# 01: compile-time error
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_test.dart b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_test.dart
new file mode 100644
index 0000000..eeabbe7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is String) {
+ try {
+ x.length;
+ x = 42;
+ } finally {
+ x.length; //# 01: compile-time error
+ }
+ x.length; //# 02: compile-time error
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_test.dart b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_test.dart
new file mode 100644
index 0000000..bca9b42
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ if (x is String) {
+ try {
+ x.length;
+ } finally {
+ x.length;
+ x = 42;
+ }
+ x.length; //# 01: compile-time error
+ }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart b/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart
new file mode 100644
index 0000000..8301ac9
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ while (x is! String) {
+ x.length; //# 01: compile-time error
+ }
+ x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart b/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart
new file mode 100644
index 0000000..468b14e
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+ while (x is String) {
+ x.length;
+ }
+ x.length; //# 01: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/truncdiv_test.dart b/tests/language_2/truncdiv_test.dart
index f6b0cc3..bd043d1 100644
--- a/tests/language_2/truncdiv_test.dart
+++ b/tests/language_2/truncdiv_test.dart
@@ -16,8 +16,11 @@
Expect.equals(i ~/ i, foo2(i));
}
}
- Expect.throws(() => foo(12, 0), (e) => e is IntegerDivisionByZeroException);
- Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
+ // We don't specify the exact exception type here, that is covered in
+ // truncdiv_zero_test. The correct answer is IntegerDivisionByZeroException,
+ // but the web platform has only one num type and can't distinguish between
+ // int and double, so it throws UnsupportedError (the behaviour for double).
+ Expect.throws(() => foo2(0));
}
foo(i, x) => i % x;
diff --git a/tests/language_2/truncdiv_zero_test.dart b/tests/language_2/truncdiv_zero_test.dart
new file mode 100644
index 0000000..34cecc3
--- /dev/null
+++ b/tests/language_2/truncdiv_zero_test.dart
@@ -0,0 +1,14 @@
+// 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 optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+import "truncdiv_test.dart" as truncdiv_test show foo, foo2;
+
+main() {
+ Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo(12, 0));
+ Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo2(0));
+}
diff --git a/tests/language_2/type_literal_canonicalization_test.dart b/tests/language_2/type_literal_canonicalization_test.dart
new file mode 100644
index 0000000..790f1b6
--- /dev/null
+++ b/tests/language_2/type_literal_canonicalization_test.dart
@@ -0,0 +1,26 @@
+// 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";
+
+class Foo {}
+
+class Box<T> {
+ Type get typeArg => T;
+}
+
+/// A typedef that defines a non-generic function type.
+typedef int Func1(bool b);
+
+/// Semantically identical to [Func], but using the Dart 2 syntax.
+typedef Func2 = int Function(bool);
+
+main() {
+ // Literals are canonicalized.
+ Expect.identical(Foo, Foo);
+ Expect.identical(Box, Box);
+ Expect.identical(new Box<Foo>().typeArg, new Box<Foo>().typeArg);
+ Expect.identical(Func1, Func1);
+ Expect.identical(Func2, Func2);
+}
diff --git a/tests/language_2/type_literal_test.dart b/tests/language_2/type_literal_test.dart
index c21c95a..6eee895 100644
--- a/tests/language_2/type_literal_test.dart
+++ b/tests/language_2/type_literal_test.dart
@@ -69,18 +69,16 @@
["GenericTypedef2", "GenericTypedef2<dynamic>", "(dynamic) => int"]);
testType(new Box<GenericTypedef<int>>().typeArg,
["GenericTypedef<int>", "(int) => int"]);
- testType(GenericFunc, ["GenericFunc", "<T>(T) => int"]);
+ testType(GenericFunc, ["GenericFunc", "<T>(T) => int", "<T1>(T1) => int"]);
testType(GenericTypedefAndFunc, [
"GenericTypedefAndFunc",
"GenericTypedefAndFunc<dynamic>",
- "<T>(T) => dynamic"
+ "<T>(T) => dynamic",
+ "<T1>(T1) => dynamic",
]);
// Literals are canonicalized.
- Expect.identical(Foo, Foo);
- Expect.identical(Box, Box);
- Expect.identical(new Box<Foo>().typeArg, new Box<Foo>().typeArg);
- Expect.identical(Func, Func);
+ // See type_literal_canonicalization_test.dart
// Static member uses are not type literals.
Foo.property = "value";
@@ -97,13 +95,18 @@
}
void testType(Type type, Object expectedToStringValues) {
+ Expect.isTrue(type is Type);
+ String text = type.toString();
+
+ // dart2js minified names should be tagged. We can still test types that don't
+ // contain minified names.
+ if (text.contains('minified:')) return;
+
if (expectedToStringValues is List) {
- var s = type.toString();
- Expect.isTrue(expectedToStringValues.contains(s),
+ Expect.isTrue(expectedToStringValues.contains(text),
'type `$type`.toString() should be one of: $expectedToStringValues.');
} else {
var string = expectedToStringValues as String;
- Expect.equals(string, type.toString());
+ Expect.equals(string, text);
}
- Expect.isTrue(type is Type);
}
diff --git a/tests/language_2/vm/reflect_core_vm_test.dart b/tests/language_2/vm/reflect_core_vm_test.dart
index e13f36e..75fff71 100644
--- a/tests/language_2/vm/reflect_core_vm_test.dart
+++ b/tests/language_2/vm/reflect_core_vm_test.dart
@@ -10,6 +10,6 @@
main() {
var s = "string";
var im = reflect(s);
- Expect.throwsNoSuchMethodError(
- () => im.invoke(const Symbol("_setAt"), [0, 65]));
+ Expect.throwsNoSuchMethodError(() =>
+ im.invoke(MirrorSystem.getSymbol("_setAt", im.type.owner), [0, 65]));
}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 1e56403..666063e 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -16,42 +16,6 @@
[ $runtime == chrome ]
html/element_animate_test/timing_dict: RuntimeError # Issue 26730
-[ $runtime == dart_precompiled ]
-isolate/count_test: Skip # Isolate.spawnUri
-isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
-isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
-isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_6610_test: Skip # Isolate.spawnUri
-isolate/mandel_isolate_test: Skip # Isolate.spawnUri
-isolate/message2_test: Skip # Isolate.spawnUri
-isolate/message_test: Skip # Isolate.spawnUri
-isolate/mint_maker_test: Skip # Isolate.spawnUri
-isolate/nested_spawn2_test: Skip # Isolate.spawnUri
-isolate/nested_spawn_test: Skip # Isolate.spawnUri
-isolate/raw_port_test: Skip # Isolate.spawnUri
-isolate/request_reply_test: Skip # Isolate.spawnUri
-isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
-isolate/spawn_function_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
-isolate/stacktrace_message_test: Skip # Isolate.spawnUri
-isolate/static_function_test: Skip # Isolate.spawnUri
-isolate/unresolved_ports_test: Skip # Isolate.spawnUri
-
[ $runtime == ff ]
convert/streamed_conversion_utf8_decode_test: Pass, Slow # Issue 12029
mirrors/mirrors_reader_test: Timeout, Slow, RuntimeError # Issue 16589
@@ -184,21 +148,18 @@
html/request_animation_frame_test: Skip # Times out. Issue 22167
html/transition_event_test: Skip # Times out. Issue 22167
+[ $runtime != dart_precompiled && ($runtime != vm || $compiler != dartk && $compiler != none) ]
+isolate/vm_rehash_test: SkipByDesign
+
[ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
*: SkipByDesign # Deprecating all Dart1 modes of execution
-[ ($compiler != precompiler || $runtime != dart_precompiled) && ($runtime != vm || $compiler != dartk && $compiler != none) ]
-isolate/vm_rehash_test: SkipByDesign
-
[ $arch == simarm || $arch == simarmv5te || $arch == simarmv6 ]
convert/utf85_test: Skip # Pass, Slow Issue 12644.
[ $arch != x64 || $compiler == dartkb || $runtime != vm ]
isolate/int32_length_overflow_test: SkipSlow
-[ $compiler == app_jit || $mode == product || $runtime != vm ]
-isolate/checked_test: Skip # Unsupported.
-
[ $compiler != none || $runtime != vm ]
isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
@@ -206,6 +167,9 @@
isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
+[ $mode == product || $runtime != vm ]
+isolate/checked_test: Skip # Unsupported.
+
[ $runtime == chrome || $runtime == chromeOnAndroid ]
html/webgl_1_test: Pass, Fail # Issue 8219
@@ -217,6 +181,46 @@
isolate/isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to pass when we have wrapper-less tests.
isolate/stacktrace_message_test: RuntimeError # Fails to send stacktrace object.
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+isolate/count_test: Skip # Isolate.spawnUri
+isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
+isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
+isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_6610_test: Skip # Isolate.spawnUri
+isolate/mandel_isolate_test: Skip # Isolate.spawnUri
+isolate/message2_test: Skip # Isolate.spawnUri
+isolate/message_test: Skip # Isolate.spawnUri
+isolate/mint_maker_test: Skip # Isolate.spawnUri
+isolate/nested_spawn2_test: Skip # Isolate.spawnUri
+isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/raw_port_test: Skip # Isolate.spawnUri
+isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
+isolate/spawn_function_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
+isolate/stacktrace_message_test: Skip # Isolate.spawnUri
+isolate/static_function_test: Skip # Isolate.spawnUri
+isolate/unresolved_ports_test: Skip # Isolate.spawnUri
+
[ $hot_reload || $hot_reload_rollback ]
async/stream_transformer_test: Pass, Fail # Closure identity
convert/chunked_conversion_utf88_test: SkipSlow
diff --git a/tests/lib_2/lib_2_app_jit.status b/tests/lib_2/lib_2_app_jit.status
index d219200..cb39a57 100644
--- a/tests/lib_2/lib_2_app_jit.status
+++ b/tests/lib_2/lib_2_app_jit.status
@@ -2,5 +2,5 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-[ $compiler == app_jit || $compiler == app_jitk ]
+[ $compiler == app_jitk ]
mirrors/*: Skip # Issue 27929: Triage
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index 368c7ba..dd4bbaa 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -82,7 +82,6 @@
js/null_test: RuntimeError # Issue 30652
math/double_pow_test: RuntimeError # Issue 29922
math/double_pow_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-math/low_test: RuntimeError # Issue 29922
math/random_big_test: RuntimeError # Issue 29922
mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
mirrors/private_types_test: RuntimeError # Issue 29922
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index c52f96f..2c6f12b 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -48,15 +48,9 @@
mirrors/redirecting_factory_test/01: CompileTimeError # Issue 34714
mirrors/redirecting_factory_test/none: CompileTimeError # Issue 34714
-[ $arch == simdbc64 && $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-isolate/isolate_complex_messages_test: Crash # http://dartbug.com/33128
-
[ $arch == simdbc64 && $hot_reload_rollback ]
convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Uses --verify_before_gc --verify_after_gc --old_gen_growth_rate=1 flags
-[ $arch == simdbc64 && ($compiler == dartk || $compiler == dartkb) ]
-isolate/issue_24243_parent_isolate_test: RuntimeError # dartbug.com/35373
-
[ $arch == x64 && $builder_tag == asan && $compiler == dartk ]
mirrors/dynamic_load_test: Fail # Memory leak (issue 34724)
@@ -207,8 +201,6 @@
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
# batch mode.
[ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
-isolate/mandel_isolate_test: Pass, Timeout
-isolate/nested_spawn2_test: Pass, RuntimeError # RuntimeError caused by timeout
mirrors/library_uri_io_test: RuntimeError # Please triage.
[ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
diff --git a/tests/lib_2/lib_2_precompiled.status b/tests/lib_2/lib_2_precompiled.status
index 9a1e896..d93502d 100644
--- a/tests/lib_2/lib_2_precompiled.status
+++ b/tests/lib_2/lib_2_precompiled.status
@@ -2,35 +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.
-[ $compiler == precompiler ]
-async/async_no_await_zones_test: RuntimeError # Issue 33700
-convert/chunked_conversion_utf88_test: Pass, Timeout
-convert/utf85_test: Pass, Timeout
-html/*: SkipByDesign # dart:html not supported on AOT.
-isolate/count_test: SkipByDesign
-isolate/cross_isolate_message_test: SkipByDesign
-isolate/illegal_msg_function_test: SkipByDesign
-isolate/illegal_msg_mirror_test: SkipByDesign
-isolate/isolate_complex_messages_test: SkipByDesign
-isolate/mandel_isolate_test: SkipByDesign
-isolate/message2_test: SkipByDesign
-isolate/message_test: SkipByDesign
-isolate/mint_maker_test: SkipByDesign
-isolate/nested_spawn2_test: SkipByDesign
-isolate/nested_spawn_test: SkipByDesign
-isolate/raw_port_test: SkipByDesign
-isolate/request_reply_test: SkipByDesign
-isolate/spawn_function_custom_class_test: SkipByDesign
-isolate/spawn_function_test: SkipByDesign
-isolate/stacktrace_message_test: SkipByDesign
-isolate/static_function_test: SkipByDesign
-isolate/unresolved_ports_test: SkipByDesign
-js/datetime_roundtrip_test: CompileTimeError
-js/null_test: CompileTimeError
-js/prototype_access_test: CompileTimeError
-mirrors/*: SkipByDesign # Mirrors not supported on AOT.
-
-[ $compiler == app_jit || $compiler == none || $compiler == precompiler ]
+[ $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
diff --git a/tests/lib_2/math/low_test.dart b/tests/lib_2/math/low_test.dart
index 6014ef5..f7e9060 100644
--- a/tests/lib_2/math/low_test.dart
+++ b/tests/lib_2/math/low_test.dart
@@ -9,7 +9,7 @@
import 'dart:math';
void main() {
- var n = (2 * (1 << 32)) ~/ 3;
+ var n = (2 * 0x100000000) ~/ 3;
var n2 = n ~/ 2;
var iterations = 200000;
diff --git a/tests/standalone_2/causal_async_stack_test.dart b/tests/standalone_2/causal_async_stack_test.dart
index faebf3e..eab14af 100644
--- a/tests/standalone_2/causal_async_stack_test.dart
+++ b/tests/standalone_2/causal_async_stack_test.dart
@@ -5,7 +5,12 @@
import "package:expect/expect.dart";
+noop() async => Future.value(null);
+
baz() async {
+ // Throw exception after the first continuation, when there is no
+ // original stack trace.
+ await noop();
throw "Bad!";
}
diff --git a/tests/standalone_2/http_launch_test.dart b/tests/standalone_2/http_launch_test.dart
index cb97f84..59f93c5 100644
--- a/tests/standalone_2/http_launch_test.dart
+++ b/tests/standalone_2/http_launch_test.dart
@@ -41,7 +41,7 @@
final File file = new File(requestPath.toFilePath());
file.exists().then((bool found) {
if (found) {
- file.openRead().pipe(request.response).catchError((e) {
+ file.openRead().cast<List<int>>().pipe(request.response).catchError((e) {
_sendNotFound(request.response);
});
} else {
diff --git a/tests/standalone_2/io/file_input_stream_test.dart b/tests/standalone_2/io/file_input_stream_test.dart
index 4d48549..68c272d 100644
--- a/tests/standalone_2/io/file_input_stream_test.dart
+++ b/tests/standalone_2/io/file_input_stream_test.dart
@@ -22,8 +22,11 @@
// File contains "Hello Dart\nwassup!\n"
File file = new File(fileName);
int linesRead = 0;
- var lineStream =
- file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+ var lineStream = file
+ .openRead()
+ .cast<List<int>>()
+ .transform(utf8.decoder)
+ .transform(new LineSplitter());
lineStream.listen((line) {
linesRead++;
if (linesRead == 1) {
@@ -213,8 +216,11 @@
// File contains 10 lines.
File file = new File(fileName);
Expect.equals(length, file.lengthSync());
- var lineStream =
- file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+ var lineStream = file
+ .openRead()
+ .cast<List<int>>()
+ .transform(utf8.decoder)
+ .transform(new LineSplitter());
int lineCount = 0;
lineStream.listen((line) {
lineCount++;
diff --git a/tests/standalone_2/io/file_stream_test.dart b/tests/standalone_2/io/file_stream_test.dart
index f5e5503..2d3577e 100644
--- a/tests/standalone_2/io/file_stream_test.dart
+++ b/tests/standalone_2/io/file_stream_test.dart
@@ -12,7 +12,11 @@
asyncStart();
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
var file = new File("${d.path}/file");
- new File(Platform.executable).openRead().pipe(file.openWrite()).then((_) {
+ new File(Platform.executable)
+ .openRead()
+ .cast<List<int>>()
+ .pipe(file.openWrite())
+ .then((_) {
var subscription;
subscription = file.openRead().listen((data) {
subscription.pause();
@@ -39,7 +43,11 @@
asyncStart();
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
var file = new File("${d.path}/file");
- new File(Platform.executable).openRead().pipe(file.openWrite()).then((_) {
+ new File(Platform.executable)
+ .openRead()
+ .cast<List<int>>()
+ .pipe(file.openWrite())
+ .then((_) {
// isEmpty will cancel the stream after first data event.
file.openRead().isEmpty.then((empty) {
Expect.isFalse(empty);
diff --git a/tests/standalone_2/io/file_test.dart b/tests/standalone_2/io/file_test.dart
index 74f57f7..8f18060 100644
--- a/tests/standalone_2/io/file_test.dart
+++ b/tests/standalone_2/io/file_test.dart
@@ -209,7 +209,7 @@
var input = file.openRead();
var output = outputFile.openWrite();
Completer done = new Completer();
- input.pipe(output).then((_) {
+ input.cast<List<int>>().pipe(output).then((_) {
var copy = outputFile.openRead();
int position = 0;
copy.listen((d) {
diff --git a/tests/standalone_2/io/http_basic_test.dart b/tests/standalone_2/io/http_basic_test.dart
index 573e005..4f389ce 100644
--- a/tests/standalone_2/io/http_basic_test.dart
+++ b/tests/standalone_2/io/http_basic_test.dart
@@ -104,7 +104,7 @@
var response = request.response;
Expect.equals("POST", request.method);
response.contentLength = request.contentLength;
- request.pipe(response);
+ request.cast<List<int>>().pipe(response);
}
// Echo the request content back to the response.
diff --git a/tests/standalone_2/io/http_client_connect_test.dart b/tests/standalone_2/io/http_client_connect_test.dart
index 9c7cb67..284c441d 100644
--- a/tests/standalone_2/io/http_client_connect_test.dart
+++ b/tests/standalone_2/io/http_client_connect_test.dart
@@ -17,7 +17,7 @@
void testGetEmptyRequest() {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
});
var client = new HttpClient();
@@ -35,7 +35,7 @@
var data = "lalala".codeUnits;
server.listen((request) {
request.response.add(data);
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
});
var client = new HttpClient();
@@ -163,7 +163,7 @@
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
Expect.equals(method[1], request.method);
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
});
Callback1 cb = method[0] as Callback1;
@@ -192,7 +192,7 @@
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
Expect.equals(method[1], request.method);
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
});
Callback2 cb = method[0] as Callback2;
@@ -220,8 +220,10 @@
.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then((clientResponse) {
- var iterator = new StreamIterator(
- clientResponse.transform(utf8.decoder).transform(new LineSplitter()));
+ var iterator = new StreamIterator(clientResponse
+ .cast<List<int>>()
+ .transform(utf8.decoder)
+ .transform(new LineSplitter()));
iterator.moveNext().then((hasValue) {
Expect.isTrue(hasValue);
Expect.equals('init', iterator.current);
diff --git a/tests/standalone_2/io/http_cross_process_test.dart b/tests/standalone_2/io/http_cross_process_test.dart
index 547cb92..598ac68 100644
--- a/tests/standalone_2/io/http_cross_process_test.dart
+++ b/tests/standalone_2/io/http_cross_process_test.dart
@@ -27,15 +27,14 @@
Future makeServer() {
return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) {
server.listen((request) {
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
});
return server;
});
}
Future runClientProcess(int port) {
- return Process
- .run(
+ return Process.run(
Platform.executable,
[]
..addAll(Platform.executableArguments)
diff --git a/tests/standalone_2/io/http_proxy_advanced_test.dart b/tests/standalone_2/io/http_proxy_advanced_test.dart
index c6d0af2..5f8758b 100644
--- a/tests/standalone_2/io/http_proxy_advanced_test.dart
+++ b/tests/standalone_2/io/http_proxy_advanced_test.dart
@@ -35,8 +35,9 @@
Future<Server> start() {
return (secure
- ? HttpServer.bindSecure("localhost", 0, serverContext)
- : HttpServer.bind("localhost", 0)).then((s) {
+ ? HttpServer.bindSecure("localhost", 0, serverContext)
+ : HttpServer.bind("localhost", 0))
+ .then((s) {
server = s;
server.listen(requestHandler);
return this;
@@ -256,9 +257,11 @@
clientRequest.headers
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
// Copy all content.
- return request.pipe(clientRequest);
+ return request.cast<List<int>>().pipe(clientRequest);
}).then((clientResponse) {
- (clientResponse as HttpClientResponse).pipe(request.response);
+ (clientResponse as HttpClientResponse)
+ .cast<List<int>>()
+ .pipe(request.response);
});
}
});
diff --git a/tests/standalone_2/io/http_proxy_test.dart b/tests/standalone_2/io/http_proxy_test.dart
index 885af5d..b153ead 100644
--- a/tests/standalone_2/io/http_proxy_test.dart
+++ b/tests/standalone_2/io/http_proxy_test.dart
@@ -34,8 +34,9 @@
Future<Server> start() {
return (secure
- ? HttpServer.bindSecure("localhost", 0, serverContext)
- : HttpServer.bind("localhost", 0)).then((s) {
+ ? HttpServer.bindSecure("localhost", 0, serverContext)
+ : HttpServer.bind("localhost", 0))
+ .then((s) {
server = s;
server.listen(requestHandler);
return this;
@@ -244,9 +245,11 @@
clientRequest.headers
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
// Copy all content.
- return request.pipe(clientRequest);
+ return request.cast<List<int>>().pipe(clientRequest);
}).then((clientResponse) {
- (clientResponse as HttpClientResponse).pipe(request.response);
+ (clientResponse as HttpClientResponse)
+ .cast<List<int>>()
+ .pipe(request.response);
});
}
});
diff --git a/tests/standalone_2/io/http_read_test.dart b/tests/standalone_2/io/http_read_test.dart
index aeb2174..5d32b15c 100644
--- a/tests/standalone_2/io/http_read_test.dart
+++ b/tests/standalone_2/io/http_read_test.dart
@@ -107,7 +107,7 @@
var response = request.response;
Expect.equals("POST", request.method);
response.contentLength = request.contentLength;
- request.pipe(response);
+ request.cast<List<int>>().pipe(response);
}
// Return a 404.
diff --git a/tests/standalone_2/io/http_reuse_server_port_test.dart b/tests/standalone_2/io/http_reuse_server_port_test.dart
index da90fe7..afcaf61 100644
--- a/tests/standalone_2/io/http_reuse_server_port_test.dart
+++ b/tests/standalone_2/io/http_reuse_server_port_test.dart
@@ -18,7 +18,7 @@
HttpServer.bind("127.0.0.1", port).then((server) {
int i = 0;
server.listen((request) {
- request.pipe(request.response);
+ request.cast<List<int>>().pipe(request.response);
i++;
if (!clean && i == 10) {
int port = server.port;
diff --git a/tests/standalone_2/io/http_server_early_client_close2_test.dart b/tests/standalone_2/io/http_server_early_client_close2_test.dart
index 80bc51c..1a84dfd 100644
--- a/tests/standalone_2/io/http_server_early_client_close2_test.dart
+++ b/tests/standalone_2/io/http_server_early_client_close2_test.dart
@@ -18,6 +18,7 @@
String name = Platform.script.toFilePath();
new File(name)
.openRead()
+ .cast<List<int>>()
.pipe(request.response)
.catchError((e) {/* ignore */});
});
diff --git a/tests/standalone_2/io/http_server_early_client_close_test.dart b/tests/standalone_2/io/http_server_early_client_close_test.dart
index 4cacde0..59841f0 100644
--- a/tests/standalone_2/io/http_server_early_client_close_test.dart
+++ b/tests/standalone_2/io/http_server_early_client_close_test.dart
@@ -111,6 +111,7 @@
String name = Platform.script.toFilePath();
new File(name)
.openRead()
+ .cast<List<int>>()
.pipe(request.response)
.catchError((e) {/* ignore */});
});
diff --git a/tests/standalone_2/io/http_server_response_test.dart b/tests/standalone_2/io/http_server_response_test.dart
index baa729b..2f2e657 100644
--- a/tests/standalone_2/io/http_server_response_test.dart
+++ b/tests/standalone_2/io/http_server_response_test.dart
@@ -67,6 +67,7 @@
testServerRequest((server, request) {
new File("__nonexistent_file_")
.openRead()
+ .cast<List<int>>()
.pipe(request.response)
.catchError((e) {
server.close();
@@ -122,6 +123,7 @@
testServerRequest((server, request) {
new File("__nonexistent_file_")
.openRead()
+ .cast<List<int>>()
.pipe(request.response)
.catchError((e) {
server.close();
diff --git a/tests/standalone_2/io/https_server_test.dart b/tests/standalone_2/io/https_server_test.dart
index ad3cc51..fe151bc 100644
--- a/tests/standalone_2/io/https_server_test.dart
+++ b/tests/standalone_2/io/https_server_test.dart
@@ -69,6 +69,7 @@
String name = Platform.script.toFilePath();
new File(name)
.openRead()
+ .cast<List<int>>()
.pipe(request.response)
.catchError((e) {/* ignore */});
});
diff --git a/tests/standalone_2/io/pipe_server_test.dart b/tests/standalone_2/io/pipe_server_test.dart
index a9a3975..0b30e2e 100644
--- a/tests/standalone_2/io/pipe_server_test.dart
+++ b/tests/standalone_2/io/pipe_server_test.dart
@@ -45,7 +45,7 @@
void connectHandler() {
String srcFileName = getDataFilename("readline_test1.dat");
Stream fileInput = new File(srcFileName).openRead();
- fileInput.pipe(_socket).then((_) {
+ fileInput.cast<List<int>>().pipe(_socket).then((_) {
var tempDir = Directory.systemTemp.createTempSync('dart_pipe_server');
var dstFileName = tempDir.path + "/readline_test1.dat";
var dstFile = new File(dstFileName);
diff --git a/tests/standalone_2/io/platform_resolved_executable_test.dart b/tests/standalone_2/io/platform_resolved_executable_test.dart
index 14be3b5..c6da572 100644
--- a/tests/standalone_2/io/platform_resolved_executable_test.dart
+++ b/tests/standalone_2/io/platform_resolved_executable_test.dart
@@ -23,7 +23,8 @@
env['PATH'] = altPath;
}
- var processResult = Process.runSync(exePath, [scriptPath],
+ var processResult = Process.runSync(
+ exePath, [...Platform.executableArguments, scriptPath],
includeParentEnvironment: false, runInShell: true, environment: env);
if (processResult.exitCode != 0) {
diff --git a/tests/standalone_2/io/stream_pipe_test.dart b/tests/standalone_2/io/stream_pipe_test.dart
index 9f4067c..de11c0a 100644
--- a/tests/standalone_2/io/stream_pipe_test.dart
+++ b/tests/standalone_2/io/stream_pipe_test.dart
@@ -67,7 +67,7 @@
String dstFileName = tempDir.path + "/readline_test1.dat";
new File(dstFileName).createSync();
var output = new File(dstFileName).openWrite();
- srcStream.pipe(output).then((_) {
+ srcStream.cast<List<int>>().pipe(output).then((_) {
bool result = compareFileContent(srcFileName, dstFileName);
new File(dstFileName).deleteSync();
tempDir.deleteSync();
@@ -92,7 +92,7 @@
var dstFile = new File(dstFileName);
dstFile.createSync();
var output = dstFile.openWrite();
- output.addStream(srcStream).then((_) {
+ output.addStream(srcStream.cast<List<int>>()).then((_) {
output.add([32]);
output.close();
output.done.then((_) {
@@ -131,9 +131,9 @@
var dstFile = new File(dstFileName);
dstFile.createSync();
var output = dstFile.openWrite();
- output.addStream(srcStream).then((_) {
+ output.addStream(srcStream.cast<List<int>>()).then((_) {
var srcStream2 = srcFile.openRead();
- output.addStream(srcStream2).then((_) {
+ output.addStream(srcStream2.cast<List<int>>()).then((_) {
output.close();
output.done.then((_) {
var src = srcFile.openSync();
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 5a8f844..fa9f5d7 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -26,15 +26,7 @@
[ $compiler == dartkb ]
io/dart_std_io_pipe_test: Pass, Timeout # Please triage
-io/platform_resolved_executable_test/00: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/01: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/02: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/03: RuntimeError
-io/platform_resolved_executable_test/04: RuntimeError
-io/platform_resolved_executable_test/05: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
io/platform_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_fail_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_test: RuntimeError # Platform.script points to dill file.
no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
[ $compiler == dartkp ]
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 38d1e2c..672a30e 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -5,10 +5,6 @@
[ $builder_tag == obfuscated ]
dwarf_stack_trace_test: Pass, RuntimeError # Issue 35563
-[ $compiler == precompiler ]
-io/web_socket_test: Pass, RuntimeError # Issue 24674
-map_insert_remove_oom_test: Skip # Heap limit too low. Increasing iteration count to make a higher limit a meaningful test makes it too slow for simarm[64] bots.
-
[ $runtime == dart_precompiled ]
http_launch_test: Skip
io/addlatexhash_test: Skip
@@ -49,6 +45,14 @@
io/test_extension_fail_test: Skip
io/test_extension_test: Skip
io/windows_environment_test: Skip
+package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
+package/scenarios/invalid/invalid_utf8_test: Skip
+package/scenarios/invalid/non_existent_packages_file_test: Skip
+package/scenarios/invalid/same_package_twice_test: Skip
+package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
+package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
+package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
+package/scenarios/packages_option_only/packages_option_only_test: Skip
[ $arch == arm && $mode == release && $runtime == dart_precompiled && $system == android ]
io/socket_cancel_connect_test: RuntimeError # Issue 34142
@@ -60,18 +64,5 @@
[ $runtime == dart_precompiled && $checked ]
io/namespace_test: RuntimeError
-[ $compiler == app_jit || $compiler == precompiler ]
-io/compile_all_test: Skip # Incompatible flag --compile_all
-
-[ $compiler == app_jit || $runtime == dart_precompiled ]
-package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
-package/scenarios/invalid/invalid_utf8_test: Skip
-package/scenarios/invalid/non_existent_packages_file_test: Skip
-package/scenarios/invalid/same_package_twice_test: Skip
-package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
-package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
-package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
-package/scenarios/packages_option_only/packages_option_only_test: Skip
-
[ $mode == product || $runtime == dart_precompiled ]
no_assert_test: SkipByDesign # Requires checked mode.
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index e77465f..5919089 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -6,20 +6,6 @@
link_natives_lazily_test: SkipByDesign # Not supported.
no_allow_absolute_addresses_test: SkipByDesign # Not supported.
-[ $compiler == app_jit ]
-full_coverage_test: Skip # Platform.executable
-io/namespace_test: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/00: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/01: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/02: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/03: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/04: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/05: RuntimeError # Issue 33168
-io/platform_test: Skip # Platform.executable
-io/test_extension_fail_test: Skip # Platform.executable
-io/test_extension_test: Skip # Platform.executable
-regress_26031_test: Skip # Platform.resolvedExecutable
-
[ $system == android ]
io/file_stat_test: Skip # Issue 26376
io/file_system_watcher_test: Skip # Issue 26376
diff --git a/tools/VERSION b/tools/VERSION
index 1a2f417..0bb2831 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 5
PATCH 0
-PRERELEASE 0
+PRERELEASE 1
PRERELEASE_PATCH 0
-ABI_VERSION 5
-OLDEST_SUPPORTED_ABI_VERSION 3
+ABI_VERSION 7
+OLDEST_SUPPORTED_ABI_VERSION 5
diff --git a/tools/approve_results.dart b/tools/approve_results.dart
index 5912f3b..c9dcf7d 100755
--- a/tools/approve_results.dart
+++ b/tools/approve_results.dart
@@ -141,6 +141,7 @@
throw new Exception("Failed to download $logUrl: ${response.statusCode}");
}
final contents = (await response
+ .cast<List<int>>()
.transform(new Utf8Decoder())
.timeout(const Duration(seconds: 60))
.toList())
@@ -186,7 +187,7 @@
? await todoFallbackLoadLog(
changelistBuild["id"],
"download_previous_results/0/steps/gsutil_find_latest_build/0/logs/"
- "raw_io.output_text_latest_/0",
+ "raw_io.output_text_latest_/0",
"gsutil_find_latest_build/0/logs/raw_io.output_text_latest_/0")
: await readFile(bot, "latest"))
.trim();
@@ -278,6 +279,7 @@
throw new Exception("Failed to request $url: ${response.statusCode}");
}
final text = await response
+ .cast<List<int>>()
.transform(utf8.decoder)
.join()
.timeout(const Duration(seconds: 30));
@@ -368,9 +370,11 @@
final testMatrixBots = <String>[];
for (final builderConfiguration in builderConfigurations) {
final steps = builderConfiguration["steps"];
- // Only consider bots that use tools/test.py.
+ // Only consider bots that use tools/test.py or custom test runners.
if (!steps.any((step) =>
- step["script"] == null || step["script"] == "tools/test.py")) {
+ step["script"] == null ||
+ step["script"] == "tools/test.py" ||
+ step["testRunner"] == true)) {
continue;
}
final builders = builderConfiguration["builders"].cast<String>();
@@ -460,6 +464,7 @@
throw new Exception("Failed to request try runs for $gerrit");
}
final Map<String, dynamic> object = await response
+ .cast<List<int>>()
.transform(new Utf8Decoder())
.transform(new JsonDecoder())
.first
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 8106385..5a0a741 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -60,6 +60,7 @@
final request = await client.getUrl(url).timeout(timeout);
final response = await request.close().timeout(timeout);
object = await response
+ .cast<List<int>>()
.transform(new Utf8Decoder())
.transform(new JsonDecoder())
.first
diff --git a/tools/bots/results.dart b/tools/bots/results.dart
index 65ae36f..c42d828 100644
--- a/tools/bots/results.dart
+++ b/tools/bots/results.dart
@@ -7,6 +7,9 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
+import 'dart:math';
+
+import 'package:pool/pool.dart';
/// The path to the gsutil script.
String gsutilPy;
@@ -18,30 +21,36 @@
const approvedResultsStoragePath =
"gs://dart-test-results-approved-results/builders";
+/// Limit the number of concurrent subprocesses by half the number of cores.
+final gsutilPool = new Pool(max(1, Platform.numberOfProcessors ~/ 2));
+
/// Runs gsutil with the provided [arguments] and returns the standard output.
/// Returns null if the requested URL didn't exist.
Future<String> runGsutil(List<String> arguments) async {
- final processResult = await Process.run(
- "python", [gsutilPy]..addAll(arguments),
- runInShell: Platform.isWindows);
- if (processResult.exitCode != 0) {
- if (processResult.exitCode == 1 &&
- processResult.stderr.contains("No URLs matched") ||
- processResult.stderr.contains("One or more URLs matched no objects")) {
- return null;
+ return gsutilPool.withResource(() async {
+ final processResult = await Process.run(
+ "python", [gsutilPy]..addAll(arguments),
+ runInShell: Platform.isWindows);
+ if (processResult.exitCode != 0) {
+ if (processResult.exitCode == 1 &&
+ processResult.stderr.contains("No URLs matched") ||
+ processResult.stderr
+ .contains("One or more URLs matched no objects")) {
+ return null;
+ }
+ String error = "Failed to run: python $gsutilPy $arguments\n"
+ "exitCode: ${processResult.exitCode}\n"
+ "stdout:\n${processResult.stdout}\n"
+ "stderr:\n${processResult.stderr}";
+ if (processResult.exitCode == 1 &&
+ processResult.stderr.contains("401 Anonymous caller")) {
+ error =
+ "\n\nYou need to authenticate by running:\npython $gsutilPy config\n";
+ }
+ throw new Exception(error);
}
- String error = "Failed to run: python $gsutilPy $arguments\n"
- "exitCode: ${processResult.exitCode}\n"
- "stdout:\n${processResult.stdout}\n"
- "stderr:\n${processResult.stderr}";
- if (processResult.exitCode == 1 &&
- processResult.stderr.contains("401 Anonymous caller")) {
- error =
- "\n\nYou need to authenticate by running:\npython $gsutilPy config\n";
- }
- throw new Exception(error);
- }
- return processResult.stdout;
+ return processResult.stdout;
+ });
}
/// Returns the contents of the provided cloud storage [path], or null if it
@@ -111,6 +120,7 @@
final results = <Map<String, dynamic>>[];
final lines = new File(path)
.openRead()
+ .cast<List<int>>()
.transform(utf8.decoder)
.transform(new LineSplitter());
await for (final line in lines) {
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 3530395..5836ea1 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -277,6 +277,20 @@
"options": {
"host-checked": true
}},
+ "dart2js-new-rti-(linux|mac|win)-x64-d8": {
+ "options": {
+ "builder-tag": "new_rti",
+ "dart2js-options": ["--experiment-new-rti"],
+ "host-checked": true
+ }},
+ "dart2js-new-rti-minified-csp-(linux|mac|win)-x64-d8": {
+ "options": {
+ "builder-tag": "new_rti",
+ "csp": true,
+ "dart2js-options": ["--experiment-new-rti"],
+ "minified": true,
+ "use-sdk": true
+ }},
"dartkp-android-(debug|product|release)-(arm|arm64)": {
"options": {
"use-elf": true
@@ -1238,6 +1252,47 @@
},
{
"builders": [
+ "dart2js-rti-linux-x64-d8"
+ ],
+ "meta": {
+ "description": "dart2js-d8 tests with new-RTI enabled"
+ },
+ "steps": [
+ {
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["dart2js_bot"]
+ },
+ {
+ "name": "dart2js new-rti tests",
+ "arguments": [
+ "-ndart2js-new-rti-linux-x64-d8",
+ "--dart2js-batch",
+ "language_2",
+ "corelib_2",
+ "dart2js_native",
+ "dart2js_extra"
+ ],
+ "shards": 6,
+ "fileset": "dart2js_hostasserts"
+ },
+ {
+ "name": "dart2js new-rti minified+csp tests",
+ "arguments": [
+ "-ndart2js-new-rti-minified-csp-linux-x64-d8",
+ "--dart2js-batch",
+ "language_2",
+ "corelib_2",
+ "dart2js_native",
+ "dart2js_extra"
+ ],
+ "shards": 6,
+ "fileset": "dart2js"
+ }
+ ]
+ },
+ {
+ "builders": [
"dart2js-strong-linux-x64-chrome",
"dart2js-strong-linux-x64-firefox",
"dart2js-strong-mac-x64-chrome",
@@ -1518,14 +1573,14 @@
{
"builders": ["dart-sdk-win"],
"meta": {
- "description": "This configuration is used by the sdk-builders for Windows."
+ "description": "This configuration is used by the sdk-builders for Windows. It also adds CQ coverage for building on Windows."
},
"steps": [
{
"name": "build dart",
"script": "tools/build.py",
"arguments": ["--arch=ia32,x64",
- "--mode=release", "create_sdk"]
+ "--mode=release", "create_sdk", "runtime_kernel"]
},
{
"name": "build gen_kernel.dart.snapshot and dart2aot",
diff --git a/tools/dart2js/class_generator/class_generator.dart b/tools/dart2js/class_generator/class_generator.dart
index 55bcdad..50af327 100644
--- a/tools/dart2js/class_generator/class_generator.dart
+++ b/tools/dart2js/class_generator/class_generator.dart
@@ -140,7 +140,7 @@
File measuring = new File("${dir.path}/measuring.js");
IOSink sink = measuring.openWrite();
sink.writeln("var start = new Date();");
- await sink.addStream(new File(fileName).openRead());
+ await sink.addStream(new File(fileName).openRead().cast<List<int>>());
sink.writeln("print(new Date() - start)");
String command;
List<String> args;
diff --git a/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart b/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
index b97460c..51b958c 100644
--- a/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
+++ b/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
@@ -47,7 +47,11 @@
}
Uri uri = sourceMapFile.resolve(path);
- new File.fromUri(uri).openRead().pipe(request.response).catchError((e) {
+ new File.fromUri(uri)
+ .openRead()
+ .cast<List<int>>()
+ .pipe(request.response)
+ .catchError((e) {
print("Error: $e");
request.response.close();
});
diff --git a/tools/dom/scripts/CSSPropertyNames.in b/tools/dom/scripts/CSSPropertyNames.in
index 27e9fb1..39b49ad 100644
--- a/tools/dom/scripts/CSSPropertyNames.in
+++ b/tools/dom/scripts/CSSPropertyNames.in
@@ -2,6 +2,7 @@
// https://codereview.chromium.org/444453006/ has been committed, in which case
// it will be pulled in from DEPS!
// Copied from http://trac.webkit.org/browser/trunk/WebCore/css/CSSPropertyNames.in
+// via. http://web.archive.org/web/20100722083519/http://trac.webkit.org/browser/trunk/WebCore/css/CSSPropertyNames.in
//
// CSS property names
//
diff --git a/tools/dom/src/KeyCode.dart b/tools/dom/src/KeyCode.dart
index e9dca60..a51d062 100644
--- a/tools/dom/src/KeyCode.dart
+++ b/tools/dom/src/KeyCode.dart
@@ -15,7 +15,7 @@
abstract class KeyCode {
// These constant names were borrowed from Closure's Keycode enumeration
// class.
- // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
+ // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
static const int WIN_KEY_FF_LINUX = 0;
static const int MAC_ENTER = 3;
static const int BACKSPACE = 8;
diff --git a/tools/dom/src/KeyboardEventStream.dart b/tools/dom/src/KeyboardEventStream.dart
index fea4654..48f7a68 100644
--- a/tools/dom/src/KeyboardEventStream.dart
+++ b/tools/dom/src/KeyboardEventStream.dart
@@ -10,7 +10,7 @@
*/
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
// This code inspired by Closure's KeyHandling library.
- // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+ // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js
/**
* The set of keys that have been pressed down without seeing their
@@ -35,7 +35,7 @@
/**
* An enumeration of key identifiers currently part of the W3C draft for DOM3
* and their mappings to keyCodes.
- * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/keyset.html#KeySet-Set
*/
static const Map<String, int> _keyIdentifier = const {
'Up': KeyCode.UP,
diff --git a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
index 12f29c3..3ee9b43 100644
--- a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
@@ -44,7 +44,7 @@
// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
-// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.
+// https://w3c.github.io/html/sec-forms.html#the-input-element.
/**
* Exposes the functionality common between all InputElement types.
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 1a82f0f..7bd3a0f 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -83,14 +83,13 @@
help: "Triple-shift operator"
#
-# Flags below this line are either retired or rejected, cannot be specified
+# Flags below this line are shipped, retired, or rejected, cannot be specified
# on the command line, and will eventually be removed.
#
control-flow-collections:
help: "Control Flow Collections"
enabledIn: '2.2.2'
- expired: true
set-literals:
help: "Set Literals"
@@ -100,4 +99,3 @@
spread-collections:
help: "Spread Collections"
enabledIn: '2.2.2'
- expired: true
\ No newline at end of file
diff --git a/tools/gardening/lib/src/luci_api.dart b/tools/gardening/lib/src/luci_api.dart
index bf808f0..93d9b6f 100644
--- a/tools/gardening/lib/src/luci_api.dart
+++ b/tools/gardening/lib/src/luci_api.dart
@@ -97,7 +97,7 @@
response.drain();
throw new HttpException(response.reasonPhrase, uri: uri);
}
- return response.transform(utf8.decoder).join();
+ return response.cast<List<int>>().transform(utf8.decoder).join();
}
/// [_makePostRequest] performs a post request to [uri], where the posted
diff --git a/tools/gardening/lib/src/util.dart b/tools/gardening/lib/src/util.dart
index 4dd25e0..0cee8c7 100644
--- a/tools/gardening/lib/src/util.dart
+++ b/tools/gardening/lib/src/util.dart
@@ -88,9 +88,13 @@
throw new HttpException(uri, response.statusCode);
}
if (timeout != null) {
- return response.timeout(timeout).transform(utf8.decoder).join();
+ return response
+ .timeout(timeout)
+ .cast<List<int>>()
+ .transform(utf8.decoder)
+ .join();
} else {
- return response.transform(utf8.decoder).join();
+ return response.cast<List<int>>().transform(utf8.decoder).join();
}
}
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
deleted file mode 100644
index b0ef7d7..0000000
--- a/tools/patch_sdk.dart
+++ /dev/null
@@ -1,831 +0,0 @@
-#!/usr/bin/env dart
-// 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.
-
-/// Command line tool to merge the SDK libraries and our patch files.
-/// This is currently designed as an offline tool, but we could automate it.
-
-import 'dart:io';
-import 'dart:isolate' show RawReceivePort;
-import 'dart:async';
-import 'dart:math' as math;
-import 'dart:convert' show jsonEncode;
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart'
- show parseCompilationUnit, parseDirectives;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-import 'package:path/path.dart' as path;
-import 'package:front_end/src/api_prototype/front_end.dart';
-import 'package:front_end/src/base/processed_options.dart';
-import 'package:front_end/src/kernel_generator_impl.dart';
-import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
-import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
-import 'package:front_end/src/fasta/kernel/utils.dart'
- show writeComponentToFile;
-import 'package:kernel/target/targets.dart';
-import 'package:vm/target/vm.dart' show VmTarget;
-import 'package:vm/target/flutter.dart' show FlutterTarget;
-
-/// Set of input files that were read by this script to generate patched SDK.
-/// We will dump it out into the depfile for ninja to use.
-///
-/// For more information see GN and Ninja references:
-/// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-dependencies-for-actions
-/// https://ninja-build.org/manual.html#_depfile
-///
-final deps = new Set<Uri>();
-
-/// Create [File] object from the given path and register it as a dependency.
-File getInputFile(String path, {canBeMissing: false}) {
- final file = new File(path);
- if (!file.existsSync()) {
- if (!canBeMissing)
- throw "patch_sdk.dart expects all inputs to exist, missing: $path";
- return null;
- }
- deps.add(Uri.base.resolveUri(file.uri));
- return file;
-}
-
-/// Read the given file synchronously as a string and register this path as
-/// a dependency.
-String readInputFile(String path, {canBeMissing: false}) =>
- getInputFile(path, canBeMissing: canBeMissing)?.readAsStringSync();
-
-Future main(List<String> argv) async {
- var port = new RawReceivePort();
- try {
- await _main(argv);
- } finally {
- port.close();
- }
-}
-
-void usage(String mode) {
- var base = path.fromUri(Platform.script);
- final self = path.relative(base);
- print('Usage: $self $mode SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES');
-
- final repositoryDir = path.relative(path.dirname(path.dirname(base)));
- final sdkExample = path.relative(path.join(repositoryDir, 'sdk'));
- final patchExample = path.relative(
- path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch'));
- final outExample = path.relative(
- path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk'));
- final packagesExample = path.relative(path.join(repositoryDir, '.packages'));
- print('For example:');
- print('\$ $self vm $sdkExample $patchExample $outExample $packagesExample');
-
- exit(1);
-}
-
-const validModes = const ['vm', 'flutter', 'runner'];
-String mode;
-bool get forVm => mode == 'vm';
-bool get forFlutter => mode == 'flutter';
-bool get forRunner => mode == 'runner';
-
-Future _main(List<String> argv) async {
- if (argv.isEmpty) usage('[${validModes.join('|')}]');
- mode = argv.first;
- if (!validModes.contains(mode)) usage('[${validModes.join('|')}]');
- if (argv.length != 5) usage(mode);
-
- var input = argv[1];
- var sdkLibIn = path.join(input, 'lib');
- var patchIn = argv[2];
- var outDir = argv[3];
- var outDirUri = Uri.base.resolveUri(new Uri.directory(outDir));
- var sdkOut = path.join(outDir, 'lib');
- var packagesFile = argv[4];
-
- await new Directory.fromUri(outDirUri).delete(recursive: true);
-
- // Parse libraries.dart
- var libContents = readInputFile(path.join(
- sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'));
- libContents = _updateLibraryMetadata(sdkOut, libContents);
- var sdkLibraries = _getSdkLibraries(libContents);
-
- var locations = <String, Map<String, String>>{};
-
- // Enumerate core libraries and apply patches
- for (SdkLibrary library in sdkLibraries) {
- if (library.isDart2JsLibrary) continue;
- _applyPatch(library, sdkLibIn, patchIn, sdkOut, locations);
- }
-
- _copyExtraLibraries(sdkOut, locations);
-
- final Uri platform = outDirUri.resolve('platform.dill.tmp');
- final Uri librariesJson = outDirUri.resolve("lib/libraries.json");
- final Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile));
- TargetFlags flags = new TargetFlags(legacyMode: true);
- Target target;
-
- switch (mode) {
- case 'vm':
- target = new VmTarget(flags);
- break;
-
- case 'flutter':
- case 'flutter_release':
- target = new FlutterTarget(flags);
- break;
-
- case 'dart2js':
- target = new Dart2jsTarget("dart2js", flags);
- break;
-
- default:
- throw "Unknown mode: $mode";
- }
-
- _writeSync(
- librariesJson.toFilePath(),
- jsonEncode({
- mode: {"libraries": locations}
- }));
-
- await compilePlatform(outDirUri, target, packages, platform);
-
- // We generate a dependency file for GN to properly regenerate the patched sdk
- // folder, outline.dill and platform.dill files when necessary: either when
- // the sdk sources change or when this script is updated. In particular:
- //
- // - sdk changes: we track the actual sources we are compiling. If we are
- // building the dart2js sdk, this includes the dart2js-specific patch
- // files.
- //
- // These files are tracked by [deps] and passed below to [writeDepsFile] in
- // the extraDependencies argument.
- //
- // - script updates: we track this script file and any code it imports (even
- // sdk libraries). Note that this script runs on the standalone VM, so any
- // sdk library used by this script indirectly depends on a VM-specific
- // patch file.
- //
- // These set of files is discovered by `getDependencies` below, and the
- // [platformForDeps] is always the VM-specific `platform.dill` file.
- var platformForDeps = platform;
- var sdkDir = outDirUri;
- if (forFlutter || forRunner) {
- // Note: this fails if `$root_out_dir/vm_platform.dill` doesn't exist. The
- // target to build the flutter patched sdk depends on
- // //runtime/vm:kernel_platform_files to ensure this file exists.
- platformForDeps = outDirUri.resolve('../vm_platform.dill');
- sdkDir = null;
- }
- deps.addAll(await getDependencies(Platform.script,
- sdk: sdkDir, packages: packages, platform: platformForDeps));
- await writeDepsFile(
- librariesJson, Uri.base.resolveUri(new Uri.file("$outDir.d")), deps);
-}
-
-/// Generates an outline.dill and platform.dill file containing the result of
-/// compiling a platform's SDK.
-///
-/// Returns a list of dependencies read by the compiler. This list can be used
-/// to create GN dependency files.
-Future<List<Uri>> compilePlatform(
- Uri patchedSdk, Target target, Uri packages, Uri output) async {
- var options = new CompilerOptions()
- ..setExitCodeOnProblem = true
- ..legacyMode = true
- ..compileSdk = true
- ..sdkRoot = patchedSdk
- ..packagesFileUri = packages
- ..target = target;
-
- var inputs = [Uri.parse('dart:core')];
- var result = await generateKernel(
- new ProcessedOptions(options: options, inputs: inputs),
- buildSummary: true,
- buildComponent: true);
- await writeComponentToFile(result.component, output);
- return result.deps;
-}
-
-Future writeDepsFile(
- Uri output, Uri depsFile, Iterable<Uri> allDependencies) async {
- if (allDependencies.isEmpty) return;
- String toRelativeFilePath(Uri uri) {
- // Ninja expects to find file names relative to the current working
- // directory. We've tried making them relative to the deps file, but that
- // doesn't work for downstream projects. Making them absolute also
- // doesn't work.
- //
- // We can test if it works by running ninja twice, for example:
- //
- // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
- // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
- //
- // The second time, ninja should say:
- //
- // ninja: Entering directory `xcodebuild/ReleaseX64'
- // ninja: no work to do.
- //
- // It's broken if it says something like this:
- //
- // ninja explain: expected depfile 'patched_sdk.d' to mention
- // 'patched_sdk/platform.dill', got
- // '/.../xcodebuild/ReleaseX64/patched_sdk/platform.dill'
- return Uri.parse(relativizeUri(uri, base: Uri.base)).toFilePath();
- }
-
- StringBuffer sb = new StringBuffer();
- sb.write(toRelativeFilePath(output));
- sb.write(":");
- for (Uri uri in allDependencies) {
- sb.write(" ");
- sb.write(toRelativeFilePath(uri));
- }
- sb.writeln();
- await new File.fromUri(depsFile).writeAsString("$sb");
-}
-
-/// Updates the contents of
-/// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include
-/// declarations for vm internal libraries.
-String _updateLibraryMetadata(String sdkOut, String libContents) {
- if (!forVm && !forFlutter && !forRunner) return libContents;
- var extraLibraries = new StringBuffer();
- extraLibraries.write('''
- "_builtin": const LibraryInfo(
- "_builtin/_builtin.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
-
- "profiler": const LibraryInfo(
- "profiler/profiler.dart",
- maturity: Maturity.DEPRECATED,
- documented: false),
-
- "_vmservice": const LibraryInfo(
- "vmservice/vmservice.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
-
- "vmservice_io": const LibraryInfo(
- "vmservice_io/vmservice_io.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
- ''');
-
- if (forFlutter) {
- extraLibraries.write('''
- "ui": const LibraryInfo(
- "ui/ui.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
- ''');
- }
-
- if (forRunner) {
- extraLibraries.write('''
- "fuchsia.builtin": const LibraryInfo(
- "fuchsia.builtin/builtin.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
- ''');
- extraLibraries.write('''
- "zircon": const LibraryInfo(
- "zircon/zircon.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
- ''');
- extraLibraries.write('''
- "fuchsia": const LibraryInfo(
- "fuchsia/fuchsia.dart",
- categories: "Client,Server",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
- ''');
- }
-
- libContents = libContents.replaceAll(
- ' libraries = const {', ' libraries = const { $extraLibraries');
- _writeSync(
- path.join(
- sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'),
- libContents);
- return libContents;
-}
-
-/// Copy internal libraries that are developed outside the sdk folder into the
-/// patched_sdk folder. For the VM< this includes files under 'runtime/bin/',
-/// for flutter, this is includes also the ui library.
-_copyExtraLibraries(String sdkOut, Map<String, Map<String, String>> locations) {
- var base = path.fromUri(Platform.script);
- var dartDir = path.dirname(path.dirname(path.absolute(base)));
-
- var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', 'builtin.dart');
- var builtinLibraryOut = path.join(sdkOut, '_builtin', '_builtin.dart');
- _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn));
- addLocation(locations, '_builtin', path.join('_builtin', '_builtin.dart'));
- for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) {
- var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file);
- var libraryOut = path.join(sdkOut, 'vmservice_io', file);
- _writeSync(libraryOut, readInputFile(libraryIn));
- }
- addLocation(locations, 'vmservice_io',
- path.join('vmservice_io', 'vmservice_io.dart'));
- addLocation(
- locations, '_vmservice', path.join('vmservice', 'vmservice.dart'));
-
- if (forFlutter) {
- // Flutter repo has this layout:
- // engine/src/
- // third_party/dart/
- // [third_party/]flutter/
- var srcDir = path
- .dirname(path.dirname(path.dirname(path.dirname(path.absolute(base)))));
- var flutterDir = new Directory(path.join(srcDir, 'flutter'));
- if (!flutterDir.existsSync()) {
- // In Fuchsia Flutter is under 'third_party'.
- flutterDir = new Directory(path.join(srcDir, 'third_party', 'flutter'));
- }
- var uiLibraryInDir = new Directory(path.join(flutterDir.path, 'lib', 'ui'));
- for (var file in uiLibraryInDir.listSync()) {
- if (!file.path.endsWith('.dart')) continue;
- var name = path.basename(file.path);
- var uiLibraryOut = path.join(sdkOut, 'ui', name);
- _writeSync(uiLibraryOut, readInputFile(file.path));
- }
- addLocation(locations, 'ui', path.join('ui', 'ui.dart'));
- }
-
- if (forRunner) {
- var gnRoot = path
- .dirname(path.dirname(path.dirname(path.dirname(path.absolute(base)))));
-
- var builtinLibraryInDir = new Directory(
- path.join(gnRoot, 'topaz', 'runtime', 'dart_runner', 'embedder'));
- for (var file in builtinLibraryInDir.listSync()) {
- if (!file.path.endsWith('.dart')) continue;
- var name = path.basename(file.path);
- var builtinLibraryOut = path.join(sdkOut, 'fuchsia.builtin', name);
- _writeSync(builtinLibraryOut, readInputFile(file.path));
- }
- addLocation(locations, 'fuchsia.builtin',
- path.join('fuchsia.builtin', 'builtin.dart'));
-
- var zirconLibraryInDir = new Directory(
- path.join(gnRoot, 'topaz', 'public', 'dart-pkg', 'zircon', 'lib'));
- for (var file in zirconLibraryInDir.listSync(recursive: true)) {
- if (!file.path.endsWith('.dart')) continue;
- var name = file.path.substring(zirconLibraryInDir.path.length + 1);
- var zirconLibraryOut = path.join(sdkOut, 'zircon', name);
- _writeSync(zirconLibraryOut, readInputFile(file.path));
- }
- addLocation(locations, 'zircon', path.join('zircon', 'zircon.dart'));
-
- var fuchsiaLibraryInDir = new Directory(
- path.join(gnRoot, 'topaz', 'public', 'dart-pkg', 'fuchsia', 'lib'));
- for (var file in fuchsiaLibraryInDir.listSync(recursive: true)) {
- if (!file.path.endsWith('.dart')) continue;
- var name = file.path.substring(fuchsiaLibraryInDir.path.length + 1);
- var fuchsiaLibraryOut = path.join(sdkOut, 'fuchsia', name);
- _writeSync(fuchsiaLibraryOut, readInputFile(file.path));
- }
- addLocation(locations, 'fuchsia', path.join('fuchsia', 'fuchsia.dart'));
- }
-}
-
-_applyPatch(SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut,
- Map<String, Map<String, String>> locations) {
- var libraryOut = path.join(sdkLibIn, library.path);
- var libraryIn = libraryOut;
-
- var libraryFile = getInputFile(libraryIn, canBeMissing: true);
- if (libraryFile != null) {
- addLocation(locations, Uri.parse(library.shortName).path,
- path.relative(libraryOut, from: sdkLibIn));
- var outPaths = <String>[libraryOut];
- var libraryContents = libraryFile.readAsStringSync();
-
- int inputModifyTime = libraryFile.lastModifiedSync().millisecondsSinceEpoch;
- var partFiles = <File>[];
- for (var part in parseDirectives(libraryContents).directives) {
- if (part is PartDirective) {
- var partPath = part.uri.stringValue;
- outPaths.add(path.join(path.dirname(libraryOut), partPath));
-
- var partFile =
- getInputFile(path.join(path.dirname(libraryIn), partPath));
- partFiles.add(partFile);
- inputModifyTime = math.max(inputModifyTime,
- partFile.lastModifiedSync().millisecondsSinceEpoch);
- }
- }
-
- // See if we can find a patch file.
- var patchPath = path.join(
- patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart');
-
- var patchFile = getInputFile(patchPath, canBeMissing: true);
- if (patchFile != null) {
- inputModifyTime = math.max(
- inputModifyTime, patchFile.lastModifiedSync().millisecondsSinceEpoch);
- }
-
- // Compute output paths
- outPaths = outPaths
- .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn)))
- .toList();
-
- // Compare output modify time with input modify time.
- bool needsUpdate = false;
- for (var outPath in outPaths) {
- var outFile = new File(outPath);
- if (!outFile.existsSync() ||
- outFile.lastModifiedSync().millisecondsSinceEpoch < inputModifyTime) {
- needsUpdate = true;
- break;
- }
- }
-
- if (needsUpdate) {
- var contents = <String>[libraryContents];
- contents.addAll(partFiles.map((f) => f.readAsStringSync()));
- if (patchFile != null) {
- var patchContents = patchFile.readAsStringSync();
- contents = _patchLibrary(patchFile.path, contents, patchContents);
- }
-
- for (var i = 0; i < outPaths.length; i++) {
- _writeSync(outPaths[i], contents[i]);
- }
- }
- }
-}
-
-/// Writes a file, creating the directory if needed.
-void _writeSync(String filePath, String contents) {
- var outDir = new Directory(path.dirname(filePath));
- if (!outDir.existsSync()) outDir.createSync(recursive: true);
-
- new File(filePath).writeAsStringSync(contents);
-}
-
-/// Merges dart:* library code with code from *_patch.dart file.
-///
-/// Takes a list of the library's parts contents, with the main library contents
-/// first in the list, and the contents of the patch file.
-///
-/// The result will have `@patch` implementations merged into the correct place
-/// (e.g. the class or top-level function declaration) and all other
-/// declarations introduced by the patch will be placed into the main library
-/// file.
-///
-/// This is purely a syntactic transformation. Unlike dart2js patch files, there
-/// is no semantic meaning given to the *_patch files, and they do not magically
-/// get their own library scope, etc.
-///
-/// Editorializing: the dart2js approach requires a Dart front end such as
-/// package:analyzer to semantically model a feature beyond what is specified
-/// in the Dart language. Since this feature is only for the convenience of
-/// writing the dart:* libraries, and not a tool given to Dart developers, it
-/// seems like a non-ideal situation. Instead we keep the preprocessing simple.
-List<String> _patchLibrary(
- String name, List<String> partsContents, String patchContents) {
- var results = <StringEditBuffer>[];
-
- // Parse the patch first. We'll need to extract bits of this as we go through
- // the other files.
- final patchFinder = new PatchFinder.parseAndVisit(name, patchContents);
-
- // Merge `external` declarations with the corresponding `@patch` code.
- for (var partContent in partsContents) {
- var partEdits = new StringEditBuffer(partContent);
- var partUnit = parseCompilationUnit(partContent);
- partUnit.accept(new PatchApplier(partEdits, patchFinder));
- results.add(partEdits);
- }
-
- if (patchFinder.patches.length != patchFinder.applied.length) {
- print('Some elements marked as @patch do not have corresponding elements:');
- for (var patched in patchFinder.patches.keys) {
- if (!patchFinder.applied.contains(patched)) {
- print('*** ${patched}');
- }
- }
- throw "Failed to apply all @patch-es";
- }
-
- return new List<String>.from(results.map((e) => e.toString()));
-}
-
-final String injectedCidFields = [
- 'Array',
- 'ExternalOneByteString',
- 'GrowableObjectArray',
- 'ImmutableArray',
- 'OneByteString',
- 'TwoByteString',
-].map((name) => "static final int cid${name} = 0;").join('\n');
-
-/// Merge `@patch` declarations into `external` declarations.
-class PatchApplier extends GeneralizingAstVisitor {
- final StringEditBuffer edits;
- final PatchFinder patch;
-
- bool _isLibrary = true; // until proven otherwise.
-
- PatchApplier(this.edits, this.patch);
-
- @override
- visitCompilationUnit(CompilationUnit node) {
- super.visitCompilationUnit(node);
- if (_isLibrary) _mergeUnpatched(node);
- }
-
- void _merge(AstNode node, int pos) {
- var code = patch.contents.substring(node.offset, node.end);
-
- // We inject a number of static fields into dart:internal.ClassID class.
- // These fields represent various VM class ids and are only used to
- // make core libraries compile. Kernel reader will actually ignore these
- // fields and instead inject concrete constants into this class.
- if (node is ClassDeclaration && node.name.name == 'ClassID') {
- code = code.replaceFirst(new RegExp(r'}$'), injectedCidFields + '}');
- }
- edits.insert(pos, '\n' + code);
- }
-
- /// Merges directives and declarations that are not `@patch` into the library.
- void _mergeUnpatched(CompilationUnit unit) {
- // Merge imports from the patch
- // TODO(jmesserly): remove duplicate imports
-
- // To patch a library, we must have a library directive
- var libDir = unit.directives.first as LibraryDirective;
- int importPos = unit.directives
- .lastWhere((d) => d is ImportDirective, orElse: () => libDir)
- .end;
- for (var d in patch.unit.directives.where((d) => d is ImportDirective)) {
- _merge(d, importPos);
- }
-
- int partPos = unit.directives.last.end;
- for (var d in patch.unit.directives.where((d) => d is PartDirective)) {
- _merge(d, partPos);
- }
-
- // Merge declarations from the patch
- int declPos = edits.original.length;
- for (var d in patch.mergeDeclarations) {
- _merge(d, declPos);
- }
- }
-
- @override
- visitPartOfDirective(PartOfDirective node) {
- _isLibrary = false;
- }
-
- @override
- visitFunctionDeclaration(FunctionDeclaration node) {
- _maybePatch(node);
- }
-
- /// Merge patches and extensions into the class
- @override
- visitClassDeclaration(ClassDeclaration node) {
- node.members.forEach(_maybePatch);
-
- var mergeMembers = patch.mergeMembers[_qualifiedName(node)];
- if (mergeMembers == null) return;
-
- // Merge members from the patch
- var pos = node.members.last.end;
- for (var member in mergeMembers) {
- var code = patch.contents.substring(member.offset, member.end);
- edits.insert(pos, '\n\n ' + code);
- }
- }
-
- void _maybePatch(AstNode node) {
- if (node is FieldDeclaration) return;
-
- var externalKeyword = (node as dynamic).externalKeyword;
-
- var name = _qualifiedName(node);
- var patchNode = patch.patches[name];
- if (patchNode == null) {
- if (externalKeyword != null) {
- print('warning: patch not found for $name: $node');
- exitCode = 1;
- }
- return;
- }
- patch.applied.add(name);
-
- Annotation patchMeta = patchNode.metadata.lastWhere(_isPatchAnnotation);
- int start = patchMeta.endToken.next.offset;
- var code = patch.contents.substring(start, patchNode.end);
-
- // For some node like static fields, the node's offset doesn't include
- // the external keyword. Also starting from the keyword lets us preserve
- // documentation comments.
- edits.replace(externalKeyword?.offset ?? node.offset, node.end, code);
- }
-}
-
-class PatchFinder extends GeneralizingAstVisitor {
- final String contents;
- final CompilationUnit unit;
-
- final Map patches = <String, Declaration>{};
- final Map mergeMembers = <String, List<ClassMember>>{};
- final List mergeDeclarations = <CompilationUnitMember>[];
- final Set<String> applied = new Set<String>();
-
- PatchFinder.parseAndVisit(String name, String contents)
- : contents = contents,
- unit = parseCompilationUnit(contents, name: name) {
- visitCompilationUnit(unit);
- }
-
- @override
- visitCompilationUnitMember(CompilationUnitMember node) {
- mergeDeclarations.add(node);
- }
-
- @override
- visitClassDeclaration(ClassDeclaration node) {
- if (_isPatch(node)) {
- var members = <ClassMember>[];
- for (var member in node.members) {
- if (_isPatch(member)) {
- patches[_qualifiedName(member)] = member;
- } else {
- members.add(member);
- }
- }
- if (members.isNotEmpty) {
- mergeMembers[_qualifiedName(node)] = members;
- }
- } else {
- mergeDeclarations.add(node);
- }
- }
-
- @override
- visitFunctionDeclaration(FunctionDeclaration node) {
- if (_isPatch(node)) {
- patches[_qualifiedName(node)] = node;
- } else {
- mergeDeclarations.add(node);
- }
- }
-
- @override
- visitFunctionBody(node) {} // skip method bodies
-}
-
-String _qualifiedName(Declaration node) {
- var parent = node.parent;
- var className = '';
- if (parent is ClassDeclaration) {
- className = parent.name.name + '.';
- }
- var name = (node as dynamic).name;
- name = (name != null ? name.name : '');
-
- var accessor = '';
- if (node is MethodDeclaration) {
- if (node.isGetter)
- accessor = 'get:';
- else if (node.isSetter) accessor = 'set:';
- }
- return className + accessor + name;
-}
-
-bool _isPatch(AnnotatedNode node) => node.metadata.any(_isPatchAnnotation);
-
-bool _isPatchAnnotation(Annotation m) =>
- m.name.name == 'patch' && m.constructorName == null && m.arguments == null;
-
-/// Editable string buffer.
-///
-/// Applies a series of edits (insertions, removals, replacements) using
-/// original location information, and composes them into the edited string.
-///
-/// For example, starting with a parsed AST with original source locations,
-/// this type allows edits to be made without regards to other edits.
-class StringEditBuffer {
- final String original;
- final _edits = <_StringEdit>[];
-
- /// Creates a new transaction.
- StringEditBuffer(this.original);
-
- bool get hasEdits => _edits.length > 0;
-
- /// Edit the original text, replacing text on the range [begin] and
- /// exclusive [end] with the [replacement] string.
- void replace(int begin, int end, String replacement) {
- _edits.add(new _StringEdit(begin, end, replacement));
- }
-
- /// Insert [string] at [offset].
- /// Equivalent to `replace(offset, offset, string)`.
- void insert(int offset, String string) => replace(offset, offset, string);
-
- /// Remove text from the range [begin] to exclusive [end].
- /// Equivalent to `replace(begin, end, '')`.
- void remove(int begin, int end) => replace(begin, end, '');
-
- /// Applies all pending [edit]s and returns a new string.
- ///
- /// This method is non-destructive: it does not discard existing edits or
- /// change the [original] string. Further edits can be added and this method
- /// can be called again.
- ///
- /// Throws [UnsupportedError] if the edits were overlapping. If no edits were
- /// made, the original string will be returned.
- String toString() {
- var sb = new StringBuffer();
- if (_edits.length == 0) return original;
-
- // Sort edits by start location.
- _edits.sort();
-
- int consumed = 0;
- for (var edit in _edits) {
- if (consumed > edit.begin) {
- sb = new StringBuffer();
- sb.write('overlapping edits. Insert at offset ');
- sb.write(edit.begin);
- sb.write(' but have consumed ');
- sb.write(consumed);
- sb.write(' input characters. List of edits:');
- for (var e in _edits) {
- sb.write('\n ');
- sb.write(e);
- }
- throw new UnsupportedError(sb.toString());
- }
-
- // Add characters from the original string between this edit and the last
- // one, if any.
- var betweenEdits = original.substring(consumed, edit.begin);
- sb.write(betweenEdits);
- sb.write(edit.replace);
- consumed = edit.end;
- }
-
- // Add any text from the end of the original string that was not replaced.
- sb.write(original.substring(consumed));
- return sb.toString();
- }
-}
-
-class _StringEdit implements Comparable<_StringEdit> {
- final int begin;
- final int end;
- final String replace;
-
- _StringEdit(this.begin, this.end, this.replace);
-
- int get length => end - begin;
-
- String toString() => '(Edit @ $begin,$end: "$replace")';
-
- int compareTo(_StringEdit other) {
- int diff = begin - other.begin;
- if (diff != 0) return diff;
- return end - other.end;
- }
-}
-
-List<SdkLibrary> _getSdkLibraries(String contents) {
- var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(false);
- parseCompilationUnit(contents).accept(libraryBuilder);
- return libraryBuilder.librariesMap.sdkLibraries;
-}
-
-void addLocation(Map<String, Map<String, String>> locations, String libraryName,
- String libraryPath) {
- assert(locations[libraryName] == null);
- locations[libraryName] = {'uri': '${path.toUri(libraryPath)}'};
-}
diff --git a/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch b/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
new file mode 100644
index 0000000..d4fdc59
--- /dev/null
+++ b/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
@@ -0,0 +1,232 @@
+diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
+index b649ca834..e181dd55b 100644
+--- a/runtime/dart_isolate.cc
++++ b/runtime/dart_isolate.cc
+@@ -163,7 +163,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
+ }
+
+ auto* isolate_data = static_cast<std::shared_ptr<DartIsolate>*>(
+- Dart_IsolateGroupData(dart_isolate));
++ Dart_IsolateData(dart_isolate));
+ if (isolate_data->get() != this) {
+ return false;
+ }
+@@ -174,7 +174,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
+ // We are entering a new scope (for the first time since initialization) and
+ // we want to restore the current scope to null when we exit out of this
+ // method. This balances the implicit Dart_EnterIsolate call made by
+- // Dart_CreateIsolateGroup (which calls the Initialize).
++ // Dart_CreateIsolate (which calls the Initialize).
+ Dart_ExitIsolate();
+
+ tonic::DartIsolateScope scope(isolate());
+@@ -636,8 +636,8 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
+ return service_isolate->isolate();
+ }
+
+-// |Dart_IsolateGroupCreateCallback|
+-Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
++// |Dart_IsolateCreateCallback|
++Dart_Isolate DartIsolate::DartIsolateCreateCallback(
+ const char* advisory_script_uri,
+ const char* advisory_script_entrypoint,
+ const char* package_root,
+@@ -720,16 +720,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
+ }
+
+ // Create the Dart VM isolate and give it the embedder object as the baton.
+- Dart_Isolate isolate = Dart_CreateIsolateGroup(
++ Dart_Isolate isolate = Dart_CreateIsolate(
+ advisory_script_uri, //
+ advisory_script_entrypoint, //
+ (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(),
+ (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(),
+ (*embedder_isolate)->GetSharedSnapshot()->GetDataMapping(),
+ (*embedder_isolate)->GetSharedSnapshot()->GetInstructionsMapping(), flags,
+- embedder_isolate.get(), // isolate_group_data
+- embedder_isolate.get(), // isolate_data
+- error);
++ embedder_isolate.get(), error);
+
+ if (isolate == nullptr) {
+ FML_DLOG(ERROR) << *error;
+@@ -772,15 +770,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
+
+ // |Dart_IsolateShutdownCallback|
+ void DartIsolate::DartIsolateShutdownCallback(
+- std::shared_ptr<DartIsolate>* isolate_group_data,
+- std::shared_ptr<DartIsolate>* isolate_data) {
+- isolate_group_data->get()->OnShutdownCallback();
++ std::shared_ptr<DartIsolate>* embedder_isolate) {
++ embedder_isolate->get()->OnShutdownCallback();
+ }
+
+-// |Dart_IsolateGroupCleanupCallback|
+-void DartIsolate::DartIsolateGroupCleanupCallback(
+- std::shared_ptr<DartIsolate>* isolate_group_data) {
+- delete isolate_group_data;
++// |Dart_IsolateCleanupCallback|
++void DartIsolate::DartIsolateCleanupCallback(
++ std::shared_ptr<DartIsolate>* embedder_isolate) {
++ delete embedder_isolate;
+ }
+
+ fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
+diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h
+index 453810b1b..407852dc2 100644
+--- a/runtime/dart_isolate.h
++++ b/runtime/dart_isolate.h
+@@ -156,8 +156,8 @@ class DartIsolate : public UIDartState {
+
+ void OnShutdownCallback();
+
+- // |Dart_IsolateGroupCreateCallback|
+- static Dart_Isolate DartIsolateGroupCreateCallback(
++ // |Dart_IsolateCreateCallback|
++ static Dart_Isolate DartIsolateCreateCallback(
+ const char* advisory_script_uri,
+ const char* advisory_script_entrypoint,
+ const char* package_root,
+@@ -186,12 +186,11 @@ class DartIsolate : public UIDartState {
+
+ // |Dart_IsolateShutdownCallback|
+ static void DartIsolateShutdownCallback(
+- std::shared_ptr<DartIsolate>* isolate_group_data,
+- std::shared_ptr<DartIsolate>* isolate_data);
++ std::shared_ptr<DartIsolate>* embedder_isolate);
+
+- // |Dart_IsolateGroupCleanupCallback|
+- static void DartIsolateGroupCleanupCallback(
+- std::shared_ptr<DartIsolate>* isolate_group_data);
++ // |Dart_IsolateCleanupCallback|
++ static void DartIsolateCleanupCallback(
++ std::shared_ptr<DartIsolate>* embedder_isolate);
+
+ FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
+ };
+diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc
+index 555d0c9ee..903e74b15 100644
+--- a/runtime/dart_vm.cc
++++ b/runtime/dart_vm.cc
+@@ -366,13 +366,12 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
+ params.vm_snapshot_data = vm_data_->GetVMSnapshot().GetDataMapping();
+ params.vm_snapshot_instructions =
+ vm_data_->GetVMSnapshot().GetInstructionsMapping();
+- params.create_group = reinterpret_cast<decltype(params.create_group)>(
+- DartIsolate::DartIsolateGroupCreateCallback);
+- params.shutdown_isolate =
+- reinterpret_cast<decltype(params.shutdown_isolate)>(
+- DartIsolate::DartIsolateShutdownCallback);
+- params.cleanup_group = reinterpret_cast<decltype(params.cleanup_group)>(
+- DartIsolate::DartIsolateGroupCleanupCallback);
++ params.create = reinterpret_cast<decltype(params.create)>(
++ DartIsolate::DartIsolateCreateCallback);
++ params.shutdown = reinterpret_cast<decltype(params.shutdown)>(
++ DartIsolate::DartIsolateShutdownCallback);
++ params.cleanup = reinterpret_cast<decltype(params.cleanup)>(
++ DartIsolate::DartIsolateCleanupCallback);
+ params.thread_exit = ThreadExitCallback;
+ params.get_service_assets = GetVMServiceAssetsArchiveCallback;
+ params.entropy_source = dart::bin::GetEntropy;
+diff --git a/shell/platform/fuchsia/dart/dart_component_controller.cc b/shell/platform/fuchsia/dart/dart_component_controller.cc
+index c8e7cc5ab..1c4f71050 100644
+--- a/shell/platform/fuchsia/dart/dart_component_controller.cc
++++ b/shell/platform/fuchsia/dart/dart_component_controller.cc
+@@ -324,13 +324,12 @@ bool DartComponentController::CreateIsolate(
+ auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
+ namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
+
+- isolate_ = Dart_CreateIsolateGroup(
++ isolate_ = Dart_CreateIsolate(
+ url_.c_str(), label_.c_str(), isolate_snapshot_data,
+ isolate_snapshot_instructions, shared_snapshot_data,
+- shared_snapshot_instructions, nullptr /* flags */,
+- state /* isolate_group_data */, state /* isolate_data */, &error);
++ shared_snapshot_instructions, nullptr /* flags */, state, &error);
+ if (!isolate_) {
+- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
++ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", error);
+ return false;
+ }
+
+diff --git a/shell/platform/fuchsia/dart/dart_runner.cc b/shell/platform/fuchsia/dart/dart_runner.cc
+index b9ded3ac4..200500d2c 100644
+--- a/shell/platform/fuchsia/dart/dart_runner.cc
++++ b/shell/platform/fuchsia/dart/dart_runner.cc
+@@ -61,13 +61,13 @@ const char* kDartVMArgs[] = {
+ // clang-format on
+ };
+
+-Dart_Isolate IsolateGroupCreateCallback(const char* uri,
+- const char* name,
+- const char* package_root,
+- const char* package_config,
+- Dart_IsolateFlags* flags,
+- void* callback_data,
+- char** error) {
++Dart_Isolate IsolateCreateCallback(const char* uri,
++ const char* name,
++ const char* package_root,
++ const char* package_config,
++ Dart_IsolateFlags* flags,
++ void* callback_data,
++ char** error) {
+ if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
+ #if defined(DART_PRODUCT)
+ *error = strdup("The service isolate is not implemented in product mode");
+@@ -81,7 +81,7 @@ Dart_Isolate IsolateGroupCreateCallback(const char* uri,
+ return NULL;
+ }
+
+-void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
++void IsolateShutdownCallback(void* callback_data) {
+ // The service isolate (and maybe later the kernel isolate) doesn't have an
+ // async loop.
+ auto dispatcher = async_get_default_dispatcher();
+@@ -92,8 +92,8 @@ void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
+ }
+ }
+
+-void IsolateGroupCleanupCallback(void* isolate_group_data) {
+- delete static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
++void IsolateCleanupCallback(void* callback_data) {
++ delete static_cast<std::shared_ptr<tonic::DartState>*>(callback_data);
+ }
+
+ void RunApplication(
+@@ -167,9 +167,9 @@ DartRunner::DartRunner() : context_(sys::ComponentContext::Create()) {
+ params.vm_snapshot_data = vm_snapshot_data_.address();
+ params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
+ #endif
+- params.create_group = IsolateGroupCreateCallback;
+- params.shutdown_isolate = IsolateShutdownCallback;
+- params.cleanup_group = IsolateGroupCleanupCallback;
++ params.create = IsolateCreateCallback;
++ params.shutdown = IsolateShutdownCallback;
++ params.cleanup = IsolateCleanupCallback;
+ params.entropy_source = EntropySource;
+ #if !defined(DART_PRODUCT)
+ params.get_service_assets = GetVMServiceAssetsArchiveCallback;
+diff --git a/shell/platform/fuchsia/dart/service_isolate.cc b/shell/platform/fuchsia/dart/service_isolate.cc
+index 5287d638f..2e6eda265 100644
+--- a/shell/platform/fuchsia/dart/service_isolate.cc
++++ b/shell/platform/fuchsia/dart/service_isolate.cc
+@@ -123,14 +123,14 @@ Dart_Isolate CreateServiceIsolate(const char* uri,
+ #endif
+
+ auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
+- Dart_Isolate isolate = Dart_CreateIsolateGroup(
++ Dart_Isolate isolate = Dart_CreateIsolate(
+ uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
+ mapped_isolate_snapshot_instructions.address(),
+ mapped_shared_snapshot_data.address(),
+- mapped_shared_snapshot_instructions.address(), nullptr /* flags */,
+- state /* isolate_group_data */, state /* isolate_data */, error);
++ mapped_shared_snapshot_instructions.address(), nullptr /* flags */, state,
++ error);
+ if (!isolate) {
+- FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
++ FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", *error);
+ return nullptr;
+ }
+
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index 7bb4919..f8d3053 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -15,6 +15,7 @@
scriptDir = os.path.dirname(os.path.realpath(__file__))
outDir = os.path.join(scriptDir, '..', 'out', 'ReleaseX64')
+abiDir = os.path.join(outDir, 'dart-sdk', 'lib', '_internal', 'abiversions')
# Info about a running test.
@@ -61,13 +62,19 @@
return Test(cmd, resultFile, logFile, version)
+# Returns whether the dill files exist for an ABI version.
+def abiVersionExists(version):
+ return os.path.isdir(os.path.join(abiDir, str(version)))
+
+
# Build tests for every supported version, and return a list of Test objects.
def buildAllTests():
abi_version = int(utils.GetAbiVersion())
oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
tests = [buildTest(None)]
for version in xrange(oldest_abi_version, abi_version + 1):
- tests.append(buildTest(version))
+ if abiVersionExists(version):
+ tests.append(buildTest(version))
return tests
@@ -150,7 +157,6 @@
def diffAllResults(tests):
allResults = readAllTestFiles(tests, lambda test: test.resultFile)
allLogs = readAllTestFiles(tests, lambda test: test.logFile)
- anyDiff = False
logDir = os.path.join(outDir, 'logs')
makeDirs(logDir)
resultFileName = os.path.join(logDir, 'results.json')
@@ -163,14 +169,13 @@
if diffs:
logRecords = allLogs[name] if name in allLogs else []
logFile.write(json.dumps(makeLog(diffs, results, logRecords)) + '\n')
- anyDiff = True
- return anyDiff
def main():
tests = buildAllTests()
runAllTests(tests)
- return 1 if diffAllResults(tests) else 0
+ diffAllResults(tests)
+ return 0
if __name__ == '__main__':
diff --git a/tools/test.dart b/tools/test.dart
index edb0f8c..4c181a0 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -261,6 +261,7 @@
final request = await client.getUrl(requestUrl);
final response = await request.close();
final Map<String, dynamic> object = await response
+ .cast<List<int>>()
.transform(new Utf8Decoder())
.transform(new JsonDecoder())
.first;
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 3ca1729..e8d91fc 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -250,11 +250,7 @@
/// Build a map of uris to digests.
final inputDigests = <Uri, List<int>>{};
for (var input in inputs) {
- var uri = Uri.parse(input.path);
- if (uri.scheme.isEmpty) {
- uri = Uri.parse('file://${input.path}');
- }
- inputDigests[uri] = input.digest;
+ inputDigests[_toUri(input.path)] = input.digest;
}
// TODO(sigmund): add support for experiments with the incremental compiler.
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index f40512c..07e8087 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -3,7 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
import("../../utils/compile_platform.gni")
-import("../../utils/generate_patch_sdk.gni")
import("../create_timestamp.gni")
import("../application_snapshot.gni")
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index e56bbfd..6069ad1 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -87,6 +87,7 @@
"$abs_main",
"-m",
"-o$abs_output",
+ "--no-source-maps",
]
}
}
diff --git a/utils/generate_patch_sdk.gni b/utils/generate_patch_sdk.gni
deleted file mode 100644
index f947fb9..0000000
--- a/utils/generate_patch_sdk.gni
+++ /dev/null
@@ -1,51 +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.
-
-import("../build/dart/dart_action.gni")
-
-_dart_root = get_path_info("..", "abspath")
-
-# Template to generate a patched_sdk folder.
-#
-# This template expects four arguments:
-# - mode: vm or dart2js (whether to build an sdk for the vm or for dart2js)
-# - input_patches_dir: directory containing the input library files.
-# - patched_sdk_dir: the output location
-# - deps: extra dependencies that must be built ahead of time.
-template("generate_patched_sdk") {
- assert(defined(invoker.input_patches_dir),
- "Need input_patches_dir in $target_name")
- assert(defined(invoker.patched_sdk_dir),
- "Need patched_sdk_dir in $target_name")
- assert(defined(invoker.mode), "Need mode in $target_name")
-
- prebuilt_dart_action(target_name) {
- forward_variables_from(invoker, [
- "deps",
- ])
-
- depfile = "$root_out_dir/${target_name}_patched_sdk.d"
-
- script = "$_dart_root/tools/patch_sdk.dart"
-
- if (defined(invoker.outputs)) {
- outputs = invoker.outputs
- } else {
- outputs = [
- # Instead of listing all outputs we list those consumed by
- # other BUILD rules.
- "$root_out_dir/${invoker.patched_sdk_dir}/platform.dill",
- "$root_out_dir/${invoker.patched_sdk_dir}/outline.dill",
- ]
- }
-
- args = [
- invoker.mode,
- rebase_path("$_dart_root/sdk"),
- rebase_path(invoker.input_patches_dir),
- rebase_path("$root_out_dir/${invoker.patched_sdk_dir}", root_build_dir),
- rebase_path("$_dart_root/.packages"),
- ]
- }
-}