Version 2.3.0-dev.0.0
Merge commit '523666a97a21a29994d8ed17cdf13a4a4b082d06' into dev
diff --git a/.packages b/.packages
index 08c0d29..c5944a1 100644
--- a/.packages
+++ b/.packages
@@ -66,6 +66,7 @@
package_config:third_party/pkg_tested/package_config/lib
package_resolver:third_party/pkg_tested/package_resolver/lib
path:third_party/pkg/path/lib
+pedantic:third_party/pkg/pedantic/lib
pool:third_party/pkg/pool/lib
protobuf:third_party/pkg/protobuf/protobuf/lib
pub:third_party/pkg/pub/lib
@@ -88,7 +89,9 @@
string_scanner:third_party/pkg/string_scanner/lib
telemetry:pkg/telemetry/lib
term_glyph:third_party/pkg/term_glyph/lib
-test:third_party/pkg/test/lib
+test:third_party/pkg/test/pkgs/test/lib
+test_api:third_party/pkg/test/pkgs/test_api/lib
+test_core:third_party/pkg/test/pkgs/test_core/lib
test_dart:tools/testing/dart
test_descriptor:third_party/pkg/test_descriptor/lib
test_process:third_party/pkg/test_process/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ebda709..124f50a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 2.3.0-dev.0.0
+
+### Tool Changes
+
+#### Linter
+
+The Linter was updated to `0.1.86` which includes the following change:
+* new lint: `prefer_inlined_adds`
+
## 2.2.1-dev.4.2
* Cherry-pick ab66a3808b28dfc94eaf0ed151c13f4fc696b5dc to dev
@@ -19,7 +28,7 @@
The Linter was updated to `0.1.85` which includes the following changes:
-* (**BREAKING**) renamed `spread_collections` to `prefer_spread_collections`
+* new lint: `prefer_inlined_adds`
* new lint: `prefer_for_elements_to_map_fromIterable`
* new lint: `prefer_if_elements_to_conditional_expressions`
* new lint: `diagnostic_describe_all_properties`
diff --git a/DEPS b/DEPS
index 9d0806f..0ad497f 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
"chromium_git": "https://chromium.googlesource.com",
"fuchsia_git": "https://fuchsia.googlesource.com",
- "co19_2_rev": "7e743ef29b4c06f1a2b8b9dc70ead60b31aab526",
+ "co19_2_rev": "a0a24a4bd5e4d913264fccfd600139af5b20c8e9",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
# should be kept up to date with the revisions pulled by the Flutter engine.
@@ -64,7 +64,7 @@
"collection_tag": "1.14.11",
"convert_tag": "2.0.2",
"crypto_tag" : "2.0.6",
- "csslib_tag" : "0.14.4+1",
+ "csslib_tag" : "0.15.0",
"dart2js_info_tag" : "0.6.0",
# Note: Updates to dart_style have to be coordinated with the infrastructure
@@ -84,21 +84,21 @@
"dartdoc_tag" : "v0.28.2",
"fixnum_tag": "0.10.9",
"glob_tag": "1.1.7",
- "html_tag" : "0.14.0",
+ "html_tag" : "0.14.0+1",
"http_io_rev": "57da05a66f5bf7df3dd7aebe7b7efe0dfc477baa",
"http_multi_server_tag" : "2.0.5",
"http_parser_tag" : "3.1.3",
"http_retry_tag": "0.1.1",
- "http_tag" : "0.12.0",
+ "http_tag" : "0.12.0+2",
"http_throttle_tag" : "1.0.2",
"idl_parser_rev": "5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "0.15.7",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.85",
+ "linter_tag": "0.1.86",
"logging_tag": "0.11.3+2",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
- "markdown_tag": "2.0.2",
+ "markdown_tag": "2.0.3",
"matcher_tag": "0.12.3",
"mime_tag": "0.9.6+2",
"mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
@@ -108,6 +108,7 @@
"package_config_tag": "1.0.5",
"package_resolver_tag": "1.0.10",
"path_tag": "1.6.2",
+ "pedantic_tag": "v1.5.0",
"ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
"pool_tag": "1.3.6",
"protobuf_rev": "0c77167b16d00b561a6055bfe26690af7f26ae88",
@@ -125,13 +126,13 @@
"source_maps_tag": "8af7cc1a1c3a193c1fba5993ce22a546a319c40e",
"source_span_tag": "1.5.5",
"stack_trace_tag": "1.9.3",
- "stream_channel_tag": "1.6.8",
+ "stream_channel_tag": "2.0.0",
"string_scanner_tag": "1.0.3",
"test_descriptor_tag": "1.1.1",
"test_process_tag": "1.0.3",
"term_glyph_tag": "1.0.1",
"test_reflective_loader_tag": "0.1.8",
- "test_tag": "1.3.4",
+ "test_tag": "test-v1.6.1",
"typed_data_tag": "1.1.6",
"unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
"usage_tag": "3.4.0",
@@ -162,7 +163,7 @@
Var("dart_root") + "/third_party/d8": {
"packages": [{
"package": "dart/d8",
- "version": "version:6.9.427.23+1",
+ "version": "version:7.5.149",
}],
"dep_type": "cipd",
},
@@ -301,6 +302,8 @@
+ "@" + Var("package_resolver_tag"),
Var("dart_root") + "/third_party/pkg/path":
Var("dart_git") + "path.git" + "@" + Var("path_tag"),
+ Var("dart_root") + "/third_party/pkg/pedantic":
+ Var("dart_git") + "pedantic.git" + "@" + Var("pedantic_tag"),
Var("dart_root") + "/third_party/pkg/pool":
Var("dart_git") + "pool.git" + "@" + Var("pool_tag"),
Var("dart_root") + "/third_party/pkg/protobuf":
diff --git a/WATCHLISTS b/WATCHLISTS
index 415a9bd..538f457 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -50,9 +50,6 @@
')$'
)
},
- 'mirrors' : {
- 'filepath': '.*mirrors.*',
- },
'observatory': {
'filepath': (
'^runtime/bin/vmservice/|'
@@ -79,8 +76,7 @@
'kernel': [ 'karlklose@google.com', 'jensj@google.com', 'kmillikin@google.com',
'alexmarkov@google.com' ],
'messages_review': [ 'dart-uxr+reviews@google.com' ],
- 'mirrors' : [ 'rmacnak@google.com' ],
- 'observatory': [ 'bkonyi@google.com', 'rmacnak@google.com' ],
+ 'observatory': [ 'bkonyi@google.com' ],
'package_vm': [ 'alexmarkov@google.com' ],
'runtime': [ 'vm-dev@dartlang.org' ],
'vm_compiler': [ 'dart-vm-compiler-team+reviews@google.com' ],
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index b8adeca..c4dc5b8 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -23,8 +23,8 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/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';
@@ -870,6 +870,32 @@
}
/**
+ * Use the given analysis [driver] to analyze the content of the
+ * AndroidManifest file at the given [path].
+ */
+ void _analyzeManifestFile(AnalysisDriver driver, String path) {
+ List<protocol.AnalysisError> convertedErrors;
+ try {
+ String content = _readFile(path);
+ ManifestValidator validator =
+ new ManifestValidator(resourceProvider.getFile(path).createSource());
+ LineInfo lineInfo = _computeLineInfo(content);
+ List<AnalysisError> errors = validator.validate(
+ content, driver.analysisOptions.chromeOsManifestChecks);
+ AnalyzerConverter converter = new AnalyzerConverter();
+ convertedErrors = converter.convertAnalysisErrors(errors,
+ lineInfo: lineInfo, options: driver.analysisOptions);
+ } catch (exception) {
+ // If the file cannot be analyzed, fall through to clear any previous
+ // errors.
+ }
+ callbacks.notificationManager.recordAnalysisErrors(
+ NotificationManager.serverId,
+ path,
+ convertedErrors ?? <protocol.AnalysisError>[]);
+ }
+
+ /**
* Use the given analysis [driver] to analyze the content of the pubspec file
* at the given [path].
*/
@@ -897,32 +923,6 @@
convertedErrors ?? <protocol.AnalysisError>[]);
}
- /**
- * Use the given analysis [driver] to analyze the content of the
- * AndroidManifest file at the given [path].
- */
- void _analyzeManifestFile(AnalysisDriver driver, String path) {
- List<protocol.AnalysisError> convertedErrors;
- try {
- String content = _readFile(path);
- ManifestValidator validator =
- new ManifestValidator(resourceProvider.getFile(path).createSource());
- LineInfo lineInfo = _computeLineInfo(content);
- List<AnalysisError> errors = validator.validate(
- content, driver.analysisOptions.chromeOsManifestChecks);
- AnalyzerConverter converter = new AnalyzerConverter();
- convertedErrors = converter.convertAnalysisErrors(errors,
- lineInfo: lineInfo, options: driver.analysisOptions);
- } catch (exception) {
- // If the file cannot be analyzed, fall through to clear any previous
- // errors.
- }
- callbacks.notificationManager.recordAnalysisErrors(
- NotificationManager.serverId,
- path,
- convertedErrors ?? <protocol.AnalysisError>[]);
- }
-
void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) {
if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
AnalysisDriver driver = info.analysisDriver;
@@ -938,6 +938,19 @@
}
}
+ void _checkForManifestUpdate(String path, ContextInfo info) {
+ if (_isManifest(path)) {
+ AnalysisDriver driver = info.analysisDriver;
+ if (driver == null) {
+ // I suspect that this happens as a result of a race condition: server
+ // has determined that the file (at [path]) is in a context, but hasn't
+ // yet created a driver for that context.
+ return;
+ }
+ _analyzeManifestFile(driver, path);
+ }
+ }
+
void _checkForPackagespecUpdate(String path, ContextInfo info) {
// Check to see if this is the .packages file for this context and if so,
// update the context's source factory.
@@ -968,19 +981,6 @@
}
}
- void _checkForManifestUpdate(String path, ContextInfo info) {
- if (_isManifest(path)) {
- AnalysisDriver driver = info.analysisDriver;
- if (driver == null) {
- // I suspect that this happens as a result of a race condition: server
- // has determined that the file (at [path]) is in a context, but hasn't
- // yet created a driver for that context.
- return;
- }
- _analyzeManifestFile(driver, path);
- }
- }
-
/**
* Compute the set of files that are being flushed, this is defined as
* the set of sources in the removed context (context.sources), that are
@@ -1139,10 +1139,23 @@
if (pubspecFile.exists) {
_analyzePubspecFile(info.analysisDriver, pubspecFile.path);
}
- File manifestFile = folder.getChildAssumingFile(MANIFEST_NAME);
- if (manifestFile.exists) {
- _analyzeManifestFile(info.analysisDriver, manifestFile.path);
+
+ void checkManifestFilesIn(Folder folder) {
+ for (var child in folder.getChildren()) {
+ if (child is File) {
+ if (child.shortName == MANIFEST_NAME &&
+ !excludedPaths.contains(child.path)) {
+ _analyzeManifestFile(info.analysisDriver, child.path);
+ }
+ } else if (child is Folder) {
+ if (!excludedPaths.contains(child.path)) {
+ checkManifestFilesIn(child);
+ }
+ }
+ }
}
+
+ checkManifestFilesIn(folder);
return info;
}
@@ -1510,13 +1523,13 @@
return false;
}
+ bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
+
bool _isPackagespec(String path) =>
pathContext.basename(path) == PACKAGE_SPEC_NAME;
bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
- bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
-
/**
* Merges [info] context into its parent.
*/
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 12a1d18..dbbd2d4 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -23,6 +23,8 @@
import 'package:analysis_server/src/services/correction/change_workspace.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
+import 'package:analysis_server/src/services/correction/fix/manifest/fix_generator.dart';
+import 'package:analysis_server/src/services/correction/fix/pubspec/fix_generator.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analysis_server/src/services/correction/organize_directives.dart';
import 'package:analysis_server/src/services/correction/sort_members.dart';
@@ -45,11 +47,17 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart' as engine;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/manifest/manifest_validator.dart';
+import 'package:analyzer/src/manifest/manifest_values.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:dart_style/dart_style.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+import 'package:path/src/context.dart';
import 'package:yaml/yaml.dart';
int test_resetCount = 0;
@@ -585,7 +593,6 @@
if (content == null) {
return errorFixesList;
}
- LineInfo lineInfo = new LineInfo.fromContent(content);
SourceFactory sourceFactory = server.getAnalysisDriver(file).sourceFactory;
List<engine.AnalysisError> errors = analyzeAnalysisOptions(
optionsFile.createSource(), content, sourceFactory);
@@ -599,6 +606,7 @@
List<Fix> fixes = await generator.computeFixes();
if (fixes.isNotEmpty) {
fixes.sort(Fix.SORT_BY_RELEVANCE);
+ LineInfo lineInfo = new LineInfo.fromContent(content);
AnalysisError serverError =
newAnalysisError_fromEngine(lineInfo, error);
AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
@@ -646,15 +654,98 @@
}
/**
+ * Compute and return the fixes associated with server-generated errors in
+ * Android manifest files.
+ */
+ Future<List<AnalysisErrorFixes>> _computeManifestFixes(
+ String file, int offset) async {
+ List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
+ File manifestFile = server.resourceProvider.getFile(file);
+ String content = _safelyRead(manifestFile);
+ if (content == null) {
+ return errorFixesList;
+ }
+ DocumentFragment document =
+ parseFragment(content, container: MANIFEST_TAG, generateSpans: true);
+ if (document == null) {
+ return errorFixesList;
+ }
+ ManifestValidator validator =
+ new ManifestValidator(manifestFile.createSource());
+ List<engine.AnalysisError> errors = validator.validate(content, true);
+ for (engine.AnalysisError error in errors) {
+ ManifestFixGenerator generator =
+ new ManifestFixGenerator(error, content, document);
+ List<Fix> fixes = await generator.computeFixes();
+ if (fixes.isNotEmpty) {
+ fixes.sort(Fix.SORT_BY_RELEVANCE);
+ LineInfo lineInfo = new LineInfo.fromContent(content);
+ AnalysisError serverError =
+ newAnalysisError_fromEngine(lineInfo, error);
+ AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
+ errorFixesList.add(errorFixes);
+ fixes.forEach((fix) {
+ errorFixes.fixes.add(fix.change);
+ });
+ }
+ }
+ return errorFixesList;
+ }
+
+ /**
+ * Compute and return the fixes associated with server-generated errors in
+ * pubspec.yaml files.
+ */
+ Future<List<AnalysisErrorFixes>> _computePubspecFixes(
+ String file, int offset) async {
+ List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
+ File pubspecFile = server.resourceProvider.getFile(file);
+ String content = _safelyRead(pubspecFile);
+ if (content == null) {
+ return errorFixesList;
+ }
+ SourceFactory sourceFactory = server.getAnalysisDriver(file).sourceFactory;
+ YamlMap pubspec = _getOptions(sourceFactory, content);
+ if (pubspec == null) {
+ return errorFixesList;
+ }
+ PubspecValidator validator = new PubspecValidator(
+ server.resourceProvider, pubspecFile.createSource());
+ List<engine.AnalysisError> errors = validator.validate(pubspec.nodes);
+ for (engine.AnalysisError error in errors) {
+ PubspecFixGenerator generator =
+ new PubspecFixGenerator(error, content, pubspec);
+ List<Fix> fixes = await generator.computeFixes();
+ if (fixes.isNotEmpty) {
+ fixes.sort(Fix.SORT_BY_RELEVANCE);
+ LineInfo lineInfo = new LineInfo.fromContent(content);
+ AnalysisError serverError =
+ newAnalysisError_fromEngine(lineInfo, error);
+ AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
+ errorFixesList.add(errorFixes);
+ fixes.forEach((fix) {
+ errorFixes.fixes.add(fix.change);
+ });
+ }
+ }
+ return errorFixesList;
+ }
+
+ /**
* Compute and return the fixes associated with server-generated errors.
*/
Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
String file, int offset) async {
+ Context context = server.resourceProvider.pathContext;
if (AnalysisEngine.isDartFileName(file)) {
return _computeDartFixes(file, offset);
- } else if (AnalysisEngine.isAnalysisOptionsFileName(
- file, server.resourceProvider.pathContext)) {
+ } else if (AnalysisEngine.isAnalysisOptionsFileName(file, context)) {
return _computeAnalysisOptionsFixes(file, offset);
+ } else if (context.basename(file) == 'pubspec.yaml') {
+ return _computePubspecFixes(file, offset);
+ } else if (context.basename(file) == 'manifest.xml') {
+ // TODO(brianwilkerson) Do we need to check more than the file name?
+ return _computeManifestFixes(file, offset);
}
return <AnalysisErrorFixes>[];
}
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
index 41fef69..c6b3256 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
@@ -51,8 +51,8 @@
/// presumed to have come from code that is already migrated.
factory DecoratedType.forElement(Element element) {
DecoratedType decorate(DartType type) {
- assert((type as TypeImpl).nullability ==
- Nullability.indeterminate); // TODO(paulberry)
+ assert((type as TypeImpl).nullabilitySuffix ==
+ NullabilitySuffix.star); // TODO(paulberry)
if (type is FunctionType) {
var decoratedType = DecoratedType(type, NullabilityNode.never,
returnType: decorate(type.returnType), positionalParameters: []);
diff --git a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
index 693b94e..3d225b5 100644
--- a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
@@ -103,13 +103,18 @@
if (element == null || element.isSynthetic) {
buffer.write(type.displayName);
} else {
- String uri = element.library.source.uri.toString();
+// String uri = element.library.source.uri.toString();
String name = element.name;
if (element is ClassMemberElement) {
String className = element.enclosingElement.name;
- buffer.write('$uri;$className;$name');
+ // TODO(brianwilkerson) Figure out why the uri is a file: URI when it
+ // ought to be a package: URI and restore the code below to include
+ // the URI in the string.
+// buffer.write('$uri;$className;$name');
+ buffer.write('$className;$name');
} else {
- buffer.write('$uri;$name');
+// buffer.write('$uri;$name');
+ buffer.write('$name');
}
}
} else {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 5f64118..b16b95c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -131,7 +131,7 @@
associatedErrorCodes: <String>['prefer_single_quotes']);
static const CONVERT_TO_SPREAD = const AssistKind(
'dart.assist.convertToSpread', 30, "Convert to a spread",
- associatedErrorCodes: <String>['spread_collections']);
+ associatedErrorCodes: <String>['prefer_spread_collections']);
static const ENCAPSULATE_FIELD =
const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
static const EXCHANGE_OPERANDS =
@@ -170,6 +170,9 @@
'dart.assist.flutter.wrap.streamBuilder', 30, "Wrap with StreamBuilder");
static const IMPORT_ADD_SHOW = const AssistKind(
'dart.assist.addShowCombinator', 30, "Add explicit 'show' combinator");
+ static const INLINE_INVOCATION = const AssistKind(
+ 'dart.assist.inline', 30, "Inline invocation of '{0}'",
+ associatedErrorCodes: <String>['prefer_inlined_adds']);
static const INTRODUCE_LOCAL_CAST_TYPE = const AssistKind(
'dart.assist.introduceLocalCast',
30,
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 64d8880..9a58459 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -134,6 +134,7 @@
await _addProposal_flutterWrapWidget();
await _addProposal_flutterWrapWidgets();
await _addProposal_importAddShow();
+ await _addProposal_inlineAdd();
await _addProposal_introduceLocalTestedType();
await _addProposal_invertIf();
await _addProposal_joinIfStatementInner();
@@ -464,6 +465,7 @@
NodeList<Expression> sections = cascade.cascadeSections;
Expression target = cascade.target;
if (target is! ListLiteral || sections[0] != invocation) {
+ // TODO(brianwilkerson) Consider extending this to handle set literals.
_coverageMarker();
return;
}
@@ -474,6 +476,8 @@
ListLiteral list = target;
Expression argument = invocation.argumentList.arguments[0];
String elementText;
+ AssistKind kind = DartAssistKind.CONVERT_TO_SPREAD;
+ List<String> args = null;
if (argument is BinaryExpression &&
argument.operator.type == TokenType.QUESTION_QUESTION) {
Expression right = argument.rightOperand;
@@ -492,20 +496,34 @@
String thenText = utils.getNodeText(argument.thenExpression);
elementText = 'if ($conditionText) ...$thenText';
}
+ } else if (argument is ListLiteral) {
+ // ..addAll([ ... ])
+ NodeList<CollectionElement> elements = argument.elements;
+ if (elements.isEmpty) {
+ // TODO(brianwilkerson) Consider adding a cleanup for the empty list
+ // case. We can essentially remove the whole invocation because it does
+ // nothing.
+ return;
+ }
+ int startOffset = elements.first.offset;
+ int endOffset = elements.last.end;
+ elementText = utils.getText(startOffset, endOffset - startOffset);
+ kind = DartAssistKind.INLINE_INVOCATION;
+ args = ['addAll'];
}
elementText ??= '...${utils.getNodeText(argument)}';
DartChangeBuilder changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- // ['a']..addAll(['b', 'c']);
if (list.elements.isNotEmpty) {
+ // ['a']..addAll(['b', 'c']);
builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
} else {
- //
+ // []..addAll(['b', 'c']);
builder.addSimpleInsertion(list.leftBracket.end, elementText);
- } // []..addAll(['b', 'c']);
+ }
builder.addDeletion(range.node(invocation));
});
- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SPREAD);
+ _addAssistFromBuilder(changeBuilder, kind, args: args);
}
Future<void> _addProposal_convertClassToMixin() async {
@@ -1211,6 +1229,29 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SET_LITERAL);
}
+ Future<void> _addProposal_convertToAbsoluteImport() async {
+ var node = this.node;
+ if (node is StringLiteral) {
+ node = node.parent;
+ }
+ if (node is ImportDirective) {
+ var importDirective = node;
+ var importUri = node.uriSource?.uri;
+ if (importUri?.scheme != 'package') {
+ return;
+ }
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ range.node(importDirective.uri), "'$importUri'");
+ });
+ _addAssistFromBuilder(
+ changeBuilder,
+ DartAssistKind.CONVERT_INTO_ABSOLUTE_IMPORT,
+ );
+ }
+ }
+
Future<void> _addProposal_convertToAsyncFunctionBody() async {
FunctionBody body = getEnclosingFunctionBody();
if (body == null ||
@@ -1744,29 +1785,6 @@
changeBuilder, DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
}
- Future<void> _addProposal_convertToAbsoluteImport() async {
- var node = this.node;
- if (node is StringLiteral) {
- node = node.parent;
- }
- if (node is ImportDirective) {
- var importDirective = node;
- var importUri = node.uriSource?.uri;
- if (importUri?.scheme != 'package') {
- return;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (builder) {
- builder.addSimpleReplacement(
- range.node(importDirective.uri), "'$importUri'");
- });
- _addAssistFromBuilder(
- changeBuilder,
- DartAssistKind.CONVERT_INTO_ABSOLUTE_IMPORT,
- );
- }
- }
-
Future<void> _addProposal_convertToMultilineString() async {
var node = this.node;
if (node is InterpolationElement) {
@@ -2823,6 +2841,48 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.IMPORT_ADD_SHOW);
}
+ Future<void> _addProposal_inlineAdd() async {
+ AstNode node = this.node;
+ if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+ _coverageMarker();
+ return;
+ }
+ SimpleIdentifier name = node;
+ MethodInvocation invocation = node.parent;
+ if (name != invocation.methodName ||
+ name.name != 'add' ||
+ !invocation.isCascaded ||
+ invocation.argumentList.arguments.length != 1) {
+ _coverageMarker();
+ return;
+ }
+ CascadeExpression cascade = invocation.thisOrAncestorOfType();
+ NodeList<Expression> sections = cascade.cascadeSections;
+ Expression target = cascade.target;
+ if (target is! ListLiteral || sections[0] != invocation) {
+ // TODO(brianwilkerson) Consider extending this to handle set literals.
+ _coverageMarker();
+ return;
+ }
+ ListLiteral list = target;
+ Expression argument = invocation.argumentList.arguments[0];
+ String elementText = utils.getNodeText(argument);
+
+ DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (list.elements.isNotEmpty) {
+ // ['a']..add(e);
+ builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+ } else {
+ // []..add(e);
+ builder.addSimpleInsertion(list.leftBracket.end, elementText);
+ }
+ builder.addDeletion(range.node(invocation));
+ });
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.INLINE_INVOCATION,
+ args: ['add']);
+ }
+
Future<void> _addProposal_introduceLocalTestedType() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 3c54bcb..7ca77e9 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -335,3 +335,10 @@
static const USE_RETHROW =
const FixKind('USE_RETHROW', 50, "Replace throw with rethrow");
}
+
+/// An enumeration of quick fix kinds for the errors found in an Android
+/// manifest file.
+class ManifestFixKind {}
+
+/// An enumeration of quick fix kinds for the errors found in a pubspec file.
+class PubspecFixKind {}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
index f558372..af92ea7 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analysis_server/src/utilities/yaml_node_locator.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/source/source_range.dart';
@@ -17,8 +18,6 @@
show SourceChange;
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
-import 'package:meta/meta.dart';
-import 'package:source_span/src/span.dart';
import 'package:yaml/yaml.dart';
/// The generator used to generate fixes in analysis options files.
@@ -175,64 +174,3 @@
return new SourceRange(startOffset, endOffset - startOffset);
}
}
-
-/// An object used to locate the [YamlNode] associated with a source range.
-/// More specifically, it will return the deepest [YamlNode] which completely
-/// encompasses the specified range.
-class YamlNodeLocator {
- /// The inclusive start offset of the range used to identify the node.
- int _startOffset = 0;
-
- /// The inclusive end offset of the range used to identify the node.
- int _endOffset = 0;
-
- /// Initialize a newly created locator to locate the deepest [YamlNode] for
- /// which `node.offset <= [start]` and `[end] < node.end`.
- ///
- /// If the [end] offset is not provided, then it is considered the same as the
- /// [start] offset.
- YamlNodeLocator({@required int start, int end})
- : this._startOffset = start,
- this._endOffset = end ?? start;
-
- /// Search within the given Yaml [node] and return the path to the most deeply
- /// nested node that includes the whole target range, or an empty list if no
- /// node was found. The path is represented by all of the elements from the
- /// starting [node] to the most deeply nested node, in reverse order.
- List<YamlNode> searchWithin(YamlNode node) {
- List<YamlNode> path = [];
- _searchWithin(path, node);
- return path;
- }
-
- void _searchWithin(List<YamlNode> path, YamlNode node) {
- SourceSpan span = node.span;
- if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
- return;
- }
- if (node is YamlList) {
- for (YamlNode element in node.nodes) {
- _searchWithin(path, element);
- if (path.isNotEmpty) {
- path.add(node);
- return;
- }
- }
- } else if (node is YamlMap) {
- Map<dynamic, YamlNode> nodeMap = node.nodes;
- for (YamlNode key in nodeMap.keys) {
- _searchWithin(path, key);
- if (path.isNotEmpty) {
- path.add(node);
- return;
- }
- _searchWithin(path, nodeMap[key]);
- if (path.isNotEmpty) {
- path.add(node);
- return;
- }
- }
- }
- path.add(node);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart
new file mode 100644
index 0000000..50ee2a7
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/manifest/fix_generator.dart
@@ -0,0 +1,144 @@
+// 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:math' as math;
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/manifest/manifest_warning_code.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ show SourceChange;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:html/dom.dart';
+import 'package:meta/meta.dart';
+import 'package:source_span/source_span.dart';
+
+/// An object used to locate the HTML [Node] associated with a source range.
+/// More specifically, it will return the deepest HTML [Node] which completely
+/// encompasses the specified range.
+class HtmlNodeLocator {
+ /// The inclusive start offset of the range used to identify the node.
+ int _startOffset = 0;
+
+ /// The inclusive end offset of the range used to identify the node.
+ int _endOffset = 0;
+
+ /// Initialize a newly created locator to locate the deepest [Node] for
+ /// which `node.offset <= [start]` and `[end] < node.end`.
+ ///
+ /// If the [end] offset is not provided, then it is considered the same as the
+ /// [start] offset.
+ HtmlNodeLocator({@required int start, int end})
+ : this._startOffset = start,
+ this._endOffset = end ?? start;
+
+ /// Search within the given HTML [node] and return the path to the most deeply
+ /// nested node that includes the whole target range, or an empty list if no
+ /// node was found. The path is represented by all of the elements from the
+ /// starting [node] to the most deeply nested node, in reverse order.
+ List<Node> searchWithin(Node node) {
+ List<Node> path = [];
+ _searchWithin(path, node);
+ return path;
+ }
+
+ void _searchWithin(List<Node> path, Node node) {
+ FileSpan span = node.sourceSpan;
+ if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
+ return;
+ }
+ for (Element element in node.children) {
+ _searchWithin(path, element);
+ if (path.isNotEmpty) {
+ path.add(node);
+ return;
+ }
+ }
+ path.add(node);
+ }
+}
+
+/// The generator used to generate fixes in Android manifest files.
+class ManifestFixGenerator {
+ final AnalysisError error;
+
+ final int errorOffset;
+
+ final int errorLength;
+
+ final String content;
+
+ final DocumentFragment document;
+
+ final LineInfo lineInfo;
+
+ final List<Fix> fixes = <Fix>[];
+
+ List<Node> coveringNodePath;
+
+ ManifestFixGenerator(this.error, this.content, this.document)
+ : errorOffset = error.offset,
+ errorLength = error.length,
+ lineInfo = new LineInfo.fromContent(content);
+
+ /// Return the absolute, normalized path to the file in which the error was
+ /// reported.
+ String get file => error.source.fullName;
+
+ /// Return the list of fixes that apply to the error being fixed.
+ Future<List<Fix>> computeFixes() async {
+ HtmlNodeLocator locator = new HtmlNodeLocator(
+ start: errorOffset, end: errorOffset + errorLength - 1);
+ coveringNodePath = locator.searchWithin(document);
+ if (coveringNodePath.isEmpty) {
+ return fixes;
+ }
+
+ ErrorCode errorCode = error.errorCode;
+ if (errorCode == ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE) {
+ } else if (errorCode ==
+ ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE) {
+ } else if (errorCode ==
+ ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE) {}
+ return fixes;
+ }
+
+ /// Add a fix whose edits were built by the [builder] that has the given
+ /// [kind]. If [args] are provided, they will be used to fill in the message
+ /// for the fix.
+ // ignore: unused_element
+ void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
+ {List args: null}) {
+ SourceChange change = builder.sourceChange;
+ if (change.edits.isEmpty) {
+ return;
+ }
+ change.message = formatList(kind.message, args);
+ fixes.add(new Fix(kind, change));
+ }
+
+ // ignore: unused_element
+ int _firstNonWhitespaceBefore(int offset) {
+ while (offset > 0 && isWhitespace(content.codeUnitAt(offset - 1))) {
+ offset--;
+ }
+ return offset;
+ }
+
+ // ignore: unused_element
+ SourceRange _lines(int start, int end) {
+ CharacterLocation startLocation = lineInfo.getLocation(start);
+ int startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
+ CharacterLocation endLocation = lineInfo.getLocation(end);
+ int endOffset = lineInfo.getOffsetOfLine(
+ math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
+ return new SourceRange(startOffset, endOffset - startOffset);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart
new file mode 100644
index 0000000..36f9a32
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/pubspec/fix_generator.dart
@@ -0,0 +1,102 @@
+// 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:math' as math;
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analysis_server/src/utilities/yaml_node_locator.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ show SourceChange;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:yaml/yaml.dart';
+
+/// The generator used to generate fixes in pubspec.yaml files.
+class PubspecFixGenerator {
+ final AnalysisError error;
+
+ final int errorOffset;
+
+ final int errorLength;
+
+ final String content;
+
+ final YamlMap options;
+
+ final LineInfo lineInfo;
+
+ final List<Fix> fixes = <Fix>[];
+
+ List<YamlNode> coveringNodePath;
+
+ PubspecFixGenerator(this.error, this.content, this.options)
+ : errorOffset = error.offset,
+ errorLength = error.length,
+ lineInfo = new LineInfo.fromContent(content);
+
+ /// Return the absolute, normalized path to the file in which the error was
+ /// reported.
+ String get file => error.source.fullName;
+
+ /// Return the list of fixes that apply to the error being fixed.
+ Future<List<Fix>> computeFixes() async {
+ YamlNodeLocator locator = new YamlNodeLocator(
+ start: errorOffset, end: errorOffset + errorLength - 1);
+ coveringNodePath = locator.searchWithin(options);
+ if (coveringNodePath.isEmpty) {
+ return fixes;
+ }
+
+ ErrorCode errorCode = error.errorCode;
+ if (errorCode == PubspecWarningCode.ASSET_DOES_NOT_EXIST) {
+ } else if (errorCode == PubspecWarningCode.ASSET_DIRECTORY_DOES_NOT_EXIST) {
+ } else if (errorCode == PubspecWarningCode.ASSET_FIELD_NOT_LIST) {
+ } else if (errorCode == PubspecWarningCode.ASSET_NOT_STRING) {
+ } else if (errorCode == PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP) {
+ } else if (errorCode == PubspecWarningCode.FLUTTER_FIELD_NOT_MAP) {
+ } else if (errorCode == PubspecWarningCode.MISSING_NAME) {
+ } else if (errorCode == PubspecWarningCode.NAME_NOT_STRING) {
+ } else if (errorCode == PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY) {}
+ return fixes;
+ }
+
+ /// Add a fix whose edits were built by the [builder] that has the given
+ /// [kind]. If [args] are provided, they will be used to fill in the message
+ /// for the fix.
+ // ignore: unused_element
+ void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
+ {List args: null}) {
+ SourceChange change = builder.sourceChange;
+ if (change.edits.isEmpty) {
+ return;
+ }
+ change.message = formatList(kind.message, args);
+ fixes.add(new Fix(kind, change));
+ }
+
+ // ignore: unused_element
+ int _firstNonWhitespaceBefore(int offset) {
+ while (offset > 0 && isWhitespace(content.codeUnitAt(offset - 1))) {
+ offset--;
+ }
+ return offset;
+ }
+
+ // ignore: unused_element
+ SourceRange _lines(int start, int end) {
+ CharacterLocation startLocation = lineInfo.getLocation(start);
+ int startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
+ CharacterLocation endLocation = lineInfo.getLocation(end);
+ int endOffset = lineInfo.getOffsetOfLine(
+ math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
+ return new SourceRange(startOffset, endOffset - startOffset);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart b/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart
new file mode 100644
index 0000000..480bb4e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/yaml_node_locator.dart
@@ -0,0 +1,68 @@
+// 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:meta/meta.dart';
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
+
+/// An object used to locate the [YamlNode] associated with a source range.
+/// More specifically, it will return the deepest [YamlNode] which completely
+/// encompasses the specified range.
+class YamlNodeLocator {
+ /// The inclusive start offset of the range used to identify the node.
+ int _startOffset = 0;
+
+ /// The inclusive end offset of the range used to identify the node.
+ int _endOffset = 0;
+
+ /// Initialize a newly created locator to locate the deepest [YamlNode] for
+ /// which `node.offset <= [start]` and `[end] < node.end`.
+ ///
+ /// If the [end] offset is not provided, then it is considered the same as the
+ /// [start] offset.
+ YamlNodeLocator({@required int start, int end})
+ : this._startOffset = start,
+ this._endOffset = end ?? start;
+
+ /// Search within the given Yaml [node] and return the path to the most deeply
+ /// nested node that includes the whole target range, or an empty list if no
+ /// node was found. The path is represented by all of the elements from the
+ /// starting [node] to the most deeply nested node, in reverse order.
+ List<YamlNode> searchWithin(YamlNode node) {
+ List<YamlNode> path = [];
+ _searchWithin(path, node);
+ return path;
+ }
+
+ void _searchWithin(List<YamlNode> path, YamlNode node) {
+ SourceSpan span = node.span;
+ if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
+ return;
+ }
+ if (node is YamlList) {
+ for (YamlNode element in node.nodes) {
+ _searchWithin(path, element);
+ if (path.isNotEmpty) {
+ path.add(node);
+ return;
+ }
+ }
+ } else if (node is YamlMap) {
+ Map<dynamic, YamlNode> nodeMap = node.nodes;
+ for (YamlNode key in nodeMap.keys) {
+ _searchWithin(path, key);
+ if (path.isNotEmpty) {
+ path.add(node);
+ return;
+ }
+ _searchWithin(path, nodeMap[key]);
+ if (path.isNotEmpty) {
+ path.add(node);
+ return;
+ }
+ }
+ }
+ path.add(node);
+ }
+}
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index a270f6c..df6f051 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -66,6 +66,36 @@
expect(error.type, AnalysisErrorType.STATIC_WARNING);
}
+ test_androidManifestFile() async {
+ String filePath = join(projectPath, 'android', 'AndroidManifest.xml');
+ String manifestFile = newFile(filePath, content: '''
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-feature android:name="android.software.home_screen" />
+</manifest>
+''').path;
+ newFile(join(projectPath, 'analysis_options.yaml'), content: '''
+analyzer:
+ optional-checks:
+ chrome-os-manifest-checks: true
+''');
+
+ Request request =
+ new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+ handleSuccessfulRequest(request);
+ await waitForTasksFinished();
+ await pumpEventQueue();
+ //
+ // Verify the error result.
+ //
+ List<AnalysisError> errors = filesErrors[manifestFile];
+ expect(errors, hasLength(1));
+ AnalysisError error = errors[0];
+ expect(error.location.file, filePath);
+ expect(error.severity, AnalysisErrorSeverity.WARNING);
+ expect(error.type, AnalysisErrorType.STATIC_WARNING);
+ }
+
test_importError() async {
createProject();
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 3f0e266..dc47e1d 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -893,25 +893,35 @@
class D with C {}
''', [
token('class', null, null),
- token('A', 'dart:core;Type', ['declaration']),
+ token('A', 'Type',
+ ['declaration']), //token('A', 'dart:core;Type', ['declaration']),
token('{', null, null),
token('}', null, null),
token('class', null, null),
- token('B', 'dart:core;Type', ['declaration']),
+ token('B', 'Type',
+ ['declaration']), //token('B', 'dart:core;Type', ['declaration']),
token('extends', null, null),
- token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+ token('A', 'dart:core;Type<A>', [
+ 'reference'
+ ]), //token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
token('{', null, null),
token('}', null, null),
token('class', null, null),
- token('C', 'dart:core;Type', ['declaration']),
+ token('C', 'Type',
+ ['declaration']), //token('C', 'dart:core;Type', ['declaration']),
token('implements', null, null),
- token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+ token('B', 'dart:core;Type<B>', [
+ 'reference'
+ ]), //token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
token('{', null, null),
token('}', null, null),
token('class', null, null),
- token('D', 'dart:core;Type', ['declaration']),
+ token('D', 'Type',
+ ['declaration']), //token('D', 'dart:core;Type', ['declaration']),
token('with', null, null),
- token('C', 'dart:core;Type<$testFileUri;C>', ['reference']),
+ token('C', 'dart:core;Type<C>', [
+ 'reference'
+ ]), //token('C', 'dart:core;Type<$testFileUri;C>', ['reference']),
token('{', null, null),
token('}', null, null),
]);
@@ -921,11 +931,16 @@
await expectTokens('''
List<int> x = null;
''', [
- token('List', 'dart:core;Type<dart:core;List>', ['reference']),
+ token('List', 'dart:core;Type<List>', [
+ 'reference'
+ ]), //token('List', 'dart:core;Type<dart:core;List>', ['reference']),
token('<', null, null),
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
token('>', null, null),
- token('x', 'dart:core;List', ['declaration']),
+ token('x', 'List',
+ ['declaration']), //token('x', 'dart:core;List', ['declaration']),
token('=', null, null),
token('null', null, null),
token(';', null, null),
@@ -937,11 +952,13 @@
var x = 'a'.length;
''', [
token('var', null, null),
- token('x', 'dart:core;int', ['declaration']),
+ token('x', 'int',
+ ['declaration']), //token('x', 'dart:core;int', ['declaration']),
token('=', null, null),
- token("'a'", 'dart:core;String', null),
+ token("'a'", 'String', null), //token("'a'", 'dart:core;String', null),
token('.', null, null),
- token('length', 'dart:core;int', ['reference']),
+ token('length', 'int',
+ ['reference']), //token('length', 'dart:core;int', ['reference']),
token(';', null, null),
]);
}
@@ -951,9 +968,10 @@
var x = true;
''', [
token('var', null, null),
- token('x', 'dart:core;bool', ['declaration']),
+ token('x', 'bool',
+ ['declaration']), //token('x', 'dart:core;bool', ['declaration']),
token('=', null, null),
- token('true', 'dart:core;bool', null),
+ token('true', 'bool', null), //token('true', 'dart:core;bool', null),
token(';', null, null),
]);
}
@@ -963,9 +981,10 @@
var x = 3.4;
''', [
token('var', null, null),
- token('x', 'dart:core;double', ['declaration']),
+ token('x', 'double',
+ ['declaration']), //token('x', 'dart:core;double', ['declaration']),
token('=', null, null),
- token('3.4', 'dart:core;double', null),
+ token('3.4', 'double', null), //token('3.4', 'dart:core;double', null),
token(';', null, null),
]);
}
@@ -975,9 +994,10 @@
var x = 7;
''', [
token('var', null, null),
- token('x', 'dart:core;int', ['declaration']),
+ token('x', 'int',
+ ['declaration']), //token('x', 'dart:core;int', ['declaration']),
token('=', null, null),
- token('7', 'dart:core;int', null),
+ token('7', 'int', null), //token('7', 'dart:core;int', null),
token(';', null, null),
]);
}
@@ -987,10 +1007,13 @@
var x = <int>[];
''', [
token('var', null, null),
- token('x', 'dart:core;List', ['declaration']),
+ token('x', 'List',
+ ['declaration']), //token('x', 'dart:core;List', ['declaration']),
token('=', null, null),
token('<', null, null),
- token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+ token("int", 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token("int", 'dart:core;Type<dart:core;int>', ['reference']),
token('>', null, null),
token('[', null, null),
token(']', null, null),
@@ -1003,12 +1026,17 @@
var x = <int, int>{};
''', [
token('var', null, null),
- token('x', 'dart:core;Map', ['declaration']),
+ token('x', 'Map',
+ ['declaration']), //token('x', 'dart:core;Map', ['declaration']),
token('=', null, null),
token('<', null, null),
- token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+ token("int", 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token("int", 'dart:core;Type<dart:core;int>', ['reference']),
// token(',', null, null),
- token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+ token("int", 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token("int", 'dart:core;Type<dart:core;int>', ['reference']),
token('>', null, null),
token('{', null, null),
token('}', null, null),
@@ -1033,10 +1061,13 @@
var x = <int>{};
''', [
token('var', null, null),
- token('x', 'dart:core;Set', ['declaration']),
+ token('x', 'Set',
+ ['declaration']), //token('x', 'dart:core;Set', ['declaration']),
token('=', null, null),
token('<', null, null),
- token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+ token("int", 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token("int", 'dart:core;Type<dart:core;int>', ['reference']),
token('>', null, null),
token('{', null, null),
token('}', null, null),
@@ -1049,9 +1080,10 @@
var x = 'a';
''', [
token('var', null, null),
- token('x', 'dart:core;String', ['declaration']),
+ token('x', 'String',
+ ['declaration']), //token('x', 'dart:core;String', ['declaration']),
token('=', null, null),
- token("'a'", 'dart:core;String', null),
+ token("'a'", 'String', null), //token("'a'", 'dart:core;String', null),
token(';', null, null),
]);
}
@@ -1063,17 +1095,27 @@
}
''', [
token('class', null, null),
- token('A', 'dart:core;Type', ['declaration']),
+ token('A', 'Type',
+ ['declaration']), //token('A', 'dart:core;Type', ['declaration']),
token('{', null, null),
- token('String', 'dart:core;Type<dart:core;String>', ['reference']),
- token('c', 'dart:core;String Function(dart:core;int, dart:core;int)',
+ token('String', 'dart:core;Type<String>', [
+ 'reference'
+ ]), //token('String', 'dart:core;Type<dart:core;String>', ['reference']),
+ token('c',
+ 'String Function(int, int)', //'dart:core;String Function(dart:core;int, dart:core;int)',
['declaration']),
token('(', null, null),
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
- token('x', 'dart:core;int', ['declaration']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('x', 'int',
+ ['declaration']), //token('x', 'dart:core;int', ['declaration']),
// token(',', null, null),
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
- token('y', 'dart:core;int', ['declaration']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('y', 'int',
+ ['declaration']), //token('y', 'dart:core;int', ['declaration']),
token(')', null, null),
token('{', null, null),
token('}', null, null),
@@ -1086,18 +1128,19 @@
var x = 'radar'.indexOf('r', 1);
''', [
token('var', null, null),
- token('x', 'dart:core;int', ['declaration']),
+ token('x', 'int',
+ ['declaration']), //token('x', 'dart:core;int', ['declaration']),
token('=', null, null),
- token("'radar'", 'dart:core;String', null),
+ token("'radar'", 'String',
+ null), //token("'radar'", 'dart:core;String', null),
token('.', null, null),
- token(
- 'indexOf',
- 'dart:core;int Function(dart:core;Pattern, dart:core;int)',
+ token('indexOf',
+ 'int Function(Pattern, int)', //'dart:core;int Function(dart:core;Pattern, dart:core;int)',
['reference']),
token('(', null, null),
- token("'r'", 'dart:core;String', null),
+ token("'r'", 'String', null), //token("'r'", 'dart:core;String', null),
// token(',', null, null),
- token('1', 'dart:core;int', null),
+ token('1', 'int', null), //token('1', 'dart:core;int', null),
token(')', null, null),
token(';', null, null),
]);
@@ -1110,19 +1153,26 @@
mixin D on A implements B {}
''', [
token('class', null, null),
- token('A', 'dart:core;Type', ['declaration']),
+ token('A', 'Type',
+ ['declaration']), //token('A', 'dart:core;Type', ['declaration']),
token('{', null, null),
token('}', null, null),
token('class', null, null),
- token('B', 'dart:core;Type', ['declaration']),
+ token('B', 'Type',
+ ['declaration']), //token('B', 'dart:core;Type', ['declaration']),
token('{', null, null),
token('}', null, null),
token('mixin', null, null),
- token('D', 'dart:core;Type', ['declaration']),
+ token('D', 'Type',
+ ['declaration']), //token('D', 'dart:core;Type', ['declaration']),
token('on', null, null),
- token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+ token('A', 'dart:core;Type<A>', [
+ 'reference'
+ ]), //token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
token('implements', null, null),
- token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+ token('B', 'dart:core;Type<B>', [
+ 'reference'
+ ]), //token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
token('{', null, null),
token('}', null, null),
]);
@@ -1134,15 +1184,23 @@
return p;
}
''', [
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
- token('f', 'dart:core;int Function(dart:core;int)', ['declaration']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('f', 'int Function(int)', [
+ 'declaration'
+ ]), //token('f', 'dart:core;int Function(dart:core;int)', ['declaration']),
token('(', null, null),
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
- token('p', 'dart:core;int', ['declaration']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('p', 'int',
+ ['declaration']), //token('p', 'dart:core;int', ['declaration']),
token(')', null, null),
token('{', null, null),
token('return', null, null),
- token('p', 'dart:core;int', ['reference']),
+ token('p', 'int',
+ ['reference']), //token('p', 'dart:core;int', ['reference']),
token(';', null, null),
token('}', null, null),
]);
@@ -1153,8 +1211,11 @@
/// Doc comment [x] with reference.
int x;
''', [
- token('int', 'dart:core;Type<dart:core;int>', ['reference']),
- token('x', 'dart:core;int', ['declaration']),
+ token('int', 'dart:core;Type<int>', [
+ 'reference'
+ ]), //token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+ token('x', 'int',
+ ['declaration']), //token('x', 'dart:core;int', ['declaration']),
token(';', null, null),
]);
}
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 8a0e7b0..930f08a 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -68,6 +68,31 @@
testFile = resourceProvider.convertPath('/project/lib/fileToBeFixed.dart');
}
+ test_dartfix_collection_if_elements() async {
+ // Add analysis options to enable ui as code
+ newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+ enable-experiment:
+ - control-flow-collections
+ - spread-collections
+''');
+ addTestFile('''
+f(bool b) {
+ return ['a', b ? 'c' : 'd', 'e'];
+}
+''');
+ createProject();
+ EditDartfixResult result =
+ await performFix(includedFixes: ['collection-if-elements']);
+ expect(result.suggestions.length, greaterThanOrEqualTo(1));
+ expect(result.hasErrors, isFalse);
+ expectEdits(result.edits, '''
+f(bool b) {
+ return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+ }
+
test_dartfix_convertClassToMixin() async {
addTestFile('''
class A {}
@@ -98,6 +123,52 @@
''');
}
+ test_dartfix_excludedSource() async {
+ // Add analysis options to exclude the lib directory then reanalyze
+ newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+ exclude:
+ - lib/**
+''');
+
+ addTestFile('''
+const double myDouble = 42.0;
+ ''');
+ createProject();
+
+ // Assert no suggestions now that source has been excluded
+ final result = await performFix();
+ expect(result.suggestions, hasLength(0));
+ expect(result.edits, hasLength(0));
+ }
+
+ test_dartfix_map_for_elements() async {
+ // Add analysis options to enable ui as code
+ newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+ enable-experiment:
+ - control-flow-collections
+ - spread-collections
+''');
+ addTestFile('''
+f(Iterable<int> i) {
+ var k = 3;
+ return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k);
+}
+''');
+ createProject();
+ EditDartfixResult result =
+ await performFix(includedFixes: ['map-for-elements']);
+ expect(result.suggestions.length, greaterThanOrEqualTo(1));
+ expect(result.hasErrors, isFalse);
+ expectEdits(result.edits, '''
+f(Iterable<int> i) {
+ var k = 3;
+ return { for (var e in i) e * 2 : k };
+}
+''');
+ }
+
test_dartfix_moveTypeArgumentToClass() async {
addTestFile('''
class A<T> { A.from(Object obj) { } }
@@ -217,25 +288,6 @@
''');
}
- test_dartfix_excludedSource() async {
- // Add analysis options to exclude the lib directory then reanalyze
- newFile('/project/analysis_options.yaml', content: '''
-analyzer:
- exclude:
- - lib/**
-''');
-
- addTestFile('''
-const double myDouble = 42.0;
- ''');
- createProject();
-
- // Assert no suggestions now that source has been excluded
- final result = await performFix();
- expect(result.suggestions, hasLength(0));
- expect(result.edits, hasLength(0));
- }
-
test_dartfix_partFile() async {
newFile('/project/lib/lib.dart', content: '''
library lib2;
@@ -283,7 +335,8 @@
- spread-collections
''');
addTestFile('''
-var l = ['a']..addAll(['b']);
+var l1 = ['b'];
+var l2 = ['a']..addAll(l1);
''');
createProject();
EditDartfixResult result =
@@ -291,59 +344,8 @@
expect(result.suggestions.length, greaterThanOrEqualTo(1));
expect(result.hasErrors, isFalse);
expectEdits(result.edits, '''
-var l = ['a', ...['b']];
-''');
- }
-
- test_dartfix_collection_if_elements() async {
- // Add analysis options to enable ui as code
- newFile('/project/analysis_options.yaml', content: '''
-analyzer:
- enable-experiment:
- - control-flow-collections
- - spread-collections
-''');
- addTestFile('''
-f(bool b) {
- return ['a', b ? 'c' : 'd', 'e'];
-}
-''');
- createProject();
- EditDartfixResult result =
- await performFix(includedFixes: ['collection-if-elements']);
- expect(result.suggestions.length, greaterThanOrEqualTo(1));
- expect(result.hasErrors, isFalse);
- expectEdits(result.edits, '''
-f(bool b) {
- return ['a', if (b) 'c' else 'd', 'e'];
-}
-''');
- }
-
- test_dartfix_map_for_elements() async {
- // Add analysis options to enable ui as code
- newFile('/project/analysis_options.yaml', content: '''
-analyzer:
- enable-experiment:
- - control-flow-collections
- - spread-collections
-''');
- addTestFile('''
-f(Iterable<int> i) {
- var k = 3;
- return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k);
-}
-''');
- createProject();
- EditDartfixResult result =
- await performFix(includedFixes: ['map-for-elements']);
- expect(result.suggestions.length, greaterThanOrEqualTo(1));
- expect(result.hasErrors, isFalse);
- expectEdits(result.edits, '''
-f(Iterable<int> i) {
- var k = 3;
- return { for (var e in i) e * 2 : k };
-}
+var l1 = ['b'];
+var l2 = ['a', ...l1];
''');
}
}
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 03fa79b..d94ac33 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -93,7 +93,8 @@
"startColumn": 5
},
"flags": 0,
- "parameters": "()"
+ "parameters": "()",
+ "returnType": "A"
},
"parameterNames": [],
"parameterTypes": [],
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
index d026fb3..6242b56 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -41,7 +41,7 @@
''');
}
- test_addAll_expression_to_emptyList() async {
+ test_addAll_expression_toEmptyList() async {
await resolveTestUnit('''
f() {
var ints = [1, 2, 3];
@@ -57,12 +57,11 @@
}
test_addAll_literal() async {
+ // This case is covered by the INLINE_INVOCATION assist.
await resolveTestUnit('''
var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
''');
- await assertHasAssist('''
-var l = ['a', ...['b']]..addAll(['c']);
-''');
+ await assertNoAssist();
}
test_addAll_nonLiteralTarget() async {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
new file mode 100644
index 0000000..a183e7f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
@@ -0,0 +1,112 @@
+// 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/src/dart/analysis/experiments.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(InlineInvocationTest);
+ });
+}
+
+@reflectiveTest
+class InlineInvocationTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.INLINE_INVOCATION;
+
+ void setUp() {
+ createAnalysisOptionsFile(experiments: [EnableString.spread_collections]);
+ super.setUp();
+ }
+
+ test_add_emptyTarget() async {
+ await resolveTestUnit('''
+var l = []..ad/*caret*/d('a')..add('b');
+''');
+ await assertHasAssist('''
+var l = ['a']..add('b');
+''');
+ }
+
+ test_add_nonEmptyTarget() async {
+ await resolveTestUnit('''
+var l = ['a']..ad/*caret*/d('b')..add('c');
+''');
+ await assertHasAssist('''
+var l = ['a', 'b']..add('c');
+''');
+ }
+
+ test_add_nonLiteralArgument() async {
+ await resolveTestUnit('''
+var e = 'b';
+var l = ['a']..add/*caret*/(e);
+''');
+ await assertHasAssist('''
+var e = 'b';
+var l = ['a', e];
+''');
+ }
+
+ test_add_nonLiteralTarget() async {
+ await resolveTestUnit('''
+var l1 = [];
+var l2 = l1..ad/*caret*/d('b')..add('c');
+''');
+ await assertNoAssist();
+ }
+
+ test_add_notFirst() async {
+ await resolveTestUnit('''
+var l = ['a']..add('b')../*caret*/add('c');
+''');
+ await assertNoAssist();
+ }
+
+ test_addAll_emptyTarget() async {
+ await resolveTestUnit('''
+var l = []..add/*caret*/All(['a'])..addAll(['b']);
+''');
+ await assertHasAssist('''
+var l = ['a']..addAll(['b']);
+''');
+ }
+
+ test_addAll_nonEmptyTarget() async {
+ await resolveTestUnit('''
+var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
+''');
+ await assertHasAssist('''
+var l = ['a', 'b']..addAll(['c']);
+''');
+ }
+
+ test_addAll_nonLiteralArgument() async {
+ await resolveTestUnit('''
+var l1 = <String>[];
+var l2 = ['a']..add/*caret*/All(l1);
+''');
+ await assertNoAssist();
+ }
+
+ test_addAll_nonLiteralTarget() async {
+ await resolveTestUnit('''
+var l1 = [];
+var l2 = l1..addAl/*caret*/l(['b'])..addAll(['c']);
+''');
+ await assertNoAssist();
+ }
+
+ test_addAll_notFirst() async {
+ await resolveTestUnit('''
+var l = ['a']..addAll(['b'])../*caret*/addAll(['c']);
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index bcf631e..bc906ab 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
@@ -56,6 +56,7 @@
import 'flutter_wrap_row_test.dart' as flutter_wrap_row;
import 'flutter_wrap_stream_builder_test.dart' as flutter_wrap_stream_builder;
import 'import_add_show_test.dart' as import_add_show;
+import 'inline_invocation_test.dart' as inline_invocation;
import 'introduce_local_cast_type_test.dart' as introduce_local_cast_type;
import 'invert_if_statement_test.dart' as invert_if_statement;
import 'join_if_with_inner_test.dart' as join_if_with_inner;
@@ -125,6 +126,7 @@
flutter_wrap_row.main();
flutter_wrap_stream_builder.main();
import_add_show.main();
+ inline_invocation.main();
introduce_local_cast_type.main();
invert_if_statement.main();
join_if_with_inner.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
index 5a19c8b..548d53a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -2,21 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
-import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
-import 'package:analyzer/error/error.dart' as engine;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart'
- show SourceFileEdit;
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:yaml/src/yaml_node.dart';
+
+import 'test_support.dart';
main() {
defineReflectiveSuite(() {
@@ -24,52 +12,16 @@
});
}
-class NonDartFixTest with ResourceProviderMixin {
- Future<void> assertHasFix(
- String initialContent, String location, String expectedContent) async {
- File optionsFile = resourceProvider.getFile('/analysis_options.yaml');
- SourceFactory sourceFactory = new SourceFactory([]);
- List<engine.AnalysisError> errors = analyzeAnalysisOptions(
- optionsFile.createSource(), initialContent, sourceFactory);
- expect(errors, hasLength(1));
- engine.AnalysisError error = errors[0];
- YamlMap options = _getOptions(sourceFactory, initialContent);
- AnalysisOptionsFixGenerator generator =
- new AnalysisOptionsFixGenerator(error, initialContent, options);
- List<Fix> fixes = await generator.computeFixes();
- expect(fixes, hasLength(1));
- List<SourceFileEdit> fileEdits = fixes[0].change.edits;
- expect(fileEdits, hasLength(1));
-
- String actualContent =
- SourceEdit.applySequence(initialContent, fileEdits[0].edits);
- expect(actualContent, expectedContent);
- }
-
- YamlMap _getOptions(SourceFactory sourceFactory, String content) {
- AnalysisOptionsProvider optionsProvider =
- new AnalysisOptionsProvider(sourceFactory);
- try {
- return optionsProvider.getOptionsFromString(content);
- } on OptionsFormatException {
- return null;
- }
- }
-}
-
@reflectiveTest
-class RemoveSettingTest extends NonDartFixTest {
+class RemoveSettingTest extends AnalysisOptionsFixTest {
test_enableSuperMixins() async {
- await assertHasFix(
- '''
+ await assertHasFix('''
analyzer:
enable-experiment:
- non-nullable
language:
enableSuperMixins: true
-''',
- 'enable',
- '''
+''', '''
analyzer:
enable-experiment:
- non-nullable
@@ -77,15 +29,12 @@
}
test_invalidExperiment_first() async {
- await assertHasFix(
- '''
+ await assertHasFix('''
analyzer:
enable-experiment:
- not-an-experiment
- non-nullable
-''',
- 'not-',
- '''
+''', '''
analyzer:
enable-experiment:
- non-nullable
@@ -93,15 +42,12 @@
}
test_invalidExperiment_last() async {
- await assertHasFix(
- '''
+ await assertHasFix('''
analyzer:
enable-experiment:
- non-nullable
- not-an-experiment
-''',
- 'not-',
- '''
+''', '''
analyzer:
enable-experiment:
- non-nullable
@@ -109,14 +55,11 @@
}
test_invalidExperiment_only() async {
- await assertHasFix(
- '''
+ await assertHasFix('''
analyzer:
enable-experiment:
- not-an-experiment
-''',
- 'not-',
- '''
+''', '''
''');
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart
new file mode 100644
index 0000000..23d6dc3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_support.dart
@@ -0,0 +1,68 @@
+// 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/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
+import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
+import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:yaml/src/yaml_node.dart';
+import 'package:yaml/yaml.dart';
+
+/// A base class providing utility methods for tests of fixes associated with
+/// errors in Dart files.
+class AnalysisOptionsFixTest with ResourceProviderMixin {
+ Future<void> assertHasFix(
+ String initialContent, String expectedContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(1));
+ List<SourceFileEdit> fileEdits = fixes[0].change.edits;
+ expect(fileEdits, hasLength(1));
+
+ String actualContent =
+ SourceEdit.applySequence(initialContent, fileEdits[0].edits);
+ expect(actualContent, expectedContent);
+ }
+
+ Future<void> assertHasNoFix(String initialContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(0));
+ }
+
+ Future<List<Fix>> _getFixes(String content) {
+ File optionsFile = getFile('/analysis_options.yaml');
+ SourceFactory sourceFactory = new SourceFactory([]);
+ List<engine.AnalysisError> errors = analyzeAnalysisOptions(
+ optionsFile.createSource(), content, sourceFactory);
+ expect(errors, hasLength(1));
+ engine.AnalysisError error = errors[0];
+ YamlMap options = _parseYaml(content);
+ AnalysisOptionsFixGenerator generator =
+ new AnalysisOptionsFixGenerator(error, content, options);
+ return generator.computeFixes();
+ }
+
+ YamlMap _parseYaml(String content) {
+ if (content == null) {
+ return new YamlMap();
+ }
+ try {
+ YamlNode doc = loadYamlNode(content);
+ if (doc is YamlMap) {
+ return doc;
+ }
+ return new YamlMap();
+ } catch (exception) {
+ return null;
+ }
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart
new file mode 100644
index 0000000..31347b93
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/manifest/test_support.dart
@@ -0,0 +1,54 @@
+// 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/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
+import 'package:analysis_server/src/services/correction/fix/manifest/fix_generator.dart';
+import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/manifest/manifest_validator.dart';
+import 'package:analyzer/src/manifest/manifest_values.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart';
+import 'package:test/test.dart';
+
+/// A base class providing utility methods for tests of fixes associated with
+/// errors in Android manifest files.
+class ManifestFixTest with ResourceProviderMixin {
+ Future<void> assertHasFix(
+ String initialContent, String expectedContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(1));
+ List<SourceFileEdit> fileEdits = fixes[0].change.edits;
+ expect(fileEdits, hasLength(1));
+
+ String actualContent =
+ SourceEdit.applySequence(initialContent, fileEdits[0].edits);
+ expect(actualContent, expectedContent);
+ }
+
+ Future<void> assertHasNoFix(String initialContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(0));
+ }
+
+ Future<List<Fix>> _getFixes(String content) {
+ File manifestFile = getFile('/package/AndroidManifest.xml');
+ DocumentFragment document =
+ parseFragment(content, container: MANIFEST_TAG, generateSpans: true);
+ expect(document, isNotNull);
+ ManifestValidator validator =
+ new ManifestValidator(manifestFile.createSource());
+ List<engine.AnalysisError> errors = validator.validate(content, true);
+ expect(errors, hasLength(1));
+ engine.AnalysisError error = errors[0];
+ ManifestFixGenerator generator =
+ new ManifestFixGenerator(error, content, document);
+ return generator.computeFixes();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
new file mode 100644
index 0000000..c884474
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
@@ -0,0 +1,67 @@
+// 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/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
+import 'package:analysis_server/src/services/correction/fix/pubspec/fix_generator.dart';
+import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:yaml/src/yaml_node.dart';
+import 'package:yaml/yaml.dart';
+
+/// A base class providing utility methods for tests of fixes associated with
+/// errors in pubspec files.
+class PubspecFixTest with ResourceProviderMixin {
+ Future<void> assertHasFix(
+ String initialContent, String expectedContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(1));
+ List<SourceFileEdit> fileEdits = fixes[0].change.edits;
+ expect(fileEdits, hasLength(1));
+
+ String actualContent =
+ SourceEdit.applySequence(initialContent, fileEdits[0].edits);
+ expect(actualContent, expectedContent);
+ }
+
+ Future<void> assertHasNoFix(String initialContent) async {
+ List<Fix> fixes = await _getFixes(initialContent);
+ expect(fixes, hasLength(0));
+ }
+
+ Future<List<Fix>> _getFixes(String content) {
+ File pubspecFile = getFile('/package/pubspec.yaml');
+ YamlMap pubspec = _parseYaml(content);
+ expect(pubspec, isNotNull);
+ PubspecValidator validator =
+ new PubspecValidator(resourceProvider, pubspecFile.createSource());
+ List<engine.AnalysisError> errors = validator.validate(pubspec.nodes);
+ expect(errors, hasLength(1));
+ engine.AnalysisError error = errors[0];
+ PubspecFixGenerator generator =
+ new PubspecFixGenerator(error, content, pubspec);
+ return generator.computeFixes();
+ }
+
+ YamlMap _parseYaml(String content) {
+ if (content == null) {
+ return new YamlMap();
+ }
+ try {
+ YamlNode doc = loadYamlNode(content);
+ if (doc is YamlMap) {
+ return doc;
+ }
+ return new YamlMap();
+ } catch (exception) {
+ return null;
+ }
+ }
+}
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 5a0e443..2cb3562 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -533,9 +533,11 @@
Element element = Element.fromJson(elementObject);
int offset = outlineObject.get("offset").getAsInt();
int length = outlineObject.get("length").getAsInt();
+ int codeOffset = outlineObject.get("codeOffset").getAsInt();
+ int codeLength = outlineObject.get("codeLength").getAsInt();
// create outline object
- Outline outline = new Outline(parent, element, offset, length);
+ Outline outline = new Outline(parent, element, offset, length, codeOffset, codeLength);
// compute children recursively
List<Outline> childrenList = Lists.newArrayList();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index da73811..7249cad 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
index e3fad08..86a7416 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
index 6bb4c35..24a3fdc 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
index 78cc51f..098fc96 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
index 96166f9..7206867 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
index 3c4d6d9..f17a385 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
index 8fb0076..0e1e94f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
index 3076de6..9e6c9f1 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
index c1dfdc9..0900624 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java
index d7fc466..488d3c9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java
index 570ef61..26586dc 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
index 86784d9..c1fb108 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java b/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java
index 75506c0..ee4c125 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java
index d7a0d19..5007ebd 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
index 8b87048..28e0a81 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
index b94893d..e7595aa 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
index c094e21..6d14ea8 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
index b441025..0669805 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java
index 7a106f8..b40cb10 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/DartFixSuggestion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Element.java b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
index d1cfc65..80f51fb 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Element.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Element.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
index 47b4534..393fcee 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
index 17fe527..2ac5f3e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
index 00ee0b1..331332e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
index 0882e91..7bbc97f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
index 1a6e868..f8770b7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
index 6cd016e..31d12df 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
index f7e951c..1bb7400 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
index 0a0125c..729480d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
index a6127cfe..399482b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetFeedback.java
index 720c686..3a31de0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetOptions.java
index d526b78..cb3e520 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ExtractWidgetOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
index b282ce8..9fda96d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutline.java b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutline.java
index 9bc666b..52029e0 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutline.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutline.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineAttribute.java b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineAttribute.java
index b18dbe9..b02f3ae 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineAttribute.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineAttribute.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineKind.java
index b083a9d..271fd31 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FlutterOutlineKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FlutterService.java b/pkg/analysis_server/tool/spec/generated/java/types/FlutterService.java
index cc71a7c..607780d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FlutterService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FlutterService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
index d30381c..8ae6957 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
index 8cce15c..3f6f408 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
index d3ac75e..075184b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
index 8ea3562..fdb868d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 4ae12e2..21d7fbc 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
index a860fd2..463b420 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
index 54505e1..e81d14a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
index 64fab48..200ec62 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java b/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java
index afa9e17..cf7f31f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java
index 0db15bd..05e9574 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java
index 808e465..c9e0af9 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
index 13f871c..30930b3 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
index c9cd093..725d973 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
index 8f1619d..a647368 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java b/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java
index 76f9a30..9efb62a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java b/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java
index d9e6e62..eeda647 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java b/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java
index de46030..1e3c7dd 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
index dacc0e1..c315c1c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
index fe31f3a..2afb4f5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
index 791789a..120d83c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
index dce3fb7..2daf9de 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
index 29c172a..f605b97 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
index 6b4a202..00fc4ca 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
index d2a8fb8..a52c112 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
index e971c4c..9d2ce11 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
index 658a494..3d2c5be 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
@@ -103,9 +103,11 @@
Element element = Element.fromJson(elementObject);
int offset = outlineObject.get("offset").getAsInt();
int length = outlineObject.get("length").getAsInt();
+ int codeOffset = outlineObject.get("codeOffset").getAsInt();
+ int codeLength = outlineObject.get("codeLength").getAsInt();
// create outline object
- Outline outline = new Outline(parent, element, offset, length);
+ Outline outline = new Outline(parent, element, offset, length, codeOffset, codeLength);
// compute children recursively
List<Outline> childrenList = Lists.newArrayList();
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
index 052a3e6..fd07ef6 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
index ca395c6..a60e46c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ParameterInfo.java b/pkg/analysis_server/tool/spec/generated/java/types/ParameterInfo.java
index 7855e12..38131d3 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ParameterInfo.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ParameterInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ParameterKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ParameterKind.java
index 4073993..43f3e4d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ParameterKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ParameterKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Position.java b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
index 349ec6a..7b17db3 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Position.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Position.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java b/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java
index 7b85f64..f1099a7 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
index 0d28027..77c6b5f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
index 13d2bbd..ea68aaf 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
index c2d9a9c..228c0ea 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
index e69bccf..362044f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
index d7025cf..03c56d5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
index 1a352f7..64c7028 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
index f0ee4b1..4caaf12 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
index 684f09f..569d3ff 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
index 8b53cbd..4adc36c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
index 72b58a1..eac650a1 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
index a9a63a5..2fa6367 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
index 6d9eb4d..0cdab8b 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index dbd738a..aa8e173 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
index b2d6b70..85a9c41 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpression.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
index 5645384..c080810 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
index 6f74132..c63089e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionExpressionTypeKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
index 62a0fb5..a54d799 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RuntimeCompletionVariable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
index f741485..f139e07 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
index fe02fb5..d22f7cb 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
index 7680299..fed7a98 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
index bddcbc9..55b2761 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
index f5a0f86..41210ff 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
index fdc0fbf..b2d6996 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
index 071328a..b9cc17e 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
index 6ae2f59..156ec7d 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * 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.
*
diff --git a/pkg/analysis_tool/lib/tools.dart b/pkg/analysis_tool/lib/tools.dart
index 74dd816..831014e 100644
--- a/pkg/analysis_tool/lib/tools.dart
+++ b/pkg/analysis_tool/lib/tools.dart
@@ -159,7 +159,7 @@
if (codeGeneratorSettings.languageName == 'java') {
header = '''
/*
- * Copyright (c) ${year ?? '2018'}, the Dart project authors. Please see the AUTHORS file
+ * Copyright (c) ${year ?? '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.
*
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 3e5b2fa..bce36d6 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2309,8 +2309,8 @@
/// Return `true` if this parameter is a required parameter. Required
/// parameters are always positional.
///
- /// Note: this will return `false` for a named parameter that is annotated with
- /// the `@required` annotation.
+ /// Note: this will return `false` for a named parameter that is annotated
+ /// with the `@required` annotation.
bool get isRequired;
/// Return the kind of this parameter.
@@ -2319,6 +2319,9 @@
/// Return the annotations associated with this parameter.
NodeList<Annotation> get metadata;
+
+ /// The 'required' keyword, or `null` if the keyword was not used.
+ Token get requiredKeyword;
}
/// The formal parameter list of a method declaration, function declaration, or
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index ab5ef3d..f934c92 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -374,6 +374,7 @@
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
Token keyword,
TypeAnnotation type,
@required Token thisKeyword,
@@ -511,6 +512,7 @@
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
TypeAnnotation returnType,
@required SimpleIdentifier identifier,
TypeParameterList typeParameters,
@@ -800,6 +802,7 @@
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
Token keyword,
TypeAnnotation type,
@required SimpleIdentifier identifier});
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index f79078a..20b425d 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -46,6 +46,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/task/api/model.dart' show AnalysisTarget;
+import 'package:meta/meta.dart';
/// An element that represents a class or a mixin. The class can be defined by
/// either a class declaration (with a class body), a mixin application (without
@@ -1047,9 +1048,16 @@
/// Return `true` if this field was explicitly marked as being covariant.
bool get isCovariant;
- /// Return {@code true} if this element is an enum constant.
+ /// Return `true` if this element is an enum constant.
bool get isEnumConstant;
+ /// Return `true` if this field uses lazy evaluation semantics.
+ ///
+ /// This will always return `false` unless the experiment 'non-nullable' is
+ /// enabled.
+ @experimental
+ bool get isLazy;
+
/// Returns `true` if this field can be overridden in strong mode.
@deprecated
bool get isVirtual;
@@ -1324,7 +1332,14 @@
/// A local variable.
///
/// Clients may not extend, implement or mix-in this class.
-abstract class LocalVariableElement implements LocalElement, VariableElement {}
+abstract class LocalVariableElement implements LocalElement, VariableElement {
+ /// Return `true` if this local variable uses lazy evaluation semantics.
+ ///
+ /// This will always return `false` unless the experiment 'non-nullable' is
+ /// enabled.
+ @experimental
+ bool get isLazy;
+}
/// An element that represents a method defined within a type.
///
@@ -1395,10 +1410,12 @@
bool get isNamed;
/// Return `true` if this parameter is a required parameter. Required
- /// parameters are always positional.
+ /// parameters are always positional, unless the experiment 'non-nullable' is
+ /// enabled, in which case named parameters can also be required.
///
- /// Note: this will return `false` for a named parameter that is annotated
- /// with the `@required` annotation.
+ /// Note: regardless of the state of the 'non-nullable' experiment, this will
+ /// return `false` for a named parameter that is annotated with the
+ /// `@required` annotation.
// TODO(brianwilkerson) Rename this to `isRequired`.
bool get isNotOptional;
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
index 769a5d9..df6cbe8 100644
--- a/pkg/analyzer/lib/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/type.dart';
+import 'package:meta/meta.dart';
/// A representation of the operations defined for the type system.
///
@@ -50,6 +51,61 @@
/// important.
bool isAssignableTo(DartType leftType, DartType rightType);
+ /// Return `true` if the [type] is a non-nullable type.
+ ///
+ /// We say that a type `T` is non-nullable if `T <: Object`. This is
+ /// equivalent to the syntactic criterion that `T` is any of:
+ /// - `Object`, `int`, `bool`, `Never`, `Function`
+ /// - Any function type
+ /// - Any class type or generic class type
+ /// - `FutureOr<S>` where `S` is non-nullable
+ /// - `X extends S` where `S` is non-nullable
+ /// - `X & S` where `S` is non-nullable
+ ///
+ /// The result of this method is undefined when the experiment 'non-nullable'
+ /// is not enabled.
+ @experimental
+ bool isNonNullable(DartType type);
+
+ /// Return `true` if the [type] is a nullable type.
+ ///
+ /// We say that a type `T` is nullable if `Null <: T`. This is equivalent to
+ /// the syntactic criterion that `T` is any of:
+ /// - `Null`
+ /// - `S?` for some `S`
+ /// - `FutureOr<S>` for some `S` where `S` is nullable
+ /// - `dynamic`
+ /// - `void`
+ ///
+ /// The result of this method is undefined when the experiment 'non-nullable'
+ /// is not enabled.
+ @experimental
+ bool isNullable(DartType type);
+
+ /// Return `true` if the [type] is a potentially non-nullable type.
+ ///
+ /// We say that a type `T` is potentially non-nullable if `T` is not nullable.
+ /// Note that this is different from saying that `T` is non-nullable. For
+ /// example, a type variable `X extends Object?` is a type which is
+ /// potentially non-nullable but not non-nullable.
+ ///
+ /// The result of this method is undefined when the experiment 'non-nullable'
+ /// is not enabled.
+ @experimental
+ bool isPotentiallyNonNullable(DartType type);
+
+ /// Return `true` if the [type] is not a potentially nullable type.
+ ///
+ /// We say that a type `T` is potentially nullable if `T` is not non-nullable.
+ /// Note that this is different from saying that `T` is nullable. For example,
+ /// a type variable `X extends Object?` is a type which is potentially
+ /// nullable but not nullable.
+ ///
+ /// The result of this method is undefined when the experiment 'non-nullable'
+ /// is not enabled.
+ @experimental
+ bool isPotentiallyNullable(DartType type);
+
/// Return `true` if the [leftType] is a subtype of the [rightType].
///
/// For the Dart 2.0 type system, the rules governing the subtype relationship
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 266e0f2..6d2713d 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -235,6 +235,11 @@
CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE,
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE,
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE,
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE,
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE,
CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS,
CompileTimeErrorCode.ON_REPEATED,
CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
@@ -296,6 +301,8 @@
HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE,
HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE,
HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
+ HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL,
+ HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE,
HintCode.INVALID_FACTORY_ANNOTATION,
HintCode.INVALID_FACTORY_METHOD_DECL,
@@ -490,6 +497,7 @@
ParserErrorCode.MISSING_TYPEDEF_PARAMETERS,
ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH,
ParserErrorCode.MIXED_PARAMETER_GROUPS,
+ ParserErrorCode.MODIFIER_OUT_OF_ORDER,
ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES,
ParserErrorCode.MULTIPLE_ON_CLAUSES,
ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES,
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index 4b86a47..54978bd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -80,13 +80,13 @@
IsExpired.non_nullable,
'Non Nullable'),
EnableString.control_flow_collections: const ExperimentalFeature(
- 2,
+ null,
EnableString.control_flow_collections,
IsEnabledByDefault.control_flow_collections,
IsExpired.control_flow_collections,
'Control Flow Collections'),
EnableString.spread_collections: const ExperimentalFeature(
- 3,
+ null,
EnableString.spread_collections,
IsEnabledByDefault.spread_collections,
IsExpired.spread_collections,
@@ -98,7 +98,7 @@
IsExpired.set_literals,
'Set Literals'),
EnableString.triple_shift: const ExperimentalFeature(
- 4,
+ 2,
EnableString.triple_shift,
IsEnabledByDefault.triple_shift,
IsExpired.triple_shift,
@@ -131,9 +131,6 @@
: _enableFlags = <bool>[
constant_update_2018 ?? IsEnabledByDefault.constant_update_2018,
non_nullable ?? IsEnabledByDefault.non_nullable,
- control_flow_collections ??
- IsEnabledByDefault.control_flow_collections,
- spread_collections ?? IsEnabledByDefault.spread_collections,
triple_shift ?? IsEnabledByDefault.triple_shift,
];
@@ -157,7 +154,7 @@
bool get constant_update_2018 => _enableFlags[0];
/// Current state for the flag "control_flow_collections"
- bool get control_flow_collections => _enableFlags[2];
+ bool get control_flow_collections => true;
/// Current state for the flag "non-nullable"
bool get non_nullable => _enableFlags[1];
@@ -166,10 +163,10 @@
bool get set_literals => true;
/// Current state for the flag "spread_collections"
- bool get spread_collections => _enableFlags[3];
+ bool get spread_collections => true;
/// Current state for the flag "triple_shift"
- bool get triple_shift => _enableFlags[4];
+ bool get triple_shift => _enableFlags[2];
/// Queries whether the given [feature] is enabled or disabled.
bool isEnabled(ExperimentalFeature feature) => feature.isExpired
@@ -188,7 +185,7 @@
static const bool constant_update_2018 = false;
/// Default state of the experiment "control-flow-collections"
- static const bool control_flow_collections = false;
+ static const bool control_flow_collections = true;
/// Default state of the experiment "non-nullable"
static const bool non_nullable = false;
@@ -197,7 +194,7 @@
static const bool set_literals = true;
/// Default state of the experiment "spread-collections"
- static const bool spread_collections = false;
+ static const bool spread_collections = true;
/// Default state of the experiment "triple-shift"
static const bool triple_shift = false;
@@ -217,7 +214,7 @@
static const bool constant_update_2018 = false;
/// Expiration status of the experiment "control-flow-collections"
- static const bool control_flow_collections = false;
+ static const bool control_flow_collections = true;
/// Expiration status of the experiment "non-nullable"
static const bool non_nullable = false;
@@ -226,7 +223,7 @@
static const bool set_literals = true;
/// Expiration status of the experiment "spread-collections"
- static const bool spread_collections = false;
+ static const bool spread_collections = true;
/// Expiration status of the experiment "triple-shift"
static const bool triple_shift = false;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 72796b5..676b8dc 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -27,6 +27,7 @@
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:pub_semver/src/version.dart';
/// Two or more string literals that are implicitly concatenated because of
/// being adjacent (separated only by whitespace).
@@ -2043,6 +2044,8 @@
@override
CompilationUnitElement declaredElement;
+ Version languageVersion;
+
/// The line information for this compilation unit.
@override
LineInfo lineInfo;
@@ -3060,6 +3063,9 @@
}
@override
+ Token get requiredKeyword => null;
+
+ @override
E accept<E>(AstVisitor<E> visitor) =>
visitor.visitDefaultFormalParameter(this);
@@ -3483,6 +3489,7 @@
@override
Iterable<SyntacticEntity> get childEntities => super._childEntities
+ ..add(keyword)
..add(_uri)
..addAll(combinators)
..add(semicolon);
@@ -3940,6 +3947,7 @@
CommentImpl comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
this.keyword,
TypeAnnotationImpl type,
this.thisKeyword,
@@ -3947,7 +3955,8 @@
SimpleIdentifierImpl identifier,
TypeParameterListImpl typeParameters,
FormalParameterListImpl parameters)
- : super(comment, metadata, covariantKeyword, identifier) {
+ : super(
+ comment, metadata, covariantKeyword, requiredKeyword, identifier) {
_type = _becomeParentOf(type);
_typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
@@ -5072,11 +5081,13 @@
CommentImpl comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
TypeAnnotationImpl returnType,
SimpleIdentifierImpl identifier,
TypeParameterListImpl typeParameters,
FormalParameterListImpl parameters)
- : super(comment, metadata, covariantKeyword, identifier) {
+ : super(
+ comment, metadata, covariantKeyword, requiredKeyword, identifier) {
_returnType = _becomeParentOf(returnType);
_typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
@@ -5649,6 +5660,7 @@
@override
Iterable<SyntacticEntity> get childEntities => super._childEntities
+ ..add(keyword)
..add(_uri)
..add(deferredKeyword)
..add(asKeyword)
@@ -7626,14 +7638,21 @@
/// The 'covariant' keyword, or `null` if the keyword was not used.
Token covariantKeyword;
+ /// The 'required' keyword, or `null` if the keyword was not used.
+ Token requiredKeyword;
+
/// The name of the parameter being declared.
SimpleIdentifierImpl _identifier;
/// Initialize a newly created formal parameter. Either or both of the
/// [comment] and [metadata] can be `null` if the parameter does not have the
/// corresponding attribute.
- NormalFormalParameterImpl(CommentImpl comment, List<Annotation> metadata,
- this.covariantKeyword, SimpleIdentifierImpl identifier) {
+ NormalFormalParameterImpl(
+ CommentImpl comment,
+ List<Annotation> metadata,
+ this.covariantKeyword,
+ this.requiredKeyword,
+ SimpleIdentifierImpl identifier) {
_comment = _becomeParentOf(comment);
_metadata = new NodeListImpl<Annotation>(this, metadata);
_identifier = _becomeParentOf(identifier);
@@ -8691,10 +8710,12 @@
CommentImpl comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
this.keyword,
TypeAnnotationImpl type,
SimpleIdentifierImpl identifier)
- : super(comment, metadata, covariantKeyword, identifier) {
+ : super(
+ comment, metadata, covariantKeyword, requiredKeyword, identifier) {
_type = _becomeParentOf(type);
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 2ce0985..deeded8 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -387,7 +387,7 @@
SimpleIdentifier identifier,
TypeParameterList typeParameters,
FormalParameterList parameters) =>
- new FieldFormalParameterImpl(comment, metadata, null, keyword, type,
+ new FieldFormalParameterImpl(comment, metadata, null, null, keyword, type,
thisKeyword, period, identifier, typeParameters, parameters);
@override
@@ -395,6 +395,7 @@
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
Token keyword,
TypeAnnotation type,
@required Token thisKeyword,
@@ -402,8 +403,18 @@
@required SimpleIdentifier identifier,
TypeParameterList typeParameters,
FormalParameterList parameters}) =>
- new FieldFormalParameterImpl(comment, metadata, covariantKeyword, keyword,
- type, thisKeyword, period, identifier, typeParameters, parameters);
+ new FieldFormalParameterImpl(
+ comment,
+ metadata,
+ covariantKeyword,
+ requiredKeyword,
+ keyword,
+ type,
+ thisKeyword,
+ period,
+ identifier,
+ typeParameters,
+ parameters);
@override
ForEachPartsWithDeclaration forEachPartsWithDeclaration(
@@ -538,20 +549,21 @@
SimpleIdentifier identifier,
TypeParameterList typeParameters,
FormalParameterList parameters) =>
- new FunctionTypedFormalParameterImpl(comment, metadata, null, returnType,
- identifier, typeParameters, parameters);
+ new FunctionTypedFormalParameterImpl(comment, metadata, null, null,
+ returnType, identifier, typeParameters, parameters);
@override
FunctionTypedFormalParameter functionTypedFormalParameter2(
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
TypeAnnotation returnType,
@required SimpleIdentifier identifier,
TypeParameterList typeParameters,
@required FormalParameterList parameters}) =>
new FunctionTypedFormalParameterImpl(comment, metadata, covariantKeyword,
- returnType, identifier, typeParameters, parameters);
+ requiredKeyword, returnType, identifier, typeParameters, parameters);
@override
GenericFunctionType genericFunctionType(
@@ -875,18 +887,19 @@
TypeAnnotation type,
SimpleIdentifier identifier) =>
new SimpleFormalParameterImpl(
- comment, metadata, null, keyword, type, identifier);
+ comment, metadata, null, null, keyword, type, identifier);
@override
SimpleFormalParameter simpleFormalParameter2(
{Comment comment,
List<Annotation> metadata,
Token covariantKeyword,
+ Token requiredKeyword,
Token keyword,
TypeAnnotation type,
@required SimpleIdentifier identifier}) =>
- new SimpleFormalParameterImpl(
- comment, metadata, covariantKeyword, keyword, type, identifier);
+ new SimpleFormalParameterImpl(comment, metadata, covariantKeyword,
+ requiredKeyword, keyword, type, identifier);
@override
SimpleIdentifier simpleIdentifier(Token token, {bool isDeclaration: false}) {
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index f3c1805..97fac61 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -43,6 +43,8 @@
/// The current library that is being analyzed.
final LibraryElement _currentLibrary;
+ final bool _constantUpdate2018Enabled;
+
ConstantEvaluationEngine _evaluationEngine;
/// Initialize a newly created constant verifier.
@@ -52,7 +54,11 @@
this._typeProvider, this.declaredVariables,
{bool forAnalysisDriver: false})
: _currentLibrary = currentLibrary,
- _typeSystem = currentLibrary.context.typeSystem {
+ _typeSystem = currentLibrary.context.typeSystem,
+ _constantUpdate2018Enabled =
+ (currentLibrary.context.analysisOptions as AnalysisOptionsImpl)
+ .experimentStatus
+ .constant_update_2018 {
this._intType = _typeProvider.intType;
this._evaluationEngine = new ConstantEvaluationEngine(
_typeProvider, declaredVariables,
@@ -613,6 +619,10 @@
verifier._errorReporter.reportErrorForNode(errorCode, element);
return false;
} else if (element is IfElement) {
+ if (!verifier._constantUpdate2018Enabled) {
+ verifier._errorReporter.reportErrorForNode(errorCode, element);
+ return false;
+ }
var conditionValue = verifier._validate(element.condition, errorCode);
var conditionBool = conditionValue?.toBoolValue();
@@ -642,6 +652,10 @@
} else if (element is MapLiteralEntry) {
return _validateMapLiteralEntry(element);
} else if (element is SpreadElement) {
+ if (!verifier._constantUpdate2018Enabled) {
+ verifier._errorReporter.reportErrorForNode(errorCode, element);
+ return false;
+ }
var value = verifier._validate(element.expression, errorCode);
if (value == null) return false;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 743595d..f2db8f0 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -661,10 +661,16 @@
}
bool get hasBeenInferred {
+ if (linkedNode != null) {
+ return linkedContext.hasOverrideInferenceDone(linkedNode);
+ }
return _unlinkedClass != null || _hasBeenInferred;
}
void set hasBeenInferred(bool hasBeenInferred) {
+ if (linkedNode != null) {
+ return linkedContext.setOverrideInferenceDone(linkedNode);
+ }
_assertNotResynthesized(_unlinkedClass);
_hasBeenInferred = hasBeenInferred;
}
@@ -830,9 +836,9 @@
@override
bool get isSimplyBounded {
-// if (linkedNode != null) {
-// return linkedNode.simplyBoundable_isSimplyBounded;
-// }
+ if (linkedNode != null) {
+ return linkedContext.isSimplyBounded(linkedNode);
+ }
return super.isSimplyBounded;
}
@@ -1021,6 +1027,12 @@
if (linkedNode != null) {
var context = enclosingUnit.linkedContext;
+
+ var coreTypes = context.bundleContext.elementFactory.coreTypes;
+ if (identical(this, coreTypes.objectClass)) {
+ return null;
+ }
+
var type = context.getSuperclass(linkedNode)?.type;
if (_isInterfaceTypeClass(type)) {
return _supertype = type;
@@ -1060,31 +1072,6 @@
return _type;
}
- @override
- List<TypeParameterElement> get typeParameters {
- if (_typeParameterElements != null) return _typeParameterElements;
-
- if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var containerRef = reference.getChild('@typeParameter');
- var typeParameters = context.getTypeParameters2(linkedNode);
- if (typeParameters == null) {
- return _typeParameterElements = const [];
- }
- return _typeParameterElements = typeParameters.typeParameters.map((node) {
- var name = node.name.name;
- var reference = containerRef.getChild(name);
- if (reference.element == null) {
- reference.node2 = node;
- TypeParameterElementImpl.forLinkedNode(this, reference, node);
- }
- return reference.element as TypeParameterElementImpl;
- }).toList();
- }
-
- return super.typeParameters;
- }
-
/// Set the type parameters defined for this class to the given
/// [typeParameters].
void set typeParameters(List<TypeParameterElement> typeParameters) {
@@ -2470,21 +2457,20 @@
/// Return the constant initializers for this element, which will be empty if
/// there are no initializers, or `null` if there was an error in the source.
List<ConstructorInitializer> get constantInitializers {
- if (_constantInitializers == null) {
-// if (linkedNode != null) {
-// var context = enclosingUnit.linkedContext;
-// return _constantInitializers ??=
-// linkedNode.constructorDeclaration_initializers.map((node) {
-// return context.readNode(node) as ConstructorInitializer;
-// }).toList();
-// }
+ if (_constantInitializers != null) return _constantInitializers;
- if (serializedExecutable != null) {
- _constantInitializers = serializedExecutable.constantInitializers
- .map((i) => _buildConstructorInitializer(i))
- .toList(growable: false);
- }
+ if (linkedNode != null) {
+ return _constantInitializers = linkedContext.getConstructorInitializers(
+ linkedNode,
+ );
}
+
+ if (serializedExecutable != null) {
+ return _constantInitializers = serializedExecutable.constantInitializers
+ .map((i) => _buildConstructorInitializer(i))
+ .toList(growable: false);
+ }
+
return _constantInitializers;
}
@@ -2626,41 +2612,39 @@
@override
ConstructorElement get redirectedConstructor {
- if (_redirectedConstructor == null) {
-// if (linkedNode != null) {
-// var context = enclosingUnit.linkedContext;
-// if (isFactory) {
-// var node = linkedNode.constructorDeclaration_redirectedConstructor;
-// if (node != null) {
-// ConstructorName ast = context.readNode(node);
-// return ast.staticElement;
-// }
-// } else {
-// for (var node in linkedNode.constructorDeclaration_initializers) {
-// if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) {
-// RedirectingConstructorInvocation ast = context.readNode(node);
-// return ast.staticElement;
-// }
-// }
-// }
-// return null;
-// }
+ if (_redirectedConstructor != null) return _redirectedConstructor;
- if (serializedExecutable != null) {
- if (serializedExecutable.isRedirectedConstructor) {
- if (serializedExecutable.isFactory) {
- _redirectedConstructor = enclosingUnit.resynthesizerContext
- .resolveConstructorRef(enclosingElement,
- serializedExecutable.redirectedConstructor);
- } else {
- _redirectedConstructor = enclosingElement.getNamedConstructor(
- serializedExecutable.redirectedConstructorName);
+ if (linkedNode != null) {
+ var context = enclosingUnit.linkedContext;
+ if (isFactory) {
+ var node = context.getConstructorRedirected(linkedNode);
+ return _redirectedConstructor = node?.staticElement;
+ } else {
+ var initializers = context.getConstructorInitializers(linkedNode);
+ for (var initializer in initializers) {
+ if (initializer is RedirectingConstructorInvocation) {
+ return _redirectedConstructor = initializer.staticElement;
}
- } else {
- return null;
}
}
+ return null;
}
+
+ if (serializedExecutable != null) {
+ if (serializedExecutable.isRedirectedConstructor) {
+ if (serializedExecutable.isFactory) {
+ _redirectedConstructor = enclosingUnit.resynthesizerContext
+ .resolveConstructorRef(
+ enclosingElement, serializedExecutable.redirectedConstructor);
+ } else {
+ _redirectedConstructor = enclosingElement.getNamedConstructor(
+ serializedExecutable.redirectedConstructorName);
+ }
+ } else {
+ return null;
+ }
+ }
+
return _redirectedConstructor;
}
@@ -4396,6 +4380,9 @@
@override
bool get hasImplicitReturnType {
+ if (linkedNode != null) {
+ return linkedContext.hasImplicitReturnType(linkedNode);
+ }
if (serializedExecutable != null) {
return serializedExecutable.returnType == null &&
serializedExecutable.kind != UnlinkedExecutableKind.constructor;
@@ -4530,9 +4517,8 @@
DartType get returnType {
if (linkedNode != null) {
if (_returnType != null) return _returnType;
- return _returnType = enclosingUnit.linkedContext.getReturnType(
- linkedNode,
- );
+ var context = enclosingUnit.linkedContext;
+ return _returnType = context.getReturnType(linkedNode);
}
if (serializedExecutable != null &&
_declaredReturnType == null &&
@@ -4549,6 +4535,9 @@
}
void set returnType(DartType returnType) {
+ if (linkedNode != null) {
+ linkedContext.setReturnType(linkedNode, returnType);
+ }
_assertNotResynthesized(serializedExecutable);
_returnType = _checkElementOfType(returnType);
}
@@ -4728,10 +4717,7 @@
if (_exportedLibrary != null) return _exportedLibrary;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var uri = context.directiveUri(librarySource.uri, linkedNode);
- var elementFactory = context.bundleContext.elementFactory;
- return _exportedLibrary = elementFactory.libraryOfUri('$uri');
+ return _exportedLibrary = linkedContext.directiveLibrary(linkedNode);
}
if (_unlinkedExportNonPublic != null) {
@@ -4859,8 +4845,9 @@
}
factory FieldElementImpl.forLinkedNodeFactory(
- ElementImpl enclosing, Reference reference, AstNode linkedNode) {
- if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) {
+ ClassElementImpl enclosing, Reference reference, AstNode linkedNode) {
+ var context = enclosing.enclosingUnit.linkedContext;
+ if (context.shouldBeConstFieldElement(linkedNode)) {
return ConstFieldElementImpl.forLinkedNode(
enclosing,
reference,
@@ -4900,7 +4887,7 @@
@override
bool get isCovariant {
if (linkedNode != null) {
- return linkedContext.isCovariantField(linkedNode);
+ return linkedContext.isCovariant(linkedNode);
}
if (_unlinkedVariable != null) {
@@ -4921,6 +4908,17 @@
enclosingElement != null && enclosingElement.isEnum && !isSynthetic;
@override
+ bool get isLazy {
+// if (linkedNode != null) {
+// return enclosingUnit.linkedContext.isLazy(linkedNode);
+// }
+// if (_unlinkedVariable != null) {
+// return _unlinkedVariable.isLazy;
+// }
+ return hasModifier(Modifier.LAZY);
+ }
+
+ @override
bool get isStatic {
if (linkedNode != null) {
return enclosingUnit.linkedContext.isStatic(linkedNode);
@@ -5121,14 +5119,6 @@
}
@override
- void set returnType(DartType returnType) {
-// if (linkedNode != null) {
-// enclosingUnit.linkedContext.setReturnType(linkedNode, returnType);
-// }
- super.returnType = returnType;
- }
-
- @override
SourceRange get visibleRange {
if (serializedExecutable != null) {
if (serializedExecutable.visibleLength == 0) {
@@ -5602,9 +5592,9 @@
@override
bool get isSimplyBounded {
-// if (linkedNode != null) {
-// return linkedNode.simplyBoundable_isSimplyBounded;
-// }
+ if (linkedNode != null) {
+ return linkedContext.isSimplyBounded(linkedNode);
+ }
return super.isSimplyBounded;
}
@@ -5915,10 +5905,7 @@
if (_importedLibrary != null) return _importedLibrary;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var uri = context.directiveUri(librarySource.uri, linkedNode);
- var elementFactory = context.bundleContext.elementFactory;
- return _importedLibrary = elementFactory.libraryOfUri('$uri');
+ return _importedLibrary = linkedContext.directiveLibrary(linkedNode);
}
if (_linkedDependency != null) {
@@ -6337,6 +6324,10 @@
@override
String get documentationComment {
+ if (linkedNode != null) {
+ var comment = linkedContext.getLibraryDocumentationComment(linkedNode);
+ return getCommentNodeRawText(comment);
+ }
if (unlinkedDefiningUnit != null) {
return unlinkedDefiningUnit.libraryDocumentationComment?.text;
}
@@ -6493,7 +6484,9 @@
.whereType<ImportDirective>()
.map((node) => ImportElementImpl.forLinkedNode(this, node))
.toList();
- var hasCore = _imports.any((import) => import.importedLibrary.isDartCore);
+ var hasCore = _imports.any((import) {
+ return import.importedLibrary?.isDartCore ?? false;
+ });
if (!hasCore) {
var elements = linkedContext.bundleContext.elementFactory;
_imports.add(ImportElementImpl(-1)
@@ -6706,8 +6699,15 @@
@override
Namespace get publicNamespace {
+ if (_publicNamespace != null) return _publicNamespace;
+
+ if (linkedNode != null) {
+ return _publicNamespace =
+ NamespaceBuilder().createPublicNamespaceForLibrary(this);
+ }
+
if (resynthesizerContext != null) {
- _publicNamespace ??= resynthesizerContext.buildPublicNamespace();
+ return _publicNamespace = resynthesizerContext.buildPublicNamespace();
}
return _publicNamespace;
}
@@ -7013,6 +7013,17 @@
}
@override
+ bool get isLazy {
+// if (linkedNode != null) {
+// return enclosingUnit.linkedContext.isLazy(linkedNode);
+// }
+// if (_unlinkedVariable != null) {
+// return _unlinkedVariable.isLazy;
+// }
+ return hasModifier(Modifier.LAZY);
+ }
+
+ @override
bool get isPotentiallyMutatedInClosure => true;
@override
@@ -7136,16 +7147,6 @@
}
@override
- DartType get returnType {
-// if (linkedNode != null) {
-// return enclosingUnit.linkedContext.getType(
-// linkedNode.methodDeclaration_returnType2,
-// );
-// }
- return super.returnType;
- }
-
- @override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitMethodElement(this);
@override
@@ -7387,25 +7388,28 @@
/// type being referred to is the return type.
static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 12);
+ /// Indicates that modifier 'lazy' was applied to the element.
+ static const Modifier LAZY = const Modifier('LAZY', 13);
+
/// Indicates that a class is a mixin application.
static const Modifier MIXIN_APPLICATION =
- const Modifier('MIXIN_APPLICATION', 13);
+ const Modifier('MIXIN_APPLICATION', 14);
/// Indicates that a class contains an explicit reference to 'super'.
static const Modifier REFERENCES_SUPER =
- const Modifier('REFERENCES_SUPER', 14);
+ const Modifier('REFERENCES_SUPER', 15);
/// Indicates that the pseudo-modifier 'set' was applied to the element.
- static const Modifier SETTER = const Modifier('SETTER', 15);
+ static const Modifier SETTER = const Modifier('SETTER', 16);
/// Indicates that the modifier 'static' was applied to the element.
- static const Modifier STATIC = const Modifier('STATIC', 16);
+ static const Modifier STATIC = const Modifier('STATIC', 17);
/// Indicates that the element does not appear in the source code but was
/// implicitly created. For example, if a class does not define any
/// constructors, an implicit zero-argument constructor will be created and it
/// will be marked as being synthetic.
- static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 17);
+ static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
static const List<Modifier> values = const [
ABSTRACT,
@@ -7421,6 +7425,7 @@
GETTER,
HAS_EXT_URI,
IMPLICIT_TYPE,
+ LAZY,
MIXIN_APPLICATION,
REFERENCES_SUPER,
SETTER,
@@ -7763,6 +7768,9 @@
@override
bool get hasImplicitType {
+ if (linkedNode != null) {
+ return linkedContext.hasImplicitType(linkedNode);
+ }
if (_unlinkedVariable != null) {
return _unlinkedVariable.type == null;
}
@@ -7875,6 +7883,9 @@
@override
void set type(DartType type) {
+ if (linkedNode != null) {
+ return linkedContext.setVariableType(linkedNode, type);
+ }
_assertNotResynthesized(_unlinkedVariable);
_type = _checkElementOfType(type);
}
@@ -8029,6 +8040,9 @@
@override
bool get hasImplicitType {
+ if (linkedNode != null) {
+ return linkedContext.hasImplicitType(linkedNode);
+ }
if (unlinkedParam != null) {
return unlinkedParam.type == null && !unlinkedParam.isFunctionTyped;
}
@@ -8099,13 +8113,9 @@
@override
bool get isCovariant {
-// if (linkedNode != null) {
-// if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-// var parameter = linkedNode.defaultFormalParameter_parameter;
-// return parameter.normalFormalParameter_isCovariant;
-// }
-// return linkedNode.normalFormalParameter_isCovariant;
-// }
+ if (linkedNode != null) {
+ return linkedContext.isCovariant(linkedNode);
+ }
if (isExplicitlyCovariant || inheritsCovariant) {
return true;
}
@@ -8377,17 +8387,25 @@
);
}
} else {
- var name = node.identifier.name;
- var reference = containerRef.getChild(name);
- if (reference.element == null) {
- reference.node2 = node;
- ParameterElementImpl.forLinkedNodeFactory(
+ if (node.identifier == null) {
+ return ParameterElementImpl.forLinkedNodeFactory(
enclosing,
- reference,
+ containerRef.getChild(''),
node,
);
+ } else {
+ var name = node.identifier.name;
+ var reference = containerRef.getChild(name);
+ if (reference.element == null) {
+ reference.node2 = node;
+ ParameterElementImpl.forLinkedNodeFactory(
+ enclosing,
+ reference,
+ node,
+ );
+ }
+ return reference.element as ParameterElement;
}
- return reference.element as ParameterElement;
}
}).toList();
}
@@ -8879,7 +8897,7 @@
DartType get type {
if (linkedNode != null) {
if (_type != null) return _type;
- return _type = enclosingUnit.linkedContext.getType(linkedNode);
+ return _type = linkedContext.getType(linkedNode);
}
if (isSynthetic && _type == null) {
if (getter != null) {
@@ -9246,7 +9264,8 @@
@override
String get name {
if (linkedNode != null) {
- return reference.name;
+ TypeParameter node = this.linkedNode;
+ return node.name.name;
}
if (_unlinkedTypeParam != null) {
return _unlinkedTypeParam.name;
@@ -9320,20 +9339,14 @@
if (_typeParameterElements != null) return _typeParameterElements;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- var containerRef = reference.getChild('@typeParameter');
- var typeParameters = context.getTypeParameters2(linkedNode);
+ var typeParameters = linkedContext.getTypeParameters2(linkedNode);
if (typeParameters == null) {
return _typeParameterElements = const [];
}
return _typeParameterElements = typeParameters.typeParameters.map((node) {
- var name = node.name.name;
- var reference = containerRef.getChild(name);
- if (reference.element == null) {
- reference.node2 = node;
- TypeParameterElementImpl.forLinkedNode(this, reference, node);
- }
- return reference.element as TypeParameterElementImpl;
+ TypeParameterElementImpl element = node.declaredElement;
+ element.enclosingElement = this;
+ return element;
}).toList();
}
@@ -9533,9 +9546,6 @@
DartObject get constantValue => evaluationResult?.value;
void set declaredType(DartType type) {
-// if (linkedNode != null) {
-// enclosingUnit.linkedContext.setVariableType(linkedNode, type);
-// }
_declaredType = _checkElementOfType(type);
}
@@ -9619,6 +9629,9 @@
DartType get type => _type ?? _declaredType;
void set type(DartType type) {
+ if (linkedNode != null) {
+ return linkedContext.setVariableType(linkedNode, type);
+ }
_type = _checkElementOfType(type);
}
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 7384095d..7a4a1e7 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -664,6 +664,9 @@
@override
bool get isEnumConstant => actualElement.isEnumConstant;
+ @override
+ bool get isLazy => actualElement.isLazy;
+
@deprecated
@override
bool get isVirtual => actualElement.isVirtual;
@@ -984,6 +987,9 @@
super.actualElement as LocalVariableElement;
@override
+ bool get isLazy => actualElement.isLazy;
+
+ @override
ElementKind get kind => ElementKind.LOCAL_VARIABLE;
@override
@@ -1171,14 +1177,14 @@
@override
PropertyAccessorElement get getter => actualElement.getter;
+ @override
+ bool get isConstantEvaluated => actualElement.isConstantEvaluated;
+
@deprecated
@override
DartType get propagatedType => null;
@override
- bool get isConstantEvaluated => actualElement.isConstantEvaluated;
-
- @override
PropertyAccessorElement get setter => actualElement.setter;
}
@@ -1259,10 +1265,10 @@
FunctionElement get initializer => actualElement.initializer;
@override
- bool get isConstantEvaluated => actualElement.isConstantEvaluated;
+ bool get isConst => actualElement.isConst;
@override
- bool get isConst => actualElement.isConst;
+ bool get isConstantEvaluated => actualElement.isConstantEvaluated;
@override
bool get isFinal => actualElement.isFinal;
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 7472796..12fd38f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -255,6 +255,9 @@
@override
bool get isEnumConstant => baseElement.isEnumConstant;
+ @override
+ bool get isLazy => baseElement.isLazy;
+
@deprecated
@override
bool get isVirtual => baseElement.isVirtual;
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index e2393ca..267f338 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -56,35 +56,14 @@
*/
class BottomTypeImpl extends TypeImpl {
/**
- * The unique instance of this class, with indeterminate nullability.
+ * The unique instance of this class.
*/
- static final BottomTypeImpl instance = instanceIndeterminate;
-
- /**
- * The unique instance of this class, nullable.
- */
- static final BottomTypeImpl instanceNullable =
- new BottomTypeImpl._(Nullability.nullable);
-
- /**
- * The unique instance of this class, with indeterminate nullability.
- */
- static final BottomTypeImpl instanceIndeterminate =
- new BottomTypeImpl._(Nullability.indeterminate);
-
- /**
- * The unique instance of this class, non-nullable.
- */
- static final BottomTypeImpl instanceNonNullable =
- new BottomTypeImpl._(Nullability.nonNullable);
-
- @override
- final Nullability nullability;
+ static final BottomTypeImpl instance = new BottomTypeImpl._();
/**
* Prevent the creation of instances of this class.
*/
- BottomTypeImpl._(this.nullability) : super(null, "<bottom>");
+ BottomTypeImpl._() : super(null, "<bottom>");
@override
int get hashCode => 0;
@@ -93,6 +72,9 @@
bool get isBottom => true;
@override
+ NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.none;
+
+ @override
bool operator ==(Object object) => identical(object, this);
@override
@@ -134,16 +116,9 @@
this;
@override
- TypeImpl withNullability(Nullability nullability) {
- switch (nullability) {
- case Nullability.nullable:
- return instanceNullable;
- case Nullability.indeterminate:
- return instanceIndeterminate;
- case Nullability.nonNullable:
- return instanceNonNullable;
- }
- throw StateError('Unexpected nullability: $nullability');
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ // The bottom type is always non-nullable.
+ return this;
}
}
@@ -153,7 +128,7 @@
*/
class CircularFunctionTypeImpl extends DynamicTypeImpl
implements _FunctionTypeImplLazy {
- CircularFunctionTypeImpl() : super._circular(Nullability.indeterminate);
+ CircularFunctionTypeImpl() : super._circular();
@override
List<ParameterElement> get baseParameters => const <ParameterElement>[];
@@ -262,7 +237,7 @@
FunctionTypeImpl substitute3(List<DartType> argumentTypes) => this;
@override
- TypeImpl withNullability(Nullability nullability) => this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
@override
void _forEachParameterType(
@@ -294,7 +269,7 @@
* `...`.
*/
class CircularTypeImpl extends DynamicTypeImpl {
- CircularTypeImpl() : super._circular(Nullability.indeterminate);
+ CircularTypeImpl() : super._circular();
@override
bool operator ==(Object object) => object is CircularTypeImpl;
@@ -332,9 +307,9 @@
DeferredFunctionTypeImpl(this._computeElement, String name,
List<DartType> typeArguments, bool isInstantiated,
- {Nullability nullability = Nullability.indeterminate})
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star})
: super._(null, name, null, typeArguments, null, null, isInstantiated,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
@override
FunctionTypedElement get element {
@@ -346,11 +321,11 @@
}
@override
- TypeImpl withNullability(Nullability nullability) {
- if (this.nullability == nullability) return this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ if (this.nullabilitySuffix == nullabilitySuffix) return this;
return DeferredFunctionTypeImpl(
_computeElement, name, typeArguments, isInstantiated,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
}
@@ -359,35 +334,14 @@
*/
class DynamicTypeImpl extends TypeImpl {
/**
- * The unique instance of this class, with indeterminate nullability.
+ * The unique instance of this class.
*/
- static final DynamicTypeImpl instance = instanceIndeterminate;
-
- /**
- * The unique instance of this class, nullable.
- */
- static final DynamicTypeImpl instanceNullable =
- new DynamicTypeImpl._(Nullability.nullable);
-
- /**
- * The unique instance of this class, with indeterminate nullability.
- */
- static final DynamicTypeImpl instanceIndeterminate =
- new DynamicTypeImpl._(Nullability.indeterminate);
-
- /**
- * The unique instance of this class, non-nullable.
- */
- static final DynamicTypeImpl instanceNonNullable =
- new DynamicTypeImpl._(Nullability.nonNullable);
-
- @override
- final Nullability nullability;
+ static final DynamicTypeImpl instance = new DynamicTypeImpl._();
/**
* Prevent the creation of instances of this class.
*/
- DynamicTypeImpl._(this.nullability)
+ DynamicTypeImpl._()
: super(new DynamicElementImpl(), Keyword.DYNAMIC.lexeme) {
(element as DynamicElementImpl).type = this;
}
@@ -395,8 +349,7 @@
/**
* Constructor used by [CircularTypeImpl].
*/
- DynamicTypeImpl._circular(this.nullability)
- : super(instance.element, Keyword.DYNAMIC.lexeme);
+ DynamicTypeImpl._circular() : super(instance.element, Keyword.DYNAMIC.lexeme);
@override
int get hashCode => 1;
@@ -405,6 +358,9 @@
bool get isDynamic => true;
@override
+ NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.none;
+
+ @override
bool operator ==(Object object) => identical(object, this);
@override
@@ -451,16 +407,9 @@
}
@override
- TypeImpl withNullability(Nullability nullability) {
- switch (nullability) {
- case Nullability.nullable:
- return instanceNullable;
- case Nullability.indeterminate:
- return instanceIndeterminate;
- case Nullability.nonNullable:
- return instanceNonNullable;
- }
- throw StateError('Unexpected nullability: $nullability');
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ // The dynamic type is always nullable.
+ return this;
}
}
@@ -469,7 +418,7 @@
*/
abstract class FunctionTypeImpl extends TypeImpl implements FunctionType {
@override
- final Nullability nullability;
+ final NullabilitySuffix nullabilitySuffix;
/**
* Initialize a newly created function type to be declared by the given
@@ -477,13 +426,13 @@
* [typeParameters], which permits later substitution.
*/
factory FunctionTypeImpl(FunctionTypedElement element,
- {Nullability nullability = Nullability.indeterminate}) {
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star}) {
if (element is FunctionTypeAliasElement) {
throw new StateError('Use FunctionTypeImpl.forTypedef for typedefs');
}
return new _FunctionTypeImplLazy._(
element, null, null, null, null, null, false,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
/**
@@ -494,10 +443,10 @@
* See https://github.com/dart-lang/sdk/issues/34657.
*/
factory FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
- {Nullability nullability = Nullability.indeterminate}) {
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star}) {
return new _FunctionTypeImplLazy._(
element, element?.name, null, null, null, null, false,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
/**
@@ -510,7 +459,7 @@
*/
factory FunctionTypeImpl.fresh(FunctionType original,
{bool force = false,
- Nullability nullability = Nullability.indeterminate}) {
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star}) {
// We build up a substitution for the type parameters,
// {variablesFresh/variables} then apply it.
@@ -559,19 +508,19 @@
function.typeParameters = freshVarElements;
function.shareParameters(newType.parameters);
return function.type =
- new FunctionTypeImpl(function, nullability: nullability);
+ new FunctionTypeImpl(function, nullabilitySuffix: nullabilitySuffix);
}
/// Creates a function type that's not associated with any element in the
/// element tree.
factory FunctionTypeImpl.synthetic(DartType returnType,
List<TypeParameterElement> typeFormals, List<ParameterElement> parameters,
- {Nullability nullability = Nullability.indeterminate}) {
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star}) {
return new _FunctionTypeImplStrict._(returnType, typeFormals, parameters,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
- FunctionTypeImpl._(Element element, String name, this.nullability)
+ FunctionTypeImpl._(Element element, String name, this.nullabilitySuffix)
: super(element, name);
@deprecated
@@ -930,7 +879,7 @@
return this;
}
return new _FunctionTypeImplStrict._(returnType, typeFormals, parameters,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
@@ -1297,7 +1246,7 @@
*/
class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
@override
- final Nullability nullability;
+ final NullabilitySuffix nullabilitySuffix;
/**
* A list containing the actual types of the type arguments.
@@ -1340,7 +1289,7 @@
* Initialize a newly created type to be declared by the given [element].
*/
InterfaceTypeImpl(ClassElement element,
- [this.prunedTypedefs, this.nullability = Nullability.indeterminate])
+ [this.prunedTypedefs, this.nullabilitySuffix = NullabilitySuffix.star])
: super(element, element.displayName);
/**
@@ -1349,14 +1298,14 @@
*/
InterfaceTypeImpl.elementWithNameAndArgs(
ClassElement element, String name, this._typeArgumentsComputer,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: prunedTypedefs = null,
super(element, name) {
_typeArguments = null;
}
InterfaceTypeImpl.explicit(ClassElement element, List<DartType> typeArguments,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: prunedTypedefs = null,
_typeArguments = typeArguments,
super(element, element.displayName);
@@ -1366,7 +1315,7 @@
* should only be used in cases where there is no declaration of the type.
*/
InterfaceTypeImpl.named(String name,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: prunedTypedefs = null,
super(null, name);
@@ -1374,11 +1323,11 @@
* Private constructor.
*/
InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: super(element, name);
InterfaceTypeImpl._withNullability(InterfaceTypeImpl original,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: _typeArguments = original._typeArguments,
_typeArgumentsComputer = original._typeArgumentsComputer,
prunedTypedefs = original.prunedTypedefs,
@@ -2229,7 +2178,7 @@
// base types.
assert(this.prunedTypedefs == null);
InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
result.typeArguments = typeArguments
.map((DartType t) => (t as TypeImpl).pruned(prune))
.toList();
@@ -2258,7 +2207,7 @@
return this;
} else {
return new InterfaceTypeImpl._(element, name, prunedTypedefs,
- nullability: nullability)
+ nullabilitySuffix: nullabilitySuffix)
..typeArguments = typeArguments;
}
}
@@ -2282,7 +2231,7 @@
}
InterfaceTypeImpl newType =
- new InterfaceTypeImpl(element, prune, nullability);
+ new InterfaceTypeImpl(element, prune, nullabilitySuffix);
newType.typeArguments = newTypeArguments;
return newType;
}
@@ -2293,9 +2242,10 @@
instantiate(argumentTypes);
@override
- TypeImpl withNullability(Nullability nullability) {
- if (this.nullability == nullability) return this;
- return InterfaceTypeImpl._withNullability(this, nullability: nullability);
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ if (this.nullabilitySuffix == nullabilitySuffix) return this;
+ return InterfaceTypeImpl._withNullability(this,
+ nullabilitySuffix: nullabilitySuffix);
}
/**
@@ -2682,16 +2632,19 @@
}
}
- Nullability computeNullability() {
- Nullability first = (firstType as InterfaceTypeImpl).nullability;
- Nullability second = (secondType as InterfaceTypeImpl).nullability;
- if (first == Nullability.nullable || second == Nullability.nullable) {
- return Nullability.nullable;
- } else if (first == Nullability.indeterminate ||
- second == Nullability.indeterminate) {
- return Nullability.indeterminate;
+ NullabilitySuffix computeNullability() {
+ NullabilitySuffix first =
+ (firstType as InterfaceTypeImpl).nullabilitySuffix;
+ NullabilitySuffix second =
+ (secondType as InterfaceTypeImpl).nullabilitySuffix;
+ if (first == NullabilitySuffix.question ||
+ second == NullabilitySuffix.question) {
+ return NullabilitySuffix.question;
+ } else if (first == NullabilitySuffix.star ||
+ second == NullabilitySuffix.star) {
+ return NullabilitySuffix.star;
}
- return Nullability.nonNullable;
+ return NullabilitySuffix.none;
}
InterfaceTypeImpl lub =
@@ -2761,24 +2714,35 @@
}
/**
- * The nullability of a type.
+ * Suffix indicating the nullability of a type.
+ *
+ * This enum describes whether a `?` or `*` would be used at the end of the
+ * canonical representation of a type. It's subtly different the notions of
+ * "nullable", "non-nullable", "potentially nullable", and "potentially
+ * non-nullable" defined by the spec. For example, the type `Null` is nullable,
+ * even though it lacks a trailing `?`.
*/
-enum Nullability {
+enum NullabilitySuffix {
/**
- * An indication that the type includes the value `null`.
+ * An indication that the canonical representation of the type under
+ * consideration ends with `?`. Types having this nullability suffix should
+ * be interpreted as being unioned with the Null type.
*/
- nullable,
+ question,
/**
- * An indication that the type is a legacy type which may be interpreted as
- * either nullable or non-nullable as appropriate.
+ * An indication that the canonical representation of the type under
+ * consideration ends with `*`. Types having this nullability suffix are
+ * called "legacy types"; it has not yet been determined whether they should
+ * be unioned with the Null type.
*/
- indeterminate,
+ star,
/**
- * An indication that the type does not include the value `null`.
+ * An indication that the canonical representation of the type under
+ * consideration does not end with either `?` or `*`.
*/
- nonNullable
+ none
}
/**
@@ -2849,9 +2813,9 @@
bool get isVoid => false;
/**
- * Return the nullability of this type.
+ * Return the nullability suffix of this type.
*/
- Nullability get nullability;
+ NullabilitySuffix get nullabilitySuffix;
/**
* Append a textual representation of this type to the given [buffer]. The set
@@ -2982,20 +2946,24 @@
}
/**
- * Return the same type, but with the given [nullability].
+ * Return the same type, but with the given [nullabilitySuffix].
*/
- TypeImpl withNullability(Nullability nullability);
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix);
void _appendNullability(StringBuffer buffer) {
- switch (nullability) {
- case Nullability.nullable:
+ if (isDynamic || isBottom || isVoid) {
+ // These types don't have nullability variations, so don't append
+ // anything.
+ return;
+ }
+ switch (nullabilitySuffix) {
+ case NullabilitySuffix.question:
buffer.write('?');
break;
- case Nullability.indeterminate:
+ case NullabilitySuffix.star:
buffer.write('*');
break;
- case Nullability.nonNullable:
- buffer.write('!');
+ case NullabilitySuffix.none:
break;
}
}
@@ -3083,14 +3051,14 @@
static bool _appendingBounds = false;
@override
- final Nullability nullability;
+ final NullabilitySuffix nullabilitySuffix;
/**
* Initialize a newly created type parameter type to be declared by the given
* [element] and to have the given name.
*/
TypeParameterTypeImpl(TypeParameterElement element,
- {this.nullability = Nullability.indeterminate})
+ {this.nullabilitySuffix = NullabilitySuffix.star})
: super(element, element.name);
@override
@@ -3254,16 +3222,16 @@
}
// TODO(scheglov) Proposed substitution rules for nullability.
- Nullability resultNullability;
- Nullability argumentNullability = argumentType.nullability;
- if (argumentNullability == Nullability.nullable ||
- nullability == Nullability.nullable) {
- resultNullability = Nullability.nullable;
- } else if (argumentNullability == Nullability.indeterminate ||
- nullability == Nullability.indeterminate) {
- resultNullability = Nullability.indeterminate;
+ NullabilitySuffix resultNullability;
+ NullabilitySuffix argumentNullability = argumentType.nullabilitySuffix;
+ if (argumentNullability == NullabilitySuffix.question ||
+ nullabilitySuffix == NullabilitySuffix.question) {
+ resultNullability = NullabilitySuffix.question;
+ } else if (argumentNullability == NullabilitySuffix.star ||
+ nullabilitySuffix == NullabilitySuffix.star) {
+ resultNullability = NullabilitySuffix.star;
} else {
- resultNullability = Nullability.nonNullable;
+ resultNullability = NullabilitySuffix.none;
}
return argumentType.withNullability(resultNullability);
@@ -3273,9 +3241,9 @@
}
@override
- TypeImpl withNullability(Nullability nullability) {
- if (this.nullability == nullability) return this;
- return TypeParameterTypeImpl(element, nullability: nullability);
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ if (this.nullabilitySuffix == nullabilitySuffix) return this;
+ return TypeParameterTypeImpl(element, nullabilitySuffix: nullabilitySuffix);
}
/**
@@ -3325,7 +3293,7 @@
bool get isUndefined => true;
@override
- Nullability get nullability => Nullability.indeterminate;
+ NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.star;
@override
bool operator ==(Object object) => identical(object, this);
@@ -3374,7 +3342,7 @@
}
@override
- TypeImpl withNullability(Nullability nullability) => this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
}
/**
@@ -3393,33 +3361,12 @@
/**
* The unique instance of this class, with indeterminate nullability.
*/
- static final VoidTypeImpl instance = instanceIndeterminate;
-
- /**
- * The unique instance of this class, nullable.
- */
- static final VoidTypeImpl instanceNullable =
- new VoidTypeImpl._(Nullability.nullable);
-
- /**
- * The unique instance of this class, with indeterminate nullability.
- */
- static final VoidTypeImpl instanceIndeterminate =
- new VoidTypeImpl._(Nullability.indeterminate);
-
- /**
- * The unique instance of this class, non-nullable.
- */
- static final VoidTypeImpl instanceNonNullable =
- new VoidTypeImpl._(Nullability.nonNullable);
-
- @override
- final Nullability nullability;
+ static final VoidTypeImpl instance = new VoidTypeImpl._();
/**
* Prevent the creation of instances of this class.
*/
- VoidTypeImpl._(this.nullability) : super(null, Keyword.VOID.lexeme);
+ VoidTypeImpl._() : super(null, Keyword.VOID.lexeme);
@override
int get hashCode => 2;
@@ -3428,6 +3375,9 @@
bool get isVoid => true;
@override
+ NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.none;
+
+ @override
bool operator ==(Object object) => identical(object, this);
@override
@@ -3464,16 +3414,9 @@
this;
@override
- TypeImpl withNullability(Nullability nullability) {
- switch (nullability) {
- case Nullability.nullable:
- return instanceNullable;
- case Nullability.indeterminate:
- return instanceIndeterminate;
- case Nullability.nonNullable:
- return instanceNonNullable;
- }
- throw StateError('Unexpected nullability: $nullability');
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ // The void type is always nullable.
+ return this;
}
}
@@ -3526,9 +3469,9 @@
this._returnType,
this._parameters,
this._isInstantiated,
- {Nullability nullability = Nullability.indeterminate})
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star})
: _typeParameters = null,
- super._(element, name, nullability);
+ super._(element, name, nullabilitySuffix);
/**
* Return the base parameter elements of this function element.
@@ -3735,7 +3678,7 @@
return new _FunctionTypeImplLazy._(element, name, prunedTypedefs,
newTypeArgs, _returnType, _parameters, true,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
@@ -3757,7 +3700,7 @@
.toList(growable: false);
return new _FunctionTypeImplLazy._(element, name, prune, typeArgs,
_returnType, _parameters, _isInstantiated,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
}
@@ -3786,15 +3729,15 @@
TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
return new _FunctionTypeImplLazy._(element, name, prune, typeArgs,
_returnType, _parameters, _isInstantiated,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
- TypeImpl withNullability(Nullability nullability) {
- if (this.nullability == nullability) return this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ if (this.nullabilitySuffix == nullabilitySuffix) return this;
return _FunctionTypeImplLazy._(element, name, prunedTypedefs,
_typeArguments, _returnType, _parameters, _isInstantiated,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
@@ -3842,8 +3785,8 @@
final List<ParameterElement> parameters;
_FunctionTypeImplStrict._(this.returnType, this.typeFormals, this.parameters,
- {Nullability nullability = Nullability.indeterminate})
- : super._(null, null, nullability);
+ {NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star})
+ : super._(null, null, nullabilitySuffix);
@override
List<TypeParameterElement> get boundTypeParameters => typeFormals;
@@ -3899,7 +3842,7 @@
returnType.substitute2(argumentTypes, parameterTypes),
const [],
_transformOrShare(parameters, transformParameter),
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
@@ -3959,14 +3902,14 @@
}
return new _FunctionTypeImplStrict._(
newReturnType, newTypeFormals, newParameters,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
- TypeImpl withNullability(Nullability nullability) {
- if (this.nullability == nullability) return this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+ if (this.nullabilitySuffix == nullabilitySuffix) return this;
return _FunctionTypeImplStrict._(returnType, typeFormals, parameters,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index b3fd95f..dbf57f9 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -8,6 +8,37 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
+/// Generates a fresh copy of the given type parameters, with their bounds
+/// substituted to reference the new parameters.
+///
+/// The returned object contains the fresh type parameter list as well as a
+/// mapping to be used for replacing other types to use the new type parameters.
+FreshTypeParameters getFreshTypeParameters(
+ List<TypeParameterElement> typeParameters) {
+ var freshParameters = new List<TypeParameterElementImpl>.generate(
+ typeParameters.length,
+ (i) => new TypeParameterElementImpl(typeParameters[i].name, -1),
+ growable: true,
+ );
+
+ var map = <TypeParameterElement, DartType>{};
+ for (int i = 0; i < typeParameters.length; ++i) {
+ map[typeParameters[i]] = new TypeParameterTypeImpl(freshParameters[i]);
+ }
+
+ var substitution = Substitution.fromMap(map);
+
+ for (int i = 0; i < typeParameters.length; ++i) {
+ var bound = typeParameters[i].bound;
+ if (bound != null) {
+ var newBound = substitution.substituteType(bound);
+ freshParameters[i].bound = newBound;
+ }
+ }
+
+ return new FreshTypeParameters(freshParameters, substitution);
+}
+
/// Returns a type where all occurrences of the given type parameters have been
/// replaced with the corresponding types.
///
@@ -27,6 +58,30 @@
return Substitution.fromMap(substitution).substituteType(type);
}
+class FreshTypeParameters {
+ final List<TypeParameterElement> freshTypeParameters;
+ final Substitution substitution;
+
+ FreshTypeParameters(this.freshTypeParameters, this.substitution);
+
+ FunctionType applyToFunctionType(FunctionType type) {
+ return new FunctionTypeImpl.synthetic(
+ substitute(type.returnType),
+ freshTypeParameters,
+ type.parameters.map((parameter) {
+ return ParameterElementImpl.synthetic(
+ parameter.name,
+ substitute(parameter.type),
+ // ignore: deprecated_member_use_from_same_package
+ parameter.parameterKind,
+ );
+ }).toList(),
+ );
+ }
+
+ DartType substitute(DartType type) => substitution.substituteType(type);
+}
+
abstract class Substitution {
static const Substitution empty = _NullSubstitution.instance;
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 64dcf19..ef261f3 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -178,6 +178,25 @@
"rename the function in the imported library.");
/**
+ * When "strict-inference" is enabled, collection literal types must be
+ * inferred via the context type, or have type arguments.
+ */
+ static const HintCode INFERENCE_FAILURE_ON_COLLECTION_LITERAL = HintCode(
+ 'INFERENCE_FAILURE_ON_COLLECTION_LITERAL',
+ "The type argument(s) of '{0}' cannot be inferred.",
+ correction: "Use explicit type argument(s) for '{0}'.");
+
+ /**
+ * When "strict-inference" is enabled, types in instance creation
+ * (constructor calls) must be inferred via the context type, or have type
+ * arguments.
+ */
+ static const HintCode INFERENCE_FAILURE_ON_INSTANCE_CREATION = HintCode(
+ 'INFERENCE_FAILURE_ON_INSTANCE_CREATION',
+ "The type argument(s) of '{0}' cannot be inferred.",
+ correction: "Use explicit type argument(s) for '{0}'.");
+
+ /**
* When "strict-inference" in enabled, uninitialized variables must be
* declared with a specific type.
*/
@@ -189,14 +208,6 @@
correction: "Try specifying the type of the variable.");
/**
- * When "strict-raw-types" is enabled, raw types must be inferred via the
- * context type, or have type arguments other than dynamic.
- */
- static const HintCode STRICT_RAW_TYPE = HintCode('STRICT_RAW_TYPE',
- "The generic type '{0}' should have explicit type arguments but doesn't.",
- correction: "Use explicit type arguments for '{0}'.");
-
- /**
* This hint is generated anywhere a @factory annotation is associated with
* anything other than a method.
*/
@@ -629,6 +640,14 @@
correction: "Try updating the SDK constraints.");
/**
+ * When "strict-raw-types" is enabled, raw types must be inferred via the
+ * context type, or have type arguments.
+ */
+ static const HintCode STRICT_RAW_TYPE = HintCode('STRICT_RAW_TYPE',
+ "The generic type '{0}' should have explicit type arguments but doesn't.",
+ correction: "Use explicit type arguments for '{0}'.");
+
+ /**
* This hint is generated anywhere where a `@sealed` class or mixin is used as
* a super-type of a class.
*/
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 6e31a4b..de2684c 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -65,7 +65,8 @@
static const ParserErrorCode COLON_IN_PLACE_OF_IN = _COLON_IN_PLACE_OF_IN;
- static const ParserErrorCode CONST_AFTER_FACTORY = _CONST_AFTER_FACTORY;
+ // TODO(danrubel): Remove this unused error code
+ static const ParserErrorCode CONST_AFTER_FACTORY = _MODIFIER_OUT_OF_ORDER;
static const ParserErrorCode CONST_AND_COVARIANT = _CONST_AND_COVARIANT;
@@ -521,6 +522,8 @@
"Can't have both positional and named parameters in a single parameter list.",
correction: "Try choosing a single style of optional parameters.");
+ static const ParserErrorCode MODIFIER_OUT_OF_ORDER = _MODIFIER_OUT_OF_ORDER;
+
static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES =
_MULTIPLE_EXTENDS_CLAUSES;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index b12e351..c02bde2 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -63,7 +63,7 @@
_CLASS_IN_CLASS,
_COLON_IN_PLACE_OF_IN,
_CONSTRUCTOR_WITH_RETURN_TYPE,
- _CONST_AFTER_FACTORY,
+ _MODIFIER_OUT_OF_ORDER,
_CONST_AND_COVARIANT,
_CONST_AND_FINAL,
_CONST_AND_VAR,
@@ -141,11 +141,6 @@
'CONSTRUCTOR_WITH_RETURN_TYPE', r"Constructors can't have a return type.",
correction: "Try removing the return type.");
-const ParserErrorCode _CONST_AFTER_FACTORY = const ParserErrorCode(
- 'CONST_AFTER_FACTORY',
- r"The modifier 'const' should be before the modifier 'factory'.",
- correction: "Try re-ordering the modifiers.");
-
const ParserErrorCode _CONST_AND_COVARIANT = const ParserErrorCode(
'CONST_AND_COVARIANT',
r"Members can't be declared to be both 'const' and 'covariant'.",
@@ -251,7 +246,7 @@
const ParserErrorCode _EXPERIMENT_NOT_ENABLED = const ParserErrorCode(
'EXPERIMENT_NOT_ENABLED',
- r"This requires the --#string experiment to be enabled.",
+ r"This requires the '#string' experiment to be enabled.",
correction:
"Try enabling this experiment by adding it to the command line when compiling and running.");
@@ -450,6 +445,11 @@
const ParserErrorCode _MISSING_STATEMENT =
const ParserErrorCode('MISSING_STATEMENT', r"Expected a statement.");
+const ParserErrorCode _MODIFIER_OUT_OF_ORDER = const ParserErrorCode(
+ 'MODIFIER_OUT_OF_ORDER',
+ r"The modifier '#string' should be before the modifier '#string2'.",
+ correction: "Try re-ordering the modifiers.");
+
const ParserErrorCode _MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
'MULTIPLE_EXTENDS_CLAUSES',
r"Each class definition can have at most one extends clause.",
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 570fc8f..5eda88c4 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -34,7 +34,7 @@
const CheckedModeCompileTimeErrorCode(
'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
"A value of type '{0}' can't be assigned to the field '{1}', which "
- "has type '{2}'.");
+ "has type '{2}'.");
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -45,7 +45,7 @@
const CheckedModeCompileTimeErrorCode(
'CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH',
"A value of type '{0}' can't be assigned to a parameter of type "
- "'{1}'.");
+ "'{1}'.");
/**
* 7.6.1 Generative Constructors: In checked mode, it is a dynamic type error
@@ -64,7 +64,7 @@
const CheckedModeCompileTimeErrorCode(
'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
"The initializer type '{0}' can't be assigned to the field type "
- "'{1}'.");
+ "'{1}'.");
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -74,7 +74,7 @@
const CheckedModeCompileTimeErrorCode(
'VARIABLE_TYPE_MISMATCH',
"A value of type '{0}' can't be assigned to a variable of type "
- "'{1}'.");
+ "'{1}'.");
/**
* Initialize a newly created error code to have the given [name]. The message
@@ -122,7 +122,7 @@
const CompileTimeErrorCode(
'ACCESS_PRIVATE_ENUM_FIELD',
"The private fields of an enum can't be accessed, even within the "
- "same library.");
+ "same library.");
/**
* 14.2 Exports: It is a compile-time error if a name <i>N</i> is re-exported
@@ -145,8 +145,8 @@
const CompileTimeErrorCode(
'AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH',
"This literal must be both a map and a set, because some elements "
- "spread a 'Map' and others spread an 'Iterable', but that isn't "
- "allowed.",
+ "spread a 'Map' and others spread an 'Iterable', but that isn't "
+ "allowed.",
correction:
"Try removing or changing some of the elements so that all of "
"the elements are consistent.");
@@ -155,8 +155,8 @@
const CompileTimeErrorCode(
'AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER',
"This literal must be either a map or a set, but none of the "
- "elements have enough type information to know which, and that isn't "
- "allowed.",
+ "elements have enough type information to know which, and that isn't "
+ "allowed.",
correction:
"Try adding type arguments to the literal (one for sets, two "
"for maps).");
@@ -297,7 +297,7 @@
const CompileTimeErrorCode(
'CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD',
"'{0}' can't be used to name both a constructor and a static field "
- "in this class.",
+ "in this class.",
correction: "Try renaming either the constructor or the field.");
/**
@@ -312,7 +312,7 @@
const CompileTimeErrorCode(
'CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD',
"'{0}' can't be used to name both a constructor and a static method "
- "in this class.",
+ "in this class.",
correction: "Try renaming either the constructor or the method.");
/**
@@ -329,7 +329,7 @@
const CompileTimeErrorCode(
'CONFLICTING_FIELD_AND_METHOD',
"Class '{0}' can't define field '{1}' and have method '{2}.{1}' "
- "with the same name.",
+ "with the same name.",
correction: "Try converting the getter to a method, or "
"renaming the field to a name that doesn't conflict.");
@@ -348,7 +348,7 @@
const CompileTimeErrorCode(
'CONFLICTING_GENERIC_INTERFACES',
"The class '{0}' cannot implement both '{1}' and '{2}' because the "
- "type arguments are different.");
+ "type arguments are different.");
/**
* 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
@@ -364,7 +364,7 @@
const CompileTimeErrorCode(
'CONFLICTING_METHOD_AND_FIELD',
"Class '{0}' can't define method '{1}' and have field '{2}.{1}' "
- "with the same name.",
+ "with the same name.",
correction: "Try converting the method to a getter, or "
"renaming the method to a name that doesn't conflict.");
@@ -382,7 +382,7 @@
const CompileTimeErrorCode(
'CONFLICTING_STATIC_AND_INSTANCE',
"Class '{0}' can't define static member '{1}' and have instance "
- "member '{2}.{1}' with the same name.",
+ "member '{2}.{1}' with the same name.",
correction:
"Try renaming the member to a name that doesn't conflict.");
@@ -398,7 +398,7 @@
const CompileTimeErrorCode(
'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
"'{0}' can't be used to name both a type variable and the class in "
- "which the type variable is defined.",
+ "which the type variable is defined.",
correction: "Try renaming either the type variable or the class.");
/**
@@ -413,7 +413,7 @@
const CompileTimeErrorCode(
'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
"'{0}' can't be used to name both a type variable and a member in "
- "this class.",
+ "this class.",
correction: "Try renaming either the type variable or the member.");
/**
@@ -439,7 +439,7 @@
const CompileTimeErrorCode(
'CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST',
"Can't define the const constructor because the field '{0}' "
- "is initialized with a non-constant value.",
+ "is initialized with a non-constant value.",
correction: "Try initializing the field to a constant value, or "
"removing the keyword 'const' from the constructor.");
@@ -458,7 +458,7 @@
const CompileTimeErrorCode(
'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
"Const constructor can't be declared for a class with a mixin "
- "that declares an instance field.",
+ "that declares an instance field.",
correction: "Try removing the 'const' keyword or "
"removing the 'with' clause from the class declaration, "
"or removing fields from the mixin class.");
@@ -476,7 +476,7 @@
const CompileTimeErrorCode(
'CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER',
"Constant constructor can't call non-constant super constructor of "
- "'{0}'.",
+ "'{0}'.",
correction: "Try calling a const constructor in the superclass, or "
"removing the keyword 'const' from the constructor.");
@@ -532,7 +532,7 @@
const CompileTimeErrorCode(
'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used to "
- "initialized a const variable.",
+ "initialized a const variable.",
correction:
"Try initializing the variable without referencing members of the "
"deferred library, or "
@@ -569,7 +569,7 @@
const CompileTimeErrorCode(
'CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS',
"The constant map entry key expression type '{0}' can't override "
- "the == operator.",
+ "the == operator.",
correction: "Try using a different value for the key, or "
"removing the keyword 'const' from the map.");
@@ -593,7 +593,7 @@
const CompileTimeErrorCode(
'CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS',
"The constant set element type '{0}' can't override "
- "the == operator.",
+ "the == operator.",
correction: "Try using a different value for the element, or "
"removing the keyword 'const' from the set.");
@@ -606,7 +606,7 @@
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_BOOL',
"In constant expressions, operands of this operator must be of type "
- "'bool'.");
+ "'bool'.");
/**
* 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
@@ -617,7 +617,7 @@
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_BOOL_INT',
"In constant expressions, operands of this operator must be of type "
- "'bool' or 'int'.");
+ "'bool' or 'int'.");
/**
* 16.12.2 Const: An expression of one of the forms e1 == e2 or e1 != e2 where
@@ -628,7 +628,7 @@
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_BOOL_NUM_STRING',
"In constant expressions, operands of this operator must be of type "
- "'bool', 'num', 'String' or 'null'.");
+ "'bool', 'num', 'String' or 'null'.");
/**
* 16.12.2 Const: An expression of one of the forms ~e, e1 ^ e2, e1 & e2,
@@ -639,7 +639,7 @@
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_INT',
"In constant expressions, operands of this operator must be of type "
- "'int'.");
+ "'int'.");
/**
* 16.12.2 Const: An expression of one of the forms e, e1 + e2, e1 - e2, e1 *
@@ -651,13 +651,13 @@
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_NUM',
"In constant expressions, operands of this operator must be of type "
- "'num'.");
+ "'num'.");
static const CompileTimeErrorCode CONST_EVAL_TYPE_TYPE =
const CompileTimeErrorCode(
'CONST_EVAL_TYPE_TYPE',
"In constant expressions, operands of this operator must be of type "
- "'Type'.");
+ "'Type'.");
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -675,7 +675,7 @@
const CompileTimeErrorCode(
'CONST_EVAL_THROWS_IDBZE',
"Evaluation of this constant expression throws an "
- "IntegerDivisionByZeroException.");
+ "IntegerDivisionByZeroException.");
/**
* 16.12.2 Const: If <i>T</i> is a parameterized type <i>S<U<sub>1</sub>,
@@ -694,7 +694,7 @@
const CompileTimeErrorCode(
'CONST_WITH_INVALID_TYPE_PARAMETERS',
"The type '{0}' is declared with {1} type parameters, but {2} type "
- "arguments were given.",
+ "arguments were given.",
correction:
"Try adjusting the number of type arguments to match the number of "
"type parameters.");
@@ -804,7 +804,7 @@
const CompileTimeErrorCode(
'DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR',
"Default values aren't allowed in factory constructors that redirect "
- "to another constructor.",
+ "to another constructor.",
correction: "Try removing the default value.");
/**
@@ -1038,7 +1038,7 @@
const CompileTimeErrorCode(
'FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER',
"Fields can't be initialized in both the parameter list and the "
- "initializers.",
+ "initializers.",
correction: "Try removing one of the initializations.");
/**
@@ -1273,7 +1273,7 @@
const CompileTimeErrorCode(
'INCONSISTENT_INHERITANCE_GETTER_AND_METHOD',
"'{0}' is inherited as a getter (from '{1}') and also a "
- "method (from '{2}').",
+ "method (from '{2}').",
correction:
"Try adjusting the supertypes of this class to remove the "
"inconsistency.");
@@ -1312,7 +1312,7 @@
const CompileTimeErrorCode(
'INITIALIZER_FOR_STATIC_FIELD',
"'{0}' is a static field in the enclosing class. Fields initialized "
- "in a constructor can't be static.",
+ "in a constructor can't be static.",
correction: "Try removing the initialization.");
/**
@@ -1348,7 +1348,7 @@
const CompileTimeErrorCode(
'INITIALIZING_FORMAL_FOR_STATIC_FIELD',
"'{0}' is a static field in the enclosing class. Fields initialized "
- "in a constructor can't be static.",
+ "in a constructor can't be static.",
correction: "Try removing the initialization.");
/**
@@ -1396,8 +1396,8 @@
const CompileTimeErrorCode(
'INTEGER_LITERAL_IMPRECISE_AS_DOUBLE',
"The integer literal is being used as a double, but can't be "
- 'represented as a 64 bit double without overflow and/or loss of '
- 'precision: {0}',
+ 'represented as a 64 bit double without overflow and/or loss of '
+ 'precision: {0}',
correction:
'Try using the BigInt class, or switch to the closest valid '
'double: {1}');
@@ -1412,7 +1412,7 @@
const CompileTimeErrorCode(
'INVALID_ANNOTATION',
"Annotation must be either a const variable reference or const "
- "constructor invocation.");
+ "constructor invocation.");
/**
* 15 Metadata: Metadata consists of a series of annotations, each of which
@@ -1484,7 +1484,7 @@
const CompileTimeErrorCode(
'INVALID_FACTORY_NAME_NOT_A_CLASS',
"The name of a factory constructor must be the same as the name of "
- "the immediately enclosing class.");
+ "the immediately enclosing class.");
static const CompileTimeErrorCode INVALID_INLINE_FUNCTION_TYPE =
const CompileTimeErrorCode('INVALID_INLINE_FUNCTION_TYPE',
@@ -1533,7 +1533,7 @@
const CompileTimeErrorCode(
'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
"Constant list literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
+ "argument, such as '{0}'.",
correction:
"Try replacing the type parameter with a different type.");
@@ -1548,7 +1548,7 @@
const CompileTimeErrorCode(
'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
"Constant map literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
+ "argument, such as '{0}'.",
correction:
"Try replacing the type parameter with a different type.");
@@ -1556,7 +1556,7 @@
const CompileTimeErrorCode(
'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
"Constant set literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
+ "argument, such as '{0}'.",
correction:
"Try replacing the type parameter with a different type.");
@@ -1567,7 +1567,7 @@
const CompileTimeErrorCode(
'INVALID_USE_OF_COVARIANT',
"The 'covariant' keyword can only be used for parameters in instance "
- "methods or before non-final instance fields.",
+ "methods or before non-final instance fields.",
correction: "Try removing the 'covariant' keyword.");
/**
@@ -1643,7 +1643,7 @@
const CompileTimeErrorCode(
'MISSING_CONST_IN_LIST_LITERAL',
"List literals must be prefixed with 'const' when used as a constant "
- "expression.",
+ "expression.",
correction: "Try adding the keyword 'const' before the literal.");
/**
@@ -1653,7 +1653,7 @@
const CompileTimeErrorCode(
'MISSING_CONST_IN_MAP_LITERAL',
"Map literals must be prefixed with 'const' when used as a constant "
- "expression.",
+ "expression.",
correction: "Try adding the keyword 'const' before the literal.");
/**
@@ -1663,7 +1663,7 @@
const CompileTimeErrorCode(
'MISSING_CONST_IN_SET_LITERAL',
"Set literals must be prefixed with 'const' when used as a constant "
- "expression.",
+ "expression.",
correction: "Try adding the keyword 'const' before the literal.");
static const CompileTimeErrorCode MISSING_DART_LIBRARY =
@@ -1691,7 +1691,7 @@
const CompileTimeErrorCode(
'MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE',
"The super-invoked member '{0}' has the type '{1}', but the "
- "concrete member in the class has type '{2}'.");
+ "concrete member in the class has type '{2}'.");
/**
* It's a compile-time error to apply a mixin to a class that doesn't
@@ -1719,7 +1719,7 @@
const CompileTimeErrorCode(
'MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER',
"The class doesn't have a concrete implementation of the "
- "super-invoked member '{0}'.");
+ "super-invoked member '{0}'.");
/**
* 9 Mixins: It is a compile-time error if a declared or derived mixin
@@ -1732,7 +1732,7 @@
const CompileTimeErrorCode(
'MIXIN_CLASS_DECLARES_CONSTRUCTOR',
"The class '{0}' can't be used as a mixin because it declares a "
- "constructor.");
+ "constructor.");
/**
* The <i>mixinMember</i> production allows the same instance or static
@@ -1761,22 +1761,22 @@
const CompileTimeErrorCode(
'MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES',
"Type parameters could not be inferred for the mixin '{0}' because "
- "the base class implements the mixin's supertype constraint "
- "'{1}' in multiple conflicting ways");
+ "the base class implements the mixin's supertype constraint "
+ "'{1}' in multiple conflicting ways");
static const CompileTimeErrorCode MIXIN_INFERENCE_NO_MATCHING_CLASS =
const CompileTimeErrorCode(
'MIXIN_INFERENCE_NO_MATCHING_CLASS',
"Type parameters could not be inferred for the mixin '{0}' because "
- "the base class does not implement the mixin's supertype "
- "constraint '{1}'");
+ "the base class does not implement the mixin's supertype "
+ "constraint '{1}'");
static const CompileTimeErrorCode MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION =
const CompileTimeErrorCode(
'MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION',
"Type parameters could not be inferred for the mixin '{0}' because "
- "no type parameter substitution could be found matching the mixin's "
- "supertype constraints");
+ "no type parameter substitution could be found matching the mixin's "
+ "supertype constraints");
/**
* 9 Mixins: It is a compile-time error if a mixin is derived from a class
@@ -1789,7 +1789,7 @@
const CompileTimeErrorCode(
'MIXIN_INHERITS_FROM_NOT_OBJECT',
"The class '{0}' can't be used as a mixin because it extends a class "
- "other than Object.");
+ "other than Object.");
/**
* A mixin declaration introduces a mixin and an interface, but not a class.
@@ -1842,7 +1842,7 @@
const CompileTimeErrorCode(
'MIXIN_REFERENCES_SUPER',
"The class '{0}' can't be used as a mixin because it references "
- "'super'.");
+ "'super'.");
static const CompileTimeErrorCode
MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS = const CompileTimeErrorCode(
@@ -1958,7 +1958,7 @@
const CompileTimeErrorCode(
'NON_CONST_MAP_AS_EXPRESSION_STATEMENT',
"A non-constant map or set literal without type arguments can't be "
- "used as an expression statement.");
+ "used as an expression statement.");
/**
* 13.9 Switch: Given a switch statement of the form <i>switch (e) {
@@ -1994,7 +1994,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as a case "
- "expression.",
+ "expression.",
correction:
"Try re-writing the switch as a series of if statements, or "
"changing the import to not be deferred.");
@@ -2019,7 +2019,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as a default "
- "parameter value.",
+ "parameter value.",
correction:
"Try leaving the default as null and initializing the parameter "
"inside the function body.");
@@ -2046,7 +2046,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as values in "
- "a 'const' list.",
+ "a 'const' list.",
correction:
"Try removing the keyword 'const' from the list literal.");
@@ -2070,7 +2070,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as keys in a "
- "const map literal.",
+ "const map literal.",
correction: "Try removing the keyword 'const' from the map literal.");
/**
@@ -2102,7 +2102,7 @@
NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY = const CompileTimeErrorCode(
'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as values in "
- "a const map literal.",
+ "a const map literal.",
correction: "Try removing the keyword 'const' from the map literal.");
/**
@@ -2128,7 +2128,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be spread into a "
- "const literal.",
+ "const literal.",
correction: "Try making the deferred import non-deferred.");
static const CompileTimeErrorCode
@@ -2136,7 +2136,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as values in "
- "an if condition inside a const collection literal.",
+ "an if condition inside a const collection literal.",
correction: "Try making the deferred import non-deferred.");
static const CompileTimeErrorCode
@@ -2144,7 +2144,7 @@
const CompileTimeErrorCode(
'NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY',
"Constant values from a deferred library can't be used as values in "
- "a 'const' set.",
+ "a 'const' set.",
correction: "Try removing the keyword 'const' from the set literal.");
/**
@@ -2203,6 +2203,53 @@
"making the called constructor not be a factory constructor.");
/**
+ * It is an error if the type `T` in the on-catch clause `on T catch` is
+ * potentially nullable.
+ */
+ static const CompileTimeErrorCode NULLABLE_TYPE_IN_CATCH_CLAUSE =
+ const CompileTimeErrorCode(
+ 'NULLABLE_TYPE_IN_CATCH_CLAUSE',
+ "A nullable type cannot be used in an 'on' clause because it isn't valid "
+ "to throw 'null'.",
+ correction: "Try removing the question mark.");
+
+ /**
+ * It is a compile-time error for a class to extend, implement, or mixin a
+ * type of the form T? for any T.
+ */
+ static const CompileTimeErrorCode NULLABLE_TYPE_IN_EXTENDS_CLAUSE =
+ const CompileTimeErrorCode('NULLABLE_TYPE_IN_EXTENDS_CLAUSE',
+ "A class cannot extend a nullable type.",
+ correction: "Try removing the question mark.");
+
+ /**
+ * It is a compile-time error for a class to extend, implement, or mixin a
+ * type of the form T? for any T.
+ */
+ static const CompileTimeErrorCode NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE =
+ const CompileTimeErrorCode('NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE',
+ "A class or mixin cannot implement a nullable type.",
+ correction: "Try removing the question mark.");
+
+ /**
+ * It is a compile-time error for a class to extend, implement, or mixin a
+ * type of the form T? for any T.
+ */
+ static const CompileTimeErrorCode NULLABLE_TYPE_IN_ON_CLAUSE =
+ const CompileTimeErrorCode('NULLABLE_TYPE_IN_ON_CLAUSE',
+ "A mixin cannot have a nullable type as a superclass constraint.",
+ correction: "Try removing the question mark.");
+
+ /**
+ * It is a compile-time error for a class to extend, implement, or mixin a
+ * type of the form T? for any T.
+ */
+ static const CompileTimeErrorCode NULLABLE_TYPE_IN_WITH_CLAUSE =
+ const CompileTimeErrorCode('NULLABLE_TYPE_IN_WITH_CLAUSE',
+ "A class or mixin cannot mix in a nullable type.",
+ correction: "Try removing the question mark.");
+
+ /**
* 7.9 Superclasses: It is a compile-time error to specify an extends clause
* for class Object.
*/
@@ -2252,7 +2299,7 @@
const CompileTimeErrorCode(
'PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER',
"The name '{0}' is already used as an import prefix and can't be "
- "used to name a top-level element.",
+ "used to name a top-level element.",
correction:
"Try renaming either the top-level element or the prefix.");
@@ -2264,7 +2311,7 @@
const CompileTimeErrorCode(
'PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT',
"The name '{0}' refers to an import prefix, so it must be followed "
- "by '.'.",
+ "by '.'.",
correction:
"Try correcting the name to refer to something other than a prefix, or "
"renaming the prefix.");
@@ -2277,7 +2324,7 @@
const CompileTimeErrorCode(
'PRIVATE_COLLISION_IN_MIXIN_APPLICATION',
"The private name '{0}', defined by '{1}', "
- "conflicts with the same name defined by '{2}'.",
+ "conflicts with the same name defined by '{2}'.",
correction: "Try removing '{1}' from the 'with' clause.");
/**
@@ -2414,7 +2461,7 @@
const CompileTimeErrorCode(
'REDIRECT_TO_NON_CLASS',
"The name '{0}' isn't a type and can't be used in a redirected "
- "constructor.",
+ "constructor.",
correction: "Try redirecting to a different constructor.");
/**
@@ -2425,7 +2472,7 @@
const CompileTimeErrorCode(
'REDIRECT_TO_NON_CONST_CONSTRUCTOR',
"Constant factory constructor can't delegate to a non-constant "
- "constructor.",
+ "constructor.",
correction: "Try redirecting to a different constructor.");
/**
@@ -2503,7 +2550,7 @@
const CompileTimeErrorCode(
'SHARED_DEFERRED_PREFIX',
"The prefix of a deferred import can't be used in other import "
- "directives.",
+ "directives.",
correction: "Try renaming one of the prefixes.");
/**
@@ -2596,7 +2643,7 @@
const CompileTimeErrorCode(
'TYPE_ALIAS_CANNOT_REFERENCE_ITSELF',
"Typedefs can't reference themselves directly or recursively via "
- "another typedef.");
+ "another typedef.");
static const CompileTimeErrorCode TYPE_PARAMETER_ON_CONSTRUCTOR =
const CompileTimeErrorCode('TYPE_PARAMETER_ON_CONSTRUCTOR',
@@ -2776,7 +2823,7 @@
const CompileTimeErrorCode(
'YIELD_EACH_IN_NON_GENERATOR',
"Yield-each statements must be in a generator function "
- "(one marked with either 'async*' or 'sync*').",
+ "(one marked with either 'async*' or 'sync*').",
correction:
"Try adding 'async*' or 'sync*' to the enclosing function.");
@@ -2788,7 +2835,7 @@
const CompileTimeErrorCode(
'YIELD_IN_NON_GENERATOR',
"Yield statements must be in a generator function "
- "(one marked with either 'async*' or 'sync*').",
+ "(one marked with either 'async*' or 'sync*').",
correction:
"Try adding 'async*' or 'sync*' to the enclosing function.");
@@ -2829,7 +2876,7 @@
const StaticTypeWarningCode(
'EXPECTED_ONE_LIST_TYPE_ARGUMENTS',
"List literals require exactly one type argument or none, "
- "but {0} found.",
+ "but {0} found.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -2840,7 +2887,7 @@
const StaticTypeWarningCode(
'EXPECTED_ONE_SET_TYPE_ARGUMENTS',
"Set literals require exactly one type argument or none, "
- "but {0} found.",
+ "but {0} found.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -2854,7 +2901,7 @@
const StaticTypeWarningCode(
'EXPECTED_TWO_MAP_TYPE_ARGUMENTS',
"Map literals require exactly two type arguments or none, "
- "but {0} found.",
+ "but {0} found.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -2865,7 +2912,7 @@
const StaticTypeWarningCode(
'ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE',
"Functions marked 'async*' must have a return type assignable to "
- "'Stream'.",
+ "'Stream'.",
correction: "Try fixing the return type of the function, or "
"removing the modifier 'async*' from the function body.");
@@ -2877,7 +2924,7 @@
const StaticTypeWarningCode(
'ILLEGAL_ASYNC_RETURN_TYPE',
"Functions marked 'async' must have a return type assignable to "
- "'Future'.",
+ "'Future'.",
correction: "Try fixing the return type of the function, or "
"removing the modifier 'async' from the function body.");
@@ -3211,7 +3258,7 @@
const StaticTypeWarningCode(
'UNDEFINED_PREFIXED_NAME',
"The name '{0}' is being referenced through the prefix '{1}', but it "
- "isn't defined in any of the libraries imported using that prefix.",
+ "isn't defined in any of the libraries imported using that prefix.",
correction: "Try correcting the prefix or "
"importing the library that defines '{0}'.");
@@ -3339,7 +3386,7 @@
const StaticTypeWarningCode(
'WRONG_NUMBER_OF_TYPE_ARGUMENTS',
"The type '{0}' is declared with {1} type parameters, "
- "but {2} type arguments were given.",
+ "but {2} type arguments were given.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -3369,7 +3416,7 @@
const StaticTypeWarningCode(
'WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD',
"The method '{0}' is declared with {1} type parameters, "
- "but {2} type arguments were given.",
+ "but {2} type arguments were given.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -3394,7 +3441,7 @@
const StaticTypeWarningCode(
'YIELD_OF_INVALID_TYPE',
"The type '{0}' implied by the 'yield' expression must be assignable "
- "to '{1}'.");
+ "to '{1}'.");
/**
* 17.6.2 For-in. If the iterable expression does not implement Iterable,
@@ -3422,7 +3469,7 @@
const StaticTypeWarningCode(
'FOR_IN_OF_INVALID_ELEMENT_TYPE',
"The type '{0}' used in the 'for' loop must implement {1} with a "
- "type argument that can be assigned to '{2}'.");
+ "type argument that can be assigned to '{2}'.");
/**
* Initialize a newly created error code to have the given [name]. The message
@@ -3584,7 +3631,7 @@
const StaticWarningCode(
'CASE_BLOCK_NOT_TERMINATED',
"The last statement of the 'case' should be 'break', 'continue', "
- "'rethrow', 'return' or 'throw'.",
+ "'rethrow', 'return' or 'throw'.",
correction: "Try adding one of the required statements.");
/**
@@ -3677,7 +3724,7 @@
const StaticWarningCode(
'FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION',
"Fields can't be initialized in the constructor if they are final "
- "and have already been initialized at their declaration.",
+ "and have already been initialized at their declaration.",
correction: "Try removing one of the initializations.");
/**
@@ -3693,7 +3740,7 @@
const StaticWarningCode(
'FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR',
"'{0}' is final and was given a value when it was declared, "
- "so it can't be set to a new value.",
+ "so it can't be set to a new value.",
correction: "Try removing one of the initializations.");
/**
@@ -3841,7 +3888,7 @@
INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = const StaticWarningCode(
'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
"Parameters can't override default values, "
- "this method overrides '{0}.{1}' where '{2}' has a different value.",
+ "this method overrides '{0}.{1}' where '{2}' has a different value.",
correction: "Try using the same default value in both methods.",
errorSeverity: ErrorSeverity.WARNING);
@@ -3857,7 +3904,7 @@
const StaticWarningCode(
'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
"Parameters can't override default values, this method overrides "
- "'{0}.{1}' where this positional parameter has a different value.",
+ "'{0}.{1}' where this positional parameter has a different value.",
correction: "Try using the same default value in both methods.",
errorSeverity: ErrorSeverity.WARNING);
@@ -3935,7 +3982,7 @@
const StaticWarningCode(
'MISMATCHED_GETTER_AND_SETTER_TYPES',
"The return type of getter '{0}' is '{1}' which isn't assignable "
- "to the type '{2}' of its setter '{3}'.",
+ "to the type '{2}' of its setter '{3}'.",
correction: "Try changing the types so that they are compatible.");
/**
@@ -3995,7 +4042,7 @@
const StaticWarningCode(
'NEW_WITH_INVALID_TYPE_PARAMETERS',
"The type '{0}' is declared with {1} type parameters, "
- "but {2} type arguments were given.",
+ "but {2} type arguments were given.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -4353,7 +4400,7 @@
const StaticWarningCode(
'SWITCH_EXPRESSION_NOT_ASSIGNABLE',
"Type '{0}' of the switch expression isn't assignable to "
- "the type '{1}' of case expressions.");
+ "the type '{1}' of case expressions.");
/**
* 15.1 Static Types: It is a static warning to use a deferred type in a type
@@ -4477,7 +4524,7 @@
const StaticWarningCode(
'UNCHECKED_USE_OF_NULLABLE_VALUE',
'The expression is nullable and must be null-checked before it can be'
- ' used.',
+ ' used.',
correction:
'Try casting or check the value is not null before using it.');
@@ -4603,29 +4650,29 @@
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_LITERAL_LIST',
"The list literal type '{0}' isn't of expected type '{1}'. The list's "
- "type can be changed with an explicit generic type argument or by "
- "changing the element types.");
+ "type can be changed with an explicit generic type argument or by "
+ "changing the element types.");
static const StrongModeCode INVALID_CAST_LITERAL_MAP = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_LITERAL_MAP',
"The map literal type '{0}' isn't of expected type '{1}'. The maps's "
- "type can be changed with an explicit generic type arguments or by "
- "changing the key and value types.");
+ "type can be changed with an explicit generic type arguments or by "
+ "changing the key and value types.");
static const StrongModeCode INVALID_CAST_LITERAL_SET = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_LITERAL_SET',
"The set literal type '{0}' isn't of expected type '{1}'. The set's "
- "type can be changed with an explicit generic type argument or by "
- "changing the element types.");
+ "type can be changed with an explicit generic type argument or by "
+ "changing the element types.");
static const StrongModeCode INVALID_CAST_FUNCTION_EXPR = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_FUNCTION_EXPR',
"The function expression type '{0}' isn't of type '{1}'. "
- "This means its parameter or return type does not match what is "
- "expected. Consider changing parameter type(s) or the returned type(s).");
+ "This means its parameter or return type does not match what is "
+ "expected. Consider changing parameter type(s) or the returned type(s).");
static const StrongModeCode INVALID_CAST_NEW_EXPR = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
@@ -4636,21 +4683,21 @@
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_METHOD',
"The method tear-off '{0}' has type '{1}' that isn't of expected type "
- "'{2}'. This means its parameter or return type does not match what is "
- "expected.");
+ "'{2}'. This means its parameter or return type does not match what is "
+ "expected.");
static const StrongModeCode INVALID_CAST_FUNCTION = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_FUNCTION',
"The function '{0}' has type '{1}' that isn't of expected type "
- "'{2}'. This means its parameter or return type does not match what is "
- "expected.");
+ "'{2}'. This means its parameter or return type does not match what is "
+ "expected.");
static const StrongModeCode INVALID_SUPER_INVOCATION = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_SUPER_INVOCATION',
"super call must be last in an initializer "
- "list (see https://goo.gl/EY6hDP): '{0}'.");
+ "list (see https://goo.gl/EY6hDP): '{0}'.");
static const StrongModeCode NON_GROUND_TYPE_CHECK_INFO = const StrongModeCode(
ErrorType.HINT,
@@ -4758,14 +4805,14 @@
ErrorType.STATIC_WARNING,
'TOP_LEVEL_INSTANCE_GETTER',
"The type of '{0}' can't be inferred because it refers to an instance "
- "getter, '{1}', which has an implicit type.",
+ "getter, '{1}', which has an implicit type.",
correction: "Add an explicit type for either '{0}' or '{1}'.");
static const StrongModeCode TOP_LEVEL_INSTANCE_METHOD = const StrongModeCode(
ErrorType.STATIC_WARNING,
'TOP_LEVEL_INSTANCE_METHOD',
"The type of '{0}' can't be inferred because it refers to an instance "
- "method, '{1}', which has an implicit type.",
+ "method, '{1}', which has an implicit type.",
correction: "Add an explicit type for either '{0}' or '{1}'.");
@override
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 1a75a35..22634cd 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -56,8 +56,9 @@
show NullValue, StackListener;
import 'package:front_end/src/scanner/errors.dart' show translateErrorToken;
import 'package:front_end/src/scanner/token.dart'
- show SyntheticStringToken, SyntheticToken;
+ show CommentToken, SyntheticStringToken, SyntheticToken;
import 'package:kernel/ast.dart' show AsyncMarker;
+import 'package:pub_semver/pub_semver.dart';
const _invalidCollectionElement = const _InvalidCollectionElement._();
@@ -68,6 +69,7 @@
final FastaErrorReporter errorReporter;
final Uri fileUri;
ScriptTag scriptTag;
+ Version languageVersion;
final List<Directive> directives = <Directive>[];
final List<CompilationUnitMember> declarations = <CompilationUnitMember>[];
final localDeclarations = <int, AstNode>{};
@@ -482,6 +484,7 @@
CompilationUnitImpl unit = ast.compilationUnit(
beginToken, scriptTag, directives, declarations, endToken)
as CompilationUnitImpl;
+ unit.languageVersion = languageVersion;
unit.isNonNullable = enableNonNullable;
push(unit);
}
@@ -2470,6 +2473,16 @@
push(ast.label(name, colon));
}
+ @override
+ void handleLanguageVersion(Token commentToken, int major, int minor) {
+ debugEvent('LanguageVersion');
+ assert(commentToken is CommentToken);
+ assert(major != null);
+ assert(minor != null);
+
+ languageVersion = Version(major, minor, 0);
+ }
+
void handleLiteralBool(Token token) {
bool value = identical(token.stringValue, "true");
assert(value || identical(token.stringValue, "false"));
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 1b53d3f..27097db 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -536,6 +536,11 @@
@override
void visitPostfixExpression(PostfixExpression node) {
Expression operand = node.operand;
+ if (node.operator.type == TokenType.BANG) {
+ // Null-assertion operator (`!`). There's nothing to do, since this is a
+ // built-in operation (there's no associated operator declaration).
+ return;
+ }
String methodName = _getPostfixOperator(node);
DartType staticType = _getStaticType(operand);
MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 0c23f5c..c37d478 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -857,6 +857,16 @@
String extension = FileNameUtilities.getExtension(fileName).toLowerCase();
return extension == SUFFIX_DART;
}
+
+ /**
+ * Return `true` if the given [fileName] is AndroidManifest.xml
+ */
+ static bool isManifestFileName(String fileName) {
+ if (fileName == null) {
+ return false;
+ }
+ return fileName.endsWith(AnalysisEngine.ANDROID_MANIFEST_FILE);
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 236bfe4..7f2f741 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -473,6 +473,7 @@
try {
_isInCatchClause = true;
_checkForTypeAnnotationDeferredClass(node.exceptionType);
+ _checkForPotentiallyNullableType(node.exceptionType);
super.visitCatchClause(node);
} finally {
_isInCatchClause = previousIsInCatchClause;
@@ -994,7 +995,7 @@
_checkTypeArgumentCount(typeArguments, 1,
StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
}
- _checkForRawTypedLiteral(node);
+ _checkForInferenceFailureOnCollectionLiteral(node);
_checkForImplicitDynamicTypedLiteral(node);
_checkForListElementTypeNotAssignable(node);
@@ -1103,9 +1104,11 @@
@override
void visitPostfixExpression(PostfixExpression node) {
- _checkForAssignmentToFinal(node.operand);
- _checkForIntNotAssignable(node.operand);
- _checkForNullableDereference(node.operand);
+ if (node.operator.type != TokenType.BANG) {
+ _checkForAssignmentToFinal(node.operand);
+ _checkForIntNotAssignable(node.operand);
+ _checkForNullableDereference(node.operand);
+ }
super.visitPostfixExpression(node);
}
@@ -1201,7 +1204,7 @@
_checkTypeArgumentCount(typeArguments, 2,
StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
}
- _checkForRawTypedLiteral(node);
+ _checkForInferenceFailureOnCollectionLiteral(node);
_checkForImplicitDynamicTypedLiteral(node);
_checkForMapTypeNotAssignable(node);
_checkForNonConstMapAsExpressionStatement3(node);
@@ -1217,7 +1220,7 @@
_checkTypeArgumentCount(typeArguments, 1,
StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
}
- _checkForRawTypedLiteral(node);
+ _checkForInferenceFailureOnCollectionLiteral(node);
_checkForImplicitDynamicTypedLiteral(node);
_checkForSetElementTypeNotAssignable3(node);
}
@@ -1315,7 +1318,12 @@
@override
void visitTypeName(TypeName node) {
_checkForTypeArgumentNotMatchingBounds(node);
- _checkForRawTypeName(node);
+ if (node.parent is ConstructorName &&
+ node.parent.parent is InstanceCreationExpression) {
+ _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
+ } else {
+ _checkForRawTypeName(node);
+ }
super.visitTypeName(node);
}
@@ -3666,6 +3674,46 @@
[directive.uri.stringValue]);
}
+ /// Checks a collection literal for an inference failure, and reports the
+ /// appropriate error if [AnalysisOptionsImpl.strictInference] is set.
+ ///
+ /// This checks if [node] does not have explicit or inferred type arguments.
+ /// When that happens, it reports a
+ /// HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL error.
+ void _checkForInferenceFailureOnCollectionLiteral(TypedLiteral node) {
+ if (!_options.strictInference || node == null) return;
+ if (node.typeArguments != null) {
+ // Type has explicit type arguments.
+ return;
+ }
+ var type = node.staticType;
+ if (_isMissingTypeArguments(node, type, type.element, node)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, node, [type.name]);
+ }
+ }
+
+ /// Checks a type on an instance creation expression for an inference
+ /// failure, and reports the appropriate error if
+ /// [AnalysisOptionsImpl.strictInference] is set.
+ ///
+ /// This checks if [node] refers to a generic type and does not have explicit
+ /// or inferred type arguments. When that happens, it reports a
+ /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
+ void _checkForInferenceFailureOnInstanceCreation(
+ TypeName node, InstanceCreationExpression inferenceContextNode) {
+ if (!_options.strictInference || node == null) return;
+ if (node.typeArguments != null) {
+ // Type has explicit type arguments.
+ return;
+ }
+ if (_isMissingTypeArguments(
+ node, node.type, node.name.staticElement, inferenceContextNode)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
+ }
+ }
+
/**
* Check that the given [typeReference] is not a type reference and that then
* the [name] is reference to an instance member.
@@ -4549,8 +4597,8 @@
if (expression == null ||
!_isNonNullable ||
expression.staticType == null ||
- (expression.staticType as TypeImpl).nullability !=
- Nullability.nullable) {
+ (expression.staticType as TypeImpl).nullabilitySuffix !=
+ NullabilitySuffix.question) {
return false;
}
@@ -4671,6 +4719,18 @@
}
/**
+ * Verify that the [type] is not potentially nullable.
+ */
+ void _checkForPotentiallyNullableType(TypeAnnotation type) {
+ if (_options.experimentStatus.non_nullable &&
+ type?.type != null &&
+ _typeSystem.isPotentiallyNullable(type.type)) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, type);
+ }
+ }
+
+ /**
* Check that the given named optional [parameter] does not begin with '_'.
*
* See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER].
@@ -4692,60 +4752,6 @@
CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
}
- /// Similar to [_checkForRawTypeName] but for list/map/set literals.
- void _checkForRawTypedLiteral(TypedLiteral node) {
- if (!_options.strictRawTypes || node == null) return;
- if (node.typeArguments != null) {
- // Type has explicit type arguments.
- return;
- }
- var type = node.staticType;
- return _checkForRawTypeErrors(node, type, type.element, node);
- }
-
- /// Given a [node] without type arguments that refers to [element], issues
- /// an error if [type] is a generic type, and the type arguments were not
- /// supplied from inference or a non-dynamic default instantiation.
- ///
- /// This function is used by other node-specific raw type checking functions
- /// (for example [_checkForRawTypeName]), and should only be called when
- /// we already know [AnalysisOptionsImpl.strictRawTypes] is true and [node]
- /// has no explicit `typeArguments`.
- ///
- /// [inferenceContextNode] is the node that has the downwards context type,
- /// if any. For example an [InstanceCreationExpression].
- ///
- /// The raw type error [HintCode.STRICT_RAW_TYPE] will *not* be reported when
- /// any of the following are true:
- ///
- /// - [inferenceContextNode] has an inference context type that does not
- /// contain `?`
- /// - [type] does not have any `dynamic` type arguments.
- /// - the element is marked with `@optionalTypeArgs` from "package:meta".
- void _checkForRawTypeErrors(AstNode node, DartType type, Element element,
- Expression inferenceContextNode) {
- assert(_options.strictRawTypes);
- // Check if this type has type arguments and at least one is dynamic.
- // If so, we may need to issue a strict-raw-types error.
- if (type is ParameterizedType &&
- type.typeArguments.any((t) => t.isDynamic)) {
- // If we have an inference context node, check if the type was inferred
- // from it. Some cases will not have a context type, such as the type
- // annotation `List` in `List list;`
- if (inferenceContextNode != null) {
- var contextType = InferenceContext.getContext(inferenceContextNode);
- if (contextType != null && UnknownInferredType.isKnown(contextType)) {
- // Type was inferred from downwards context: not an error.
- return;
- }
- }
- if (element.hasOptionalTypeArgs) {
- return;
- }
- _errorReporter.reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [type]);
- }
- }
-
/// Checks a type annotation for a raw generic type, and reports the
/// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
///
@@ -4758,16 +4764,11 @@
// Type has explicit type arguments.
return;
}
- var parent = node.parent;
- InstanceCreationExpression inferenceContextNode;
- if (parent is ConstructorName) {
- var grandparent = parent.parent;
- if (grandparent is InstanceCreationExpression) {
- inferenceContextNode = grandparent;
- }
+ if (_isMissingTypeArguments(
+ node, node.type, node.name.staticElement, null)) {
+ _errorReporter
+ .reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
}
- return _checkForRawTypeErrors(
- node, node.type, node.name.staticElement, inferenceContextNode);
}
/**
@@ -5207,7 +5208,7 @@
}
/**
- * Verify that the given type [name] is not a deferred type.
+ * Verify that the [type] is not a deferred type.
*
* See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
*/
@@ -5414,8 +5415,8 @@
}
if (target.staticType != null &&
- (target.staticType as TypeImpl).nullability ==
- Nullability.nonNullable) {
+ (target.staticType as TypeImpl).nullabilitySuffix ==
+ NullabilitySuffix.none) {
_errorReporter.reportErrorForToken(
HintCode.UNNECESSARY_NULL_AWARE_CALL, operator, []);
}
@@ -6111,6 +6112,46 @@
return false;
}
+ /// Given a [node] without type arguments that refers to [element], issues
+ /// an error if [type] is a generic type, and the type arguments were not
+ /// supplied from inference or a non-dynamic default instantiation.
+ ///
+ /// This function is used by other node-specific type checking functions, and
+ /// should only be called when [node] has no explicit `typeArguments`.
+ ///
+ /// [inferenceContextNode] is the node that has the downwards context type,
+ /// if any. For example an [InstanceCreationExpression].
+ ///
+ /// This function will return false if any of the following are true:
+ ///
+ /// - [inferenceContextNode] has an inference context type that does not
+ /// contain `?`
+ /// - [type] does not have any `dynamic` type arguments.
+ /// - the element is marked with `@optionalTypeArgs` from "package:meta".
+ bool _isMissingTypeArguments(AstNode node, DartType type, Element element,
+ Expression inferenceContextNode) {
+ // Check if this type has type arguments and at least one is dynamic.
+ // If so, we may need to issue a strict-raw-types error.
+ if (type is ParameterizedType &&
+ type.typeArguments.any((t) => t.isDynamic)) {
+ // If we have an inference context node, check if the type was inferred
+ // from it. Some cases will not have a context type, such as the type
+ // annotation `List` in `List list;`
+ if (inferenceContextNode != null) {
+ var contextType = InferenceContext.getContext(inferenceContextNode);
+ if (contextType != null && UnknownInferredType.isKnown(contextType)) {
+ // Type was inferred from downwards context: not an error.
+ return false;
+ }
+ }
+ if (element.hasOptionalTypeArgs) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
/**
* Return `true` if the given 'this' [expression] is in a valid context.
*/
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index fa863d1..9295e4f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1833,7 +1833,7 @@
}
void _checkForDeadNullCoalesce(TypeImpl lhsType, Expression rhs) {
- if (lhsType.nullability == Nullability.nonNullable) {
+ if (_isNonNullableUnit && _typeSystem.isNonNullable(lhsType)) {
_errorReporter.reportErrorForNode(HintCode.DEAD_CODE, rhs, []);
}
}
@@ -3632,7 +3632,7 @@
const ResolverErrorCode(
'PART_OF_UNNAMED_LIBRARY',
"Library is unnamed. Expected a URI not a library name '{0}' in the "
- "part-of directive.",
+ "part-of directive.",
correction:
"Try changing the part-of directive to a URI, or try including a"
" different part.");
@@ -3851,13 +3851,6 @@
// TODO(brianwilkerson) Remove this method.
}
- /// A client is about to resolve a member in the given class declaration.
- void prepareToResolveMembersInClass(ClassDeclaration node) {
- _enclosingClassDeclaration = node;
- enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
- }
-
/// Set information about enclosing declarations.
void prepareEnclosingDeclarations({
ClassElement enclosingClassElement,
@@ -3869,6 +3862,13 @@
_enclosingFunction = enclosingExecutableElement;
}
+ /// A client is about to resolve a member in the given class declaration.
+ void prepareToResolveMembersInClass(ClassDeclaration node) {
+ _enclosingClassDeclaration = node;
+ enclosingClass = node.declaredElement;
+ typeAnalyzer.thisType = enclosingClass?.type;
+ }
+
/// Visit the given [comment] if it is not `null`.
void safelyVisitComment(Comment comment) {
if (comment != null) {
@@ -6640,16 +6640,16 @@
return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
}
- Nullability _getNullability(bool hasQuestion) {
- Nullability nullability;
+ NullabilitySuffix _getNullability(bool hasQuestion) {
+ NullabilitySuffix nullability;
if (isNonNullableUnit) {
if (hasQuestion) {
- nullability = Nullability.nullable;
+ nullability = NullabilitySuffix.question;
} else {
- nullability = Nullability.nonNullable;
+ nullability = NullabilitySuffix.none;
}
} else {
- nullability = Nullability.indeterminate;
+ nullability = NullabilitySuffix.star;
}
return nullability;
}
@@ -6793,6 +6793,25 @@
bool _isTypeNameInTypeArgumentList(TypeName typeName) =>
typeName.parent is TypeArgumentList;
+ /// Given a [typeName] that has a question mark, report an error and return
+ /// `true` if it appears in a location where a nullable type is not allowed.
+ void _reportInvalidNullableType(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is ExtendsClause || parent is ClassTypeAlias) {
+ reportErrorForNode(
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, typeName);
+ } else if (parent is ImplementsClause) {
+ reportErrorForNode(
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, typeName);
+ } else if (parent is OnClause) {
+ reportErrorForNode(
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE, typeName);
+ } else if (parent is WithClause) {
+ reportErrorForNode(
+ CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, typeName);
+ }
+ }
+
void _resolveClassElement(TypeName node, Identifier typeName,
TypeArgumentList argumentList, ClassElement element) {
_setElement(typeName, element);
@@ -6832,19 +6851,22 @@
var parent = node.parent;
- Nullability nullability;
+ NullabilitySuffix nullabilitySuffix;
if (parent is ClassTypeAlias ||
parent is ExtendsClause ||
parent is ImplementsClause ||
parent is OnClause ||
parent is WithClause) {
- nullability = Nullability.nonNullable;
+ if (node.question != null) {
+ _reportInvalidNullableType(node);
+ }
+ nullabilitySuffix = NullabilitySuffix.none;
} else {
- nullability = _getNullability(node.question != null);
+ nullabilitySuffix = _getNullability(node.question != null);
}
var type = InterfaceTypeImpl.explicit(element, typeArguments,
- nullability: nullability);
+ nullabilitySuffix: nullabilitySuffix);
if (shouldUseWithClauseInferredTypes) {
if (parent is WithClause && parameterCount != 0) {
@@ -7170,6 +7192,9 @@
/// Return the type representing the built-in type 'Map'.
InterfaceType get mapType;
+ /// Return the type representing the built-in type 'Never'.
+ InterfaceType get neverType;
+
/// Return a list containing all of the types that cannot be either extended
/// or implemented.
List<InterfaceType> get nonSubtypableTypes;
@@ -7315,8 +7340,8 @@
/// An shared object representing the value 'null'.
DartObjectImpl _nullObject;
- /// The type representing the type 'Set'.
- InterfaceType _setType;
+ /// The type representing the type 'Never'.
+ InterfaceType _neverType;
/// The type representing the type 'Null'.
InterfaceType _nullType;
@@ -7327,6 +7352,9 @@
/// The type representing the built-in type 'Object'.
InterfaceType _objectType;
+ /// The type representing the type 'Set'.
+ InterfaceType _setType;
+
/// The type representing the built-in type 'StackTrace'.
InterfaceType _stackTraceType;
@@ -7351,18 +7379,7 @@
/// Initialize a newly created type provider to provide the types defined in
/// the given [coreLibrary] and [asyncLibrary].
TypeProviderImpl(LibraryElement coreLibrary, LibraryElement asyncLibrary) {
- Namespace coreNamespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(coreLibrary);
- Namespace asyncNamespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(asyncLibrary);
- _initializeFrom(coreNamespace, asyncNamespace);
- }
-
- /// Initialize a newly created type provider to provide the types defined in
- /// the given [Namespace]s.
- TypeProviderImpl.forNamespaces(
- Namespace coreNamespace, Namespace asyncNamespace) {
- _initializeFrom(coreNamespace, asyncNamespace);
+ _initializeFrom(coreLibrary, asyncLibrary);
}
@override
@@ -7420,6 +7437,9 @@
InterfaceType get mapType => _mapType;
@override
+ InterfaceType get neverType => _neverType;
+
+ @override
DartObjectImpl get nullObject {
if (_nullObject == null) {
_nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
@@ -7460,12 +7480,18 @@
@override
DartType get undefinedType => _undefinedType;
- /// Return the type with the given name from the given namespace, or `null` if
- /// there is no class with the given name.
- ///
- /// @param namespace the namespace in which to search for the given name
- /// @param typeName the name of the type being searched for
- /// @return the type that was found
+ InterfaceType _createNever(Namespace namespace) {
+ // TODO(brianwilkerson) Remove this method when the class is defined in the
+ // SDK.
+ CompilationUnitElement compilationUnit =
+ boolType.element.getAncestor((e) => e is CompilationUnitElement);
+ ClassElementImpl element = ElementFactory.classElement('Never', objectType);
+ element.enclosingElement = compilationUnit;
+ return element.type;
+ }
+
+ /// Return the type with the given [typeName] from the given [namespace], or
+ /// `null` if there is no class with the given name.
InterfaceType _getType(Namespace namespace, String typeName) {
Element element = namespace.get(typeName);
if (element == null) {
@@ -7478,28 +7504,36 @@
/// Initialize the types provided by this type provider from the given
/// [Namespace]s.
- void _initializeFrom(Namespace coreNamespace, Namespace asyncNamespace) {
- _boolType = _getType(coreNamespace, "bool");
+ void _initializeFrom(
+ LibraryElement coreLibrary, LibraryElement asyncLibrary) {
+ Namespace coreNamespace =
+ new NamespaceBuilder().createPublicNamespaceForLibrary(coreLibrary);
+ Namespace asyncNamespace =
+ new NamespaceBuilder().createPublicNamespaceForLibrary(asyncLibrary);
+
+ _boolType = _getType(coreNamespace, 'bool');
_bottomType = BottomTypeImpl.instance;
- _deprecatedType = _getType(coreNamespace, "Deprecated");
- _doubleType = _getType(coreNamespace, "double");
+ _deprecatedType = _getType(coreNamespace, 'Deprecated');
+ _doubleType = _getType(coreNamespace, 'double');
_dynamicType = DynamicTypeImpl.instance;
- _functionType = _getType(coreNamespace, "Function");
- _futureOrType = _getType(asyncNamespace, "FutureOr");
- _futureType = _getType(asyncNamespace, "Future");
- _intType = _getType(coreNamespace, "int");
- _iterableType = _getType(coreNamespace, "Iterable");
- _listType = _getType(coreNamespace, "List");
- _mapType = _getType(coreNamespace, "Map");
- _nullType = _getType(coreNamespace, "Null");
- _numType = _getType(coreNamespace, "num");
- _objectType = _getType(coreNamespace, "Object");
- _setType = _getType(coreNamespace, "Set");
- _stackTraceType = _getType(coreNamespace, "StackTrace");
- _streamType = _getType(asyncNamespace, "Stream");
- _stringType = _getType(coreNamespace, "String");
- _symbolType = _getType(coreNamespace, "Symbol");
- _typeType = _getType(coreNamespace, "Type");
+ _functionType = _getType(coreNamespace, 'Function');
+ _futureOrType = _getType(asyncNamespace, 'FutureOr');
+ _futureType = _getType(asyncNamespace, 'Future');
+ _intType = _getType(coreNamespace, 'int');
+ _iterableType = _getType(coreNamespace, 'Iterable');
+ _listType = _getType(coreNamespace, 'List');
+ _mapType = _getType(coreNamespace, 'Map');
+ _neverType =
+ _getType(coreNamespace, 'Never') ?? _createNever(coreNamespace);
+ _nullType = _getType(coreNamespace, 'Null');
+ _numType = _getType(coreNamespace, 'num');
+ _objectType = _getType(coreNamespace, 'Object');
+ _setType = _getType(coreNamespace, 'Set');
+ _stackTraceType = _getType(coreNamespace, 'StackTrace');
+ _streamType = _getType(asyncNamespace, 'Stream');
+ _stringType = _getType(coreNamespace, 'String');
+ _symbolType = _getType(coreNamespace, 'Symbol');
+ _typeType = _getType(coreNamespace, 'Type');
_undefinedType = UndefinedTypeImpl.instance;
_futureDynamicType = _futureType.instantiate(<DartType>[_dynamicType]);
_futureNullType = _futureType.instantiate(<DartType>[_nullType]);
@@ -7519,6 +7553,8 @@
/// we can analyze older SDKs.
static InterfaceType createPlaceholderFutureOr(
InterfaceType futureType, InterfaceType objectType) {
+ // TODO(brianwilkerson) Remove this method now that the class has been
+ // defined.
var compilationUnit =
futureType.element.getAncestor((e) => e is CompilationUnitElement);
var element = ElementFactory.classElement('FutureOr', objectType, ['T']);
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 682b4f3..285df36 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -726,13 +726,19 @@
@override
void visitPostfixExpression(PostfixExpression node) {
Expression operand = node.operand;
- DartType staticType = _getStaticType(operand, read: true);
+ TypeImpl staticType = _getStaticType(operand, read: true);
- // No need to check for `intVar++`, the result is `int`.
- if (!staticType.isDartCoreInt) {
- var operatorElement = node.staticElement;
- var operatorReturnType = _computeStaticReturnType(operatorElement);
- _checkForInvalidAssignmentIncDec(node, operand, operatorReturnType);
+ if (node.operator.type == TokenType.BANG) {
+ // TODO(paulberry): This does the wrong thing if staticType is a type
+ // parameter type.
+ staticType = staticType.withNullability(NullabilitySuffix.none);
+ } else {
+ // No need to check for `intVar++`, the result is `int`.
+ if (!staticType.isDartCoreInt) {
+ var operatorElement = node.staticElement;
+ var operatorReturnType = _computeStaticReturnType(operatorElement);
+ _checkForInvalidAssignmentIncDec(node, operand, operatorReturnType);
+ }
}
_recordStaticType(node, staticType);
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 30b176b..bb052ad 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -119,6 +119,11 @@
InterfaceType _mapObjectObjectType;
/**
+ * The type representing the built-in type 'Never'.
+ */
+ InterfaceType _neverType;
+
+ /**
* An shared object representing the value 'null'.
*/
DartObjectImpl _nullObject;
@@ -442,6 +447,16 @@
}
@override
+ InterfaceType get neverType {
+ if (_neverType == null) {
+ ClassElementImpl neverElement =
+ ElementFactory.classElement('Never', objectType);
+ _neverType = neverElement.type;
+ }
+ return _neverType;
+ }
+
+ @override
DartObjectImpl get nullObject {
if (_nullObject == null) {
_nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
@@ -607,11 +622,13 @@
void _initDartAsync() {
Source asyncSource;
- if (_driver == null) {
+ if (_driver != null) {
+ asyncSource = _driver.sourceFactory.forUri(DartSdk.DART_ASYNC);
+ } else if (_context != null) {
asyncSource = _context.sourceFactory.forUri(DartSdk.DART_ASYNC);
_context.setContents(asyncSource, "");
} else {
- asyncSource = _driver.sourceFactory.forUri(DartSdk.DART_ASYNC);
+ asyncSource = null;
}
CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index ec1a06f..b2fa6c8 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -958,7 +958,7 @@
type.typeArguments, (t) => _substituteType(t, lowerBound, visitType));
if (identical(type.typeArguments, newTypeArgs)) return type;
return new InterfaceTypeImpl(
- type.element, type.prunedTypedefs, type.nullability)
+ type.element, type.prunedTypedefs, type.nullabilitySuffix)
..typeArguments = newTypeArgs;
}
if (type is FunctionType) {
@@ -982,7 +982,7 @@
return new FunctionTypeImpl.synthetic(
newReturnType, type.typeFormals, newParameters,
- nullability: (type as TypeImpl).nullability);
+ nullabilitySuffix: (type as TypeImpl).nullabilitySuffix);
}
return type;
}
@@ -1229,8 +1229,8 @@
?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
typeParam,
' Inferred candidate type $inferred has type parameters'
- ' ${(inferred as FunctionType).typeFormals}, but a function with'
- ' type parameters cannot be used as a type argument.'
+ ' ${(inferred as FunctionType).typeFormals}, but a function with'
+ ' type parameters cannot be used as a type argument.'
]);
// Heuristic: Using a generic function type as a bound makes subtyping
@@ -1261,8 +1261,8 @@
?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
typeParam,
"\nRecursive bound cannot be instantiated: '$typeParamBound'."
- "\nConsider passing explicit type argument(s) "
- "to the generic.\n\n'"
+ "\nConsider passing explicit type argument(s) "
+ "to the generic.\n\n'"
]);
}
}
@@ -1922,6 +1922,27 @@
*/
bool isMoreSpecificThan(DartType leftType, DartType rightType);
+ @override
+ bool isNonNullable(DartType type) {
+ if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
+ return false;
+ } else if (type.isDartAsyncFutureOr) {
+ isNonNullable((type as InterfaceType).typeArguments[0]);
+ }
+ return (type as TypeImpl).nullabilitySuffix != NullabilitySuffix.question &&
+ (type is TypeParameterType ? isNonNullable(type.bound) : true);
+ }
+
+ @override
+ bool isNullable(DartType type) {
+ if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
+ return true;
+ } else if (type.isDartAsyncFutureOr) {
+ isNullable((type as InterfaceType).typeArguments[0]);
+ }
+ return (type as TypeImpl).nullabilitySuffix != NullabilitySuffix.none;
+ }
+
/// Check that [f1] is a subtype of [f2] for a member override.
///
/// This is different from the normal function subtyping in two ways:
@@ -1929,6 +1950,12 @@
/// - it allows opt-in covariant parameters.
bool isOverrideSubtypeOf(FunctionType f1, FunctionType f2);
+ @override
+ bool isPotentiallyNonNullable(DartType type) => !isNullable(type);
+
+ @override
+ bool isPotentiallyNullable(DartType type) => !isNonNullable(type);
+
/**
* Return `true` if the [leftType] is a subtype of the [rightType] (that is,
* if leftType <: rightType).
@@ -2231,7 +2258,7 @@
bool get isDynamic => true;
@override
- Nullability get nullability => Nullability.indeterminate;
+ NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.star;
@override
bool operator ==(Object object) => identical(object, this);
@@ -2293,7 +2320,7 @@
}
@override
- TypeImpl withNullability(Nullability nullability) => this;
+ TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
/// Given a [type] T, return true if it does not have an unknown type `?`.
static bool isKnown(DartType type) => !isUnknown(type);
diff --git a/pkg/analyzer/lib/src/manifest/manifest_validator.dart b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
index f18f9bd..c83e616 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_validator.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
@@ -40,9 +40,11 @@
var features = manifest?.getElementsByTagName(USES_FEATURE_TAG) ?? [];
var permissions =
manifest?.getElementsByTagName(USES_PERMISSION_TAG) ?? [];
+ var activities = _findActivityElements(manifest);
_validateFeatures(features, reporter);
_validatePermissions(permissions, features, reporter);
+ _validateActivities(activities, reporter);
}
return recorder.errors;
}
@@ -93,6 +95,39 @@
});
}
+ /*
+ * Validate the 'activity' tags.
+ */
+ _validateActivities(List<Element> activites, ErrorReporter reporter) {
+ activites.forEach((activity) {
+ var attributes = activity.attributes;
+ if (attributes.containsKey(ATTRIBUTE_SCREEN_ORIENTATION)) {
+ var value = attributes[ATTRIBUTE_SCREEN_ORIENTATION];
+ if (UNSUPPORTED_ORIENTATIONS
+ .contains(attributes[ATTRIBUTE_SCREEN_ORIENTATION])) {
+ _reportErrorForNode(reporter, activity, ATTRIBUTE_SCREEN_ORIENTATION,
+ ManifestWarningCode.SETTING_ORIENTATION_ON_ACTIVITY);
+ }
+ }
+ if (attributes.containsKey(ATTRIBUTE_RESIZEABLE_ACTIVITY)) {
+ if (attributes[ATTRIBUTE_RESIZEABLE_ACTIVITY] == 'false') {
+ _reportErrorForNode(reporter, activity, ATTRIBUTE_RESIZEABLE_ACTIVITY,
+ ManifestWarningCode.NON_RESIZABLE_ACTIVITY);
+ }
+ }
+ });
+ }
+
+ List<Element> _findActivityElements(Element manifest) {
+ var applications = manifest?.getElementsByTagName(APPLICATION_TAG);
+ var applicationElement = (applications != null && applications.isNotEmpty)
+ ? applications.first
+ : null;
+ var activities =
+ applicationElement?.getElementsByTagName(ACTIVITY_TAG) ?? [];
+ return activities;
+ }
+
bool _hasFeatureCamera(List<Element> features) =>
features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA);
diff --git a/pkg/analyzer/lib/src/manifest/manifest_values.dart b/pkg/analyzer/lib/src/manifest/manifest_values.dart
index ea1b59d..db96a93 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_values.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_values.dart
@@ -5,7 +5,7 @@
/*
* The arritbute values to check for compatibiltiy with Chrome OS.
*
- */
+*/
const String MANIFEST_TAG = 'manifest';
@@ -13,10 +13,21 @@
const String USES_FEATURE_TAG = 'uses-feature';
+const String APPLICATION_TAG = 'application';
+
+const String ACTIVITY_TAG = 'activity';
+
const String ANDROID_NAME = 'android:name';
const String ANDROID_REQUIRED = 'android:required';
+// The parser does not maintain camelcase for attributes
+// Use 'resizeableactivity' instead of 'resizeableActivity'
+const String ATTRIBUTE_RESIZEABLE_ACTIVITY = 'android:resizeableactivity';
+
+// Use 'screenorientation' instead of 'screenOrientation'
+const String ATTRIBUTE_SCREEN_ORIENTATION = 'android:screenorientation';
+
const String HARDWARE_FEATURE_CAMERA = 'android.hardware.camera';
const String HARDWARE_FEATURE_CAMERA_AUTOFOCUS =
@@ -99,3 +110,14 @@
return null;
}
}
+
+const UNSUPPORTED_ORIENTATIONS = <String>[
+ 'landscape',
+ 'portrait',
+ 'reverseLandscape',
+ 'reversePortrait',
+ 'sensorLandscape',
+ 'sensorPortrait',
+ 'userLandscape',
+ 'userPortrait'
+];
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
index 0e0928c..8cd566c 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -46,6 +46,29 @@
"Try adding the uses-feature with required=\"false\" attribute value.");
/**
+ * A code indicating that the activity is set to be non resizable.
+ */
+ static const ManifestWarningCode NON_RESIZABLE_ACTIVITY =
+ const ManifestWarningCode(
+ 'NON_RESIZABLE_ACTIVITY',
+ "The `<activity>` element should be allowed to be resized to allow " +
+ "users to take advantage of the multi-window environment on Chrome OS",
+ correction: "Consider declaring the corresponding " +
+ "activity element with `resizableActivity=\"true\"` attribute.");
+
+ /**
+ * A code indicating that the activity is locked to an orientation.
+ */
+ static const ManifestWarningCode SETTING_ORIENTATION_ON_ACTIVITY =
+ const ManifestWarningCode(
+ 'SETTING_ORIENTATION_ON_ACTIVITY',
+ "The `<activity>` element should not be locked to any orientation so " +
+ "that users can take advantage of the multi-window environments " +
+ "and larger screens on Chrome OS",
+ correction: "Consider declaring the corresponding activity element with" +
+ " `screenOrientation=\"unspecified\"` or `\"fullSensor\"` attribute.");
+
+ /**
* Initialize a newly created warning code to have the given [name], [message]
* and [correction].
*/
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 8337641..431ccb0 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1242,6 +1242,7 @@
parent: classDeclaration,
requiredParameterCount:
_getFormalParameterRequiredCount(parameters),
+ returnType: node.name.name,
);
hasConstructor = true;
}
@@ -1270,7 +1271,7 @@
parent: classDeclaration,
relevanceTags: null,
requiredParameterCount: 0,
- returnType: null,
+ returnType: node.name.name,
typeParameters: null,
));
}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index fd78d94..7b27b6c 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -4658,6 +4658,7 @@
int _variantField_17;
int _variantField_18;
int _variantField_19;
+ LinkedNodeTypeBuilder _variantField_23;
bool _variantField_27;
LinkedNodeBuilder _variantField_9;
LinkedNodeBuilder _variantField_12;
@@ -4676,9 +4677,8 @@
LinkedNodeBuilder _variantField_14;
bool _isSynthetic;
idl.LinkedNodeKind _kind;
- String _variantField_23;
- bool _variantField_31;
String _variantField_20;
+ bool _variantField_31;
String _variantField_22;
LinkedNodeVariablesDeclarationBuilder _variantField_32;
@@ -4714,12 +4714,6 @@
return _variantField_24;
}
- @override
- LinkedNodeTypeBuilder get typeName_type {
- assert(kind == idl.LinkedNodeKind.typeName);
- return _variantField_24;
- }
-
/// The explicit or inferred return type of a function typed node.
set actualReturnType(LinkedNodeTypeBuilder value) {
assert(kind == idl.LinkedNodeKind.functionDeclaration ||
@@ -4749,11 +4743,6 @@
_variantField_24 = value;
}
- set typeName_type(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_24 = value;
- }
-
@override
List<LinkedNodeBuilder> get adjacentStrings_strings {
assert(kind == idl.LinkedNodeKind.adjacentStrings);
@@ -8175,6 +8164,12 @@
}
@override
+ int get typeParameter_id {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ return _variantField_16 ??= 0;
+ }
+
+ @override
int get typeParameterList_rightBracket {
assert(kind == idl.LinkedNodeKind.typeParameterList);
return _variantField_16 ??= 0;
@@ -8508,6 +8503,12 @@
_variantField_16 = value;
}
+ set typeParameter_id(int value) {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ assert(value == null || value >= 0);
+ _variantField_16 = value;
+ }
+
set typeParameterList_rightBracket(int value) {
assert(kind == idl.LinkedNodeKind.typeParameterList);
assert(value == null || value >= 0);
@@ -9143,6 +9144,117 @@
}
@override
+ LinkedNodeTypeBuilder get assignmentExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.assignmentExpression);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get binaryExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.binaryExpression);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get constructorName_elementType {
+ assert(kind == idl.LinkedNodeKind.constructorName);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get indexExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.indexExpression);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get postfixExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.postfixExpression);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get prefixExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.prefixExpression);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get redirectingConstructorInvocation_elementType {
+ assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get simpleIdentifier_elementType {
+ assert(kind == idl.LinkedNodeKind.simpleIdentifier);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get superConstructorInvocation_elementType {
+ assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
+ return _variantField_23;
+ }
+
+ @override
+ LinkedNodeTypeBuilder get typeName_type {
+ assert(kind == idl.LinkedNodeKind.typeName);
+ return _variantField_23;
+ }
+
+ set assignmentExpression_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.assignmentExpression);
+ _variantField_23 = value;
+ }
+
+ set binaryExpression_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.binaryExpression);
+ _variantField_23 = value;
+ }
+
+ set constructorName_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.constructorName);
+ _variantField_23 = value;
+ }
+
+ set indexExpression_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.indexExpression);
+ _variantField_23 = value;
+ }
+
+ set postfixExpression_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.postfixExpression);
+ _variantField_23 = value;
+ }
+
+ set prefixExpression_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.prefixExpression);
+ _variantField_23 = value;
+ }
+
+ set redirectingConstructorInvocation_elementType(
+ LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
+ _variantField_23 = value;
+ }
+
+ set simpleIdentifier_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.simpleIdentifier);
+ _variantField_23 = value;
+ }
+
+ set superConstructorInvocation_elementType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
+ _variantField_23 = value;
+ }
+
+ set typeName_type(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.typeName);
+ _variantField_23 = value;
+ }
+
+ @override
bool get booleanLiteral_value {
assert(kind == idl.LinkedNodeKind.booleanLiteral);
return _variantField_27 ??= false;
@@ -9745,20 +9857,27 @@
}
@override
- String get namespaceDirective_selectedUriContent {
+ String get namespaceDirective_selectedUri {
assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- return _variantField_23 ??= '';
+ kind == idl.LinkedNodeKind.importDirective);
+ return _variantField_20 ??= '';
}
- set namespaceDirective_selectedUriContent(String value) {
+ @override
+ String get simpleStringLiteral_value {
+ assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
+ return _variantField_20 ??= '';
+ }
+
+ set namespaceDirective_selectedUri(String value) {
assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_23 = value;
+ kind == idl.LinkedNodeKind.importDirective);
+ _variantField_20 = value;
+ }
+
+ set simpleStringLiteral_value(String value) {
+ assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
+ _variantField_20 = value;
}
@override
@@ -9792,17 +9911,6 @@
}
@override
- String get simpleStringLiteral_value {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- return _variantField_20 ??= '';
- }
-
- set simpleStringLiteral_value(String value) {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- _variantField_20 = value;
- }
-
- @override
String get uriBasedDirective_uriContent {
assert(kind == idl.LinkedNodeKind.exportDirective ||
kind == idl.LinkedNodeKind.importDirective ||
@@ -10052,6 +10160,7 @@
int binaryExpression_element,
LinkedNodeBuilder binaryExpression_rightOperand,
int binaryExpression_operator,
+ LinkedNodeTypeBuilder binaryExpression_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.binaryExpression,
_variantField_24 = binaryExpression_invokeType,
@@ -10059,6 +10168,7 @@
_variantField_15 = binaryExpression_element,
_variantField_7 = binaryExpression_rightOperand,
_variantField_16 = binaryExpression_operator,
+ _variantField_23 = binaryExpression_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.functionExpressionInvocation({
@@ -10091,17 +10201,6 @@
_variantField_25 = expression_type,
_variantField_14 = invocationExpression_arguments;
- LinkedNodeBuilder.typeName({
- LinkedNodeTypeBuilder typeName_type,
- LinkedNodeBuilder typeName_name,
- int typeName_question,
- LinkedNodeBuilder typeName_typeArguments,
- }) : _kind = idl.LinkedNodeKind.typeName,
- _variantField_24 = typeName_type,
- _variantField_6 = typeName_name,
- _variantField_15 = typeName_question,
- _variantField_7 = typeName_typeArguments;
-
LinkedNodeBuilder.adjacentStrings({
List<LinkedNodeBuilder> adjacentStrings_strings,
LinkedNodeTypeBuilder expression_type,
@@ -10271,7 +10370,7 @@
int directive_semicolon,
List<LinkedNodeBuilder> namespaceDirective_configurations,
LinkedNodeBuilder uriBasedDirective_uri,
- String namespaceDirective_selectedUriContent,
+ String namespaceDirective_selectedUri,
String uriBasedDirective_uriContent,
}) : _kind = idl.LinkedNodeKind.exportDirective,
_variantField_2 = namespaceDirective_combinators,
@@ -10282,7 +10381,7 @@
_variantField_33 = directive_semicolon,
_variantField_3 = namespaceDirective_configurations,
_variantField_14 = uriBasedDirective_uri,
- _variantField_23 = namespaceDirective_selectedUriContent,
+ _variantField_20 = namespaceDirective_selectedUri,
_variantField_22 = uriBasedDirective_uriContent;
LinkedNodeBuilder.importDirective({
@@ -10297,7 +10396,7 @@
int directive_semicolon,
List<LinkedNodeBuilder> namespaceDirective_configurations,
LinkedNodeBuilder uriBasedDirective_uri,
- String namespaceDirective_selectedUriContent,
+ String namespaceDirective_selectedUri,
String uriBasedDirective_uriContent,
}) : _kind = idl.LinkedNodeKind.importDirective,
_variantField_2 = namespaceDirective_combinators,
@@ -10311,7 +10410,7 @@
_variantField_33 = directive_semicolon,
_variantField_3 = namespaceDirective_configurations,
_variantField_14 = uriBasedDirective_uri,
- _variantField_23 = namespaceDirective_selectedUriContent,
+ _variantField_20 = namespaceDirective_selectedUri,
_variantField_22 = uriBasedDirective_uriContent;
LinkedNodeBuilder.onClause({
@@ -10601,7 +10700,6 @@
int uriBasedDirective_uriElement,
int directive_semicolon,
LinkedNodeBuilder uriBasedDirective_uri,
- String namespaceDirective_selectedUriContent,
String uriBasedDirective_uriContent,
}) : _kind = idl.LinkedNodeKind.partDirective,
_variantField_11 = annotatedNode_comment,
@@ -10610,7 +10708,6 @@
_variantField_19 = uriBasedDirective_uriElement,
_variantField_33 = directive_semicolon,
_variantField_14 = uriBasedDirective_uri,
- _variantField_23 = namespaceDirective_selectedUriContent,
_variantField_22 = uriBasedDirective_uriContent;
LinkedNodeBuilder.partOfDirective({
@@ -10621,7 +10718,6 @@
int partOfDirective_ofKeyword,
int directive_keyword,
int directive_semicolon,
- String namespaceDirective_selectedUriContent,
}) : _kind = idl.LinkedNodeKind.partOfDirective,
_variantField_11 = annotatedNode_comment,
_variantField_4 = annotatedNode_metadata,
@@ -10629,8 +10725,7 @@
_variantField_7 = partOfDirective_uri,
_variantField_16 = partOfDirective_ofKeyword,
_variantField_18 = directive_keyword,
- _variantField_33 = directive_semicolon,
- _variantField_23 = namespaceDirective_selectedUriContent;
+ _variantField_33 = directive_semicolon;
LinkedNodeBuilder.topLevelVariableDeclaration({
LinkedNodeBuilder annotatedNode_comment,
@@ -10649,6 +10744,7 @@
LinkedNodeBuilder typeParameter_bound,
int typeParameter_extendsKeyword,
LinkedNodeBuilder typeParameter_name,
+ int typeParameter_id,
int codeLength,
int codeOffset,
}) : _kind = idl.LinkedNodeKind.typeParameter,
@@ -10657,6 +10753,7 @@
_variantField_6 = typeParameter_bound,
_variantField_15 = typeParameter_extendsKeyword,
_variantField_7 = typeParameter_name,
+ _variantField_16 = typeParameter_id,
_variantField_34 = codeLength,
_variantField_33 = codeOffset;
@@ -10745,12 +10842,14 @@
int assignmentExpression_element,
LinkedNodeBuilder assignmentExpression_rightHandSide,
int assignmentExpression_operator,
+ LinkedNodeTypeBuilder assignmentExpression_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.assignmentExpression,
_variantField_6 = assignmentExpression_leftHandSide,
_variantField_15 = assignmentExpression_element,
_variantField_7 = assignmentExpression_rightHandSide,
_variantField_16 = assignmentExpression_operator,
+ _variantField_23 = assignmentExpression_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.awaitExpression({
@@ -10851,11 +10950,13 @@
int constructorName_element,
LinkedNodeBuilder constructorName_type,
int constructorName_period,
+ LinkedNodeTypeBuilder constructorName_elementType,
}) : _kind = idl.LinkedNodeKind.constructorName,
_variantField_6 = constructorName_name,
_variantField_15 = constructorName_element,
_variantField_7 = constructorName_type,
- _variantField_16 = constructorName_period;
+ _variantField_16 = constructorName_period,
+ _variantField_23 = constructorName_elementType;
LinkedNodeBuilder.continueStatement({
LinkedNodeBuilder continueStatement_label,
@@ -11043,6 +11144,7 @@
int indexExpression_period,
int indexExpression_leftBracket,
int indexExpression_rightBracket,
+ LinkedNodeTypeBuilder indexExpression_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.indexExpression,
_variantField_6 = indexExpression_index,
@@ -11051,6 +11153,7 @@
_variantField_16 = indexExpression_period,
_variantField_17 = indexExpression_leftBracket,
_variantField_18 = indexExpression_rightBracket,
+ _variantField_23 = indexExpression_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.instanceCreationExpression({
@@ -11144,11 +11247,13 @@
LinkedNodeBuilder postfixExpression_operand,
int postfixExpression_element,
int postfixExpression_operator,
+ LinkedNodeTypeBuilder postfixExpression_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.postfixExpression,
_variantField_6 = postfixExpression_operand,
_variantField_15 = postfixExpression_element,
_variantField_16 = postfixExpression_operator,
+ _variantField_23 = postfixExpression_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.prefixedIdentifier({
@@ -11166,11 +11271,13 @@
LinkedNodeBuilder prefixExpression_operand,
int prefixExpression_element,
int prefixExpression_operator,
+ LinkedNodeTypeBuilder prefixExpression_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.prefixExpression,
_variantField_6 = prefixExpression_operand,
_variantField_15 = prefixExpression_element,
_variantField_16 = prefixExpression_operator,
+ _variantField_23 = prefixExpression_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.propertyAccess({
@@ -11190,12 +11297,14 @@
LinkedNodeBuilder redirectingConstructorInvocation_constructorName,
int redirectingConstructorInvocation_period,
int redirectingConstructorInvocation_thisKeyword,
+ LinkedNodeTypeBuilder redirectingConstructorInvocation_elementType,
}) : _kind = idl.LinkedNodeKind.redirectingConstructorInvocation,
_variantField_6 = redirectingConstructorInvocation_arguments,
_variantField_15 = redirectingConstructorInvocation_element,
_variantField_7 = redirectingConstructorInvocation_constructorName,
_variantField_16 = redirectingConstructorInvocation_period,
- _variantField_17 = redirectingConstructorInvocation_thisKeyword;
+ _variantField_17 = redirectingConstructorInvocation_thisKeyword,
+ _variantField_23 = redirectingConstructorInvocation_elementType;
LinkedNodeBuilder.returnStatement({
LinkedNodeBuilder returnStatement_expression,
@@ -11219,12 +11328,14 @@
LinkedNodeBuilder superConstructorInvocation_constructorName,
int superConstructorInvocation_period,
int superConstructorInvocation_superKeyword,
+ LinkedNodeTypeBuilder superConstructorInvocation_elementType,
}) : _kind = idl.LinkedNodeKind.superConstructorInvocation,
_variantField_6 = superConstructorInvocation_arguments,
_variantField_15 = superConstructorInvocation_element,
_variantField_7 = superConstructorInvocation_constructorName,
_variantField_16 = superConstructorInvocation_period,
- _variantField_17 = superConstructorInvocation_superKeyword;
+ _variantField_17 = superConstructorInvocation_superKeyword,
+ _variantField_23 = superConstructorInvocation_elementType;
LinkedNodeBuilder.throwExpression({
LinkedNodeBuilder throwExpression_expression,
@@ -11235,6 +11346,17 @@
_variantField_15 = throwExpression_throwKeyword,
_variantField_25 = expression_type;
+ LinkedNodeBuilder.typeName({
+ LinkedNodeBuilder typeName_name,
+ int typeName_question,
+ LinkedNodeBuilder typeName_typeArguments,
+ LinkedNodeTypeBuilder typeName_type,
+ }) : _kind = idl.LinkedNodeKind.typeName,
+ _variantField_6 = typeName_name,
+ _variantField_15 = typeName_question,
+ _variantField_7 = typeName_typeArguments,
+ _variantField_23 = typeName_type;
+
LinkedNodeBuilder.variableDeclarationStatement({
LinkedNodeBuilder variableDeclarationStatement_variables,
int variableDeclarationStatement_semicolon,
@@ -11332,10 +11454,12 @@
LinkedNodeBuilder.simpleIdentifier({
int simpleIdentifier_element,
int simpleIdentifier_token,
+ LinkedNodeTypeBuilder simpleIdentifier_elementType,
LinkedNodeTypeBuilder expression_type,
}) : _kind = idl.LinkedNodeKind.simpleIdentifier,
_variantField_15 = simpleIdentifier_element,
_variantField_16 = simpleIdentifier_token,
+ _variantField_23 = simpleIdentifier_elementType,
_variantField_25 = expression_type;
LinkedNodeBuilder.simpleStringLiteral({
@@ -11386,6 +11510,7 @@
_variantField_6?.flushInformative();
_variantField_7?.flushInformative();
_variantField_8?.flushInformative();
+ _variantField_23?.flushInformative();
_variantField_9?.flushInformative();
_variantField_12?.flushInformative();
_variantField_5?.forEach((b) => b.flushInformative());
@@ -11459,7 +11584,8 @@
signature.addString(this._variantField_20 ?? '');
signature.addDouble(this._variantField_21 ?? 0.0);
signature.addString(this._variantField_22 ?? '');
- signature.addString(this._variantField_23 ?? '');
+ signature.addBool(this._variantField_23 != null);
+ this._variantField_23?.collectApiSignature(signature);
signature.addBool(this._variantField_24 != null);
this._variantField_24?.collectApiSignature(signature);
signature.addBool(this._variantField_25 != null);
@@ -11493,6 +11619,7 @@
fb.Offset offset_variantField_6;
fb.Offset offset_variantField_7;
fb.Offset offset_variantField_8;
+ fb.Offset offset_variantField_23;
fb.Offset offset_variantField_9;
fb.Offset offset_variantField_12;
fb.Offset offset_variantField_5;
@@ -11503,7 +11630,6 @@
fb.Offset offset_variantField_25;
fb.Offset offset_variantField_30;
fb.Offset offset_variantField_14;
- fb.Offset offset_variantField_23;
fb.Offset offset_variantField_20;
fb.Offset offset_variantField_22;
fb.Offset offset_variantField_32;
@@ -11530,6 +11656,9 @@
if (_variantField_8 != null) {
offset_variantField_8 = _variantField_8.finish(fbBuilder);
}
+ if (_variantField_23 != null) {
+ offset_variantField_23 = _variantField_23.finish(fbBuilder);
+ }
if (_variantField_9 != null) {
offset_variantField_9 = _variantField_9.finish(fbBuilder);
}
@@ -11562,9 +11691,6 @@
if (_variantField_14 != null) {
offset_variantField_14 = _variantField_14.finish(fbBuilder);
}
- if (_variantField_23 != null) {
- offset_variantField_23 = fbBuilder.writeString(_variantField_23);
- }
if (_variantField_20 != null) {
offset_variantField_20 = fbBuilder.writeString(_variantField_20);
}
@@ -11611,6 +11737,9 @@
if (_variantField_19 != null && _variantField_19 != 0) {
fbBuilder.addUint32(19, _variantField_19);
}
+ if (offset_variantField_23 != null) {
+ fbBuilder.addOffset(23, offset_variantField_23);
+ }
if (_variantField_27 == true) {
fbBuilder.addBool(27, true);
}
@@ -11667,15 +11796,12 @@
if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
fbBuilder.addUint8(0, _kind.index);
}
- if (offset_variantField_23 != null) {
- fbBuilder.addOffset(23, offset_variantField_23);
+ if (offset_variantField_20 != null) {
+ fbBuilder.addOffset(20, offset_variantField_20);
}
if (_variantField_31 == true) {
fbBuilder.addBool(31, true);
}
- if (offset_variantField_20 != null) {
- fbBuilder.addOffset(20, offset_variantField_20);
- }
if (offset_variantField_22 != null) {
fbBuilder.addOffset(22, offset_variantField_22);
}
@@ -11714,6 +11840,7 @@
int _variantField_17;
int _variantField_18;
int _variantField_19;
+ idl.LinkedNodeType _variantField_23;
bool _variantField_27;
idl.LinkedNode _variantField_9;
idl.LinkedNode _variantField_12;
@@ -11732,9 +11859,8 @@
idl.LinkedNode _variantField_14;
bool _isSynthetic;
idl.LinkedNodeKind _kind;
- String _variantField_23;
- bool _variantField_31;
String _variantField_20;
+ bool _variantField_31;
String _variantField_22;
idl.LinkedNodeVariablesDeclaration _variantField_32;
@@ -11779,14 +11905,6 @@
}
@override
- idl.LinkedNodeType get typeName_type {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
List<idl.LinkedNode> get adjacentStrings_strings {
assert(kind == idl.LinkedNodeKind.adjacentStrings);
_variantField_2 ??=
@@ -14400,6 +14518,14 @@
}
@override
+ int get typeParameter_id {
+ assert(kind == idl.LinkedNodeKind.typeParameter);
+ _variantField_16 ??=
+ const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
+ return _variantField_16;
+ }
+
+ @override
int get typeParameterList_rightBracket {
assert(kind == idl.LinkedNodeKind.typeParameterList);
_variantField_16 ??=
@@ -14828,6 +14954,86 @@
}
@override
+ idl.LinkedNodeType get assignmentExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.assignmentExpression);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get binaryExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.binaryExpression);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get constructorName_elementType {
+ assert(kind == idl.LinkedNodeKind.constructorName);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get indexExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.indexExpression);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get postfixExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.postfixExpression);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get prefixExpression_elementType {
+ assert(kind == idl.LinkedNodeKind.prefixExpression);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get redirectingConstructorInvocation_elementType {
+ assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get simpleIdentifier_elementType {
+ assert(kind == idl.LinkedNodeKind.simpleIdentifier);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get superConstructorInvocation_elementType {
+ assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
+ idl.LinkedNodeType get typeName_type {
+ assert(kind == idl.LinkedNodeKind.typeName);
+ _variantField_23 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
+ return _variantField_23;
+ }
+
+ @override
bool get booleanLiteral_value {
assert(kind == idl.LinkedNodeKind.booleanLiteral);
_variantField_27 ??=
@@ -15230,14 +15436,20 @@
}
@override
- String get namespaceDirective_selectedUriContent {
+ String get namespaceDirective_selectedUri {
assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_23 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 23, '');
- return _variantField_23;
+ kind == idl.LinkedNodeKind.importDirective);
+ _variantField_20 ??=
+ const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
+ return _variantField_20;
+ }
+
+ @override
+ String get simpleStringLiteral_value {
+ assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
+ _variantField_20 ??=
+ const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
+ return _variantField_20;
}
@override
@@ -15261,14 +15473,6 @@
}
@override
- String get simpleStringLiteral_value {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- _variantField_20 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
- return _variantField_20;
- }
-
- @override
String get uriBasedDirective_uriContent {
assert(kind == idl.LinkedNodeKind.exportDirective ||
kind == idl.LinkedNodeKind.importDirective ||
@@ -15561,6 +15765,9 @@
binaryExpression_rightOperand.toJson();
if (binaryExpression_operator != 0)
_result["binaryExpression_operator"] = binaryExpression_operator;
+ if (binaryExpression_elementType != null)
+ _result["binaryExpression_elementType"] =
+ binaryExpression_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -15600,16 +15807,6 @@
_result["invocationExpression_arguments"] =
invocationExpression_arguments.toJson();
}
- if (kind == idl.LinkedNodeKind.typeName) {
- if (typeName_type != null)
- _result["typeName_type"] = typeName_type.toJson();
- if (typeName_name != null)
- _result["typeName_name"] = typeName_name.toJson();
- if (typeName_question != 0)
- _result["typeName_question"] = typeName_question;
- if (typeName_typeArguments != null)
- _result["typeName_typeArguments"] = typeName_typeArguments.toJson();
- }
if (kind == idl.LinkedNodeKind.adjacentStrings) {
if (adjacentStrings_strings.isNotEmpty)
_result["adjacentStrings_strings"] =
@@ -15823,9 +16020,9 @@
.toList();
if (uriBasedDirective_uri != null)
_result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- if (namespaceDirective_selectedUriContent != '')
- _result["namespaceDirective_selectedUriContent"] =
- namespaceDirective_selectedUriContent;
+ if (namespaceDirective_selectedUri != '')
+ _result["namespaceDirective_selectedUri"] =
+ namespaceDirective_selectedUri;
if (uriBasedDirective_uriContent != '')
_result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
}
@@ -15860,9 +16057,9 @@
.toList();
if (uriBasedDirective_uri != null)
_result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- if (namespaceDirective_selectedUriContent != '')
- _result["namespaceDirective_selectedUriContent"] =
- namespaceDirective_selectedUriContent;
+ if (namespaceDirective_selectedUri != '')
+ _result["namespaceDirective_selectedUri"] =
+ namespaceDirective_selectedUri;
if (uriBasedDirective_uriContent != '')
_result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
}
@@ -16213,9 +16410,6 @@
_result["directive_semicolon"] = directive_semicolon;
if (uriBasedDirective_uri != null)
_result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- if (namespaceDirective_selectedUriContent != '')
- _result["namespaceDirective_selectedUriContent"] =
- namespaceDirective_selectedUriContent;
if (uriBasedDirective_uriContent != '')
_result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
}
@@ -16236,9 +16430,6 @@
_result["directive_keyword"] = directive_keyword;
if (directive_semicolon != 0)
_result["directive_semicolon"] = directive_semicolon;
- if (namespaceDirective_selectedUriContent != '')
- _result["namespaceDirective_selectedUriContent"] =
- namespaceDirective_selectedUriContent;
}
if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
if (annotatedNode_comment != null)
@@ -16265,6 +16456,7 @@
_result["typeParameter_extendsKeyword"] = typeParameter_extendsKeyword;
if (typeParameter_name != null)
_result["typeParameter_name"] = typeParameter_name.toJson();
+ if (typeParameter_id != 0) _result["typeParameter_id"] = typeParameter_id;
if (codeLength != 0) _result["codeLength"] = codeLength;
if (codeOffset != 0) _result["codeOffset"] = codeOffset;
}
@@ -16368,6 +16560,9 @@
if (assignmentExpression_operator != 0)
_result["assignmentExpression_operator"] =
assignmentExpression_operator;
+ if (assignmentExpression_elementType != null)
+ _result["assignmentExpression_elementType"] =
+ assignmentExpression_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -16481,6 +16676,9 @@
_result["constructorName_type"] = constructorName_type.toJson();
if (constructorName_period != 0)
_result["constructorName_period"] = constructorName_period;
+ if (constructorName_elementType != null)
+ _result["constructorName_elementType"] =
+ constructorName_elementType.toJson();
}
if (kind == idl.LinkedNodeKind.continueStatement) {
if (continueStatement_label != null)
@@ -16676,6 +16874,9 @@
_result["indexExpression_leftBracket"] = indexExpression_leftBracket;
if (indexExpression_rightBracket != 0)
_result["indexExpression_rightBracket"] = indexExpression_rightBracket;
+ if (indexExpression_elementType != null)
+ _result["indexExpression_elementType"] =
+ indexExpression_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -16776,6 +16977,9 @@
_result["postfixExpression_element"] = postfixExpression_element;
if (postfixExpression_operator != 0)
_result["postfixExpression_operator"] = postfixExpression_operator;
+ if (postfixExpression_elementType != null)
+ _result["postfixExpression_elementType"] =
+ postfixExpression_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -16798,6 +17002,9 @@
_result["prefixExpression_element"] = prefixExpression_element;
if (prefixExpression_operator != 0)
_result["prefixExpression_operator"] = prefixExpression_operator;
+ if (prefixExpression_elementType != null)
+ _result["prefixExpression_elementType"] =
+ prefixExpression_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -16828,6 +17035,9 @@
if (redirectingConstructorInvocation_thisKeyword != 0)
_result["redirectingConstructorInvocation_thisKeyword"] =
redirectingConstructorInvocation_thisKeyword;
+ if (redirectingConstructorInvocation_elementType != null)
+ _result["redirectingConstructorInvocation_elementType"] =
+ redirectingConstructorInvocation_elementType.toJson();
}
if (kind == idl.LinkedNodeKind.returnStatement) {
if (returnStatement_expression != null)
@@ -16861,6 +17071,9 @@
if (superConstructorInvocation_superKeyword != 0)
_result["superConstructorInvocation_superKeyword"] =
superConstructorInvocation_superKeyword;
+ if (superConstructorInvocation_elementType != null)
+ _result["superConstructorInvocation_elementType"] =
+ superConstructorInvocation_elementType.toJson();
}
if (kind == idl.LinkedNodeKind.throwExpression) {
if (throwExpression_expression != null)
@@ -16871,6 +17084,16 @@
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
+ if (kind == idl.LinkedNodeKind.typeName) {
+ if (typeName_name != null)
+ _result["typeName_name"] = typeName_name.toJson();
+ if (typeName_question != 0)
+ _result["typeName_question"] = typeName_question;
+ if (typeName_typeArguments != null)
+ _result["typeName_typeArguments"] = typeName_typeArguments.toJson();
+ if (typeName_type != null)
+ _result["typeName_type"] = typeName_type.toJson();
+ }
if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
if (variableDeclarationStatement_variables != null)
_result["variableDeclarationStatement_variables"] =
@@ -16966,6 +17189,9 @@
_result["simpleIdentifier_element"] = simpleIdentifier_element;
if (simpleIdentifier_token != 0)
_result["simpleIdentifier_token"] = simpleIdentifier_token;
+ if (simpleIdentifier_elementType != null)
+ _result["simpleIdentifier_elementType"] =
+ simpleIdentifier_elementType.toJson();
if (expression_type != null)
_result["expression_type"] = expression_type.toJson();
}
@@ -17180,6 +17406,7 @@
"binaryExpression_element": binaryExpression_element,
"binaryExpression_rightOperand": binaryExpression_rightOperand,
"binaryExpression_operator": binaryExpression_operator,
+ "binaryExpression_elementType": binaryExpression_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -17212,16 +17439,6 @@
"kind": kind,
};
}
- if (kind == idl.LinkedNodeKind.typeName) {
- return {
- "typeName_type": typeName_type,
- "typeName_name": typeName_name,
- "typeName_question": typeName_question,
- "typeName_typeArguments": typeName_typeArguments,
- "isSynthetic": isSynthetic,
- "kind": kind,
- };
- }
if (kind == idl.LinkedNodeKind.adjacentStrings) {
return {
"adjacentStrings_strings": adjacentStrings_strings,
@@ -17386,8 +17603,7 @@
"uriBasedDirective_uri": uriBasedDirective_uri,
"isSynthetic": isSynthetic,
"kind": kind,
- "namespaceDirective_selectedUriContent":
- namespaceDirective_selectedUriContent,
+ "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
"uriBasedDirective_uriContent": uriBasedDirective_uriContent,
};
}
@@ -17406,8 +17622,7 @@
"uriBasedDirective_uri": uriBasedDirective_uri,
"isSynthetic": isSynthetic,
"kind": kind,
- "namespaceDirective_selectedUriContent":
- namespaceDirective_selectedUriContent,
+ "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
"uriBasedDirective_uriContent": uriBasedDirective_uriContent,
};
}
@@ -17650,8 +17865,6 @@
"uriBasedDirective_uri": uriBasedDirective_uri,
"isSynthetic": isSynthetic,
"kind": kind,
- "namespaceDirective_selectedUriContent":
- namespaceDirective_selectedUriContent,
"uriBasedDirective_uriContent": uriBasedDirective_uriContent,
};
}
@@ -17666,8 +17879,6 @@
"directive_semicolon": directive_semicolon,
"isSynthetic": isSynthetic,
"kind": kind,
- "namespaceDirective_selectedUriContent":
- namespaceDirective_selectedUriContent,
};
}
if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
@@ -17689,6 +17900,7 @@
"typeParameter_bound": typeParameter_bound,
"typeParameter_extendsKeyword": typeParameter_extendsKeyword,
"typeParameter_name": typeParameter_name,
+ "typeParameter_id": typeParameter_id,
"codeLength": codeLength,
"codeOffset": codeOffset,
"isSynthetic": isSynthetic,
@@ -17770,6 +17982,7 @@
"assignmentExpression_rightHandSide":
assignmentExpression_rightHandSide,
"assignmentExpression_operator": assignmentExpression_operator,
+ "assignmentExpression_elementType": assignmentExpression_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -17866,6 +18079,7 @@
"constructorName_element": constructorName_element,
"constructorName_type": constructorName_type,
"constructorName_period": constructorName_period,
+ "constructorName_elementType": constructorName_elementType,
"isSynthetic": isSynthetic,
"kind": kind,
};
@@ -18041,6 +18255,7 @@
"indexExpression_period": indexExpression_period,
"indexExpression_leftBracket": indexExpression_leftBracket,
"indexExpression_rightBracket": indexExpression_rightBracket,
+ "indexExpression_elementType": indexExpression_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -18145,6 +18360,7 @@
"postfixExpression_operand": postfixExpression_operand,
"postfixExpression_element": postfixExpression_element,
"postfixExpression_operator": postfixExpression_operator,
+ "postfixExpression_elementType": postfixExpression_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -18165,6 +18381,7 @@
"prefixExpression_operand": prefixExpression_operand,
"prefixExpression_element": prefixExpression_element,
"prefixExpression_operator": prefixExpression_operator,
+ "prefixExpression_elementType": prefixExpression_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -18192,6 +18409,8 @@
redirectingConstructorInvocation_period,
"redirectingConstructorInvocation_thisKeyword":
redirectingConstructorInvocation_thisKeyword,
+ "redirectingConstructorInvocation_elementType":
+ redirectingConstructorInvocation_elementType,
"isSynthetic": isSynthetic,
"kind": kind,
};
@@ -18224,6 +18443,8 @@
"superConstructorInvocation_period": superConstructorInvocation_period,
"superConstructorInvocation_superKeyword":
superConstructorInvocation_superKeyword,
+ "superConstructorInvocation_elementType":
+ superConstructorInvocation_elementType,
"isSynthetic": isSynthetic,
"kind": kind,
};
@@ -18237,6 +18458,16 @@
"kind": kind,
};
}
+ if (kind == idl.LinkedNodeKind.typeName) {
+ return {
+ "typeName_name": typeName_name,
+ "typeName_question": typeName_question,
+ "typeName_typeArguments": typeName_typeArguments,
+ "typeName_type": typeName_type,
+ "isSynthetic": isSynthetic,
+ "kind": kind,
+ };
+ }
if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
return {
"variableDeclarationStatement_variables":
@@ -18344,6 +18575,7 @@
return {
"simpleIdentifier_element": simpleIdentifier_element,
"simpleIdentifier_token": simpleIdentifier_token,
+ "simpleIdentifier_elementType": simpleIdentifier_elementType,
"expression_type": expression_type,
"isSynthetic": isSynthetic,
"kind": kind,
@@ -18891,13 +19123,13 @@
implements idl.LinkedNodeType {
List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
LinkedNodeTypeBuilder _functionReturnType;
- List<int> _functionTypeParameters;
+ List<LinkedNodeTypeTypeParameterBuilder> _functionTypeParameters;
int _genericTypeAliasReference;
List<LinkedNodeTypeBuilder> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
- int _typeParameterParameter;
+ int _typeParameterId;
@override
List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
@@ -18916,11 +19148,10 @@
}
@override
- List<int> get functionTypeParameters => _functionTypeParameters ??= <int>[];
+ List<LinkedNodeTypeTypeParameterBuilder> get functionTypeParameters =>
+ _functionTypeParameters ??= <LinkedNodeTypeTypeParameterBuilder>[];
- /// References to [LinkedNodeReferences].
- set functionTypeParameters(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
+ set functionTypeParameters(List<LinkedNodeTypeTypeParameterBuilder> value) {
this._functionTypeParameters = value;
}
@@ -18965,24 +19196,23 @@
}
@override
- int get typeParameterParameter => _typeParameterParameter ??= 0;
+ int get typeParameterId => _typeParameterId ??= 0;
- /// Reference to a [LinkedNodeReferences].
- set typeParameterParameter(int value) {
+ set typeParameterId(int value) {
assert(value == null || value >= 0);
- this._typeParameterParameter = value;
+ this._typeParameterId = value;
}
LinkedNodeTypeBuilder(
{List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
LinkedNodeTypeBuilder functionReturnType,
- List<int> functionTypeParameters,
+ List<LinkedNodeTypeTypeParameterBuilder> functionTypeParameters,
int genericTypeAliasReference,
List<LinkedNodeTypeBuilder> genericTypeAliasTypeArguments,
int interfaceClass,
List<LinkedNodeTypeBuilder> interfaceTypeArguments,
idl.LinkedNodeTypeKind kind,
- int typeParameterParameter})
+ int typeParameterId})
: _functionFormalParameters = functionFormalParameters,
_functionReturnType = functionReturnType,
_functionTypeParameters = functionTypeParameters,
@@ -18991,12 +19221,13 @@
_interfaceClass = interfaceClass,
_interfaceTypeArguments = interfaceTypeArguments,
_kind = kind,
- _typeParameterParameter = typeParameterParameter;
+ _typeParameterId = typeParameterId;
/// Flush [informative] data recursively.
void flushInformative() {
_functionFormalParameters?.forEach((b) => b.flushInformative());
_functionReturnType?.flushInformative();
+ _functionTypeParameters?.forEach((b) => b.flushInformative());
_genericTypeAliasTypeArguments?.forEach((b) => b.flushInformative());
_interfaceTypeArguments?.forEach((b) => b.flushInformative());
}
@@ -19018,7 +19249,7 @@
} else {
signature.addInt(this._functionTypeParameters.length);
for (var x in this._functionTypeParameters) {
- signature.addInt(x);
+ x?.collectApiSignature(signature);
}
}
signature.addInt(this._interfaceClass ?? 0);
@@ -19031,7 +19262,7 @@
}
}
signature.addInt(this._kind == null ? 0 : this._kind.index);
- signature.addInt(this._typeParameterParameter ?? 0);
+ signature.addInt(this._typeParameterId ?? 0);
signature.addInt(this._genericTypeAliasReference ?? 0);
if (this._genericTypeAliasTypeArguments == null) {
signature.addInt(0);
@@ -19058,8 +19289,8 @@
offset_functionReturnType = _functionReturnType.finish(fbBuilder);
}
if (!(_functionTypeParameters == null || _functionTypeParameters.isEmpty)) {
- offset_functionTypeParameters =
- fbBuilder.writeListUint32(_functionTypeParameters);
+ offset_functionTypeParameters = fbBuilder.writeList(
+ _functionTypeParameters.map((b) => b.finish(fbBuilder)).toList());
}
if (!(_genericTypeAliasTypeArguments == null ||
_genericTypeAliasTypeArguments.isEmpty)) {
@@ -19097,8 +19328,8 @@
if (_kind != null && _kind != idl.LinkedNodeTypeKind.bottom) {
fbBuilder.addUint8(5, _kind.index);
}
- if (_typeParameterParameter != null && _typeParameterParameter != 0) {
- fbBuilder.addUint32(6, _typeParameterParameter);
+ if (_typeParameterId != null && _typeParameterId != 0) {
+ fbBuilder.addUint32(6, _typeParameterId);
}
return fbBuilder.endTable();
}
@@ -19122,13 +19353,13 @@
List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
idl.LinkedNodeType _functionReturnType;
- List<int> _functionTypeParameters;
+ List<idl.LinkedNodeTypeTypeParameter> _functionTypeParameters;
int _genericTypeAliasReference;
List<idl.LinkedNodeType> _genericTypeAliasTypeArguments;
int _interfaceClass;
List<idl.LinkedNodeType> _interfaceTypeArguments;
idl.LinkedNodeTypeKind _kind;
- int _typeParameterParameter;
+ int _typeParameterId;
@override
List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
@@ -19148,9 +19379,12 @@
}
@override
- List<int> get functionTypeParameters {
+ List<idl.LinkedNodeTypeTypeParameter> get functionTypeParameters {
_functionTypeParameters ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
+ const fb.ListReader<idl.LinkedNodeTypeTypeParameter>(
+ const _LinkedNodeTypeTypeParameterReader())
+ .vTableGet(
+ _bc, _bcOffset, 2, const <idl.LinkedNodeTypeTypeParameter>[]);
return _functionTypeParameters;
}
@@ -19191,10 +19425,10 @@
}
@override
- int get typeParameterParameter {
- _typeParameterParameter ??=
+ int get typeParameterId {
+ _typeParameterId ??=
const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
- return _typeParameterParameter;
+ return _typeParameterId;
}
}
@@ -19208,7 +19442,8 @@
if (functionReturnType != null)
_result["functionReturnType"] = functionReturnType.toJson();
if (functionTypeParameters.isNotEmpty)
- _result["functionTypeParameters"] = functionTypeParameters;
+ _result["functionTypeParameters"] =
+ functionTypeParameters.map((_value) => _value.toJson()).toList();
if (genericTypeAliasReference != 0)
_result["genericTypeAliasReference"] = genericTypeAliasReference;
if (genericTypeAliasTypeArguments.isNotEmpty)
@@ -19221,8 +19456,7 @@
interfaceTypeArguments.map((_value) => _value.toJson()).toList();
if (kind != idl.LinkedNodeTypeKind.bottom)
_result["kind"] = kind.toString().split('.')[1];
- if (typeParameterParameter != 0)
- _result["typeParameterParameter"] = typeParameterParameter;
+ if (typeParameterId != 0) _result["typeParameterId"] = typeParameterId;
return _result;
}
@@ -19236,7 +19470,7 @@
"interfaceClass": interfaceClass,
"interfaceTypeArguments": interfaceTypeArguments,
"kind": kind,
- "typeParameterParameter": typeParameterParameter,
+ "typeParameterId": typeParameterId,
};
@override
@@ -19381,6 +19615,116 @@
String toString() => convert.json.encode(toJson());
}
+class LinkedNodeTypeTypeParameterBuilder extends Object
+ with _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ LinkedNodeTypeBuilder _bound;
+ String _name;
+
+ @override
+ LinkedNodeTypeBuilder get bound => _bound;
+
+ set bound(LinkedNodeTypeBuilder value) {
+ this._bound = value;
+ }
+
+ @override
+ String get name => _name ??= '';
+
+ set name(String value) {
+ this._name = value;
+ }
+
+ LinkedNodeTypeTypeParameterBuilder({LinkedNodeTypeBuilder bound, String name})
+ : _bound = bound,
+ _name = name;
+
+ /// Flush [informative] data recursively.
+ void flushInformative() {
+ _bound?.flushInformative();
+ }
+
+ /// Accumulate non-[informative] data into [signature].
+ void collectApiSignature(api_sig.ApiSignature signature) {
+ signature.addString(this._name ?? '');
+ signature.addBool(this._bound != null);
+ this._bound?.collectApiSignature(signature);
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ fb.Offset offset_bound;
+ fb.Offset offset_name;
+ if (_bound != null) {
+ offset_bound = _bound.finish(fbBuilder);
+ }
+ if (_name != null) {
+ offset_name = fbBuilder.writeString(_name);
+ }
+ fbBuilder.startTable();
+ if (offset_bound != null) {
+ fbBuilder.addOffset(1, offset_bound);
+ }
+ if (offset_name != null) {
+ fbBuilder.addOffset(0, offset_name);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _LinkedNodeTypeTypeParameterReader
+ extends fb.TableReader<_LinkedNodeTypeTypeParameterImpl> {
+ const _LinkedNodeTypeTypeParameterReader();
+
+ @override
+ _LinkedNodeTypeTypeParameterImpl createObject(
+ fb.BufferContext bc, int offset) =>
+ new _LinkedNodeTypeTypeParameterImpl(bc, offset);
+}
+
+class _LinkedNodeTypeTypeParameterImpl extends Object
+ with _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _LinkedNodeTypeTypeParameterImpl(this._bc, this._bcOffset);
+
+ idl.LinkedNodeType _bound;
+ String _name;
+
+ @override
+ idl.LinkedNodeType get bound {
+ _bound ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
+ return _bound;
+ }
+
+ @override
+ String get name {
+ _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+ return _name;
+ }
+}
+
+abstract class _LinkedNodeTypeTypeParameterMixin
+ implements idl.LinkedNodeTypeTypeParameter {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (bound != null) _result["bound"] = bound.toJson();
+ if (name != '') _result["name"] = name;
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "bound": bound,
+ "name": name,
+ };
+
+ @override
+ String toString() => convert.json.encode(toJson());
+}
+
class LinkedNodeUnitBuilder extends Object
with _LinkedNodeUnitMixin
implements idl.LinkedNodeUnit {
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index bb86ffb..25f838b 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -406,8 +406,6 @@
function,
- genericTypeAlias,
-
interface,
typeParameter,
@@ -1861,6 +1859,8 @@
variantField_19:uint (id: 19);
+ variantField_23:LinkedNodeType (id: 23);
+
variantField_27:bool (id: 27);
variantField_9:LinkedNode (id: 9);
@@ -1897,12 +1897,10 @@
kind:LinkedNodeKind (id: 0);
- variantField_23:string (id: 23);
+ variantField_20:string (id: 20);
variantField_31:bool (id: 31);
- variantField_20:string (id: 20);
-
variantField_22:string (id: 22);
variantField_32:LinkedNodeVariablesDeclaration (id: 32);
@@ -1945,8 +1943,7 @@
functionReturnType:LinkedNodeType (id: 1);
- /// References to [LinkedNodeReferences].
- functionTypeParameters:[uint] (id: 2);
+ functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
genericTypeAliasReference:uint (id: 7);
@@ -1959,8 +1956,7 @@
kind:LinkedNodeTypeKind (id: 5);
- /// Reference to a [LinkedNodeReferences].
- typeParameterParameter:uint (id: 6);
+ typeParameterId:uint (id: 6);
}
/// Information about a formal parameter in a function type.
@@ -1972,6 +1968,13 @@
type:LinkedNodeType (id: 2);
}
+/// Information about a type parameter in a function type.
+table LinkedNodeTypeTypeParameter {
+ bound:LinkedNodeType (id: 1);
+
+ name:string (id: 0);
+}
+
/// Information about a single library in a [LinkedNodeLibrary].
table LinkedNodeUnit {
node:LinkedNode (id: 2);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 4b897bc..0bf34e0 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -915,6 +915,9 @@
@VariantId(15, variant: LinkedNodeKind.assignmentExpression)
int get assignmentExpression_element;
+ @VariantId(23, variant: LinkedNodeKind.assignmentExpression)
+ LinkedNodeType get assignmentExpression_elementType;
+
@VariantId(6, variant: LinkedNodeKind.assignmentExpression)
LinkedNode get assignmentExpression_leftHandSide;
@@ -933,6 +936,9 @@
@VariantId(15, variant: LinkedNodeKind.binaryExpression)
int get binaryExpression_element;
+ @VariantId(23, variant: LinkedNodeKind.binaryExpression)
+ LinkedNodeType get binaryExpression_elementType;
+
@VariantId(24, variant: LinkedNodeKind.binaryExpression)
LinkedNodeType get binaryExpression_invokeType;
@@ -1229,6 +1235,9 @@
@VariantId(15, variant: LinkedNodeKind.constructorName)
int get constructorName_element;
+ @VariantId(23, variant: LinkedNodeKind.constructorName)
+ LinkedNodeType get constructorName_elementType;
+
@VariantId(6, variant: LinkedNodeKind.constructorName)
LinkedNode get constructorName_name;
@@ -1668,6 +1677,9 @@
@VariantId(15, variant: LinkedNodeKind.indexExpression)
int get indexExpression_element;
+ @VariantId(23, variant: LinkedNodeKind.indexExpression)
+ LinkedNodeType get indexExpression_elementType;
+
@VariantId(6, variant: LinkedNodeKind.indexExpression)
LinkedNode get indexExpression_index;
@@ -1862,13 +1874,11 @@
])
List<LinkedNode> get namespaceDirective_configurations;
- @VariantId(23, variantList: [
+ @VariantId(20, variantList: [
LinkedNodeKind.exportDirective,
LinkedNodeKind.importDirective,
- LinkedNodeKind.partDirective,
- LinkedNodeKind.partOfDirective,
])
- String get namespaceDirective_selectedUriContent;
+ String get namespaceDirective_selectedUri;
@VariantId(6, variant: LinkedNodeKind.nativeClause)
LinkedNode get nativeClause_name;
@@ -1950,6 +1960,9 @@
@VariantId(15, variant: LinkedNodeKind.postfixExpression)
int get postfixExpression_element;
+ @VariantId(23, variant: LinkedNodeKind.postfixExpression)
+ LinkedNodeType get postfixExpression_elementType;
+
@VariantId(6, variant: LinkedNodeKind.postfixExpression)
LinkedNode get postfixExpression_operand;
@@ -1968,6 +1981,9 @@
@VariantId(15, variant: LinkedNodeKind.prefixExpression)
int get prefixExpression_element;
+ @VariantId(23, variant: LinkedNodeKind.prefixExpression)
+ LinkedNodeType get prefixExpression_elementType;
+
@VariantId(6, variant: LinkedNodeKind.prefixExpression)
LinkedNode get prefixExpression_operand;
@@ -1992,6 +2008,9 @@
@VariantId(15, variant: LinkedNodeKind.redirectingConstructorInvocation)
int get redirectingConstructorInvocation_element;
+ @VariantId(23, variant: LinkedNodeKind.redirectingConstructorInvocation)
+ LinkedNodeType get redirectingConstructorInvocation_elementType;
+
@VariantId(16, variant: LinkedNodeKind.redirectingConstructorInvocation)
int get redirectingConstructorInvocation_period;
@@ -2040,6 +2059,9 @@
@VariantId(15, variant: LinkedNodeKind.simpleIdentifier)
int get simpleIdentifier_element;
+ @VariantId(23, variant: LinkedNodeKind.simpleIdentifier)
+ LinkedNodeType get simpleIdentifier_elementType;
+
@VariantId(16, variant: LinkedNodeKind.simpleIdentifier)
int get simpleIdentifier_token;
@@ -2076,6 +2098,9 @@
@VariantId(15, variant: LinkedNodeKind.superConstructorInvocation)
int get superConstructorInvocation_element;
+ @VariantId(23, variant: LinkedNodeKind.superConstructorInvocation)
+ LinkedNodeType get superConstructorInvocation_elementType;
+
@VariantId(16, variant: LinkedNodeKind.superConstructorInvocation)
int get superConstructorInvocation_period;
@@ -2210,7 +2235,7 @@
@VariantId(15, variant: LinkedNodeKind.typeName)
int get typeName_question;
- @VariantId(24, variant: LinkedNodeKind.typeName)
+ @VariantId(23, variant: LinkedNodeKind.typeName)
LinkedNodeType get typeName_type;
@VariantId(7, variant: LinkedNodeKind.typeName)
@@ -2222,6 +2247,9 @@
@VariantId(15, variant: LinkedNodeKind.typeParameter)
int get typeParameter_extendsKeyword;
+ @VariantId(16, variant: LinkedNodeKind.typeParameter)
+ int get typeParameter_id;
+
@VariantId(7, variant: LinkedNodeKind.typeParameter)
LinkedNode get typeParameter_name;
@@ -2501,9 +2529,8 @@
@Id(1)
LinkedNodeType get functionReturnType;
- /// References to [LinkedNodeReferences].
@Id(2)
- List<int> get functionTypeParameters;
+ List<LinkedNodeTypeTypeParameter> get functionTypeParameters;
@Id(7)
int get genericTypeAliasReference;
@@ -2521,9 +2548,8 @@
@Id(5)
LinkedNodeTypeKind get kind;
- /// Reference to a [LinkedNodeReferences].
@Id(6)
- int get typeParameterParameter;
+ int get typeParameterId;
}
/// Information about a formal parameter in a function type.
@@ -2543,12 +2569,20 @@
bottom,
dynamic_,
function,
- genericTypeAlias,
interface,
typeParameter,
void_
}
+/// Information about a type parameter in a function type.
+abstract class LinkedNodeTypeTypeParameter extends base.SummaryClass {
+ @Id(1)
+ LinkedNodeType get bound;
+
+ @Id(0)
+ String get name;
+}
+
/// Information about a single library in a [LinkedNodeLibrary].
abstract class LinkedNodeUnit extends base.SummaryClass {
@Id(2)
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index df84918..012a2ac 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -5347,6 +5347,7 @@
InterfaceType _listType;
InterfaceType _mapType;
InterfaceType _mapObjectObjectType;
+ InterfaceType _neverType;
InterfaceType _nullType;
InterfaceType _numType;
InterfaceType _objectType;
@@ -5431,6 +5432,10 @@
_mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
@override
+ InterfaceType get neverType =>
+ _neverType ??= _buildInterfaceType(_linker.coreLibrary, 'Never');
+
+ @override
DartObjectImpl get nullObject {
// TODO(paulberry): implement if needed
throw new UnimplementedError();
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index dcb3d5f..f31b076 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -128,6 +128,7 @@
InterfaceType _listType;
InterfaceType _mapType;
InterfaceType _mapObjectObjectType;
+ InterfaceType _neverType;
DartObjectImpl _nullObject;
InterfaceType _nullType;
InterfaceType _numType;
@@ -266,6 +267,12 @@
}
@override
+ InterfaceType get neverType {
+ assert(_coreLibrary != null);
+ return _neverType ??= _getType(_coreLibrary, 'Never');
+ }
+
+ @override
DartObjectImpl get nullObject {
if (_nullObject == null) {
_nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index e08c4f6..15cab36 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -8,23 +8,16 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
/// Deserializer of fully resolved ASTs from flat buffers.
class AstBinaryReader {
final LinkedUnitContext _unitContext;
- ElementImpl _enclosingElement;
- Reference _localRef;
- int _localRefNextId;
- List<ParameterElement> _localParameters;
-
/// Set to `true` when this reader is used to lazily read its unit.
bool isLazy = false;
@@ -45,35 +38,19 @@
return _readType(data);
}
- /// Run [f] that reads nodes with local declarations, making sure that
- /// [_localRef] is ready for adding local references.
- T withLocalScope<T>(ElementImpl enclosingElement, T f()) {
- var isLocalContextOwner = _localRef == null;
- try {
- if (_localRef == null) {
- _enclosingElement = enclosingElement;
- _localRef = Reference.root().getChild('@local');
- _localRefNextId = 0;
- }
- return f();
- } finally {
- if (isLocalContextOwner) {
- _enclosingElement = null;
- _localRef = null;
- _localRefNextId = null;
- _localParameters = null;
- }
- }
- }
+ Element _elementOfComponents(
+ int rawElementIndex,
+ LinkedNodeType definingTypeNode,
+ ) {
+ var element = _getElement(rawElementIndex);
+ if (definingTypeNode == null) return element;
- ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
- if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
- return ParameterKind.NAMED;
+ var definingType = _readType(definingTypeNode);
+ if (element is ConstructorElement) {
+ return ConstructorMember.from(element, definingType);
+ } else {
+ throw UnimplementedError('(${element.runtimeType}) $element');
}
- if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
- return ParameterKind.POSITIONAL;
- }
- return ParameterKind.REQUIRED;
}
T _getElement<T extends Element>(int index) {
@@ -81,11 +58,6 @@
return bundleContext.elementOfIndex(index);
}
- List<T> _getElements<T extends Element>(List<int> indexList) {
- var bundleContext = _unitContext.bundleContext;
- return bundleContext.elementsOfIndexes(indexList);
- }
-
Token _getToken(int index) {
return _unitContext.tokensContext.tokenOfIndex(index);
}
@@ -160,7 +132,10 @@
_getToken(data.assignmentExpression_operator),
_readNode(data.assignmentExpression_rightHandSide),
)
- ..staticElement = _getElement(data.assignmentExpression_element)
+ ..staticElement = _elementOfComponents(
+ data.assignmentExpression_element,
+ data.assignmentExpression_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -177,7 +152,10 @@
_getToken(data.binaryExpression_operator),
_readNode(data.binaryExpression_rightOperand),
)
- ..staticElement = _getElement(data.binaryExpression_element)
+ ..staticElement = _elementOfComponents(
+ data.binaryExpression_element,
+ data.binaryExpression_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -240,7 +218,7 @@
_getToken(data.classDeclaration_abstractKeyword),
_getToken(data.classDeclaration_classKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+ _readNode(data.classOrMixinDeclaration_typeParameters),
_readNodeLazy(data.classDeclaration_extendsClause),
_readNodeLazy(data.classDeclaration_withClause),
_readNodeLazy(data.classOrMixinDeclaration_implementsClause),
@@ -259,7 +237,7 @@
_readNodeListLazy(data.annotatedNode_metadata),
_getToken(data.typeAlias_typedefKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classTypeAlias_typeParameters),
+ _readNode(data.classTypeAlias_typeParameters),
_getToken(data.classTypeAlias_equals),
_getToken(data.classTypeAlias_abstractKeyword),
_readNodeLazy(data.classTypeAlias_superclass),
@@ -360,7 +338,10 @@
_readNode(data.constructorName_type),
_getToken(data.constructorName_period),
_readNode(data.constructorName_name),
- )..staticElement = _getElement(data.constructorName_element);
+ )..staticElement = _elementOfComponents(
+ data.constructorName_element,
+ data.constructorName_elementType,
+ );
}
ContinueStatement _read_continueStatement(LinkedNode data) {
@@ -613,37 +594,11 @@
}
FunctionExpression _read_functionExpression(LinkedNode data) {
- var prevLocalParameters = _localParameters;
- var thisLocalParameters = <ParameterElement>[];
- _localParameters = thisLocalParameters;
-
var node = astFactory.functionExpression(
- _readNodeLazy(data.functionExpression_typeParameters),
+ _readNode(data.functionExpression_typeParameters),
_readNodeLazy(data.functionExpression_formalParameters),
_readNodeLazy(data.functionExpression_body),
);
- _localParameters = prevLocalParameters;
-
- if (_localRef != null) {
- throw UnimplementedError();
-// var element = FunctionElementImpl.forLinkedNode(
-// _enclosingElement,
-// _localRef.getChild('${_localRefNextId++}'),
-// data,
-// );
-// element.parameters = thisLocalParameters;
-//
-// var body = node.body;
-// if (body.isAsynchronous) {
-// element.asynchronous = true;
-// }
-// if (body.isGenerator) {
-// element.generator = true;
-// }
-//
-// element.type = new FunctionTypeImpl(element);
-// (node as FunctionExpressionImpl).declaredElement = element;
- }
LazyFunctionExpression.setData(node, data);
return node;
}
@@ -664,7 +619,7 @@
_getToken(data.typeAlias_typedefKeyword),
_readNodeLazy(data.functionTypeAlias_returnType),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.functionTypeAlias_typeParameters),
+ _readNode(data.functionTypeAlias_typeParameters),
_readNodeLazy(data.functionTypeAlias_formalParameters),
_getToken(data.typeAlias_semicolon),
);
@@ -684,19 +639,6 @@
typeParameters:
_readNode(data.functionTypedFormalParameter_typeParameters),
);
-
- if (_localRef != null) {
- throw UnimplementedError();
-// var name = node.identifier.name;
-// var element = ParameterElementImpl.forLinkedNodeFactory(
-// _enclosingElement,
-// _localRef.getChild('${_localRefNextId++}').getChild(name),
-// data,
-// );
-// _localParameters.add(element);
-// node.identifier.staticElement = element;
- }
-
LazyFormalParameter.setData(node, data);
return node;
}
@@ -705,7 +647,7 @@
GenericFunctionTypeImpl node = astFactory.genericFunctionType(
_readNodeLazy(data.genericFunctionType_returnType),
_getToken(data.genericFunctionType_functionKeyword),
- _readNodeLazy(data.genericFunctionType_typeParameters),
+ _readNode(data.genericFunctionType_typeParameters),
_readNodeLazy(data.genericFunctionType_formalParameters),
question: _getToken(data.genericFunctionType_question),
);
@@ -720,7 +662,7 @@
_readNodeList(data.annotatedNode_metadata),
_getToken(data.typeAlias_typedefKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.genericTypeAlias_typeParameters),
+ _readNode(data.genericTypeAlias_typeParameters),
_getToken(data.genericTypeAlias_equals),
_readNodeLazy(data.genericTypeAlias_functionType),
_getToken(data.typeAlias_semicolon),
@@ -792,7 +734,10 @@
_getToken(data.indexExpression_rightBracket),
)
..period = _getToken(data.indexExpression_period)
- ..staticElement = _getElement(data.indexExpression_element)
+ ..staticElement = _elementOfComponents(
+ data.indexExpression_element,
+ data.indexExpression_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -896,7 +841,7 @@
_getToken(data.methodDeclaration_propertyKeyword),
_getToken(data.methodDeclaration_operatorKeyword),
_readNode(data.methodDeclaration_name),
- _readNodeLazy(data.methodDeclaration_typeParameters),
+ _readNode(data.methodDeclaration_typeParameters),
_readNodeLazy(data.methodDeclaration_formalParameters),
_readNodeLazy(data.methodDeclaration_body),
);
@@ -920,7 +865,7 @@
_readNodeList(data.annotatedNode_metadata),
_getToken(data.mixinDeclaration_mixinKeyword),
_readNode(data.namedCompilationUnitMember_name),
- _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+ _readNode(data.classOrMixinDeclaration_typeParameters),
_readNodeLazy(data.mixinDeclaration_onClause),
_readNodeLazy(data.classOrMixinDeclaration_implementsClause),
_getToken(data.classOrMixinDeclaration_leftBracket),
@@ -1005,7 +950,10 @@
_readNode(data.postfixExpression_operand),
_getToken(data.postfixExpression_operator),
)
- ..staticElement = _getElement(data.postfixExpression_element)
+ ..staticElement = _elementOfComponents(
+ data.postfixExpression_element,
+ data.postfixExpression_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -1022,7 +970,10 @@
_getToken(data.prefixExpression_operator),
_readNode(data.prefixExpression_operand),
)
- ..staticElement = _getElement(data.prefixExpression_element)
+ ..staticElement = _elementOfComponents(
+ data.prefixExpression_element,
+ data.prefixExpression_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -1041,8 +992,10 @@
_getToken(data.redirectingConstructorInvocation_period),
_readNode(data.redirectingConstructorInvocation_constructorName),
_readNode(data.redirectingConstructorInvocation_arguments),
- )..staticElement =
- _getElement(data.redirectingConstructorInvocation_element);
+ )..staticElement = _elementOfComponents(
+ data.redirectingConstructorInvocation_element,
+ data.redirectingConstructorInvocation_elementType,
+ );
}
RethrowExpression _read_rethrowExpression(LinkedNode data) {
@@ -1097,20 +1050,6 @@
metadata: _readNodeList(data.normalFormalParameter_metadata),
keyword: _getToken(data.simpleFormalParameter_keyword),
);
-
- if (_localRef != null) {
- throw UnimplementedError();
-// var name = node.identifier.name;
-// var element = ParameterElementImpl.forLinkedNodeFactory(
-// _enclosingElement,
-// _localRef.getChild('${_localRefNextId++}').getChild(name),
-// data,
-// );
-// _localParameters.add(element);
-// node.identifier.staticElement = element;
-// node.declaredElement = element;
- }
-
LazyFormalParameter.setData(node, data);
return node;
}
@@ -1119,7 +1058,10 @@
return astFactory.simpleIdentifier(
_getToken(data.simpleIdentifier_token),
)
- ..staticElement = _getElement(data.simpleIdentifier_element)
+ ..staticElement = _elementOfComponents(
+ data.simpleIdentifier_element,
+ data.simpleIdentifier_elementType,
+ )
..staticType = _readType(data.expression_type);
}
@@ -1149,7 +1091,10 @@
_getToken(data.superConstructorInvocation_period),
_readNode(data.superConstructorInvocation_constructorName),
_readNode(data.superConstructorInvocation_arguments),
- )..staticElement = _getElement(data.superConstructorInvocation_element);
+ )..staticElement = _elementOfComponents(
+ data.superConstructorInvocation_element,
+ data.superConstructorInvocation_elementType,
+ );
}
SuperExpression _read_superExpression(LinkedNode data) {
@@ -1256,6 +1201,7 @@
_readNodeLazy(data.typeParameter_bound),
);
LazyTypeParameter.setData(node, data);
+ _unitContext.addTypeParameter(data.typeParameter_id, node);
return node;
}
@@ -1588,57 +1534,6 @@
}
DartType _readType(LinkedNodeType data) {
- if (data == null) return null;
-
- switch (data.kind) {
- case LinkedNodeTypeKind.bottom:
- return BottomTypeImpl.instance;
- case LinkedNodeTypeKind.dynamic_:
- return DynamicTypeImpl.instance;
- case LinkedNodeTypeKind.function:
- return FunctionTypeImpl.synthetic(
- _readType(data.functionReturnType),
- _getElements(data.functionTypeParameters),
- data.functionFormalParameters
- .map((p) => ParameterElementImpl.synthetic(
- p.name, _readType(p.type), _formalParameterKind(p.kind)))
- .toList(),
- );
- case LinkedNodeTypeKind.interface:
- var element = _getElement(data.interfaceClass);
- if (element != null) {
- return InterfaceTypeImpl.explicit(
- element,
- _readTypes(
- data.interfaceTypeArguments,
- const <InterfaceType>[],
- ),
- );
- }
- return DynamicTypeImpl.instance;
- case LinkedNodeTypeKind.typeParameter:
- var element = _getElement(data.typeParameterParameter);
- // TODO(scheglov) Remove when references include all type parameters.
- element ??= TypeParameterElementImpl('', -1);
- return TypeParameterTypeImpl(element);
- case LinkedNodeTypeKind.void_:
- return VoidTypeImpl.instance;
- default:
- throw UnimplementedError('Type kind: ${data.kind}');
- }
- }
-
- List<T> _readTypes<T extends DartType>(
- List<LinkedNodeType> dataList,
- List<T> ifEmpty,
- ) {
- if (dataList.isEmpty) return ifEmpty;
-
- var result = List<T>(dataList.length);
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- result[i] = _readType(data);
- }
- return result;
+ return _unitContext.readType(data);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 0766c24..76a97c7 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -8,7 +8,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -18,7 +17,7 @@
/// Serializer of fully resolved ASTs into flat buffers.
class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
- final LinkingBundleContext _linkingBundleContext;
+ final LinkingBundleContext _linkingContext;
final TokensContext _tokensContext;
/// This field is set temporary while visiting [FieldDeclaration] or
@@ -26,7 +25,7 @@
/// in these declarations.
LinkedNodeVariablesDeclarationBuilder _variablesDeclaration;
- AstBinaryWriter(this._linkingBundleContext, this._tokensContext);
+ AstBinaryWriter(this._linkingContext, this._tokensContext);
@override
LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
@@ -93,8 +92,10 @@
@override
LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.assignmentExpression(
- assignmentExpression_element: _getReferenceIndex(node.staticElement),
+ assignmentExpression_element: elementComponents.rawElement,
+ assignmentExpression_elementType: elementComponents.definingType,
assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
assignmentExpression_operator: _getToken(node.operator),
assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
@@ -113,8 +114,10 @@
@override
LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.binaryExpression(
- binaryExpression_element: _getReferenceIndex(node.staticElement),
+ binaryExpression_element: elementComponents.rawElement,
+ binaryExpression_elementType: elementComponents.definingType,
binaryExpression_leftOperand: node.leftOperand.accept(this),
binaryExpression_operator: _getToken(node.operator),
binaryExpression_rightOperand: node.rightOperand.accept(this),
@@ -208,6 +211,7 @@
classTypeAlias_withClause: node.withClause.accept(this),
);
_storeTypeAlias(builder, node);
+ _storeIsSimpleBounded(builder, node);
return builder;
}
@@ -302,8 +306,10 @@
@override
LinkedNodeBuilder visitConstructorName(ConstructorName node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.constructorName(
- constructorName_element: _getReferenceIndex(node.staticElement),
+ constructorName_element: elementComponents.rawElement,
+ constructorName_elementType: elementComponents.definingType,
constructorName_name: node.name?.accept(this),
constructorName_period: _getToken(node.period),
constructorName_type: node.type.accept(this),
@@ -597,6 +603,7 @@
);
_storeTypeAlias(builder, node);
_writeActualReturnType(builder, node);
+ _storeIsSimpleBounded(builder, node);
return builder;
}
@@ -636,6 +643,7 @@
genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
);
_storeTypeAlias(builder, node);
+ _storeIsSimpleBounded(builder, node);
return builder;
}
@@ -694,8 +702,10 @@
@override
LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.indexExpression(
- indexExpression_element: _getReferenceIndex(node.staticElement),
+ indexExpression_element: elementComponents.rawElement,
+ indexExpression_elementType: elementComponents.definingType,
indexExpression_index: node.index.accept(this),
indexExpression_leftBracket: _getToken(node.leftBracket),
indexExpression_period: _getToken(node.period),
@@ -929,9 +939,11 @@
@override
LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.postfixExpression(
expression_type: _writeType(node.staticType),
- postfixExpression_element: _getReferenceIndex(node.staticElement),
+ postfixExpression_element: elementComponents.rawElement,
+ postfixExpression_elementType: elementComponents.definingType,
postfixExpression_operand: node.operand.accept(this),
postfixExpression_operator: _getToken(node.operator),
);
@@ -949,9 +961,11 @@
@override
LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
return LinkedNodeBuilder.prefixExpression(
expression_type: _writeType(node.staticType),
- prefixExpression_element: _getReferenceIndex(node.staticElement),
+ prefixExpression_element: elementComponents.rawElement,
+ prefixExpression_elementType: elementComponents.definingType,
prefixExpression_operand: node.operand.accept(this),
prefixExpression_operator: _getToken(node.operator),
);
@@ -971,13 +985,15 @@
@override
LinkedNodeBuilder visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
var builder = LinkedNodeBuilder.redirectingConstructorInvocation(
redirectingConstructorInvocation_arguments:
node.argumentList.accept(this),
redirectingConstructorInvocation_constructorName:
node.constructorName?.accept(this),
- redirectingConstructorInvocation_element:
- _getReferenceIndex(node.staticElement),
+ redirectingConstructorInvocation_element: elementComponents.rawElement,
+ redirectingConstructorInvocation_elementType:
+ elementComponents.definingType,
redirectingConstructorInvocation_period: _getToken(node.period),
redirectingConstructorInvocation_thisKeyword: _getToken(node.thisKeyword),
);
@@ -1052,8 +1068,10 @@
}
}
+ var elementComponents = _componentsOfElement(element);
return LinkedNodeBuilder.simpleIdentifier(
- simpleIdentifier_element: _getReferenceIndex(element),
+ simpleIdentifier_element: elementComponents.rawElement,
+ simpleIdentifier_elementType: elementComponents.definingType,
simpleIdentifier_token: _getToken(node.token),
expression_type: _writeType(node.staticType),
);
@@ -1088,12 +1106,13 @@
@override
LinkedNodeBuilder visitSuperConstructorInvocation(
SuperConstructorInvocation node) {
+ var elementComponents = _componentsOfElement(node.staticElement);
var builder = LinkedNodeBuilder.superConstructorInvocation(
superConstructorInvocation_arguments: node.argumentList.accept(this),
superConstructorInvocation_constructorName:
node.constructorName?.accept(this),
- superConstructorInvocation_element:
- _getReferenceIndex(node.staticElement),
+ superConstructorInvocation_element: elementComponents.rawElement,
+ superConstructorInvocation_elementType: elementComponents.definingType,
superConstructorInvocation_period: _getToken(node.period),
superConstructorInvocation_superKeyword: _getToken(node.superKeyword),
);
@@ -1222,6 +1241,9 @@
typeParameter_name: node.name.accept(this));
_storeDeclaration(builder, node);
_storeCodeOffsetLength(builder, node);
+ builder.typeParameter_id = _linkingContext.idOfTypeParameter(
+ node.declaredElement,
+ );
return builder;
}
@@ -1307,19 +1329,15 @@
return node.accept(this);
}
- int _getReferenceIndex(Element element) {
- if (element == null) return 0;
-
+ _ElementComponents _componentsOfElement(Element element) {
if (element is Member) {
- element = (element as Member).baseElement;
+ var elementIndex = _indexOfElement(element.baseElement);
+ var definingTypeNode = _writeType(element.definingType);
+ return _ElementComponents(elementIndex, definingTypeNode);
}
- var reference = (element as ElementImpl).reference;
- if (identical(element, DynamicElementImpl.instance)) {
- reference = _linkingBundleContext.dynamicReference;
- }
-
- return _linkingBundleContext.indexOfReference(reference);
+ var elementIndex = _indexOfElement(element);
+ return _ElementComponents(elementIndex, null);
}
int _getToken(Token token) {
@@ -1335,6 +1353,10 @@
return result;
}
+ int _indexOfElement(Element element) {
+ return _linkingContext.indexOfElement(element);
+ }
+
void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
builder
..annotatedNode_comment = node.documentationComment?.accept(this)
@@ -1356,6 +1378,7 @@
..classOrMixinDeclaration_typeParameters =
node.typeParameters?.accept(this);
_storeNamedCompilationUnitMember(builder, node);
+ _storeIsSimpleBounded(builder, node);
}
void _storeCodeOffsetLength(LinkedNodeBuilder builder, AstNode node) {
@@ -1460,6 +1483,12 @@
..invocationExpression_typeArguments = node.typeArguments?.accept(this);
}
+ void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) {
+ var flag = LazyAst.isSimplyBounded(node);
+ // TODO(scheglov) Check for `null` when writing resolved AST.
+ builder.simplyBoundable_isSimplyBounded = flag;
+ }
+
void _storeNamedCompilationUnitMember(
LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
_storeCompilationUnitMember(builder, node);
@@ -1473,7 +1502,7 @@
builder
..namespaceDirective_combinators = _writeNodeList(node.combinators)
..namespaceDirective_configurations = _writeNodeList(node.configurations)
- ..namespaceDirective_selectedUriContent = node.selectedUriContent
+ ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node)
..directive_semicolon = _getToken(node.semicolon);
}
@@ -1517,7 +1546,7 @@
builder
..uriBasedDirective_uri = node.uri.accept(this)
..uriBasedDirective_uriContent = node.uriContent
- ..uriBasedDirective_uriElement = _getReferenceIndex(node.uriElement);
+ ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
}
void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
@@ -1545,6 +1574,14 @@
}
LinkedNodeTypeBuilder _writeType(DartType type) {
- return _linkingBundleContext.writeType(type);
+ return _linkingContext.writeType(type);
}
}
+
+/// Components of a [Member] - the raw element, and the defining type.
+class _ElementComponents {
+ final int rawElement;
+ final LinkedNodeType definingType;
+
+ _ElementComponents(this.rawElement, this.definingType);
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index ab43e11..a8a0d5a 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -21,6 +21,7 @@
AstNode node, {
ClassElement enclosingClassElement,
ExecutableElement enclosingExecutableElement,
+ bool doAstRewrite = false,
}) {
var source = _FakeSource();
var errorListener = AnalysisErrorListener.NULL_LISTENER;
@@ -30,7 +31,13 @@
nameScope: _nameScope);
node.accept(typeResolverVisitor);
-// expression.accept(_astRewriteVisitor);
+ if (doAstRewrite) {
+ var astRewriteVisitor = new AstRewriteVisitor(_linker.typeSystem,
+ _library, source, _linker.typeProvider, errorListener,
+ nameScope: _nameScope);
+ node.accept(astRewriteVisitor);
+ }
+
// expression.accept(_variableResolverVisitor);
// if (_linker.getAst != null) {
// expression.accept(_partialResolverVisitor);
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index be3a93a..dab6481 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -3,9 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart' as ast;
-import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/scope.dart' show LibraryScope;
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -13,6 +12,7 @@
import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
import 'package:analyzer/src/summary2/default_value_resolver.dart';
import 'package:analyzer/src/summary2/export.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
@@ -20,8 +20,6 @@
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/reference_resolver.dart';
import 'package:analyzer/src/summary2/scope.dart';
-import 'package:analyzer/src/summary2/top_level_inference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
class SourceLibraryBuilder {
final Linker linker;
@@ -31,7 +29,7 @@
LinkedLibraryContext context;
- LibraryElement element;
+ LibraryElementImpl element;
LibraryScope libraryScope;
/// Local declarations.
@@ -48,22 +46,33 @@
var unitContext = context.units[0];
for (var directive in unitContext.unit_withDirectives.directives) {
if (directive is ast.ExportDirective) {
- var relativeUriStr = directive.uri.stringValue;
- var relativeUri = Uri.parse(relativeUriStr);
- var uri = resolveRelativeUri(this.uri, relativeUri);
- var exported = linker.builders[uri];
- if (exported != null) {
- var combinators = directive.combinators.map((node) {
- if (node is ast.ShowCombinator) {
- var nameList = node.shownNames.map((i) => i.name).toList();
- return Combinator.show(nameList);
- } else if (node is ast.HideCombinator) {
- var nameList = node.hiddenNames.map((i) => i.name).toList();
- return Combinator.hide(nameList);
- }
- }).toList();
+ Uri uri;
+ try {
+ uri = _selectAbsoluteUri(directive);
+ if (uri == null) continue;
+ } on FormatException {
+ continue;
+ }
- exported.exporters.add(new Export(this, exported, combinators));
+ var combinators = directive.combinators.map((node) {
+ if (node is ast.ShowCombinator) {
+ var nameList = node.shownNames.map((i) => i.name).toList();
+ return Combinator.show(nameList);
+ } else if (node is ast.HideCombinator) {
+ var nameList = node.hiddenNames.map((i) => i.name).toList();
+ return Combinator.hide(nameList);
+ }
+ }).toList();
+
+ var exported = linker.builders[uri];
+ var export = Export(this, exported, combinators);
+ if (exported != null) {
+ exported.exporters.add(export);
+ } else {
+ var references = linker.elementFactory.exportsOfLibrary('$uri');
+ for (var reference in references) {
+ export.addToExportScope(reference.name, reference);
+ }
}
}
}
@@ -275,16 +284,12 @@
});
}
- void performTopLevelInference() {
- TopLevelInference(linker, reference).infer();
- }
-
void resolveConstructors() {
- ConstructorInitializerResolver(linker, reference).resolve();
+ ConstructorInitializerResolver(linker, element).resolve();
}
void resolveDefaultValues() {
- DefaultValueResolver(linker, reference).resolve();
+ DefaultValueResolver(linker, element).resolve();
}
void resolveMetadata() {
@@ -294,11 +299,12 @@
}
}
- void resolveTypes(NodesToBuildType nodesToBuildType) {
+ void resolveTypes(List<ast.AstNode> nodesToBuildType) {
for (var unitContext in context.units) {
var unitRef = reference.getChild('@unit');
var unitReference = unitRef.getChild(unitContext.uriStr);
var resolver = ReferenceResolver(
+ linker.linkingBundleContext,
nodesToBuildType,
linker.elementFactory,
element,
@@ -309,6 +315,20 @@
}
}
+ void resolveUriDirectives() {
+ var unitContext = context.units[0];
+ for (var directive in unitContext.unit.directives) {
+ if (directive is ast.NamespaceDirective) {
+ try {
+ var uri = _selectAbsoluteUri(directive);
+ if (uri != null) {
+ LazyDirective.setSelectedUri(directive, '$uri');
+ }
+ } on FormatException {}
+ }
+ }
+ }
+
void storeExportScope() {
var linkingBundleContext = linker.linkingBundleContext;
for (var reference in exportScope.map.values) {
@@ -317,48 +337,40 @@
}
}
- static void build(Linker linker, Source librarySource,
- Map<Source, ast.CompilationUnit> libraryUnits) {
- var libraryUriStr = librarySource.uri.toString();
+ Uri _selectAbsoluteUri(ast.NamespaceDirective directive) {
+ var relativeUriStr = _selectRelativeUri(
+ directive.configurations,
+ directive.uri.stringValue,
+ );
+ if (relativeUriStr.isEmpty) return null;
+ var relativeUri = Uri.parse(relativeUriStr);
+ return resolveRelativeUri(this.uri, relativeUri);
+ }
+
+ String _selectRelativeUri(
+ List<ast.Configuration> configurations,
+ String defaultUri,
+ ) {
+ for (var configuration in configurations) {
+ var name = configuration.name.components.join('.');
+ var value = configuration.value ?? 'true';
+ if (linker.declaredVariables.get(name) == (value)) {
+ return configuration.uri.stringValue;
+ }
+ }
+ return defaultUri;
+ }
+
+ static void build(Linker linker, LinkInputLibrary inputLibrary) {
+ var libraryUri = inputLibrary.source.uri;
+ var libraryUriStr = '$libraryUri';
var libraryReference = linker.rootReference.getChild(libraryUriStr);
- var unitNodeList = <LinkedNodeUnitBuilder>[];
var libraryNode = LinkedNodeLibraryBuilder(
- units: unitNodeList,
uriStr: libraryUriStr,
);
- var builder = SourceLibraryBuilder(
- linker,
- librarySource.uri,
- libraryReference,
- libraryNode,
- );
- linker.builders[builder.uri] = builder;
-
- var unitMap = <String, ast.CompilationUnit>{};
- ast.CompilationUnit definingUnit;
- for (var unitSource in libraryUnits.keys) {
- var unit = libraryUnits[unitSource];
- definingUnit ??= unit;
- unitMap['${unitSource.uri}'] = unit;
- }
-
- builder.context = linker.bundleContext
- .addLinkingLibrary(libraryUriStr, libraryNode, unitMap);
-
-// if (libraryUriStr == 'dart:core') {
-// for (var declaration in unitNode.compilationUnit_declarations) {
-// if (declaration.kind == LinkedNodeKind.classDeclaration) {
-// var nameNode = declaration.namedCompilationUnitMember_name;
-// if (unitContext.getSimpleName(nameNode) == 'Object') {
-// declaration.classDeclaration_isDartObject = true;
-// }
-// }
-// }
-// }
-// }
-
+ var definingUnit = inputLibrary.units[0].unit;
for (var directive in definingUnit.directives) {
if (directive is ast.LibraryDirective) {
var name = directive.name;
@@ -368,6 +380,20 @@
break;
}
}
+
+ var builder = SourceLibraryBuilder(
+ linker,
+ libraryUri,
+ libraryReference,
+ libraryNode,
+ );
+ linker.builders[builder.uri] = builder;
+
+ builder.context = linker.bundleContext.addLinkingLibrary(
+ libraryUriStr,
+ libraryNode,
+ inputLibrary,
+ );
}
}
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
index a0cc02e..fbb7919 100644
--- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -3,37 +3,28 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary2/ast_resolver.dart';
import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
class ConstructorInitializerResolver {
- Linker _linker;
- LibraryElementImpl _libraryElement;
+ final Linker _linker;
+ final LibraryElementImpl _libraryElement;
- Scope _libraryScope;
- Scope _classScope;
-
- LinkedUnitContext _linkedContext;
-
+ ClassElement _classElement;
ConstructorElement _constructorElement;
- LinkedNodeBuilder _constructorNode;
+ ConstructorDeclarationImpl _constructorNode;
AstResolver _astResolver;
- ConstructorInitializerResolver(this._linker, Reference libraryRef) {
- _libraryElement = _linker.elementFactory.elementOfReference(libraryRef);
- _libraryScope = LibraryScope(_libraryElement);
- }
+ ConstructorInitializerResolver(this._linker, this._libraryElement);
void resolve() {
- for (CompilationUnitElementImpl unit in _libraryElement.units) {
- _linkedContext = unit.linkedContext;
+ for (var unit in _libraryElement.units) {
for (var classElement in unit.types) {
- _classScope = ClassScope(_libraryScope, classElement);
+ _classElement = classElement;
for (var constructorElement in classElement.constructors) {
_constructor(constructorElement);
}
@@ -44,70 +35,47 @@
void _constructor(ConstructorElementImpl constructorElement) {
if (constructorElement.isSynthetic) return;
-// _constructorElement = constructorElement;
-// _constructorNode = constructorElement.linkedNode;
-//
-// var functionScope = FunctionScope(_classScope, constructorElement);
-// functionScope.defineParameters();
-//
-// var nameScope = ConstructorInitializerScope(
-// functionScope,
-// constructorElement,
-// );
-//
-// _astResolver = AstResolver(_linker, _libraryElement, nameScope);
-//
-// _initializers();
-// _redirectedConstructor();
+ _constructorElement = constructorElement;
+ _constructorNode = constructorElement.linkedNode;
+
+ var functionScope = LinkingNodeContext.get(_constructorNode).scope;
+ var initializerScope = ConstructorInitializerScope(
+ functionScope,
+ constructorElement,
+ );
+
+ _astResolver = AstResolver(_linker, _libraryElement, initializerScope);
+
+ _initializers();
+ _redirectedConstructor();
}
void _initializers() {
- throw UnimplementedError();
+ var initializers = _constructorNode.initializers;
-// bool isConst = _constructorNode.constructorDeclaration_constKeyword != 0;
-//
-// var initializers = _constructorNode.constructorDeclaration_initializers;
-// var resolvedList = List<LinkedNodeBuilder>();
-// for (var i = 0; i < initializers.length; ++i) {
-// var unresolvedNode = initializers[i];
-//
-// // Keep only initializers of constant constructors; or redirects.
-// if (!isConst &&
-// unresolvedNode.kind !=
-// LinkedNodeKind.redirectingConstructorInvocation) {
-// continue;
-// }
-//
-// var reader = AstBinaryReader(_linkedContext);
-// var unresolvedAst = reader.readNode(unresolvedNode);
-//
-// var resolvedNode = _astResolver.resolve(
-// _linkedContext,
-// unresolvedAst,
-// enclosingClassElement: _constructorElement.enclosingElement,
-// enclosingExecutableElement: _constructorElement,
-// );
-// resolvedList.add(resolvedNode);
-// }
-// _constructorNode.constructorDeclaration_initializers = resolvedList;
+ var isConst = _constructorNode.constKeyword != null;
+ if (!isConst) {
+ initializers.clear();
+ return;
+ }
+
+ for (var initializer in initializers) {
+ _astResolver.resolve(
+ initializer,
+ enclosingClassElement: _classElement,
+ enclosingExecutableElement: _constructorElement,
+ );
+ }
}
void _redirectedConstructor() {
- throw UnimplementedError();
-
-// var redirectedConstructorNode =
-// _constructorNode.constructorDeclaration_redirectedConstructor;
-// if (redirectedConstructorNode == null) return;
-//
-// var reader = AstBinaryReader(_linkedContext);
-// var unresolvedAst = reader.readNode(redirectedConstructorNode);
-// var resolvedNode = _astResolver.resolve(
-// _linkedContext,
-// unresolvedAst,
-// enclosingClassElement: _constructorElement.enclosingElement,
-// enclosingExecutableElement: _constructorElement,
-// );
-// _constructorNode.constructorDeclaration_redirectedConstructor =
-// resolvedNode;
+ var redirected = _constructorNode.redirectedConstructor;
+ if (redirected != null) {
+ _astResolver.resolve(
+ redirected,
+ enclosingClassElement: _classElement,
+ enclosingExecutableElement: _constructorElement,
+ );
+ }
}
}
diff --git a/pkg/analyzer/lib/src/summary2/core_types.dart b/pkg/analyzer/lib/src/summary2/core_types.dart
new file mode 100644
index 0000000..289ea8e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/core_types.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+
+class CoreTypes {
+ final LinkedElementFactory _elementFactory;
+
+ LibraryElement _coreLibrary;
+ ClassElement _objectClass;
+
+ CoreTypes(this._elementFactory);
+
+ LibraryElement get coreLibrary {
+ return _coreLibrary ??= _elementFactory.libraryOfUri('dart:core');
+ }
+
+ ClassElement get objectClass {
+ return _objectClass ??= _getCoreClass('Object');
+ }
+
+ ClassElement _getCoreClass(String name) {
+ return coreLibrary.getType(name);
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
index 4ee405d..f531465 100644
--- a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -10,45 +11,35 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/summary2/ast_resolver.dart';
import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
class DefaultValueResolver {
- Linker _linker;
- LibraryElementImpl _libraryElement;
- LinkedUnitContext _linkedContext;
+ final Linker _linker;
+ final LibraryElementImpl _libraryElement;
- ClassElement _enclosingClassElement;
- ExecutableElement _enclosingExecutableElement;
-
- Scope _libraryScope;
- Scope _classScope;
+ ClassElement _classElement;
+ ExecutableElement _executableElement;
+ Scope _scope;
AstResolver _astResolver;
- DefaultValueResolver(this._linker, Reference libraryRef) {
- _libraryElement = _linker.elementFactory.elementOfReference(libraryRef);
- _libraryScope = LibraryScope(_libraryElement);
- }
+ DefaultValueResolver(this._linker, this._libraryElement);
void resolve() {
for (CompilationUnitElementImpl unit in _libraryElement.units) {
- _linkedContext = unit.linkedContext;
-
for (var classElement in unit.types) {
- _enclosingClassElement = classElement;
- _classScope = TypeParameterScope(_libraryScope, classElement);
+ _classElement = classElement;
for (var element in classElement.constructors) {
_constructor(element);
}
for (var element in classElement.methods) {
+ _setScopeFromElement(element);
_method(element);
}
- _enclosingClassElement = null;
- _classScope = null;
+ _classElement = null;
}
for (var element in unit.functions) {
@@ -61,54 +52,46 @@
if (element.isSynthetic) return;
_astResolver = null;
- _enclosingExecutableElement = element;
+ _executableElement = element;
+ _setScopeFromElement(element);
_parameters(element.parameters);
}
void _function(FunctionElementImpl element) {
_astResolver = null;
- _enclosingExecutableElement = element;
+ _executableElement = element;
+ _setScopeFromElement(element);
_parameters(element.parameters);
}
void _method(MethodElementImpl element) {
_astResolver = null;
- _enclosingExecutableElement = element;
+ _executableElement = element;
+ _setScopeFromElement(element);
_parameters(element.parameters);
}
void _parameter(ParameterElementImpl parameter) {
- if (parameter.isNotOptional) return;
+ Expression defaultValue;
+ var node = parameter.linkedNode;
+ if (node is DefaultFormalParameter) {
+ defaultValue = node.defaultValue;
+ }
+ if (defaultValue == null) return;
-// LinkedNodeBuilder node = parameter.linkedNode;
-// var unresolvedNode = node.defaultFormalParameter_defaultValue;
-// if (unresolvedNode == null) return;
-//
-// var reader = AstBinaryReader(_linkedContext);
-// var unresolvedAst = reader.readNode(unresolvedNode);
-//
-// if (_astResolver == null) {
-// var scope = FunctionScope(
-// _classScope ?? _libraryScope,
-// _enclosingExecutableElement,
-// );
-// _astResolver = AstResolver(_linker, _libraryElement, scope);
-// }
-//
-// var contextType = TypeVariableEliminator(_linker.typeProvider)
-// .substituteType(parameter.type);
-// InferenceContext.setType(unresolvedAst, contextType);
-//
-// var resolvedNode = _astResolver.resolve(
-// _linkedContext,
-// unresolvedAst,
-// enclosingClassElement: _enclosingClassElement,
-// enclosingExecutableElement: _enclosingExecutableElement,
-// );
-// node.defaultFormalParameter_defaultValue = resolvedNode;
+ var contextType = TypeVariableEliminator(_linker.typeProvider)
+ .substituteType(parameter.type);
+ InferenceContext.setType(defaultValue, contextType);
+
+ _astResolver ??= AstResolver(_linker, _libraryElement, _scope);
+ _astResolver.resolve(
+ defaultValue,
+ enclosingClassElement: _classElement,
+ enclosingExecutableElement: _executableElement,
+ );
}
void _parameters(List<ParameterElement> parameters) {
@@ -116,6 +99,10 @@
_parameter(parameter);
}
}
+
+ void _setScopeFromElement(Element element) {
+ _scope = LinkingNodeContext.get((element as ElementImpl).linkedNode).scope;
+ }
}
class TypeVariableEliminator extends Substitution {
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index d4f01c5..77b9527 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -11,6 +11,8 @@
/// Accessor for reading AST lazily, or read data that is stored in IDL, but
/// cannot be stored in AST, like inferred types.
class LazyAst {
+ static const _hasOverrideInferenceKey = 'lazyAst_hasOverrideInference';
+ static const _isSimplyBoundedKey = 'lazyAst_simplyBounded';
static const _returnTypeKey = 'lazyAst_returnType';
static const _typeKey = 'lazyAst_type';
@@ -26,10 +28,26 @@
return node.getProperty(_typeKey);
}
+ static bool hasOverrideInferenceDone(AstNode node) {
+ return node.getProperty(_hasOverrideInferenceKey) ?? false;
+ }
+
+ static bool isSimplyBounded(AstNode node) {
+ return node.getProperty(_isSimplyBoundedKey);
+ }
+
+ static void setOverrideInferenceDone(AstNode node) {
+ node.setProperty(_hasOverrideInferenceKey, true);
+ }
+
static void setReturnType(AstNode node, DartType type) {
node.setProperty(_returnTypeKey, type);
}
+ static void setSimplyBounded(AstNode node, bool simplyBounded) {
+ node.setProperty(_isSimplyBoundedKey, simplyBounded);
+ }
+
static void setType(AstNode node, DartType type) {
node.setProperty(_typeKey, type);
}
@@ -45,7 +63,6 @@
bool _hasImplementsClause = false;
bool _hasMembers = false;
bool _hasMetadata = false;
- bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassDeclaration(this.data);
@@ -123,19 +140,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = LazyClassDeclaration.get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classOrMixinDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void readWithClause(
AstBinaryReader reader,
ClassDeclaration node,
@@ -151,6 +155,7 @@
static void setData(ClassDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyClassDeclaration(data));
+ LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}
}
@@ -163,7 +168,6 @@
bool _hasImplementsClause = false;
bool _hasMetadata = false;
bool _hasSuperclass = false;
- bool _hasTypeParameters = false;
bool _hasWithClause = false;
LazyClassTypeAlias(this.data);
@@ -228,19 +232,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void readWithClause(
AstBinaryReader reader,
ClassTypeAlias node,
@@ -256,6 +247,7 @@
static void setData(ClassTypeAlias node, LinkedNode data) {
node.setProperty(_key, LazyClassTypeAlias(data));
+ LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}
}
@@ -267,7 +259,9 @@
bool _hasBody = false;
bool _hasDocumentationComment = false;
bool _hasFormalParameters = false;
+ bool _hasInitializers = false;
bool _hasMetadata = false;
+ bool _hasRedirectedConstructor = false;
LazyConstructorDeclaration(this.data);
@@ -314,6 +308,21 @@
}
}
+ static void readInitializers(
+ AstBinaryReader reader,
+ ConstructorDeclaration node,
+ ) {
+ var lazy = get(node);
+ if (lazy != null && !lazy._hasInitializers) {
+ var dataList = lazy.data.constructorDeclaration_initializers;
+ for (var i = 0; i < dataList.length; ++i) {
+ var data = dataList[i];
+ node.initializers[i] = reader.readNode(data);
+ }
+ lazy._hasInitializers = true;
+ }
+ }
+
static void readMetadata(
AstBinaryReader reader,
ConstructorDeclaration node,
@@ -329,6 +338,19 @@
}
}
+ static void readRedirectedConstructor(
+ AstBinaryReader reader,
+ ConstructorDeclaration node,
+ ) {
+ var lazy = get(node);
+ if (lazy != null && !lazy._hasRedirectedConstructor) {
+ node.redirectedConstructor = reader.readNode(
+ lazy.data.constructorDeclaration_redirectedConstructor,
+ );
+ lazy._hasRedirectedConstructor = true;
+ }
+ }
+
static void setData(ConstructorDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyConstructorDeclaration(data));
}
@@ -336,6 +358,7 @@
class LazyDirective {
static const _key = 'lazyAst';
+ static const _uriKey = 'lazyAst_selectedUri';
final LinkedNode data;
@@ -347,6 +370,10 @@
return node.getProperty(_key);
}
+ static String getSelectedUri(UriBasedDirective node) {
+ return node.getProperty(_uriKey);
+ }
+
static void readMetadata(AstBinaryReader reader, Directive node) {
var lazy = get(node);
if (lazy != null && !lazy._hasMetadata) {
@@ -361,6 +388,13 @@
static void setData(Directive node, LinkedNode data) {
node.setProperty(_key, LazyDirective(data));
+ if (node is NamespaceDirective) {
+ node.setProperty(_uriKey, data.namespaceDirective_selectedUri);
+ }
+ }
+
+ static void setSelectedUri(UriBasedDirective node, String uriStr) {
+ node.setProperty(_uriKey, uriStr);
}
}
@@ -605,6 +639,7 @@
AstBinaryReader reader,
FunctionDeclaration node,
) {
+ readFunctionExpression(reader, node);
if (reader.isLazy) {
var lazy = get(node);
if (!lazy._hasReturnType) {
@@ -668,7 +703,6 @@
bool _hasBody = false;
bool _hasFormalParameters = false;
- bool _hasTypeParameters = false;
LazyFunctionExpression(this.data);
@@ -702,19 +736,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- FunctionExpression node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.functionExpression_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(FunctionExpression node, LinkedNode data) {
node.setProperty(_key, LazyFunctionExpression(data));
}
@@ -729,7 +750,6 @@
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
- bool _hasTypeParameters = false;
LazyFunctionTypeAlias(this.data);
@@ -793,21 +813,9 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.functionTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(FunctionTypeAlias node, LinkedNode data) {
node.setProperty(_key, LazyFunctionTypeAlias(data));
+ LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}
}
@@ -865,7 +873,6 @@
bool _hasDocumentationComment = false;
bool _hasFunction = false;
- bool _hasTypeParameters = false;
LazyGenericTypeAlias(this.data);
@@ -899,21 +906,9 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.genericTypeAlias_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(GenericTypeAlias node, LinkedNode data) {
node.setProperty(_key, LazyGenericTypeAlias(data));
+ LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}
}
@@ -927,7 +922,6 @@
bool _hasFormalParameters = false;
bool _hasMetadata = false;
bool _hasReturnType = false;
- bool _hasTypeParameters = false;
LazyMethodDeclaration(this.data);
@@ -1004,19 +998,6 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.methodDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(MethodDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyMethodDeclaration(data));
}
@@ -1031,7 +1012,6 @@
bool _hasOnClause = false;
bool _hasImplementsClause = false;
bool _hasMembers = false;
- bool _hasTypeParameters = false;
LazyMixinDeclaration(this.data);
@@ -1085,7 +1065,7 @@
MixinDeclarationImpl node,
) {
var lazy = get(node);
- if (!lazy._hasOnClause) {
+ if (lazy != null && !lazy._hasOnClause) {
node.onClause = reader.readNode(
lazy.data.mixinDeclaration_onClause,
);
@@ -1093,21 +1073,9 @@
}
}
- static void readTypeParameters(
- AstBinaryReader reader,
- MixinDeclarationImpl node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeParameters) {
- node.typeParameters = reader.readNode(
- lazy.data.classOrMixinDeclaration_typeParameters,
- );
- lazy._hasTypeParameters = true;
- }
- }
-
static void setData(MixinDeclaration node, LinkedNode data) {
node.setProperty(_key, LazyMixinDeclaration(data));
+ LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 989a7f4..77430ea 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -3,10 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
+import 'package:analyzer/dart/ast/ast.dart' show AstNode, CompilationUnit;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -20,21 +21,26 @@
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/linking_bundle_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/summary2/simply_bounded.dart';
import 'package:analyzer/src/summary2/tokens_writer.dart';
+import 'package:analyzer/src/summary2/top_level_inference.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
LinkResult link(
AnalysisOptions analysisOptions,
SourceFactory sourceFactory,
- List<LinkedNodeBundle> inputs,
- Map<Source, Map<Source, CompilationUnit>> unitMap,
+ DeclaredVariables declaredVariables,
+ List<LinkedNodeBundle> inputBundles,
+ List<LinkInputLibrary> inputLibraries,
) {
- var linker = Linker(analysisOptions, sourceFactory);
- linker.link(inputs, unitMap);
+ var linker = Linker(analysisOptions, sourceFactory, declaredVariables);
+ linker.link(inputBundles, inputLibraries);
return LinkResult(linker.linkingBundle);
}
class Linker {
+ final DeclaredVariables declaredVariables;
+
final Reference rootReference = Reference.root();
LinkedElementFactory elementFactory;
@@ -50,7 +56,11 @@
Dart2TypeSystem typeSystem;
InheritanceManager2 inheritance;
- Linker(AnalysisOptions analysisOptions, SourceFactory sourceFactory) {
+ Linker(
+ AnalysisOptions analysisOptions,
+ SourceFactory sourceFactory,
+ this.declaredVariables,
+ ) {
var dynamicRef = rootReference.getChild('dart:core').getChild('dynamic');
dynamicRef.element = DynamicElementImpl.instance;
@@ -73,15 +83,15 @@
);
}
- void link(List<LinkedNodeBundle> inputs,
- Map<Source, Map<Source, CompilationUnit>> unitMap) {
- for (var input in inputs) {
+ void link(List<LinkedNodeBundle> inputBundles,
+ List<LinkInputLibrary> inputLibraries) {
+ for (var input in inputBundles) {
var inputBundleContext = LinkedBundleContext(elementFactory, input);
elementFactory.addBundle(inputBundleContext);
}
- for (var librarySource in unitMap.keys) {
- SourceLibraryBuilder.build(this, librarySource, unitMap[librarySource]);
+ for (var inputLibrary in inputLibraries) {
+ SourceLibraryBuilder.build(this, inputLibrary);
}
// TODO(scheglov) do in build() ?
elementFactory.addBundle(bundleContext);
@@ -104,11 +114,13 @@
}
void _buildOutlines() {
+ _resolveUriDirectives();
_addExporters();
_computeLibraryScopes();
_addSyntheticConstructors();
_createTypeSystem();
_resolveTypes();
+ _createLoadLibraryFunctions();
_performTopLevelInference();
_resolveConstructors();
_resolveDefaultValues();
@@ -196,6 +208,12 @@
);
}
+ void _createLoadLibraryFunctions() {
+ for (var library in builders.values) {
+ library.element.createLoadLibraryFunction(typeProvider);
+ }
+ }
+
void _createTypeSystem() {
var coreRef = rootReference.getChild('dart:core');
var coreLib = elementFactory.elementOfReference(coreRef);
@@ -215,21 +233,19 @@
}
void _performTopLevelInference() {
- for (var library in builders.values) {
- library.performTopLevelInference();
- }
+ TopLevelInference(this).infer();
}
void _resolveConstructors() {
-// for (var library in builders.values) {
-// library.resolveConstructors();
-// }
+ for (var library in builders.values) {
+ library.resolveConstructors();
+ }
}
void _resolveDefaultValues() {
-// for (var library in builders.values) {
-// library.resolveDefaultValues();
-// }
+ for (var library in builders.values) {
+ library.resolveDefaultValues();
+ }
}
void _resolveMetadata() {
@@ -239,13 +255,33 @@
}
void _resolveTypes() {
- var nodesToBuildType = NodesToBuildType();
+ var nodesToBuildType = <AstNode>[];
for (var library in builders.values) {
library.resolveTypes(nodesToBuildType);
}
-// computeSimplyBounded(bundleContext, builders.values);
- TypeBuilder(linkingBundleContext).build(nodesToBuildType);
+ computeSimplyBounded(bundleContext, builders.values);
+ TypeBuilder(typeSystem).build(nodesToBuildType);
}
+
+ void _resolveUriDirectives() {
+ for (var library in builders.values) {
+ library.resolveUriDirectives();
+ }
+ }
+}
+
+class LinkInputLibrary {
+ final Source source;
+ final List<LinkInputUnit> units;
+
+ LinkInputLibrary(this.source, this.units);
+}
+
+class LinkInputUnit {
+ final Source source;
+ final CompilationUnit unit;
+
+ LinkInputUnit(this.source, this.unit);
}
class LinkResult {
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index 88f8655..bb079ee 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -2,14 +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/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -45,25 +41,29 @@
LinkedBundleContext.forAst(this.elementFactory, this._references)
: _bundle = null;
- LinkedLibraryContext addLinkingLibrary(String uriStr,
- LinkedNodeLibraryBuilder data, Map<String, CompilationUnit> unitMap) {
+ LinkedLibraryContext addLinkingLibrary(
+ String uriStr,
+ LinkedNodeLibraryBuilder data,
+ LinkInputLibrary inputLibrary,
+ ) {
var uriStr = data.uriStr;
var libraryContext = LinkedLibraryContext(uriStr, this, data);
libraryMap[uriStr] = libraryContext;
- var uriUriStrList = unitMap.keys.toList();
- for (var unitIndex = 0; unitIndex < uriUriStrList.length; ++unitIndex) {
- var unitUriStr = uriUriStrList[unitIndex];
- var unit = unitMap[unitUriStr];
- var unitContext = LinkedUnitContext(
- this,
- libraryContext,
- unitIndex,
- unitUriStr,
- null,
- unit: unit,
+ var unitIndex = 0;
+ for (var inputUnit in inputLibrary.units) {
+ var source = inputUnit.source;
+ var unitUriStr = source != null ? '${source.uri}' : '';
+ libraryContext.units.add(
+ LinkedUnitContext(
+ this,
+ libraryContext,
+ unitIndex++,
+ unitUriStr,
+ null,
+ unit: inputUnit.unit,
+ ),
);
- libraryContext.units.add(unitContext);
}
return libraryContext;
}
@@ -82,52 +82,6 @@
return result;
}
- InterfaceType getInterfaceType(LinkedNodeType linkedType) {
- var type = getType(linkedType);
- if (type is InterfaceType && !type.element.isEnum) {
- return type;
- }
- return null;
- }
-
- DartType getType(LinkedNodeType linkedType) {
- var kind = linkedType.kind;
- if (kind == LinkedNodeTypeKind.dynamic_) {
- return DynamicTypeImpl.instance;
- } else if (kind == LinkedNodeTypeKind.genericTypeAlias) {
- var reference = referenceOfIndex(linkedType.genericTypeAliasReference);
- return GenericTypeAliasElementImpl.typeAfterSubstitution(
- elementFactory.elementOfReference(reference),
- linkedType.genericTypeAliasTypeArguments.map(getType).toList(),
- );
- } else if (kind == LinkedNodeTypeKind.function) {
- var returnType = getType(linkedType.functionReturnType);
- var formalParameters = linkedType.functionFormalParameters.map((p) {
- return ParameterElementImpl.synthetic(
- p.name,
- getType(p.type),
- _formalParameterKind(p.kind),
- );
- }).toList();
- return FunctionElementImpl.synthetic(formalParameters, returnType).type;
- } else if (kind == LinkedNodeTypeKind.interface) {
- var reference = referenceOfIndex(linkedType.interfaceClass);
- Element element = elementFactory.elementOfReference(reference);
- return InterfaceTypeImpl.explicit(
- element,
- linkedType.interfaceTypeArguments.map(getType).toList(),
- );
- } else if (kind == LinkedNodeTypeKind.typeParameter) {
- var reference = referenceOfIndex(linkedType.typeParameterParameter);
- Element element = elementFactory.elementOfReference(reference);
- return TypeParameterTypeImpl(element);
- } else if (kind == LinkedNodeTypeKind.void_) {
- return VoidTypeImpl.instance;
- } else {
- throw UnimplementedError('$kind');
- }
- }
-
Reference referenceOfIndex(int index) {
var reference = _references[index];
if (reference != null) return reference;
@@ -147,16 +101,6 @@
return reference;
}
-
- ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
- if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
- return ParameterKind.NAMED;
- }
- if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
- return ParameterKind.POSITIONAL;
- }
- return ParameterKind.REQUIRED;
- }
}
class LinkedLibraryContext {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index e16238f..41b8880 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/core_types.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -19,9 +20,15 @@
final Reference rootReference;
final Map<String, LinkedLibraryContext> libraryMap = {};
+ CoreTypes _coreTypes;
+
LinkedElementFactory(
this.analysisContext, this.analysisSession, this.rootReference);
+ CoreTypes get coreTypes {
+ return _coreTypes ??= CoreTypes(this);
+ }
+
void addBundle(LinkedBundleContext context) {
libraryMap.addAll(context.libraryMap);
}
@@ -152,11 +159,6 @@
return _typeAlias(unit, reference);
}
- if (parentName == '@typeParameter') {
- var enclosing = elementOfReference(parent2) as TypeParameterizedElement;
- return _typeParameter(enclosing, reference);
- }
-
if (parentName == '@unit') {
elementOfReference(parent2);
// Creating a library fills all its units.
@@ -248,7 +250,14 @@
libraryElement.definingCompilationUnit = units[0];
libraryElement.parts = units.skip(1).toList();
- return reference.element = libraryElement;
+ reference.element = libraryElement;
+
+ var typeProvider = elementFactory.analysisContext.typeProvider;
+ if (typeProvider != null) {
+ libraryElement.createLoadLibraryFunction(typeProvider);
+ }
+
+ return libraryElement;
}
EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) {
@@ -296,14 +305,6 @@
return reference.element;
}
- Element _typeParameter(
- TypeParameterizedElement enclosing, Reference reference) {
- enclosing.typeParameters;
- // Requesting type parameters sets elements for all their references.
- assert(reference.element != null);
- return reference.element;
- }
-
/// Index nodes for which we choose to create elements individually,
/// for example [ClassDeclaration], so that its [Reference] has the node,
/// and we can call the [ClassElementImpl] constructor.
@@ -314,20 +315,33 @@
) {
var classRef = unitRef.getChild('@class');
var enumRef = unitRef.getChild('@enum');
+ var functionRef = unitRef.getChild('@function');
var typeAliasRef = unitRef.getChild('@typeAlias');
+ var variableRef = unitRef.getChild('@variable');
for (var declaration in unitNode.declarations) {
if (declaration is ClassDeclaration) {
var name = declaration.name.name;
classRef.getChild(name).node2 = declaration;
+ } else if (declaration is ClassTypeAlias) {
+ var name = declaration.name.name;
+ classRef.getChild(name).node2 = declaration;
} else if (declaration is EnumDeclaration) {
var name = declaration.name.name;
enumRef.getChild(name).node2 = declaration;
+ } else if (declaration is FunctionDeclaration) {
+ var name = declaration.name.name;
+ functionRef.getChild(name).node2 = declaration;
} else if (declaration is FunctionTypeAlias) {
var name = declaration.name.name;
typeAliasRef.getChild(name).node2 = declaration;
} else if (declaration is GenericTypeAlias) {
var name = declaration.name.name;
typeAliasRef.getChild(name).node2 = declaration;
+ } else if (declaration is TopLevelVariableDeclaration) {
+ for (var variable in declaration.variables.variables) {
+ var name = variable.name.name;
+ variableRef.getChild(name).node2 = declaration;
+ }
}
}
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 0451be4..7c044db 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -3,10 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/ast_binary_reader.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
@@ -27,6 +28,17 @@
CompilationUnit _unit;
bool _hasDirectivesRead = false;
+ /// Mapping from identifiers to real or synthetic type parameters.
+ ///
+ /// Real type parameters have corresponding [TypeParameter] nodes, and are
+ /// referenced from other AST nodes.
+ ///
+ /// Synthetic type parameters are added when [readType] begins reading a
+ /// [FunctionType], and removed when reading is done.
+ final Map<int, TypeParameterElement> _typeParameters = {};
+
+ int _nextSyntheticTypeParameterId = 0x10000;
+
LinkedUnitContext(this.bundleContext, this.libraryContext,
this.indexInLibrary, this.uriStr, this.data,
{CompilationUnit unit})
@@ -59,11 +71,20 @@
return _unit;
}
- /// Return the absolute URI referenced in the [directive].
- Uri directiveUri(Uri libraryUri, UriBasedDirective directive) {
- var relativeUriStr = directive.uri.stringValue;
- var relativeUri = Uri.parse(relativeUriStr);
- return resolveRelativeUri(libraryUri, relativeUri);
+ /// Every [TypeParameter] node has [TypeParameterElement], which is created
+ /// during reading of this node. All type parameter nodes are read before
+ /// any nodes that reference them (bounds are read lazily later).
+ void addTypeParameter(int id, TypeParameter node) {
+ var element = TypeParameterElementImpl.forLinkedNode(null, null, node);
+ _typeParameters[id] = element;
+ node.name.staticElement = element;
+ }
+
+ /// Return the [LibraryElement] referenced in the [node].
+ LibraryElement directiveLibrary(UriBasedDirective node) {
+ var uriStr = LazyDirective.getSelectedUri(node);
+ if (uriStr == null || uriStr.isEmpty) return null;
+ return bundleContext.elementFactory.libraryOfUri(uriStr);
}
int getCodeLength(AstNode node) {
@@ -116,6 +137,18 @@
return '';
}
+ List<ConstructorInitializer> getConstructorInitializers(
+ ConstructorDeclaration node,
+ ) {
+ LazyConstructorDeclaration.readInitializers(_astReader, node);
+ return node.initializers;
+ }
+
+ ConstructorName getConstructorRedirected(ConstructorDeclaration node) {
+ LazyConstructorDeclaration.readRedirectedConstructor(_astReader, node);
+ return node.redirectedConstructor;
+ }
+
Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
if (node is ClassOrMixinDeclaration) {
var members = _getClassOrMixinMembers(node);
@@ -257,7 +290,20 @@
}
InterfaceType getInterfaceType(LinkedNodeType linkedType) {
- return bundleContext.getInterfaceType(linkedType);
+ var type = readType(linkedType);
+ if (type is InterfaceType && !type.element.isEnum) {
+ return type;
+ }
+ return null;
+ }
+
+ Comment getLibraryDocumentationComment(CompilationUnit unit) {
+ for (var directive in unit.directives) {
+ if (directive is LibraryDirective) {
+ return directive.documentationComment;
+ }
+ }
+ return null;
}
List<Annotation> getLibraryMetadata(CompilationUnit unit) {
@@ -448,10 +494,8 @@
TypeParameterList getTypeParameters2(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is ConstructorDeclaration) {
return null;
@@ -459,21 +503,16 @@
LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return getTypeParameters2(node.functionExpression);
} else if (node is FunctionExpression) {
- LazyFunctionExpression.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is GenericFunctionType) {
return node.typeParameters;
} else if (node is GenericTypeAlias) {
- LazyGenericTypeAlias.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readTypeParameters(_astReader, node);
return node.typeParameters;
} else {
throw UnimplementedError('${node.runtimeType}');
@@ -500,6 +539,30 @@
}
}
+ bool hasImplicitReturnType(AstNode node) {
+ if (node is MethodDeclaration) {
+ return node.returnType == null;
+ }
+ return false;
+ }
+
+ bool hasImplicitType(AstNode node) {
+ if (node is VariableDeclaration) {
+ VariableDeclarationList parent = node.parent;
+ return parent.type == null;
+ } else if (node is SimpleFormalParameter) {
+ return node.type == null;
+ }
+ return false;
+ }
+
+ bool hasOverrideInferenceDone(AstNode node) {
+ // Only nodes in the libraries being linked might be not inferred yet.
+ if (_astReader.isLazy) return true;
+
+ return LazyAst.hasOverrideInferenceDone(node);
+ }
+
bool isAbstract(AstNode node) {
if (node is ClassDeclaration) {
return node.abstractKeyword != null;
@@ -551,8 +614,10 @@
return isConstKeyword(node.variableDeclarationList_keyword);
}
- bool isCovariantField(AstNode node) {
- if (node is VariableDeclaration) {
+ bool isCovariant(AstNode node) {
+ if (node is FormalParameter) {
+ return node.covariantKeyword != null;
+ } else if (node is VariableDeclaration) {
var parent2 = node.parent.parent;
return parent2 is FieldDeclaration && parent2.covariantKeyword != null;
}
@@ -627,6 +692,10 @@
}
}
+ bool isSimplyBounded(AstNode node) {
+ return LazyAst.isSimplyBounded(node);
+ }
+
bool isStatic(AstNode node) {
if (node is FunctionDeclaration) {
return true;
@@ -659,16 +728,86 @@
return _astReader.readNode(linkedNode);
}
- void setReturnType(LinkedNodeBuilder node, DartType type) {
- throw UnimplementedError();
-// var typeData = bundleContext.linking.writeType(type);
-// node.functionDeclaration_returnType2 = typeData;
+ DartType readType(LinkedNodeType linkedType) {
+ if (linkedType == null) return null;
+
+ var kind = linkedType.kind;
+ if (kind == LinkedNodeTypeKind.bottom) {
+ return BottomTypeImpl.instance;
+ } else if (kind == LinkedNodeTypeKind.dynamic_) {
+ return DynamicTypeImpl.instance;
+ } else if (kind == LinkedNodeTypeKind.function) {
+ var typeParameterDataList = linkedType.functionTypeParameters;
+
+ var typeParameters = <TypeParameterElement>[];
+ for (var typeParameterData in typeParameterDataList) {
+ var element = TypeParameterElementImpl(typeParameterData.name, -1);
+ typeParameters.add(element);
+ _typeParameters[_nextSyntheticTypeParameterId++] = element;
+ }
+
+ var returnType = readType(linkedType.functionReturnType);
+ var formalParameters = linkedType.functionFormalParameters.map((p) {
+ var type = readType(p.type);
+ var kind = _formalParameterKind(p.kind);
+ return ParameterElementImpl.synthetic(p.name, type, kind);
+ }).toList();
+
+ for (var i = 0; i < typeParameterDataList.length; ++i) {
+ _typeParameters.remove(--_nextSyntheticTypeParameterId);
+ }
+
+ return FunctionTypeImpl.synthetic(
+ returnType,
+ typeParameters,
+ formalParameters,
+ );
+ } else if (kind == LinkedNodeTypeKind.interface) {
+ var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
+ return InterfaceTypeImpl.explicit(
+ element,
+ linkedType.interfaceTypeArguments.map(readType).toList(),
+ );
+ } else if (kind == LinkedNodeTypeKind.typeParameter) {
+ var id = linkedType.typeParameterId;
+ var element = _typeParameters[id];
+ assert(element != null);
+ return TypeParameterTypeImpl(element);
+ } else if (kind == LinkedNodeTypeKind.void_) {
+ return VoidTypeImpl.instance;
+ } else {
+ throw UnimplementedError('$kind');
+ }
}
- void setVariableType(LinkedNodeBuilder node, DartType type) {
- throw UnimplementedError();
-// var typeData = bundleContext.linking.writeType(type);
-// node.simpleFormalParameter_type2 = typeData;
+ void setOverrideInferenceDone(AstNode node) {
+ assert(!_astReader.isLazy);
+ LazyAst.setOverrideInferenceDone(node);
+ }
+
+ void setReturnType(AstNode node, DartType type) {
+ LazyAst.setReturnType(node, type);
+ }
+
+ void setVariableType(AstNode node, DartType type) {
+ LazyAst.setType(node, type);
+ }
+
+ bool shouldBeConstFieldElement(AstNode node) {
+ if (node is VariableDeclaration) {
+ VariableDeclarationList variableList = node.parent;
+ if (variableList.isConst) return true;
+
+ if (variableList.isFinal) {
+ ClassDeclaration classDeclaration = variableList.parent.parent;
+ for (var member in classDeclaration.members) {
+ if (member is ConstructorDeclaration && member.constKeyword != null) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
@@ -681,6 +820,16 @@
}
}
+ ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
+ if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
+ return ParameterKind.NAMED;
+ }
+ if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
+ return ParameterKind.POSITIONAL;
+ }
+ return ParameterKind.REQUIRED;
+ }
+
List<ClassMember> _getClassOrMixinMembers(ClassOrMixinDeclaration node) {
if (node is ClassDeclaration) {
LazyClassDeclaration.readMembers(_astReader, node);
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index 6a9fc44..06d86ce 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -5,7 +5,9 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -28,8 +30,35 @@
name: [''],
);
+ final Map<TypeParameterElement, int> _typeParameters = Map.identity();
+ int _nextTypeParameterId = 1;
+ int _nextSyntheticTypeParameterId = 0x10000;
+
LinkingBundleContext(this.dynamicReference);
+ void addTypeParameter(TypeParameterElement element) {
+ _typeParameters[element] = _nextTypeParameterId++;
+ }
+
+ int idOfTypeParameter(TypeParameterElement element) {
+ return _typeParameters[element];
+ }
+
+ int indexOfElement(Element element) {
+ if (element == null) return 0;
+
+ if (identical(element, DynamicElementImpl.instance)) {
+ return indexOfReference(dynamicReference);
+ }
+
+ if (element is Member) {
+ element = (element as Member).baseElement;
+ }
+
+ var reference = (element as ElementImpl).reference;
+ return indexOfReference(reference);
+ }
+
int indexOfReference(Reference reference) {
if (reference == null) return 0;
if (reference.parent == null) return 0;
@@ -56,29 +85,18 @@
kind: LinkedNodeTypeKind.dynamic_,
);
} else if (type is FunctionType) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.function,
- functionFormalParameters: type.parameters
- .map((p) => LinkedNodeTypeFormalParameterBuilder(
- // ignore: deprecated_member_use_from_same_package
- kind: _formalParameterKind(p.parameterKind),
- name: p.name,
- type: writeType(p.type),
- ))
- .toList(),
- functionReturnType: writeType(type.returnType),
- functionTypeParameters: _getReferences(type.typeParameters),
- );
+ return _writeFunctionType(type);
} else if (type is InterfaceType) {
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.interface,
- interfaceClass: _getReferenceIndex(type.element),
+ interfaceClass: indexOfElement(type.element),
interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
);
} else if (type is TypeParameterType) {
+ TypeParameterElementImpl element = type.element;
return LinkedNodeTypeBuilder(
kind: LinkedNodeTypeKind.typeParameter,
- typeParameterParameter: _getReferenceIndex(type.element),
+ typeParameterId: _typeParameters[element],
);
} else if (type is VoidType) {
return LinkedNodeTypeBuilder(
@@ -89,7 +107,9 @@
}
}
- LinkedNodeFormalParameterKind _formalParameterKind(ParameterKind kind) {
+ LinkedNodeFormalParameterKind _formalParameterKind(ParameterElement p) {
+ // ignore: deprecated_member_use_from_same_package
+ var kind = p.parameterKind;
if (kind == ParameterKind.NAMED) {
return LinkedNodeFormalParameterKind.optionalNamed;
}
@@ -99,19 +119,57 @@
return LinkedNodeFormalParameterKind.required;
}
- int _getReferenceIndex(Element element) {
- if (element == null) return 0;
+ FunctionType _toSyntheticFunctionType(FunctionType type) {
+ var typeParameters = type.typeFormals;
- var reference = (element as ElementImpl).reference;
- return indexOfReference(reference);
+ if (typeParameters.isEmpty) return type;
+
+ var onlySyntheticTypeParameters = typeParameters.every((e) {
+ return e is TypeParameterElementImpl && e.linkedNode == null;
+ });
+ if (onlySyntheticTypeParameters) return type;
+
+ var parameters = getFreshTypeParameters(typeParameters);
+ return parameters.applyToFunctionType(type);
}
- List<int> _getReferences(List<Element> elements) {
- var result = List<int>(elements.length);
- for (var i = 0; i < elements.length; ++i) {
- var element = elements[i];
- result[i] = _getReferenceIndex(element);
+ LinkedNodeTypeBuilder _writeFunctionType(FunctionType type) {
+ type = _toSyntheticFunctionType(type);
+
+ var typeParameterBuilders = <LinkedNodeTypeTypeParameterBuilder>[];
+
+ var typeParameters = type.typeFormals;
+ for (var i = 0; i < typeParameters.length; ++i) {
+ var typeParameter = typeParameters[i];
+ _typeParameters[typeParameter] = _nextSyntheticTypeParameterId++;
+ typeParameterBuilders.add(
+ LinkedNodeTypeTypeParameterBuilder(name: typeParameter.name),
+ );
}
+
+ for (var i = 0; i < typeParameters.length; ++i) {
+ var typeParameter = typeParameters[i];
+ typeParameterBuilders[i].bound = writeType(typeParameter.bound);
+ }
+
+ var result = LinkedNodeTypeBuilder(
+ kind: LinkedNodeTypeKind.function,
+ functionFormalParameters: type.parameters
+ .map((p) => LinkedNodeTypeFormalParameterBuilder(
+ kind: _formalParameterKind(p),
+ name: p.name,
+ type: writeType(p.type),
+ ))
+ .toList(),
+ functionReturnType: writeType(type.returnType),
+ functionTypeParameters: typeParameterBuilders,
+ );
+
+ for (var typeParameter in typeParameters) {
+ _typeParameters.remove(typeParameter);
+ --_nextSyntheticTypeParameterId;
+ }
+
return result;
}
}
diff --git a/pkg/analyzer/lib/src/summary2/linking_node_scope.dart b/pkg/analyzer/lib/src/summary2/linking_node_scope.dart
new file mode 100644
index 0000000..7617125
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/linking_node_scope.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+
+/// This class provides access to [Scope]s corresponding to [AstNode]s.
+class LinkingNodeContext {
+ static const _key = 'linkingNodeContext';
+
+ final Scope scope;
+
+ LinkingNodeContext(AstNode node, this.scope) {
+ node.setProperty(_key, this);
+ }
+
+ static LinkingNodeContext get(AstNode node) {
+ LinkingNodeContext context = node.getProperty(_key);
+ if (context == null) {
+ throw StateError('No context for: $node');
+ }
+ return context;
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 7f8af39..989ab17 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -71,8 +71,6 @@
bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
- bool get isTypeParameter => parent != null && parent.name == '@typeParameter';
-
int get numOfChildren => _children != null ? _children.length : 0;
/// Return the child with the given name, or `null` if does not exist.
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 4d27523e..8601a46 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -10,29 +10,9 @@
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
-
-// TODO(scheglov) This class is not used, not [get] yet.
-class LinkingNodeContext {
- static const _key = 'linkingNodeContext';
-
- final Scope scope;
-
- LinkingNodeContext(this.scope);
-
- static LinkingNodeContext get(AstNode node) {
- LinkingNodeContext context = node.getProperty(_key);
- if (context == null) {
- throw StateError('No context for: $node');
- }
- return context;
- }
-
- static void set(AstNode node, LinkingNodeContext context) {
- node.setProperty(_key, context);
- }
-}
//class ReferenceResolver {
// final LinkingBundleContext linkingBundleContext;
@@ -530,7 +510,8 @@
/// the type is set, otherwise we keep it empty, so we will attempt to infer
/// it later).
class ReferenceResolver extends ThrowingAstVisitor<void> {
- final NodesToBuildType nodesToBuildType;
+ final LinkingBundleContext linkingContext;
+ final List<AstNode> nodesToBuildType;
final LinkedElementFactory elementFactory;
final LibraryElement _libraryElement;
@@ -538,6 +519,7 @@
Scope scope;
ReferenceResolver(
+ this.linkingContext,
this.nodesToBuildType,
this.elementFactory,
this._libraryElement,
@@ -556,6 +538,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -564,7 +547,7 @@
node.name.staticElement = element;
scope = new TypeParameterScope(scope, element);
scope = new ClassScope(scope, element);
- LinkingNodeContext.set(node, LinkingNodeContext(scope));
+ LinkingNodeContext(node, scope);
node.typeParameters?.accept(this);
node.extendsClause?.accept(this);
@@ -584,6 +567,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -592,7 +576,7 @@
node.name.staticElement = element;
scope = new TypeParameterScope(scope, element);
scope = new ClassScope(scope, element);
- LinkingNodeContext.set(node, LinkingNodeContext(scope));
+ LinkingNodeContext(node, scope);
node.typeParameters?.accept(this);
node.superclass?.accept(this);
@@ -605,13 +589,32 @@
@override
void visitCompilationUnit(CompilationUnit node) {
- LinkingNodeContext.set(node, LinkingNodeContext(scope));
+ LinkingNodeContext(node, scope);
node.declarations.accept(this);
}
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
+ var outerScope = scope;
+ var outerReference = reference;
+
+ var name = node.name?.name ?? '';
+ reference = reference.getChild('@constructor').getChild(name);
+
+ var element = ConstructorElementImpl.forLinkedNode(
+ outerReference.element,
+ reference,
+ node,
+ );
+
+ var functionScope = FunctionScope(scope, element);
+ functionScope.defineParameters();
+ LinkingNodeContext(node, functionScope);
+
node.parameters?.accept(this);
+
+ scope = outerScope;
+ reference = outerReference;
}
@override
@@ -639,7 +642,7 @@
void visitFieldFormalParameter(FieldFormalParameter node) {
node.type?.accept(this);
node.parameters?.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
}
@override
@@ -655,6 +658,7 @@
var name = node.name.name;
reference = reference.getChild('@function').getChild(name);
+ _createTypeParameterElements(node.functionExpression.typeParameters);
var element = FunctionElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -662,11 +666,11 @@
);
node.name.staticElement = element;
scope = new FunctionScope(scope, element);
- LinkingNodeContext.set(node, LinkingNodeContext(scope));
+ LinkingNodeContext(node, scope);
node.returnType?.accept(this);
node.functionExpression.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
scope = outerScope;
reference = outerReference;
@@ -686,6 +690,7 @@
var name = node.name.name;
reference = reference.getChild('@typeAlias').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericTypeAliasElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -697,7 +702,7 @@
node.returnType?.accept(this);
node.typeParameters?.accept(this);
node.parameters.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
scope = outerScope;
reference = outerReference;
@@ -709,7 +714,7 @@
node.typeParameters?.accept(this);
node.parameters.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
}
@override
@@ -720,6 +725,7 @@
var name = '${outerReference.numOfChildren}';
reference = reference.getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericFunctionTypeElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -730,8 +736,8 @@
node.returnType?.accept(this);
node.typeParameters?.accept(this);
node.parameters.accept(this);
- nodesToBuildType.addTypeAnnotation(node);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
+ nodesToBuildType.add(node);
scope = outerScope;
reference = outerReference;
@@ -745,6 +751,7 @@
var name = node.name.name;
reference = reference.getChild('@typeAlias').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = GenericTypeAliasElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -773,6 +780,7 @@
var name = node.name.name;
reference = reference.getChild('@method').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = MethodElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -780,12 +788,12 @@
);
node.name.staticElement = element;
scope = new FunctionScope(scope, element);
- LinkingNodeContext.set(node, LinkingNodeContext(scope));
+ LinkingNodeContext(node, scope);
node.returnType?.accept(this);
node.parameters?.accept(this);
node.typeParameters?.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
scope = outerScope;
reference = outerReference;
@@ -799,6 +807,7 @@
var name = node.name.name;
reference = reference.getChild('@class').getChild(name);
+ _createTypeParameterElements(node.typeParameters);
var element = ClassElementImpl.forLinkedNode(
outerReference.element,
reference,
@@ -825,7 +834,7 @@
@override
void visitSimpleFormalParameter(SimpleFormalParameter node) {
node.type?.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
}
@override
@@ -857,7 +866,7 @@
node.typeArguments?.accept(this);
- nodesToBuildType.addTypeAnnotation(node);
+ nodesToBuildType.add(node);
}
@override
@@ -873,11 +882,25 @@
@override
void visitVariableDeclarationList(VariableDeclarationList node) {
node.type?.accept(this);
- nodesToBuildType.addDeclaration(node);
+ nodesToBuildType.add(node);
}
@override
void visitWithClause(WithClause node) {
node.mixinTypes.accept(this);
}
+
+ void _createTypeParameterElement(TypeParameter node) {
+ var element = TypeParameterElementImpl.forLinkedNode(null, null, node);
+ node.name.staticElement = element;
+ linkingContext.addTypeParameter(element);
+ }
+
+ void _createTypeParameterElements(TypeParameterList typeParameterList) {
+ if (typeParameterList == null) return;
+
+ for (var typeParameter in typeParameterList.typeParameters) {
+ _createTypeParameterElement(typeParameter);
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 13a6dc4..cac5831 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -2,16 +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 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart' show LinkedNode;
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary/link.dart' as graph
show DependencyWalker, Node;
import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
/// Compute simple-boundedness for all classes and generic types aliases in
/// the source [libraryBuilders]. There might be dependencies between them,
@@ -23,14 +21,17 @@
var walker = SimplyBoundedDependencyWalker(bundleContext);
var nodes = <SimplyBoundedNode>[];
for (var libraryBuilder in libraryBuilders) {
- var unitsRef = libraryBuilder.reference.getChild('@unit');
- for (var unitRef in unitsRef.children) {
- for (var classRef in unitRef.getChild('@class').children) {
- var node = walker.getNode(classRef);
+ for (var unit in libraryBuilder.element.units) {
+ for (var element in unit.functionTypeAliases) {
+ var node = walker.getNode(element);
nodes.add(node);
}
- for (var ref in unitRef.getChild('@typeAlias').children) {
- var node = walker.getNode(ref);
+ for (var element in unit.mixins) {
+ var node = walker.getNode(element);
+ nodes.add(node);
+ }
+ for (var element in unit.types) {
+ var node = walker.getNode(element);
nodes.add(node);
}
}
@@ -40,8 +41,7 @@
if (!node.isEvaluated) {
walker.walk(node);
}
- LinkedNodeBuilder builder = node._reference.node;
- builder.simplyBoundable_isSimplyBounded = node.isSimplyBounded;
+ LazyAst.setSimplyBounded(node._node, node.isSimplyBounded);
}
}
@@ -49,7 +49,7 @@
class SimplyBoundedDependencyWalker
extends graph.DependencyWalker<SimplyBoundedNode> {
final LinkedBundleContext bundleContext;
- final Map<Reference, SimplyBoundedNode> nodeMap = {};
+ final Map<Element, SimplyBoundedNode> nodeMap = Map.identity();
SimplyBoundedDependencyWalker(this.bundleContext);
@@ -65,31 +65,56 @@
}
}
- SimplyBoundedNode getNode(Reference reference) {
- var node = nodeMap[reference];
- if (node == null) {
- if (reference.isClass) {
- var parameters = LinkedUnitContext.getTypeParameters(reference.node);
- node = SimplyBoundedNode(
+ SimplyBoundedNode getNode(Element element) {
+ var graphNode = nodeMap[element];
+ if (graphNode == null) {
+ var node = (element as ElementImpl).linkedNode;
+ if (node is ClassDeclaration) {
+ var parameters = node.typeParameters?.typeParameters;
+ graphNode = SimplyBoundedNode(
this,
- reference,
- parameters ?? const <LinkedNode>[],
- const <LinkedNode>[],
+ node,
+ parameters ?? const <TypeParameter>[],
+ const <TypeAnnotation>[],
);
- } else if (reference.isTypeAlias) {
- var parameters = LinkedUnitContext.getTypeParameters(reference.node);
- node = SimplyBoundedNode(
+ } else if (node is ClassTypeAlias) {
+ var parameters = node.typeParameters?.typeParameters;
+ graphNode = SimplyBoundedNode(
this,
- reference,
- parameters ?? const <LinkedNode>[],
- _collectTypedefRhsTypes(reference.node),
+ node,
+ parameters ?? const <TypeParameter>[],
+ const <TypeAnnotation>[],
+ );
+ } else if (node is FunctionTypeAlias) {
+ var parameters = node.typeParameters?.typeParameters;
+ graphNode = SimplyBoundedNode(
+ this,
+ node,
+ parameters ?? const <TypeParameter>[],
+ _collectTypedefRhsTypes(node),
+ );
+ } else if (node is GenericTypeAlias) {
+ var parameters = node.typeParameters?.typeParameters;
+ graphNode = SimplyBoundedNode(
+ this,
+ node,
+ parameters ?? const <TypeParameter>[],
+ _collectTypedefRhsTypes(node),
+ );
+ } else if (node is MixinDeclaration) {
+ var parameters = node.typeParameters?.typeParameters;
+ graphNode = SimplyBoundedNode(
+ this,
+ node,
+ parameters ?? const <TypeParameter>[],
+ const <TypeAnnotation>[],
);
} else {
- throw UnimplementedError('$reference');
+ throw UnimplementedError('(${node.runtimeType}) $node');
}
- nodeMap[reference] = node;
+ nodeMap[element] = graphNode;
}
- return node;
+ return graphNode;
}
/// Collects all the type references appearing on the "right hand side" of a
@@ -100,33 +125,19 @@
/// declaration, the type that *would* appear after the "=" if it were
/// converted to a new style typedef declaration. This means that type
/// parameter declarations and their bounds are not included.
- static List<LinkedNode> _collectTypedefRhsTypes(LinkedNode node) {
- var kind = node.kind;
- if (kind == LinkedNodeKind.functionTypeAlias) {
- var types = <LinkedNode>[];
- _TypeCollector.addType(
- types,
- node.functionTypeAlias_returnType,
- );
- _TypeCollector.visitParameters(
- types,
- node.functionTypeAlias_formalParameters,
- );
- return types;
- } else if (kind == LinkedNodeKind.genericTypeAlias) {
- var types = <LinkedNode>[];
- var function = node.genericTypeAlias_functionType;
- _TypeCollector.addType(
- types,
- function.genericFunctionType_returnType,
- );
- _TypeCollector.visitParameters(
- types,
- function.genericFunctionType_formalParameters,
- );
- return types;
+ static List<TypeAnnotation> _collectTypedefRhsTypes(AstNode node) {
+ if (node is FunctionTypeAlias) {
+ var collector = _TypeCollector();
+ collector.addType(node.returnType);
+ collector.visitParameters(node.parameters);
+ return collector.types;
+ } else if (node is GenericTypeAlias) {
+ var collector = _TypeCollector();
+ collector.addType(node.functionType.returnType);
+ collector.visitParameters(node.functionType.parameters);
+ return collector.types;
} else {
- throw StateError('$kind');
+ throw StateError('(${node.runtimeType}) $node');
}
}
}
@@ -135,14 +146,14 @@
/// whether types are simply bounded.
class SimplyBoundedNode extends graph.Node<SimplyBoundedNode> {
final SimplyBoundedDependencyWalker _walker;
- final Reference _reference;
+ final AstNode _node;
/// The type parameters of the type whose simple-boundedness we check.
- final List<LinkedNode> _typeParameters;
+ final List<TypeParameter> _typeParameters;
/// If the type whose simple-boundedness we check is a typedef, the types
/// appearing in its "right hand side".
- final List<LinkedNode> _rhsTypes;
+ final List<TypeAnnotation> _rhsTypes;
@override
bool isEvaluated = false;
@@ -159,7 +170,7 @@
SimplyBoundedNode(
this._walker,
- this._reference,
+ this._node,
this._typeParameters,
this._rhsTypes,
);
@@ -168,7 +179,7 @@
List<SimplyBoundedNode> computeDependencies() {
var dependencies = <SimplyBoundedNode>[];
for (var typeParameter in _typeParameters) {
- var bound = typeParameter.typeParameter_bound;
+ var bound = typeParameter.bound;
if (bound != null) {
if (!_visitType(dependencies, bound, false)) {
// Note: we might consider setting isEvaluated=true here to prevent an
@@ -223,35 +234,32 @@
/// If `false` is returned, further visiting is short-circuited.
///
/// Otherwise `true` is returned.
- bool _visitType(List<SimplyBoundedNode> dependencies, LinkedNode type,
+ bool _visitType(List<SimplyBoundedNode> dependencies, TypeAnnotation type,
bool allowTypeParameters) {
if (type == null) return true;
- if (type.kind == LinkedNodeKind.typeName) {
- var element = TypeBuilder.typeNameElementIndex(type.typeName_name);
- var reference = _walker.bundleContext.referenceOfIndex(element);
+ if (type is TypeName) {
+ var element = type.name.staticElement;
- if (reference.isTypeParameter) {
+ if (element is TypeParameterElement) {
return allowTypeParameters;
}
- var arguments = type.typeName_typeArguments;
+ var arguments = type.typeArguments;
if (arguments == null) {
- var graphNode = _walker.nodeMap[reference];
+ var graphNode = _walker.nodeMap[element];
// If not a node being linked, then the flag is already set.
if (graphNode == null) {
- if (reference.isClass || reference.isTypeAlias) {
- var elementFactory = _walker.bundleContext.elementFactory;
- var node = elementFactory.nodeOfReference(reference);
- return node.simplyBoundable_isSimplyBounded;
+ if (element is TypeParameterizedElement) {
+ return element.isSimplyBounded;
}
return true;
}
dependencies.add(graphNode);
} else {
- for (var argument in arguments.typeArgumentList_arguments) {
+ for (var argument in arguments.arguments) {
if (!_visitType(dependencies, argument, allowTypeParameters)) {
return false;
}
@@ -260,14 +268,11 @@
return true;
}
- if (type.kind == LinkedNodeKind.genericFunctionType) {
- var types = <LinkedNode>[];
- _TypeCollector.addType(types, type.genericFunctionType_returnType);
- _TypeCollector.visitParameters(
- types,
- type.genericFunctionType_formalParameters,
- );
- for (var type in types) {
+ if (type is GenericFunctionType) {
+ var collector = _TypeCollector();
+ collector.addType(type.returnType);
+ collector.visitParameters(type.parameters);
+ for (var type in collector.types) {
if (!_visitType(dependencies, type, allowTypeParameters)) {
return false;
}
@@ -275,39 +280,36 @@
return true;
}
- throw UnimplementedError('${type.kind}');
+ throw UnimplementedError('(${type.runtimeType}) $type');
}
}
-/// Helper for collecting type annotations in formal parameters.
+/// Helper for collecting type annotations.
class _TypeCollector {
- static void addType(List<LinkedNode> types, LinkedNode type) {
+ final List<TypeAnnotation> types = [];
+
+ void addType(TypeAnnotation type) {
if (type != null) {
types.add(type);
}
}
- static void visitParameter(List<LinkedNode> types, LinkedNode parameter) {
- var kind = parameter.kind;
- if (kind == LinkedNodeKind.defaultFormalParameter) {
- visitParameter(types, parameter.defaultFormalParameter_parameter);
- } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
- addType(types, parameter.functionTypedFormalParameter_returnType);
- visitParameters(
- types,
- parameter.functionTypedFormalParameter_formalParameters,
- );
- } else if (kind == LinkedNodeKind.simpleFormalParameter) {
- addType(types, parameter.simpleFormalParameter_type);
+ void visitParameter(FormalParameter node) {
+ if (node is DefaultFormalParameter) {
+ visitParameter(node.parameter);
+ } else if (node is FunctionTypedFormalParameter) {
+ addType(node.returnType);
+ visitParameters(node.parameters);
+ } else if (node is SimpleFormalParameter) {
+ addType(node.type);
} else {
- throw UnimplementedError('$kind');
+ throw UnimplementedError('(${node.runtimeType}) $node');
}
}
- static void visitParameters(List<LinkedNode> types, LinkedNode parameters) {
- assert(parameters.kind == LinkedNodeKind.formalParameterList);
- for (var parameter in parameters.formalParameterList_parameters) {
- visitParameter(types, parameter);
+ void visitParameters(FormalParameterList parameterList) {
+ for (var parameter in parameterList.parameters) {
+ visitParameter(parameter);
}
}
}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index c5b38e4..60b10d9 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -3,16 +3,21 @@
// 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:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/summary/link.dart' as graph
+ show DependencyWalker, Node;
import 'package:analyzer/src/summary2/ast_resolver.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
+import 'package:analyzer/src/task/strong_mode.dart';
DartType _dynamicIfNull(DartType type) {
if (type == null || type.isBottom || type.isDartCoreNull) {
@@ -21,73 +26,55 @@
return type;
}
-/// TODO(scheglov) This is not a valid implementation of top-level inference.
-/// See https://bit.ly/2HYfAKg
-///
-/// In general inference of constructor field formal parameters should be
-/// interleaved with inference of fields. There are resynthesis tests that
-/// fail because of this limitation.
+AstNode _getLinkedNode(Element element) {
+ return (element as ElementImpl).linkedNode;
+}
+
class TopLevelInference {
final Linker linker;
- LibraryElementImpl _libraryElement;
- Scope _libraryScope;
- Scope _nameScope;
+ TopLevelInference(this.linker);
- LinkedUnitContext _linkedContext;
- CompilationUnitElementImpl unitElement;
-
- TopLevelInference(this.linker, Reference libraryRef) {
- _libraryElement = linker.elementFactory.elementOfReference(libraryRef);
- _libraryScope = LibraryScope(_libraryElement);
- _nameScope = _libraryScope;
- }
-
- DynamicTypeImpl get _dynamicType {
- return DynamicTypeImpl.instance;
- }
-
- VoidTypeImpl get _voidType => VoidTypeImpl.instance;
+ DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
void infer() {
- _setOmittedReturnTypes();
- _inferFieldsTemporary();
+ _performOverrideInference();
+ _InitializerInference(linker).perform();
_inferConstructorFieldFormals();
}
void _inferConstructorFieldFormals() {
- for (CompilationUnitElementImpl unit in _libraryElement.units) {
- this.unitElement = unit;
- _linkedContext = unit.linkedContext;
+ for (var builder in linker.builders.values) {
+ for (var unit in builder.element.units) {
+ for (var class_ in unit.types) {
+ var fields = <String, DartType>{};
+ for (var field in class_.fields) {
+ if (field.isSynthetic) continue;
- for (var class_ in unit.types) {
- var fields = <String, DartType>{};
- for (FieldElementImpl field in class_.fields) {
- if (field.isSynthetic) continue;
-
- var name = field.name;
- var type = field.type;
- if (type == null) {
- throw StateError('Field $name should have a type.');
+ var name = field.name;
+ var type = field.type;
+ if (type == null) {
+ throw StateError('Field $name should have a type.');
+ }
+ fields[name] ??= type;
}
- fields[name] ??= type;
- }
- for (ConstructorElementImpl constructor in class_.constructors) {
- for (ParameterElementImpl parameter in constructor.parameters) {
- if (parameter is FieldFormalParameterElement) {
- FormalParameter node = parameter.linkedNode;
- if (node is DefaultFormalParameter) {
- var defaultParameter = node as DefaultFormalParameter;
- node = defaultParameter.parameter;
- }
+ for (var constructor in class_.constructors) {
+ for (var parameter in constructor.parameters) {
+ if (parameter is FieldFormalParameterElement) {
+ var node = _getLinkedNode(parameter);
+ if (node is DefaultFormalParameter) {
+ var defaultParameter = node as DefaultFormalParameter;
+ node = defaultParameter.parameter;
+ }
- if (node is FieldFormalParameter &&
- node.type == null &&
- node.parameters == null) {
- var name = parameter.name;
- var type = fields[name] ?? _dynamicType;
- LazyAst.setType(node, type);
+ if (node is FieldFormalParameter &&
+ node.type == null &&
+ node.parameters == null) {
+ var name = parameter.name;
+ var type = fields[name] ?? _dynamicType;
+ LazyAst.setType(node, type);
+ }
}
}
}
@@ -96,116 +83,162 @@
}
}
- void _inferFieldsTemporary() {
- for (CompilationUnitElementImpl unit in _libraryElement.units) {
- this.unitElement = unit;
- _linkedContext = unit.linkedContext;
-
- for (var class_ in unit.types) {
- _inferFieldsTemporaryClass(class_);
- }
-
- for (var mixin_ in unit.mixins) {
- _inferFieldsTemporaryClass(mixin_);
- }
-
- for (TopLevelVariableElementImpl variable in unit.topLevelVariables) {
- if (variable.isSynthetic) continue;
- VariableDeclaration node = variable.linkedNode;
- VariableDeclarationList parent = node.parent;
- if (parent.type == null || _linkedContext.isConst(node)) {
- _inferVariableTypeFromInitializerTemporary(node);
- }
+ void _performOverrideInference() {
+ for (var builder in linker.builders.values) {
+ for (var unit in builder.element.units) {
+ new InstanceMemberInferrer(
+ linker.typeProvider,
+ linker.inheritance,
+ ).inferCompilationUnit(unit);
}
}
}
+}
- void _inferFieldsTemporaryClass(ClassElement class_) {
- var prevScope = _nameScope;
+class _InferenceDependenciesCollector extends RecursiveAstVisitor<void> {
+ final Set<PropertyInducingElement> _set = Set.identity();
- _nameScope = TypeParameterScope(_nameScope, class_);
- _nameScope = ClassScope(_nameScope, class_);
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ var element = node.staticElement;
+ if (element is PropertyAccessorElement && element.isGetter) {
+ _set.add(element.variable);
+ }
+ }
+}
- for (FieldElementImpl field in class_.fields) {
- if (field.isSynthetic) continue;
- VariableDeclaration node = field.linkedNode;
- VariableDeclarationList parent = node.parent;
- // TODO(scheglov) Use inheritance
- // TODO(scheglov) infer in the correct order
- if (parent.type == null || parent.isConst) {
- _inferVariableTypeFromInitializerTemporary(node);
- }
+class _InferenceNode extends graph.Node<_InferenceNode> {
+ final _InferenceWalker _walker;
+ final LibraryElement _library;
+ final Scope _scope;
+ final VariableDeclaration _node;
+
+ @override
+ bool isEvaluated = false;
+
+ _InferenceNode(this._walker, this._library, this._scope, this._node);
+
+ @override
+ List<_InferenceNode> computeDependencies() {
+ _node.initializer.accept(LocalElementBuilder(ElementHolder(), null));
+
+ _resolveInitializer();
+
+ var collector = _InferenceDependenciesCollector();
+ _node.initializer.accept(collector);
+
+ if (collector._set.isEmpty) {
+ return const <_InferenceNode>[];
}
- _nameScope = prevScope;
+ return collector._set
+ .map(_walker.getNode)
+ .where((node) => node != null)
+ .toList();
}
- void _inferVariableTypeFromInitializerTemporary(VariableDeclaration node) {
- var initializer = node.initializer;
+ void evaluate() {
+ _resolveInitializer();
- if (initializer == null) {
- LazyAst.setType(node, _dynamicType);
- return;
- }
-
- var astResolver = AstResolver(linker, _libraryElement, _nameScope);
- astResolver.resolve(initializer);
-
- VariableDeclarationList parent = node.parent;
+ VariableDeclarationList parent = _node.parent;
if (parent.type == null) {
- var initializerType = initializer.staticType;
+ var initializerType = _node.initializer.staticType;
initializerType = _dynamicIfNull(initializerType);
- LazyAst.setType(node, initializerType);
+ LazyAst.setType(_node, initializerType);
+ }
+
+ isEvaluated = true;
+ }
+
+ void markCircular() {
+ LazyAst.setType(_node, DynamicTypeImpl.instance);
+ isEvaluated = true;
+ }
+
+ void _resolveInitializer() {
+ var astResolver = AstResolver(_walker._linker, _library, _scope);
+ astResolver.resolve(_node.initializer, doAstRewrite: true);
+ }
+}
+
+class _InferenceWalker extends graph.DependencyWalker<_InferenceNode> {
+ final Linker _linker;
+ final Map<Element, _InferenceNode> _nodes = Map.identity();
+
+ _InferenceWalker(this._linker);
+
+ void addNode(Element element, LibraryElement library, Scope scope,
+ VariableDeclaration node) {
+ _nodes[element] = _InferenceNode(this, library, scope, node);
+ }
+
+ @override
+ void evaluate(_InferenceNode v) {
+ v.evaluate();
+ }
+
+ @override
+ void evaluateScc(List<_InferenceNode> scc) {
+ for (var node in scc) {
+ node.markCircular();
}
}
- void _setOmittedReturnTypes() {
- for (CompilationUnitElementImpl unit in _libraryElement.units) {
- this.unitElement = unit;
- _linkedContext = unit.linkedContext;
+ _InferenceNode getNode(Element element) {
+ return _nodes[element];
+ }
- for (var class_ in unit.types) {
- _setOmittedReturnTypesClass(class_);
- }
-
- for (var mixin_ in unit.mixins) {
- _setOmittedReturnTypesClass(mixin_);
- }
-
- for (FunctionElementImpl function in unit.functions) {
- FunctionDeclaration node = function.linkedNode;
- if (node.returnType == null) {
- LazyAst.setReturnType(node, _dynamicType);
- }
- }
-
- for (PropertyAccessorElementImpl accessor in unit.accessors) {
- if (accessor.isSynthetic) continue;
- if (accessor.isSetter) {
- LazyAst.setReturnType(accessor.linkedNode, _voidType);
- }
+ void walkNodes() {
+ for (var node in _nodes.values) {
+ if (!node.isEvaluated) {
+ walk(node);
}
}
}
+}
- void _setOmittedReturnTypesClass(ClassElement class_) {
- for (MethodElementImpl method in class_.methods) {
- MethodDeclaration node = method.linkedNode;
- if (node.returnType == null) {
- LazyAst.setReturnType(node, _dynamicType);
+class _InitializerInference {
+ final Linker _linker;
+ final _InferenceWalker _walker;
+
+ LibraryElement _library;
+ Scope _scope;
+
+ _InitializerInference(this._linker) : _walker = _InferenceWalker(_linker);
+
+ void perform() {
+ for (var builder in _linker.builders.values) {
+ _library = builder.element;
+ for (var unit in _library.units) {
+ for (var class_ in unit.types) {
+ var node = _getLinkedNode(class_);
+ _scope = LinkingNodeContext.get(node).scope;
+ for (var element in class_.fields) {
+ _addNode(element);
+ }
+ }
+
+ _scope = builder.libraryScope;
+ for (var element in unit.topLevelVariables) {
+ _addNode(element);
+ }
}
}
+ _walker.walkNodes();
+ }
- for (PropertyAccessorElementImpl accessor in class_.accessors) {
- if (accessor.isSynthetic) continue;
+ void _addNode(PropertyInducingElement element) {
+ if (element.isSynthetic) return;
- MethodDeclaration node = accessor.linkedNode;
- if (node.returnType != null) continue;
-
- if (accessor.isSetter) {
- LazyAst.setReturnType(node, _voidType);
+ VariableDeclaration node = _getLinkedNode(element);
+ VariableDeclarationList variableList = node.parent;
+ if (variableList.type == null || element.isConst) {
+ if (node.initializer != null) {
+ _walker.addNode(element, _library, _scope, node);
} else {
- LazyAst.setReturnType(node, _dynamicType);
+ if (LazyAst.getType(node) == null) {
+ LazyAst.setType(node, DynamicTypeImpl.instance);
+ }
}
}
}
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 3588181..9a677ee 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -9,82 +9,68 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
-/// Type annotations and declarations to build types for.
-///
-/// Not all types can be build during reference resolution phase.
-/// For example `A` means `A<num>` if `class A<T extends num>`, but we don't
-/// know this until we resolved `A` declaration, and we might have not yet.
-///
-/// So, we remember type annotations that should be resolved later, and
-/// declarations to set types from explicit type annotations.
-class NodesToBuildType {
- final List<NodeToBuildType> items = [];
-
- void addDeclaration(AstNode declaration) {
- items.add(NodeToBuildType._(null, declaration));
- }
-
- void addTypeAnnotation(TypeAnnotation typeAnnotation) {
- items.add(NodeToBuildType._(typeAnnotation, null));
- }
-}
-
-/// A type annotation to build type for, or a declaration to set its explicitly
-/// declared type.
-class NodeToBuildType {
- final TypeAnnotation typeAnnotation;
- final AstNode declaration;
-
- NodeToBuildType._(this.typeAnnotation, this.declaration);
-}
-
-/// Build types in a [NodesToBuildType].
class TypeBuilder {
- final LinkingBundleContext bundleContext;
+ final Dart2TypeSystem typeSystem;
- TypeBuilder(this.bundleContext);
+ /// The set of type annotations, and declaration in the build unit, for which
+ /// we need to build types, but have not built yet.
+ final Set<AstNode> _nodesToBuildType = Set.identity();
- DynamicTypeImpl get _dynamicType {
- return DynamicTypeImpl.instance;
- }
+ TypeBuilder(this.typeSystem);
- void build(NodesToBuildType nodesToBuildType) {
- for (var item in nodesToBuildType.items) {
- if (item.typeAnnotation != null) {
- var node = item.typeAnnotation;
- if (node is GenericFunctionType) {
- _buildGenericFunctionType(node);
- } else if (node is TypeName) {
- _buildTypeName(node);
- } else {
- throw StateError('${node.runtimeType}');
- }
- } else if (item.declaration != null) {
- _setTypesForDeclaration(item.declaration);
- }
+ DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
+
+ VoidTypeImpl get _voidType => VoidTypeImpl.instance;
+
+ /// The [nodes] list is a mix of [TypeAnnotation]s and declarations, where
+ /// usually type annotations come before declarations that use them, but this
+ /// is not guaranteed, and not even always possible. For example references
+ /// to typedefs declared in another unit being built - we need to build types
+ /// for this typedef, which might reference another unit (encountered before
+ /// or after the one defining the typedef).
+ void build(List<AstNode> nodes) {
+ _nodesToBuildType.addAll(nodes);
+ for (var item in nodes) {
+ _build(item);
}
}
- DartType _buildFunctionType(
+ void _build(AstNode node) {
+ if (node == null) return;
+ if (!_nodesToBuildType.remove(node)) return;
+
+ if (node is TypeAnnotation) {
+ _typeAnnotation(node);
+ } else {
+ _declaration(node);
+ }
+ }
+
+ FunctionType _buildFunctionType(
+ TypeParameterList typeParameterList,
TypeAnnotation returnTypeNode,
FormalParameterList parameterList,
) {
var returnType = returnTypeNode?.type ?? _dynamicType;
- // TODO(scheglov) type parameters
- var typeParameters = const <TypeParameterElement>[];
+ List<TypeParameterElement> typeParameters;
+ if (typeParameterList != null) {
+ typeParameters = typeParameterList.typeParameters
+ .map<TypeParameterElement>((p) => p.declaredElement)
+ .toList();
+ } else {
+ typeParameters = const <TypeParameterElement>[];
+ }
- var formalParameters = parameterList.parameters.map((p) {
- // TODO(scheglov) other types and kinds
+ var formalParameters = parameterList.parameters.map((parameter) {
return ParameterElementImpl.synthetic(
- (p as SimpleFormalParameter).identifier.name,
- LazyAst.getType(p),
- ParameterKind.REQUIRED,
+ parameter.identifier?.name ?? '',
+ LazyAst.getType(parameter),
+ // ignore: deprecated_member_use_from_same_package
+ parameter.kind,
);
}).toList();
@@ -95,12 +81,109 @@
);
}
- void _buildGenericFunctionType(GenericFunctionTypeImpl node) {
- // TODO(scheglov) Type parameters?
- node.type = _buildFunctionType(node.returnType, node.parameters);
+ void _declaration(AstNode node) {
+ if (node is FieldFormalParameter) {
+ _fieldFormalParameter(node);
+ } else if (node is FunctionDeclaration) {
+ var defaultReturnType = node.isSetter ? _voidType : _dynamicType;
+ var returnType = node.returnType?.type ?? defaultReturnType;
+ LazyAst.setReturnType(node, returnType);
+ } else if (node is FunctionTypeAlias) {
+ _functionTypeAlias(node);
+ } else if (node is FunctionTypedFormalParameter) {
+ _functionTypedFormalParameter(node);
+ } else if (node is GenericFunctionType) {
+ _genericFunctionType(node);
+ } else if (node is MethodDeclaration) {
+ var defaultReturnType = node.isSetter ? _voidType : _dynamicType;
+ var returnType = node.returnType?.type ?? defaultReturnType;
+ LazyAst.setReturnType(node, returnType);
+ } else if (node is SimpleFormalParameter) {
+ _build(node.type);
+ LazyAst.setType(node, node.type?.type ?? _dynamicType);
+ } else if (node is VariableDeclarationList) {
+ var type = node.type?.type;
+ if (type != null) {
+ for (var variable in node.variables) {
+ LazyAst.setType(variable, type);
+ }
+ }
+ } else {
+ throw UnimplementedError('${node.runtimeType}');
+ }
}
- void _buildTypeName(TypeName node) {
+ void _fieldFormalParameter(FieldFormalParameter node) {
+ var parameterList = node.parameters;
+ if (parameterList != null) {
+ var type = _buildFunctionType(
+ node.typeParameters,
+ node.type,
+ parameterList,
+ );
+ LazyAst.setType(node, type);
+ } else {
+ LazyAst.setType(node, node.type?.type ?? _dynamicType);
+ }
+ }
+
+ void _formalParameterList(FormalParameterList node) {
+ for (var formalParameter in node.parameters) {
+ if (formalParameter is SimpleFormalParameter) {
+ _build(formalParameter);
+ }
+ }
+ }
+
+ void _functionTypeAlias(FunctionTypeAlias node) {
+ var returnTypeNode = node.returnType;
+ _build(returnTypeNode);
+ LazyAst.setReturnType(node, returnTypeNode?.type ?? _dynamicType);
+
+ _typeParameterList(node.typeParameters);
+ _formalParameterList(node.parameters);
+ }
+
+ void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ var type = _buildFunctionType(
+ node.typeParameters,
+ node.returnType,
+ node.parameters,
+ );
+ LazyAst.setType(node, type);
+ }
+
+ void _genericFunctionType(GenericFunctionTypeImpl node) {
+ var returnTypeNode = node.returnType;
+ _build(returnTypeNode);
+ LazyAst.setReturnType(node, returnTypeNode?.type ?? _dynamicType);
+
+ _typeParameterList(node.typeParameters);
+ _formalParameterList(node.parameters);
+
+ node.type = _buildFunctionType(
+ node.typeParameters,
+ node.returnType,
+ node.parameters,
+ );
+ }
+
+ List<DartType> _listOfDynamic(int typeParametersLength) {
+ return List<DartType>.filled(typeParametersLength, _dynamicType);
+ }
+
+ void _typeAnnotation(TypeAnnotation node) {
+ if (node is GenericFunctionType) {
+ _genericFunctionType(node);
+ } else if (node is TypeName) {
+ node.type = _dynamicType;
+ _typeName(node);
+ } else {
+ throw StateError('${node.runtimeType}');
+ }
+ }
+
+ void _typeName(TypeName node) {
var element = node.name.staticElement;
List<DartType> typeArguments;
@@ -113,220 +196,65 @@
if (element.isEnum) {
node.type = InterfaceTypeImpl.explicit(element, const []);
} else {
- // TODO(scheglov) Use instantiate to bounds.
+ var rawType = element.type;
+
var typeParametersLength = element.typeParameters.length;
- if (typeArguments == null ||
- typeArguments.length != typeParametersLength) {
- typeArguments = List<DartType>.filled(
- typeParametersLength,
- DynamicTypeImpl.instance,
- );
+ if (typeParametersLength == 0) {
+ node.type = rawType;
+ return;
}
+
+ if (typeArguments == null) {
+ node.type = typeSystem.instantiateToBounds(rawType);
+ return;
+ }
+
+ if (typeArguments.length != typeParametersLength) {
+ typeArguments = _listOfDynamic(typeParametersLength);
+ }
+
node.type = InterfaceTypeImpl.explicit(element, typeArguments);
}
} else if (element is GenericTypeAliasElement) {
- // TODO(scheglov) Use instantiate to bounds.
- var typeParametersLength = element.typeParameters.length;
- if (typeArguments == null ||
- typeArguments.length != typeParametersLength) {
- typeArguments = List<DartType>.filled(
- typeParametersLength,
- DynamicTypeImpl.instance,
+ _build((element as ElementImpl).linkedNode);
+
+ var rawType = element.function.type;
+
+ var typeParameters = element.typeParameters;
+ var typeParametersLength = typeParameters.length;
+ if (typeParametersLength == 0) {
+ node.type = rawType;
+ return;
+ }
+
+ if (typeArguments == null) {
+ typeArguments = typeSystem.instantiateTypeFormalsToBounds(
+ typeParameters,
);
+ } else if (typeArguments.length != typeParametersLength) {
+ typeArguments = _listOfDynamic(typeParametersLength);
}
var substitution = Substitution.fromPairs(
- element.typeParameters,
+ typeParameters,
typeArguments,
);
-
- // TODO(scheglov) Not sure if I like this.
- var type = substitution.substituteType(element.function.type);
- node.type = type;
+ node.type = substitution.substituteType(rawType);
} else if (element is TypeParameterElement) {
node.type = TypeParameterTypeImpl(element);
} else {
-// throw UnimplementedError('${element.runtimeType}');
- // TODO(scheglov) implement
- node.type = DynamicTypeImpl.instance;
- }
-
-// var referenceIndex = typeNameElementIndex(node.typeName_name);
-// var reference = bundleContext.referenceOfIndex(referenceIndex);
-//
-// List<LinkedNodeTypeBuilder> typeArguments;
-// var typeArgumentList = node.typeName_typeArguments;
-// if (typeArgumentList != null) {
-// typeArguments = typeArgumentList.typeArgumentList_arguments
-// .map((node) => _getType(node))
-// .toList();
-// }
-//
-// if (reference.isClass) {
-// // TODO(scheglov) Use instantiate to bounds.
-// var typeParametersLength = _typeParametersLength(reference);
-// if (typeArguments == null ||
-// typeArguments.length != typeParametersLength) {
-// typeArguments = List<LinkedNodeTypeBuilder>.filled(
-// typeParametersLength,
-// _dynamicType,
-// );
-// }
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.interface,
-// interfaceClass: referenceIndex,
-// interfaceTypeArguments: typeArguments,
-// );
-// } else if (reference.isDynamic) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.dynamic_,
-// );
-// } else if (reference.isTypeAlias) {
-// // TODO(scheglov) Use instantiate to bounds.
-// var typeParametersLength = _typeParametersLength(reference);
-// if (typeArguments == null ||
-// typeArguments.length != typeParametersLength) {
-// typeArguments = List<LinkedNodeTypeBuilder>.filled(
-// typeParametersLength,
-// _dynamicType,
-// );
-// }
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.genericTypeAlias,
-// genericTypeAliasReference: referenceIndex,
-// genericTypeAliasTypeArguments: typeArguments,
-// );
-// } else if (reference.isEnum) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.interface,
-// interfaceClass: referenceIndex,
-// );
-// } else if (reference.isTypeParameter) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.typeParameter,
-// typeParameterParameter: referenceIndex,
-// );
-// } else {
-// node.typeName_type = _dynamicType;
-// }
- }
-
- void _fieldFormalParameter(FieldFormalParameter node) {
- var parameterList = node.parameters;
- if (parameterList != null) {
- var type = _buildFunctionType(node.type, parameterList);
- LazyAst.setType(node, type);
- } else {
- LazyAst.setType(node, node.type?.type ?? _dynamicType);
+ // We might get all kinds of elements, including not type at all.
+ // For example a PrefixElement, or a getter, etc.
+ // In all these cases the type is dynamic.
+ node.type = _dynamicType;
}
}
- void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
- var type = _buildFunctionType(node.returnType, node.parameters);
- LazyAst.setType(node, type);
- }
+ void _typeParameterList(TypeParameterList node) {
+ if (node == null) return;
-// LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) {
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.defaultFormalParameter) {
-// return _getFormalParameterType(node.defaultFormalParameter_parameter);
-// }
-// if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-// return node.functionTypedFormalParameter_type2;
-// }
-// if (kind == LinkedNodeKind.simpleFormalParameter) {
-// return _getType(node.simpleFormalParameter_type);
-// }
-// throw UnimplementedError('$kind');
-// }
-
-// LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
-// if (node == null) return _dynamicType;
-//
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.genericFunctionType) {
-// return node.genericFunctionType_type;
-// } else if (kind == LinkedNodeKind.typeName) {
-// return node.typeName_type;
-// } else {
-// throw UnimplementedError('$kind');
-// }
-// }
-
- void _setTypesForDeclaration(AstNode node) {
- if (node is FieldFormalParameter) {
- _fieldFormalParameter(node);
- } else if (node is FunctionDeclaration) {
- LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
- } else if (node is FunctionTypeAlias) {
- LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
- } else if (node is FunctionTypedFormalParameter) {
- _functionTypedFormalParameter(node);
- } else if (node is GenericFunctionType) {
- LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
- } else if (node is MethodDeclaration) {
- if (node.returnType != null) {
- LazyAst.setReturnType(node, node.returnType.type);
- }
- } else if (node is SimpleFormalParameter) {
- // TODO(scheglov) use top-level inference
- LazyAst.setType(node, node.type?.type ?? _dynamicType);
- } else if (node is VariableDeclarationList) {
- var type = node.type?.type;
- if (type != null) {
- for (var variable in node.variables) {
- LazyAst.setType(variable, type);
- }
- }
- } else {
- throw UnimplementedError('${node.runtimeType}');
- }
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.fieldFormalParameter) {
-// _fieldFormalParameter(node);
-// } else if (kind == LinkedNodeKind.functionDeclaration) {
-// node.functionDeclaration_returnType2 = _getType(
-// node.functionDeclaration_returnType,
-// );
-// } else if (kind == LinkedNodeKind.functionTypeAlias) {
-// node.functionTypeAlias_returnType2 = _getType(
-// node.functionTypeAlias_returnType,
-// );
-// } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-// _functionTypedFormalParameter(node);
-// } else if (kind == LinkedNodeKind.genericFunctionType) {
-// node.genericFunctionType_returnType2 = _getType(
-// node.genericFunctionType_returnType,
-// );
-// } else if (kind == LinkedNodeKind.methodDeclaration) {
-// node.methodDeclaration_returnType2 = _getType(
-// node.methodDeclaration_returnType,
-// );
-// } else if (kind == LinkedNodeKind.simpleFormalParameter) {
-// node.simpleFormalParameter_type2 = _getType(
-// node.simpleFormalParameter_type,
-// );
-// } else if (kind == LinkedNodeKind.variableDeclarationList) {
-// var typeNode = node.variableDeclarationList_type;
-// for (var variable in node.variableDeclarationList_variables) {
-// variable.variableDeclaration_type2 = _getType(typeNode);
-// }
-// } else {
-// throw UnimplementedError('$kind');
-// }
- }
-
-// int _typeParametersLength(Reference reference) {
-// var node = bundleContext.elementFactory.nodeOfReference(reference);
-// return LinkedUnitContext.getTypeParameters(node)?.length ?? 0;
-// }
-
- static int typeNameElementIndex(LinkedNode name) {
- if (name.kind == LinkedNodeKind.simpleIdentifier) {
- return name.simpleIdentifier_element;
- } else {
- var identifier = name.prefixedIdentifier_identifier;
- return identifier.simpleIdentifier_element;
+ for (var typeParameter in node.typeParameters) {
+ _build(typeParameter.bound);
}
}
}
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 0ae39f9..35a6337 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -156,6 +156,7 @@
DartType type = matchingParameter?.type ?? typeProvider.dynamicType;
if (parameterType == null) {
if (type is FunctionType &&
+ type.element != null &&
type.element is! TypeDefiningElement &&
type.element.enclosingElement is! TypeDefiningElement) {
// The resulting parameter's type element has an `enclosingElement` of
diff --git a/pkg/analyzer/test/error/error_test.dart b/pkg/analyzer/test/error/error_test.dart
index b68dbac..e07ea71 100644
--- a/pkg/analyzer/test/error/error_test.dart
+++ b/pkg/analyzer/test/error/error_test.dart
@@ -12,16 +12,17 @@
import '../generated/parser_test.dart';
-List<String> _analyzerRootComponents;
-
main() {
- _analyzerRootComponents =
- path.split(path.fromUri(Platform.script.resolve("../../")));
+ _analyzerRootComponents = path.split(path.fromUri(Platform.script));
+ int index = _analyzerRootComponents.lastIndexOf('analyzer');
+ _analyzerRootComponents = _analyzerRootComponents.sublist(0, index + 1);
defineReflectiveSuite(() {
defineReflectiveTests(ErrorCodeValuesTest);
});
}
+List<String> _analyzerRootComponents;
+
@reflectiveTest
class ErrorCodeValuesTest extends ParserTestCase {
bool bad() {
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 6318820..46f7960 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class CheckedModeCompileTimeErrorCodeTest extends DriverResolutionTest {
test_assertion_throws() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(int x, int y) : assert(x < y);
}
@@ -46,7 +46,7 @@
test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() async {
// Null always passes runtime type checks, even when the type is
// unresolved.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final Unresolved x;
const A(String this.x);
@@ -151,7 +151,7 @@
test_fieldFormalParameterAssignableToField_typedef() async {
// foo has the runtime type dynamic -> dynamic, so it is not assignable
// to A.f.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
typedef String Int2String(int x);
class A {
final Int2String f;
@@ -175,7 +175,7 @@
}
test_fieldFormalParameterNotAssignableToField() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final int x;
const A(this.x);
@@ -191,7 +191,7 @@
// According to checked-mode type checking rules, a value of type A is not
// assignable to a field of type B, because B extends A (the subtyping
// relationship is in the wrong direction).
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
}
@@ -208,7 +208,7 @@
}
test_fieldFormalParameterNotAssignableToField_fieldType() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final int x;
const A(this.x);
@@ -221,7 +221,7 @@
}
test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final Unresolved x;
const A(String this.x);
@@ -237,7 +237,7 @@
// According to checked-mode type checking rules, a value of type A is not
// assignable to a field of type B, because B implements A (the subtyping
// relationship is in the wrong direction).
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
}
@@ -253,7 +253,7 @@
test_fieldFormalParameterNotAssignableToField_list() async {
// <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(List<int> x);
}
@@ -265,7 +265,7 @@
test_fieldFormalParameterNotAssignableToField_map_keyMismatch() async {
// <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
// Map<int, int>.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(Map<int, int> x);
}
@@ -277,7 +277,7 @@
test_fieldFormalParameterNotAssignableToField_map_valueMismatch() async {
// <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
// Map<int, int>.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(Map<int, int> x);
}
@@ -287,7 +287,7 @@
}
test_fieldFormalParameterNotAssignableToField_optional() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final int x;
const A([this.x = 'foo']);
@@ -302,7 +302,7 @@
test_fieldFormalParameterNotAssignableToField_typedef() async {
// foo has the runtime type String -> int, so it should not be assignable
// to A.f (A.f requires it to be int -> String).
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
typedef String Int2String(int x);
class A {
final Int2String f;
@@ -317,7 +317,7 @@
}
test_fieldInitializerNotAssignable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
final int x;
const A() : x = '';
@@ -329,7 +329,7 @@
}
test_fieldTypeMismatch() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(x) : y = x;
final int y;
@@ -339,7 +339,7 @@
}
test_fieldTypeMismatch_generic() async {
- await assertErrorsInCode(
+ await assertErrorCodesInCode(
r'''
class C<T> {
final T x = y;
@@ -356,7 +356,7 @@
}
test_fieldTypeMismatch_unresolved() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(x) : y = x;
final Unresolved y;
@@ -369,7 +369,7 @@
}
test_fieldTypeOk_generic() async {
- await assertErrorsInCode(
+ await assertErrorCodesInCode(
r'''
class C<T> {
final T x = y;
@@ -395,7 +395,7 @@
test_fieldTypeOk_unresolved_null() async {
// Null always passes runtime type checks, even when the type is
// unresolved.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(x) : y = x;
final Unresolved y;
@@ -405,27 +405,27 @@
}
test_listElementTypeNotAssignable() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String> [42];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
test_listLiteral_inferredElementType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const Object x = [1];
const List<String> y = x;
''', [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
}
test_mapLiteral_inferredKeyType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const Object x = {1: 1};
const Map<String, dynamic> y = x;
''', [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
}
test_mapLiteral_inferredValueType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const Object x = {1: 1};
const Map<dynamic, String> y = x;
''', [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
@@ -451,7 +451,7 @@
test_parameterAssignable_undefined_null() async {
// Null always passes runtime type checks, even when the type is
// unresolved.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(Unresolved x);
}
@@ -460,7 +460,7 @@
}
test_parameterNotAssignable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(int x);
}
@@ -472,7 +472,7 @@
}
test_parameterNotAssignable_typeSubstitution() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<T> {
const A(T x);
}
@@ -484,7 +484,7 @@
}
test_parameterNotAssignable_undefined() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A(Unresolved x);
}
@@ -496,7 +496,7 @@
}
test_redirectingConstructor_paramTypeMismatch() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A.a1(x) : this.a2(x);
const A.a2(String x);
@@ -506,7 +506,7 @@
}
test_superConstructor_paramTypeMismatch() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class C {
final double d;
const C(this.d);
@@ -527,13 +527,13 @@
test_topLevelVarAssignable_undefined_null() async {
// Null always passes runtime type checks, even when the type is
// unresolved.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const Unresolved x = null;
''', [StaticWarningCode.UNDEFINED_CLASS]);
}
test_topLevelVarNotAssignable() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const int x = 'foo';
''', [
CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
@@ -542,7 +542,7 @@
}
test_topLevelVarNotAssignable_undefined() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const Unresolved x = 'foo';
''', [
CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 2ab9c7b..f8b7ac6 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -88,7 +88,7 @@
test_defaultValueInFunctionTypeAlias_new_named() async {
// This test used to fail with UI as code enabled. Test the fix here.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
typedef F = int Function({Map<String, String> m: const {}});
''', [
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
@@ -98,7 +98,7 @@
test_defaultValueInFunctionTypeAlias_new_named_ambiguous() async {
// Test that the strong checker does not crash when given an ambiguous
// set or map literal.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
typedef F = int Function({Object m: const {1, 2: 3}});
''', [
ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
@@ -114,7 +114,7 @@
..enabledExperiments = [EnableString.control_flow_collections];
test_awaitForIn_declaredVariableWrongType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
import 'dart:async';
f() async {
Stream<String> stream;
@@ -124,7 +124,7 @@
}
test_awaitForIn_existingVariableWrongType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
import 'dart:async';
f() async {
Stream<String> stream;
@@ -135,7 +135,7 @@
}
test_awaitForIn_notStream() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() async {
await for (var i in true) {}
}
@@ -143,7 +143,7 @@
}
test_duplicateDefinition_for_initializers() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
for (int i = 0, i = 0; i < 5;) {}
}
@@ -151,14 +151,14 @@
}
test_expectedOneListTypeArgument() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
<int, int>[];
}''', [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]);
}
test_expectedOneSetTypeArgument() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
<int, int, int>{2, 3};
}''', [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS]);
@@ -167,21 +167,21 @@
test_expectedTwoMapTypeArguments_three_ambiguous() async {
// TODO(brianwilkerson) We probably need a new error code for "expected
// either one or two type arguments" to handle the ambiguous case.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
<int, int, int>{};
}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
}
test_expectedTwoMapTypeArguments_three_map() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
<int, int, int>{1:2};
}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
}
test_forIn_declaredVariableWrongType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() {
for (int i in <String>[]) {}
}
@@ -189,7 +189,7 @@
}
test_forIn_existingVariableWrongType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() {
int i;
for (i in <String>[]) {}
@@ -198,7 +198,7 @@
}
test_forIn_notIterable() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() {
for (var i in true) {}
}
@@ -206,7 +206,7 @@
}
test_forIn_typeBoundBad() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class Foo<T extends Iterable<int>> {
void method(T iterable) {
for (String i in iterable) {}
@@ -216,7 +216,7 @@
}
test_forInWithConstVariable_forEach_identifier() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
const x = 0;
for (x in [0, 1, 2]) {}
@@ -225,7 +225,7 @@
}
test_forInWithConstVariable_forEach_loopVariable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
for (const x in [0, 1, 2]) {}
}
@@ -233,7 +233,7 @@
}
test_generalizedVoid_useOfInForeachIterableError() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
void main() {
void x;
for (var v in x) {}
@@ -242,7 +242,7 @@
}
test_generalizedVoid_useOfVoidInForeachVariableError() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
void main() {
void x;
var y;
@@ -252,7 +252,7 @@
}
test_invalidTypeArgumentInConstList() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<E> {
m() {
return const <E>[];
@@ -262,7 +262,7 @@
}
test_invalidTypeArgumentInConstMap_key() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<E> {
m() {
return const <E, String>{};
@@ -272,7 +272,7 @@
}
test_invalidTypeArgumentInConstMap_value() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<E> {
m() {
return const <String, E>{};
@@ -282,7 +282,7 @@
}
test_invalidTypeArgumentInConstSet_class() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<E> {
m() {
return const <E>{};
@@ -292,20 +292,20 @@
}
test_listElementTypeNotAssignable_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String>[42];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
test_mapValueTypeNotAssignable_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String, String>{'a' : 2};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
test_nonBoolCondition_for_declaration() async {
// https://github.com/dart-lang/sdk/issues/24713
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
for (int i = 0; 3;) {}
}
@@ -314,7 +314,7 @@
test_nonBoolCondition_for_expression() async {
// https://github.com/dart-lang/sdk/issues/24713
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
int i;
for (i = 0; 3;) {}
@@ -325,7 +325,7 @@
// TODO(danrubel) Fasta is not recovering well.
// Ideally we would produce a single diagnostic:
// CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
{'a' : 0, 'b' : 1}.length;
}
@@ -351,7 +351,7 @@
// TODO(danrubel) Fasta is not recovering well.
// Ideally we would produce a single diagnostic:
// CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
{'a' : 0, 'b' : 1};
}
@@ -373,7 +373,7 @@
}
test_setElementTypeNotAssignable_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String>{42};
''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
@@ -382,7 +382,7 @@
@reflectiveTest
class InvalidTypeArgumentInConstSetTest extends DriverResolutionTest {
test_class() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<E> {
m() {
return const <E>{};
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 738676c..ef81da6 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -2058,6 +2058,30 @@
void test_nullCheckPropertyAccess3() {
parseNNBDCompilationUnit('f() { var x = super.p! + 7; }');
}
+
+ void test_postfix_null_assertion_and_unary_prefix_operator_precedence() {
+ // -x! is parsed as -(x!).
+ var unit = parseNNBDCompilationUnit('void main() { -x!; }');
+ var function = unit.declarations[0] as FunctionDeclaration;
+ var body = function.functionExpression.body as BlockFunctionBody;
+ var statement = body.block.statements[0] as ExpressionStatement;
+ var outerExpression = statement.expression as PrefixExpression;
+ expect(outerExpression.operator.type, TokenType.MINUS);
+ var innerExpression = outerExpression.operand as PostfixExpression;
+ expect(innerExpression.operator.type, TokenType.BANG);
+ }
+
+ void test_postfix_null_assertion_of_postfix_expression() {
+ // x++! is parsed as (x++)!.
+ var unit = parseNNBDCompilationUnit('void main() { x++!; }');
+ var function = unit.declarations[0] as FunctionDeclaration;
+ var body = function.functionExpression.body as BlockFunctionBody;
+ var statement = body.block.statements[0] as ExpressionStatement;
+ var outerExpression = statement.expression as PostfixExpression;
+ expect(outerExpression.operator.type, TokenType.BANG);
+ var innerExpression = outerExpression.operand as PostfixExpression;
+ expect(innerExpression.operator.type, TokenType.PLUS_PLUS);
+ }
}
/**
@@ -2730,6 +2754,101 @@
@reflectiveTest
class TopLevelParserTest_Fasta extends FastaParserTestCase
with TopLevelParserTestMixin {
+ void test_languageVersion_afterImport() {
+ var unit = parseCompilationUnit('''
+import 'foo.dart';
+// @dart = 2.3
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion, isNull);
+ }
+
+ void test_languageVersion_beforeComment() {
+ var unit = parseCompilationUnit('''
+// some other comment
+// @dart = 2.3
+// yet another comment
+import 'foo.dart';
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion.major, 2);
+ expect(unit.languageVersion.minor, 3);
+ }
+
+ void test_languageVersion_beforeFunction() {
+ var unit = parseCompilationUnit('''
+// @dart = 2.3
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion.major, 2);
+ expect(unit.languageVersion.minor, 3);
+ }
+
+ void test_languageVersion_beforeImport() {
+ var unit = parseCompilationUnit('''
+// @dart = 2.3
+import 'foo.dart';
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion.major, 2);
+ expect(unit.languageVersion.minor, 3);
+ }
+
+ void test_languageVersion_beforeImport_afterScript() {
+ var unit = parseCompilationUnit('''
+#!/bin/dart
+// @dart = 2.3
+import 'foo.dart';
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion.major, 2);
+ expect(unit.languageVersion.minor, 3);
+ }
+
+ void test_languageVersion_beforeLibrary() {
+ var unit = parseCompilationUnit('''
+// @dart = 2.3
+library foo;
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion.major, 2);
+ expect(unit.languageVersion.minor, 3);
+ }
+
+ void test_languageVersion_incomplete_version() {
+ var unit = parseCompilationUnit('''
+// @dart = 2.
+library foo;
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion, isNull);
+ }
+
+ void test_languageVersion_invalid_identifier() {
+ var unit = parseCompilationUnit('''
+// @dart = blat
+library foo;
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion, isNull);
+ }
+
+ void test_languageVersion_invalid_version() {
+ var unit = parseCompilationUnit('''
+// @dart = 2.x
+library foo;
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion, isNull);
+ }
+
+ void test_languageVersion_unspecified() {
+ var unit = parseCompilationUnit('''
+main() {}
+''') as CompilationUnitImpl;
+ expect(unit.languageVersion, isNull);
+ }
+
void test_parseClassDeclaration_native_allowed() {
allowNativeClause = true;
test_parseClassDeclaration_native();
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index fae0a92..13c908b 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -3933,13 +3933,26 @@
}
void test_invalidInterpolation_missingClosingBrace_issue35900() {
- parseCompilationUnit(r"main () { print('${x' '); }", errors: [
- expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
- expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 26, 1),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 3),
- expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 23, 1),
- expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 27, 0),
- ]);
+ parseCompilationUnit(r"main () { print('${x' '); }",
+ errors: usingFastaParser
+ ? [
+ expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+ expectedError(
+ ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 26, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 3),
+ expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 23, 1),
+ expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 27, 0),
+ ]
+ : [
+ expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1),
+ expectedError(
+ ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 26, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 3),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 23, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 23, 1),
+ expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 23, 1),
+ expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 23, 1),
+ ]);
}
void test_invalidInterpolationIdentifier_startWithDigit() {
@@ -5364,6 +5377,20 @@
errors: [expectedError(ParserErrorCode.TYPEDEF_IN_CLASS, 10, 7)]);
}
+ void test_unexpectedCommaThenInterpolation() {
+ // https://github.com/Dart-Code/Dart-Code/issues/1548
+ parseCompilationUnit(r"main() { String s = 'a' 'b', 'c$foo'; return s; }",
+ errors: usingFastaParser
+ ? [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 29, 2),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 29, 2),
+ ]
+ : [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 29, 2),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 29, 1),
+ ]);
+ }
+
void test_unexpectedTerminatorForParameterGroup_named() {
createParser('(a, b})');
FormalParameterList list = parser.parseFormalParameterList();
@@ -7888,6 +7915,18 @@
expect(throwExpression.expression, isNotNull);
}
+ void test_parseUnaryExpression_decrement_identifier_index() {
+ PrefixExpression expression = parseExpression('--a[0]');
+ expect(expression, isNotNull);
+ assertNoErrors();
+ expect(expression.operator, isNotNull);
+ expect(expression.operator.type, TokenType.MINUS_MINUS);
+ expect(expression.operand, isNotNull);
+ IndexExpression operand = expression.operand as IndexExpression;
+ expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>());
+ expect(operand.index is IntegerLiteral, isTrue);
+ }
+
void test_parseUnaryExpression_decrement_normal() {
PrefixExpression expression = parseUnaryExpression('--x');
expect(expression, isNotNull);
@@ -7940,6 +7979,18 @@
expect(operand.operand, isNotNull);
}
+ void test_parseUnaryExpression_increment_identifier_index() {
+ PrefixExpression expression = parseExpression('++a[0]');
+ expect(expression, isNotNull);
+ assertNoErrors();
+ expect(expression.operator, isNotNull);
+ expect(expression.operator.type, TokenType.PLUS_PLUS);
+ expect(expression.operand, isNotNull);
+ IndexExpression operand = expression.operand as IndexExpression;
+ expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>());
+ expect(operand.index is IntegerLiteral, isTrue);
+ }
+
void test_parseUnaryExpression_increment_normal() {
PrefixExpression expression = parseUnaryExpression('++x');
expect(expression, isNotNull);
@@ -7973,6 +8024,18 @@
expect(operand.propertyName.name, "x");
}
+ void test_parseUnaryExpression_minus_identifier_index() {
+ PrefixExpression expression = parseExpression('-a[0]');
+ expect(expression, isNotNull);
+ assertNoErrors();
+ expect(expression.operator, isNotNull);
+ expect(expression.operator.type, TokenType.MINUS);
+ expect(expression.operand, isNotNull);
+ IndexExpression operand = expression.operand as IndexExpression;
+ expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>());
+ expect(operand.index is IntegerLiteral, isTrue);
+ }
+
void test_parseUnaryExpression_minus_normal() {
PrefixExpression expression = parseUnaryExpression('-x');
expect(expression, isNotNull);
@@ -8026,6 +8089,18 @@
expect(expression.operator.type, TokenType.TILDE);
expect(expression.operand, isNotNull);
}
+
+ void test_parseUnaryExpression_tilde_identifier_index() {
+ PrefixExpression expression = parseExpression('~a[0]');
+ expect(expression, isNotNull);
+ assertNoErrors();
+ expect(expression.operator, isNotNull);
+ expect(expression.operator.type, TokenType.TILDE);
+ expect(expression.operand, isNotNull);
+ IndexExpression operand = expression.operand as IndexExpression;
+ expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>());
+ expect(operand.index is IntegerLiteral, isTrue);
+ }
}
/**
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index a90bde8..3da22d1 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -168,7 +168,7 @@
@reflectiveTest
class ErrorResolverTest extends DriverResolutionTest {
test_breakLabelOnSwitchMember() async {
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
class A {
void m(int i) {
switch (i) {
@@ -182,7 +182,7 @@
}
test_continueLabelOnSwitch() async {
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
class A {
void m(int i) {
l: switch (i) {
@@ -201,7 +201,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
ParserErrorCode.EXPECTED_TOKEN
]);
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 7924563..47bfbff 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -715,7 +715,8 @@
a.f = a.f.toString();
}''');
await resolveTestFile();
- assertTestErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ assertTestErrorsWithCodes(
+ [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verifyTestResolved();
}
@@ -795,7 +796,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
verifyTestResolved();
}
@@ -823,7 +824,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
verifyTestResolved();
}
@@ -862,7 +863,7 @@
b[0][0] = 'hi';
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verifyTestResolved();
}
@@ -903,7 +904,8 @@
class B {}
class C = Object with A;''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verifyTestResolved();
var a = findElement.class_('A');
@@ -917,7 +919,7 @@
}
class C = Object with A;''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
);
verifyTestResolved();
@@ -949,7 +951,7 @@
}
class C = Object with A;''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
verifyTestResolved();
var a = findElement.class_('A');
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index b6ba562..25a512d 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -18,23 +18,15 @@
import 'analysis_context_factory.dart';
-/**
- * The class `EngineTestCase` defines utility methods for making assertions.
- */
+/// The class `EngineTestCase` defines utility methods for making assertions.
class EngineTestCase {
- /**
- * Flag indicating whether the fasta parser is being used.
- */
+ /// Return `true` if the fasta parser is being used.
bool get usingFastaParser => Parser.useFasta;
- /**
- * Assert that the given collection has the same number of elements as the number of specified
- * names, and that for each specified name, a corresponding element can be found in the given
- * collection with that name.
- *
- * @param elements the elements
- * @param names the names
- */
+ /// Assert that the given collection of [elements] has the same number of
+ /// elements as the number of specified [names], and that for each specified
+ /// name, a corresponding element can be found in the given collection with
+ /// that name.
void assertNamedElements(List<Element> elements, List<String> names) {
for (String elemName in names) {
bool found = false;
@@ -64,13 +56,8 @@
resourceProvider: new MemoryResourceProvider());
}
- /**
- * Return the getter in the given type with the given name. Inherited getters are ignored.
- *
- * @param type the type in which the getter is declared
- * @param getterName the name of the getter to be returned
- * @return the property accessor element representing the getter with the given name
- */
+ /// Return the getter in the given [type] with the given [name]. Inherited
+ /// getters are ignored.
PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
for (PropertyAccessorElement accessor in type.element.accessors) {
if (accessor.isGetter && accessor.name == getterName) {
@@ -80,13 +67,8 @@
fail("Could not find getter named $getterName in ${type.displayName}");
}
- /**
- * Return the method in the given type with the given name. Inherited methods are ignored.
- *
- * @param type the type in which the method is declared
- * @param methodName the name of the method to be returned
- * @return the method element representing the method with the given name
- */
+ /// Return the method in the given [type] with the given [name]. Inherited
+ /// methods are ignored.
MethodElement getMethod(InterfaceType type, String methodName) {
for (MethodElement method in type.element.methods) {
if (method.name == methodName) {
@@ -100,9 +82,7 @@
void tearDown() {}
- /**
- * @return the [AstNode] with requested type at offset of the "prefix".
- */
+ /// Return the [AstNode] with requested type at offset of the [prefix].
static AstNode findNode(
AstNode root, String code, String prefix, Predicate<AstNode> predicate) {
int offset = code.indexOf(prefix);
@@ -113,9 +93,7 @@
return node.thisOrAncestorMatching(predicate);
}
- /**
- * Find the [SimpleIdentifier] with at offset of the "prefix".
- */
+ /// Find the [SimpleIdentifier] with at offset of the [prefix].
static SimpleIdentifier findSimpleIdentifier(
AstNode root, String code, String prefix) {
int offset = code.indexOf(prefix);
@@ -126,110 +104,144 @@
}
}
-/**
- * A description of an error that is expected to be reported.
- */
+/// A description of an error that is expected to be reported.
class ExpectedError {
- /**
- * An empty array of error descriptors used when no errors are expected.
- */
+ /// An empty array of error descriptors used when no errors are expected.
static List<ExpectedError> NO_ERRORS = <ExpectedError>[];
- /**
- * The error code associated with the error.
- */
+ /// The error code associated with the error.
final ErrorCode code;
- /**
- * The offset of the beginning of the error's region.
- */
+ /// The offset of the beginning of the error's region.
final int offset;
- /**
- * The offset of the beginning of the error's region.
- */
+ /// The offset of the beginning of the error's region.
final int length;
- /**
- * Initialize a newly created error description.
- */
+ /// Initialize a newly created error description.
ExpectedError(this.code, this.offset, this.length);
+
+ /// 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;
+ }
}
-/**
- * An error listener that collects all of the errors passed to it for later
- * examination.
- */
+/// An error listener that collects all of the errors passed to it for later
+/// examination.
class GatheringErrorListener implements AnalysisErrorListener {
- /**
- * A flag indicating whether error ranges are to be compared when comparing
- * expected and actual errors.
- */
+ /// A flag indicating whether error ranges are to be compared when comparing
+ /// expected and actual errors.
final bool checkRanges;
- /**
- * A list containing the errors that were collected.
- */
+ /// A list containing the errors that were collected.
List<AnalysisError> _errors = <AnalysisError>[];
- /**
- * A table mapping sources to the line information for the source.
- */
+ /// A table mapping sources to the line information for the source.
Map<Source, LineInfo> _lineInfoMap = <Source, LineInfo>{};
- /**
- * Initialize a newly created error listener to collect errors.
- */
+ /// Initialize a newly created error listener to collect errors.
GatheringErrorListener({this.checkRanges = Parser.useFasta});
- /**
- * Return the errors that were collected.
- */
+ /// Return the errors that were collected.
List<AnalysisError> get errors => _errors;
- /**
- * Return `true` if at least one error has been gathered.
- */
+ /// Return `true` if at least one error has been gathered.
bool get hasErrors => _errors.length > 0;
- /**
- * Add the given [errors] to this listener.
- */
+ /// Add the given [errors] to this listener.
void addAll(List<AnalysisError> errors) {
for (AnalysisError error in errors) {
onError(error);
}
}
- /**
- * Add all of the errors recorded by the given [listener] to this listener.
- */
+ /// Add all of the errors recorded by the given [listener] to this listener.
void addAll2(RecordingErrorListener listener) {
addAll(listener.errors);
}
- /**
- * Assert that the number of errors that have been gathered matches the number
- * of [expectedErrors] and that they have the expected error codes and
- * locations. The order in which the errors were gathered is ignored.
- */
+ /// Assert that the number of errors that have been gathered matches the
+ /// number of [expectedErrors] and that they have the expected error codes and
+ /// locations. The order in which the errors were gathered is ignored.
void assertErrors(List<ExpectedError> expectedErrors) {
- if (_errors.length != expectedErrors.length) {
- _fail(expectedErrors);
- }
- List<ExpectedError> remainingErrors = expectedErrors.toList();
- for (AnalysisError error in _errors) {
- if (!_foundAndRemoved(remainingErrors, error)) {
- _fail(expectedErrors);
+ //
+ // Match actual errors to expected errors.
+ //
+ List<AnalysisError> unmatchedActual = errors.toList();
+ List<ExpectedError> unmatchedExpected = expectedErrors.toList();
+ int actualIndex = 0;
+ while (actualIndex < unmatchedActual.length) {
+ bool matchFound = false;
+ int expectedIndex = 0;
+ while (expectedIndex < unmatchedExpected.length) {
+ if (unmatchedExpected[expectedIndex]
+ .matches(unmatchedActual[actualIndex])) {
+ matchFound = true;
+ unmatchedActual.removeAt(actualIndex);
+ unmatchedExpected.removeAt(expectedIndex);
+ break;
+ }
+ expectedIndex++;
}
+ if (!matchFound) {
+ actualIndex++;
+ }
+ }
+ //
+ // Write the results.
+ //
+ StringBuffer buffer = new StringBuffer();
+ if (unmatchedExpected.isNotEmpty) {
+ buffer.writeln('Expected but did not find:');
+ for (ExpectedError expected in unmatchedExpected) {
+ buffer.write(' ');
+ buffer.write(expected.code);
+ buffer.write(' [');
+ buffer.write(expected.offset);
+ buffer.write(', ');
+ buffer.write(expected.length);
+ buffer.writeln(']');
+ }
+ }
+ if (unmatchedActual.isNotEmpty) {
+ if (buffer.isNotEmpty) {
+ buffer.writeln();
+ }
+ buffer.writeln('Found but did not expect:');
+ for (AnalysisError actual in unmatchedActual) {
+ buffer.write(' ');
+ buffer.write(actual.errorCode);
+ buffer.write(' [');
+ buffer.write(actual.offset);
+ buffer.write(', ');
+ buffer.write(actual.length);
+ buffer.writeln(']');
+ }
+ }
+ if (buffer.isNotEmpty) {
+ errors.sort((first, second) => first.offset.compareTo(second.offset));
+ buffer.writeln();
+ buffer.writeln('To accept the current state, expect:');
+ for (AnalysisError actual in errors) {
+ buffer.write(' error(');
+ buffer.write(actual.errorCode);
+ buffer.write(', ');
+ buffer.write(actual.offset);
+ buffer.write(', ');
+ buffer.write(actual.length);
+ buffer.writeln('),');
+ }
+ fail(buffer.toString());
}
}
- /**
- * Assert that the number of errors that have been gathered matches the number
- * of [expectedErrorCodes] and that they have the expected error codes. The
- * order in which the errors were gathered is ignored.
- */
+ /// Assert that the number of errors that have been gathered matches the
+ /// number of [expectedErrorCodes] and that they have the expected error
+ /// codes. The order in which the errors were gathered is ignored.
void assertErrorsWithCodes(
[List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) {
StringBuffer buffer = new StringBuffer();
@@ -310,12 +322,10 @@
}
}
- /**
- * Assert that the number of errors that have been gathered matches the number
- * of [expectedSeverities] and that there are the same number of errors and
- * warnings as specified by the argument. The order in which the errors were
- * gathered is ignored.
- */
+ /// Assert that the number of errors that have been gathered matches the
+ /// number of [expectedSeverities] and that there are the same number of
+ /// errors and warnings as specified by the argument. The order in which the
+ /// errors were gathered is ignored.
void assertErrorsWithSeverities(List<ErrorSeverity> expectedSeverities) {
int expectedErrorCount = 0;
int expectedWarningCount = 0;
@@ -337,27 +347,23 @@
}
if (expectedErrorCount != actualErrorCount ||
expectedWarningCount != actualWarningCount) {
- fail(
- "Expected $expectedErrorCount errors and $expectedWarningCount warnings, found $actualErrorCount errors and $actualWarningCount warnings");
+ fail("Expected $expectedErrorCount errors "
+ "and $expectedWarningCount warnings, "
+ "found $actualErrorCount errors "
+ "and $actualWarningCount warnings");
}
}
- /**
- * Assert that no errors have been gathered.
- */
+ /// Assert that no errors have been gathered.
void assertNoErrors() {
assertErrors(ExpectedError.NO_ERRORS);
}
- /**
- * Return the line information associated with the given [source], or `null`
- * if no line information has been associated with the source.
- */
+ /// Return the line information associated with the given [source], or `null`
+ /// if no line information has been associated with the source.
LineInfo getLineInfo(Source source) => _lineInfoMap[source];
- /**
- * Return `true` if an error with the given [errorCode] has been gathered.
- */
+ /// Return `true` if an error with the given [errorCode] has been gathered.
bool hasError(ErrorCode errorCode) {
for (AnalysisError error in _errors) {
if (identical(error.errorCode, errorCode)) {
@@ -372,79 +378,17 @@
_errors.add(error);
}
- /**
- * Set the line information associated with the given [source] to the given
- * list of [lineStarts].
- */
+ /// Set the line information associated with the given [source] to the given
+ /// list of [lineStarts].
void setLineInfo(Source source, List<int> lineStarts) {
_lineInfoMap[source] = new LineInfo(lineStarts);
}
-
- /**
- * Return `true` if the [actualError] matches the [expectedError].
- */
- bool _equalErrors(ExpectedError expectedError, AnalysisError actualError) {
- if (!identical(expectedError.code, actualError.errorCode)) {
- return false;
- } else if (!checkRanges) {
- return true;
- }
- return expectedError.offset == actualError.offset &&
- expectedError.length == actualError.length;
- }
-
- /**
- * Assert that the number of errors that have been gathered matches the number
- * of [expectedErrors] and that they have the expected error codes. The order
- * in which the errors were gathered is ignored.
- */
- void _fail(List<ExpectedError> expectedErrors) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Expected ");
- buffer.write(expectedErrors.length);
- buffer.write(" errors:");
- for (ExpectedError error in expectedErrors) {
- buffer.writeln();
- int offset = error.offset;
- buffer.write(' ${error.code} ($offset..${offset + error.length})');
- }
- buffer.writeln();
- buffer.write("found ");
- buffer.write(_errors.length);
- buffer.write(" errors:");
- for (AnalysisError error in _errors) {
- buffer.writeln();
- int offset = error.offset;
- buffer.write(' ${error.errorCode} '
- '($offset..${offset + error.length}): ${error.message}');
- }
- fail(buffer.toString());
- }
-
- /**
- * Search through the given list of [errors] for an error that is equal to the
- * [targetError]. If one is found, remove it from the list and return `true`,
- * otherwise return `false` without modifying the list.
- */
- bool _foundAndRemoved(List<ExpectedError> errors, AnalysisError targetError) {
- for (ExpectedError error in errors) {
- if (_equalErrors(error, targetError)) {
- errors.remove(error);
- return true;
- }
- }
- return false;
- }
}
-/**
- * Instances of the class [TestLogger] implement a logger that can be used by
- * tests.
- */
+/// Instances of the class [TestLogger] implement a logger that can be used by
+/// tests.
class TestLogger implements Logger {
- /**
- * All logged messages.
- */
+ /// All logged messages.
List<String> log = [];
@override
@@ -464,15 +408,11 @@
int _modificationStamp = 0;
bool exists2 = true;
- /**
- * A flag indicating whether an exception should be generated when an attempt
- * is made to access the contents of this source.
- */
+ /// A flag indicating whether an exception should be generated when an attempt
+ /// is made to access the contents of this source.
bool generateExceptionOnRead = false;
- /**
- * The number of times that the contents of this source have been requested.
- */
+ /// The number of times that the contents of this source have been requested.
int readCount = 0;
TestSource([this._name = '/test.dart', this._contents]);
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 190bc9b..9084e64 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -35,9 +35,33 @@
defineReflectiveTests(StrongGenericFunctionInferenceTest);
defineReflectiveTests(StrongLeastUpperBoundTest);
defineReflectiveTests(StrongGreatestLowerBoundTest);
+ defineReflectiveTests(TypeSystemTest);
});
}
+abstract class AbstractTypeSystemTest {
+ TypeProvider typeProvider;
+ Dart2TypeSystem typeSystem;
+
+ DartType get bottomType => typeProvider.bottomType;
+ InterfaceType get doubleType => typeProvider.doubleType;
+ DartType get dynamicType => typeProvider.dynamicType;
+ InterfaceType get functionType => typeProvider.functionType;
+ InterfaceType get intType => typeProvider.intType;
+ InterfaceType get iterableType => typeProvider.iterableType;
+ InterfaceType get listType => typeProvider.listType;
+ DartType get nullType => typeProvider.nullType;
+ InterfaceType get numType => typeProvider.numType;
+ InterfaceType get objectType => typeProvider.objectType;
+ InterfaceType get stringType => typeProvider.stringType;
+ DartType get voidType => VoidTypeImpl.instance;
+
+ void setUp() {
+ typeProvider = new TestTypeProvider();
+ typeSystem = new Dart2TypeSystem(typeProvider);
+ }
+}
+
/**
* Base class for testing LUB and GLB in spec and strong mode.
*/
@@ -826,26 +850,7 @@
}
@reflectiveTest
-class StrongAssignabilityTest {
- TypeProvider typeProvider;
- TypeSystem typeSystem;
-
- DartType get bottomType => typeProvider.bottomType;
- InterfaceType get doubleType => typeProvider.doubleType;
- DartType get dynamicType => typeProvider.dynamicType;
- InterfaceType get functionType => typeProvider.functionType;
- InterfaceType get intType => typeProvider.intType;
- InterfaceType get listType => typeProvider.listType;
- InterfaceType get numType => typeProvider.numType;
- InterfaceType get objectType => typeProvider.objectType;
- InterfaceType get stringType => typeProvider.stringType;
- DartType get voidType => VoidTypeImpl.instance;
-
- void setUp() {
- typeProvider = new TestTypeProvider();
- typeSystem = new Dart2TypeSystem(typeProvider);
- }
-
+class StrongAssignabilityTest extends AbstractTypeSystemTest {
void test_isAssignableTo_bottom_isBottom() {
DartType interfaceType = ElementFactory.classElement2('A', []).type;
List<DartType> interassignable = <DartType>[
@@ -1111,28 +1116,7 @@
}
@reflectiveTest
-class StrongGenericFunctionInferenceTest {
- TypeProvider typeProvider;
- Dart2TypeSystem typeSystem;
-
- DartType get bottomType => typeProvider.bottomType;
- InterfaceType get doubleType => typeProvider.doubleType;
- DartType get dynamicType => typeProvider.dynamicType;
- InterfaceType get functionType => typeProvider.functionType;
- InterfaceType get intType => typeProvider.intType;
- InterfaceType get iterableType => typeProvider.iterableType;
- InterfaceType get listType => typeProvider.listType;
- DartType get nullType => typeProvider.nullType;
- InterfaceType get numType => typeProvider.numType;
- InterfaceType get objectType => typeProvider.objectType;
- InterfaceType get stringType => typeProvider.stringType;
- DartType get voidType => VoidTypeImpl.instance;
-
- void setUp() {
- typeProvider = new TestTypeProvider();
- typeSystem = new Dart2TypeSystem(typeProvider);
- }
-
+class StrongGenericFunctionInferenceTest extends AbstractTypeSystemTest {
void test_boundedByAnotherTypeParameter() {
// <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
var tFrom = TypeBuilder.variable('TFrom');
@@ -2293,3 +2277,167 @@
static TypeParameterType variable(String name, {DartType bound}) =>
ElementFactory.typeParameterWithType(name, bound).type;
}
+
+@reflectiveTest
+class TypeSystemTest extends AbstractTypeSystemTest {
+ DartType get futureOrWithNoneType =>
+ typeProvider.futureOrType.instantiate([noneType]);
+ DartType get futureOrWithQuestionType =>
+ typeProvider.futureOrType.instantiate([questionType]);
+ DartType get futureOrWithStarType =>
+ typeProvider.futureOrType.instantiate([starType]);
+
+ DartType get noneType => (typeProvider.stringType as TypeImpl)
+ .withNullability(NullabilitySuffix.none);
+
+ DartType get questionType => (typeProvider.stringType as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+
+ DartType get starType => (typeProvider.stringType as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
+
+ test_isNonNullable_dynamic() {
+ expect(typeSystem.isNonNullable(dynamicType), false);
+ }
+
+ test_isNonNullable_futureOr_noneArg() {
+ expect(typeSystem.isNonNullable(futureOrWithNoneType), true);
+ }
+
+ test_isNonNullable_futureOr_questionArg() {
+ expect(typeSystem.isNonNullable(futureOrWithQuestionType), true);
+ }
+
+ test_isNonNullable_futureOr_starArg() {
+ expect(typeSystem.isNonNullable(futureOrWithStarType), true);
+ }
+
+ test_isNonNullable_none() {
+ expect(typeSystem.isNonNullable(noneType), 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_void() {
+ expect(typeSystem.isNonNullable(voidType), false);
+ }
+
+ test_isNullable_dynamic() {
+ expect(typeSystem.isNullable(dynamicType), true);
+ }
+
+ test_isNullable_futureOr_noneArg() {
+ expect(typeSystem.isNullable(futureOrWithNoneType), true);
+ }
+
+ test_isNullable_futureOr_questionArg() {
+ expect(typeSystem.isNullable(futureOrWithQuestionType), true);
+ }
+
+ test_isNullable_futureOr_starArg() {
+ expect(typeSystem.isNullable(futureOrWithStarType), true);
+ }
+
+ test_isNullable_none() {
+ expect(typeSystem.isNullable(noneType), 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_void() {
+ expect(typeSystem.isNullable(voidType), true);
+ }
+
+ test_isPotentiallyNonNullable_dynamic() {
+ expect(typeSystem.isPotentiallyNonNullable(dynamicType), false);
+ }
+
+ test_isPotentiallyNonNullable_futureOr_noneArg() {
+ expect(typeSystem.isPotentiallyNonNullable(futureOrWithNoneType), false);
+ }
+
+ test_isPotentiallyNonNullable_futureOr_questionArg() {
+ expect(
+ typeSystem.isPotentiallyNonNullable(futureOrWithQuestionType), false);
+ }
+
+ test_isPotentiallyNonNullable_futureOr_starArg() {
+ expect(typeSystem.isPotentiallyNonNullable(futureOrWithStarType), false);
+ }
+
+ test_isPotentiallyNonNullable_none() {
+ expect(typeSystem.isPotentiallyNonNullable(noneType), true);
+ }
+
+ test_isPotentiallyNonNullable_null() {
+ expect(typeSystem.isPotentiallyNonNullable(nullType), false);
+ }
+
+ test_isPotentiallyNonNullable_question() {
+ expect(typeSystem.isPotentiallyNonNullable(questionType), false);
+ }
+
+ test_isPotentiallyNonNullable_star() {
+ expect(typeSystem.isPotentiallyNonNullable(starType), false);
+ }
+
+ test_isPotentiallyNonNullable_void() {
+ expect(typeSystem.isPotentiallyNonNullable(voidType), false);
+ }
+
+ test_isPotentiallyNullable_dynamic() {
+ expect(typeSystem.isPotentiallyNullable(dynamicType), true);
+ }
+
+ test_isPotentiallyNullable_futureOr_noneArg() {
+ expect(typeSystem.isPotentiallyNullable(futureOrWithNoneType), false);
+ }
+
+ test_isPotentiallyNullable_futureOr_questionArg() {
+ expect(typeSystem.isPotentiallyNullable(futureOrWithQuestionType), false);
+ }
+
+ test_isPotentiallyNullable_futureOr_starArg() {
+ expect(typeSystem.isPotentiallyNullable(futureOrWithStarType), false);
+ }
+
+ test_isPotentiallyNullable_none() {
+ expect(typeSystem.isPotentiallyNullable(noneType), false);
+ }
+
+ test_isPotentiallyNullable_null() {
+ expect(typeSystem.isPotentiallyNullable(nullType), true);
+ }
+
+ test_isPotentiallyNullable_question() {
+ expect(typeSystem.isPotentiallyNullable(questionType), true);
+ }
+
+ test_isPotentiallyNullable_star() {
+ expect(typeSystem.isPotentiallyNullable(starType), false);
+ }
+
+ test_isPotentiallyNullable_void() {
+ expect(typeSystem.isPotentiallyNullable(voidType), true);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index a49a209..f384b0d 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -32,7 +32,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo; // ref'), findElement.getter('foo'));
}
@@ -50,7 +51,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(
findNode.simple('foo; // ref'),
findElement.getter('foo', of: 'Foo'),
@@ -69,7 +71,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo; // ref'), findElement.method('foo'));
}
@@ -155,7 +158,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo = 0;'), findElement.setter('foo'));
}
@@ -167,7 +171,8 @@
class C extends A implements B {}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
}
test_conflictingGenericInterfaces_viaMixin() async {
@@ -178,7 +183,8 @@
class C extends A with B {}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
}
test_element_allSupertypes() async {
@@ -296,7 +302,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
@@ -309,7 +315,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
@@ -346,7 +352,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
@@ -359,7 +365,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
]);
}
@@ -398,7 +404,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingFieldAndMethod_inSuper_getter() async {
@@ -411,7 +418,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingFieldAndMethod_inSuper_setter() async {
@@ -424,7 +432,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingMethodAndField_inSuper_field() async {
@@ -437,7 +446,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_conflictingMethodAndField_inSuper_getter() async {
@@ -450,7 +460,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_conflictingMethodAndField_inSuper_setter() async {
@@ -463,7 +474,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_conflictingStaticAndInstance_inClass_getter_getter() async {
@@ -474,7 +486,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_getter_method() async {
@@ -485,7 +498,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
@@ -496,7 +510,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_getter() async {
@@ -507,7 +522,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_method() async {
@@ -518,7 +534,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_setter() async {
@@ -529,7 +546,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
@@ -540,7 +558,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_method() async {
@@ -551,7 +570,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
@@ -562,7 +582,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
@@ -575,7 +596,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
@@ -588,7 +610,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
@@ -601,7 +624,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
@@ -614,7 +638,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_method() async {
@@ -627,7 +652,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
@@ -640,7 +666,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
@@ -653,7 +680,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
@@ -666,7 +694,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_getter_getter() async {
@@ -679,7 +708,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_getter_method() async {
@@ -692,7 +722,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_getter_setter() async {
@@ -705,7 +736,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_method_getter() async {
@@ -718,7 +750,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_method_method() async {
@@ -731,7 +764,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_method_setter() async {
@@ -744,7 +778,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_setter_method() async {
@@ -757,7 +792,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inMixin_setter_setter() async {
@@ -770,7 +806,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_getter_getter() async {
@@ -783,7 +820,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_getter_method() async {
@@ -796,7 +834,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_getter_setter() async {
@@ -809,7 +848,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_method_getter() async {
@@ -822,7 +862,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_method_method() async {
@@ -835,7 +876,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_method_setter() async {
@@ -848,7 +890,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_setter_method() async {
@@ -861,7 +904,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inSuper_setter_setter() async {
@@ -874,7 +918,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_duplicateConstructorDefault() async {
@@ -885,7 +930,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
]);
}
@@ -898,7 +943,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
]);
}
@@ -911,7 +956,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_field_field_static() async {
@@ -922,7 +967,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_field_getter() async {
@@ -933,7 +978,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_field_method() async {
@@ -944,7 +989,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_getter_getter() async {
@@ -955,7 +1000,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_getter_method() async {
@@ -966,7 +1011,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_method_getter() async {
@@ -977,7 +1022,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_method_method() async {
@@ -988,7 +1033,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_method_setter() async {
@@ -999,7 +1044,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_OK_fieldFinal_setter() async {
@@ -1043,7 +1088,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_setter_setter() async {
@@ -1054,7 +1099,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_extendsNonClass_dynamic() async {
@@ -1062,7 +1107,7 @@
class A extends dynamic {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -1076,7 +1121,7 @@
class A extends E {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -1093,7 +1138,7 @@
class A extends M {} // ref
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -1110,7 +1155,7 @@
class A extends v {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -1124,7 +1169,7 @@
class B implements A, A {} // ref
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
var a = findElement.class_('A');
assertTypeName(findNode.typeName('A, A {} // ref'), a, 'A');
@@ -1136,7 +1181,7 @@
class A {} class C{}
class B implements A, A, A, A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
CompileTimeErrorCode.IMPLEMENTS_REPEATED
@@ -1150,7 +1195,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_getter_static() async {
@@ -1160,7 +1205,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
var method = findNode.methodDeclaration('C =>');
expect(method.isGetter, isTrue);
@@ -1175,7 +1220,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_setter_static() async {
@@ -1185,7 +1230,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
var method = findNode.methodDeclaration('C(_)');
expect(method.isSetter, isTrue);
@@ -1200,7 +1245,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
@@ -1220,7 +1265,7 @@
abstract class X implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
@@ -1307,7 +1352,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
]);
}
@@ -1320,7 +1365,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
]);
}
@@ -1336,7 +1381,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
@@ -1352,7 +1397,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
@@ -1368,7 +1413,7 @@
abstract class C implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1384,7 +1429,7 @@
abstract class C implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1400,7 +1445,7 @@
abstract class C implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1416,7 +1461,7 @@
abstract class C implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1432,7 +1477,7 @@
abstract class C implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1458,7 +1503,7 @@
class A extends B {}
class B extends A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1469,7 +1514,7 @@
class A extends B {}
class B implements A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1480,7 +1525,7 @@
class A implements B {}
class B implements A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1491,7 +1536,7 @@
class M1 = Object with M2;
class M2 = Object with M1;''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1506,7 +1551,7 @@
class M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
]);
@@ -1517,7 +1562,7 @@
abstract class A implements A {}
class B implements A {}''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
@@ -1527,7 +1572,7 @@
abstract class B implements A {}
class C implements A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1540,7 +1585,7 @@
abstract class C implements A {}
class D implements A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -1550,7 +1595,7 @@
test_recursiveInterfaceInheritanceExtends() async {
addTestFile("class A extends A {}");
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS]);
}
@@ -1562,7 +1607,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS,
]);
}
@@ -1570,7 +1615,7 @@
test_recursiveInterfaceInheritanceImplements() async {
addTestFile("class A implements A {}");
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
@@ -1580,14 +1625,14 @@
class M {}
class B = A with M implements B;''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
test_recursiveInterfaceInheritanceWith() async {
addTestFile("class M = Object with M;");
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH,
]);
}
@@ -1601,7 +1646,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_GETTER]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_GETTER]);
}
test_undefinedSuperMethod() async {
@@ -1613,7 +1658,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
}
test_undefinedSuperOperator_binaryExpression() async {
@@ -1625,7 +1670,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperOperator_indexBoth() async {
@@ -1637,7 +1682,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
]);
@@ -1652,7 +1697,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperOperator_indexSetter() async {
@@ -1664,7 +1709,7 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperSetter() async {
@@ -1676,6 +1721,6 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 39a9d4a..0283b13 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -142,7 +142,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
]);
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index c21ca09..c731596 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -27,7 +27,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_inference_listLiteral() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index a3cadc7..7974854 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -29,7 +29,7 @@
C<G> x;
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
@@ -41,7 +41,7 @@
C<Function<S>()> x;
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
@@ -55,7 +55,7 @@
}
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
@@ -69,7 +69,7 @@
}
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
@@ -85,7 +85,7 @@
}
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
@@ -97,7 +97,7 @@
F<Function<S>()> x;
''');
await resolveTestFile();
- assertTestErrors(
+ assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index cb5ac0b..b9e9d61 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -29,7 +29,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -70,7 +70,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 8bfb1f0..98ee882 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -19,6 +19,24 @@
with InstanceCreationResolutionMixin {}
mixin InstanceCreationResolutionMixin implements ResolutionTest {
+ test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
+ addTestFile(r'''
+final foo = Map<int>();
+''');
+ await resolveTestFile();
+ assertTestErrorsWithCodes([
+ StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
+ ]);
+
+ var creation = findNode.instanceCreation('Map<int>');
+ assertInstanceCreation(
+ creation,
+ mapElement,
+ 'Map<dynamic, dynamic>',
+ expectedConstructorMember: true,
+ );
+ }
+
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew() async {
addTestFile(r'''
class Foo<X> {
@@ -30,7 +48,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -45,24 +63,6 @@
// );
}
- test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
- addTestFile(r'''
-final foo = Map<int>();
-''');
- await resolveTestFile();
- assertTestErrors([
- StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
- ]);
-
- var creation = findNode.instanceCreation('Map<int>');
- assertInstanceCreation(
- creation,
- mapElement,
- 'Map<dynamic, dynamic>',
- expectedConstructorMember: true,
- );
- }
-
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew_prefix() async {
newFile('/test/lib/a.dart', content: '''
class Foo<X> {
@@ -77,7 +77,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -105,7 +105,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -133,7 +133,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index f5a709a..307d438 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -31,7 +31,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
var invocation = findNode.methodInvocation('foo(0)');
assertMethodInvocation(
@@ -55,7 +56,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
var invocation = findNode.methodInvocation('foo(0)');
assertMethodInvocation(
@@ -79,7 +81,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
var invocation = findNode.methodInvocation('foo(); // ref');
assertMethodInvocation(
@@ -187,7 +190,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.AMBIGUOUS_IMPORT,
]);
@@ -213,7 +216,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.AMBIGUOUS_IMPORT,
]);
@@ -233,7 +236,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
]);
_assertInvalidInvocation(
@@ -254,7 +257,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
_assertInvalidInvocation(
@@ -271,7 +274,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
_assertInvalidInvocation(
@@ -396,7 +399,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
_assertInvalidInvocation(
@@ -417,7 +420,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
_assertInvalidInvocation(
@@ -440,7 +443,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
_assertInvalidInvocation(
@@ -463,7 +466,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -487,7 +490,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -511,7 +514,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
_assertInvalidInvocation(
@@ -528,7 +531,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_FUNCTION,
]);
_assertUnresolvedMethodInvocation('foo(0)');
@@ -543,7 +546,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_FUNCTION,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -556,7 +559,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.UNDEFINED_IDENTIFIER,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -570,7 +573,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -586,7 +589,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -607,7 +610,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -622,7 +625,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -637,7 +640,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('C.T();');
@@ -650,7 +653,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -664,7 +667,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -679,7 +682,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -692,7 +695,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
}
@@ -724,7 +727,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
_assertUnresolvedMethodInvocation('_foo(0);');
@@ -741,7 +744,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
}
@@ -756,7 +759,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
}
@@ -772,7 +775,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
]);
_assertUnresolvedMethodInvocation('foo(0);');
@@ -792,7 +795,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
]);
@@ -816,7 +819,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
]);
_assertUnresolvedMethodInvocation('foo(1);');
@@ -836,7 +839,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
]);
_assertUnresolvedMethodInvocation('foo(1);');
@@ -854,7 +857,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
_assertInvalidInvocation(
@@ -873,7 +876,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
_assertInvalidInvocation(
@@ -892,7 +895,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
assertMethodInvocation(
@@ -911,7 +914,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
_assertInvalidInvocation(
@@ -930,7 +933,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
// TODO(scheglov) Resolve fully, or don't resolve at all.
@@ -949,7 +952,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
// TODO(scheglov) Resolve fully, or don't resolve at all.
@@ -968,7 +971,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
// TODO(scheglov) Resolve fully, or don't resolve at all.
@@ -988,7 +991,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
]);
assertMethodInvocation(
@@ -1008,7 +1011,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
]);
assertMethodInvocation(
@@ -1498,7 +1501,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
assertElement(findNode.simple('math()'), findElement.prefix('math'));
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index b84f31a..46ff61b 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -150,7 +150,8 @@
mixin M on A implements B {}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
}
test_element() async {
@@ -237,7 +238,8 @@
mixin as {}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
}
test_error_builtInIdentifierAsTypeName_OK_on() async {
@@ -266,7 +268,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_getter_method() async {
@@ -277,7 +280,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_getter_setter() async {
@@ -288,7 +292,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_getter() async {
@@ -299,7 +304,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_method() async {
@@ -310,7 +316,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_method_setter() async {
@@ -321,7 +328,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_getter() async {
@@ -332,7 +340,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_method() async {
@@ -343,7 +352,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inClass_setter_setter() async {
@@ -354,7 +364,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_getter_getter() async {
@@ -367,7 +378,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_getter_method() async {
@@ -380,7 +392,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_getter_setter() async {
@@ -393,7 +406,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_method_getter() async {
@@ -406,7 +420,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_method_method() async {
@@ -419,7 +434,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_method_setter() async {
@@ -432,7 +448,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_setter_method() async {
@@ -445,7 +462,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inConstraint_setter_setter() async {
@@ -458,7 +476,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_getter() async {
@@ -471,7 +490,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_method() async {
@@ -484,7 +504,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_getter_setter() async {
@@ -497,7 +518,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_getter() async {
@@ -510,7 +532,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_method() async {
@@ -523,7 +546,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_method_setter() async {
@@ -536,7 +560,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_setter_method() async {
@@ -549,7 +574,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingStaticAndInstance_inInterface_setter_setter() async {
@@ -562,7 +588,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE]);
}
test_error_conflictingTypeVariableAndClass() async {
@@ -570,7 +597,7 @@
mixin M<M> {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
]);
}
@@ -582,7 +609,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
]);
}
@@ -594,7 +621,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
]);
}
@@ -606,7 +633,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
]);
}
@@ -618,7 +645,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
]);
}
@@ -630,7 +657,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER,
]);
}
@@ -643,7 +670,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_field_method() async {
@@ -654,7 +681,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_getter() async {
@@ -665,7 +692,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_getter_method() async {
@@ -676,7 +703,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_method() async {
@@ -687,7 +714,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_method_getter() async {
@@ -698,7 +725,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_duplicateDefinition_setter() async {
@@ -709,7 +736,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
}
test_error_finalNotInitialized() async {
@@ -719,7 +746,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([StaticWarningCode.FINAL_NOT_INITIALIZED]);
+ assertTestErrorsWithCodes([StaticWarningCode.FINAL_NOT_INITIALIZED]);
}
test_error_finalNotInitialized_OK() async {
@@ -740,7 +767,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
]);
@@ -754,7 +781,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
var element = findElement.mixin('M');
var constructorElement = element.constructors.single;
@@ -775,7 +803,7 @@
var mathImport = findElement.import('dart:math');
var randomElement = mathImport.importedLibrary.getType('Random');
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
]);
@@ -793,7 +821,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
]);
@@ -810,7 +838,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
ParserErrorCode.EXPECTED_TYPE_NAME,
]);
@@ -829,7 +857,7 @@
''');
await resolveTestFile();
CompileTimeErrorCode.IMPLEMENTS_REPEATED;
- assertTestErrors([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
}
test_error_memberWithClassName_getter() async {
@@ -839,7 +867,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_getter_static() async {
@@ -849,7 +877,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_setter() async {
@@ -859,7 +887,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_setter_static() async {
@@ -869,7 +897,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_mixinApplicationConcreteSuperInvokedMemberType_method() async {
@@ -895,7 +923,7 @@
abstract class X extends B with M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
]);
}
@@ -933,7 +961,7 @@
abstract class X extends A with M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
]);
}
@@ -957,7 +985,7 @@
class X extends A with M1, M2 {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER
]);
}
@@ -977,7 +1005,7 @@
class X extends A with M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER
]);
}
@@ -997,7 +1025,7 @@
abstract class X extends A with M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
]);
}
@@ -1147,7 +1175,7 @@
abstract class X extends A with M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
]);
}
@@ -1161,7 +1189,7 @@
class X = Object with M;
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
]);
}
@@ -1175,7 +1203,7 @@
class X = A<double> with M;
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
]);
}
@@ -1199,7 +1227,7 @@
class X = C with M;
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
]);
}
@@ -1265,7 +1293,7 @@
class X = C with M;
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
]);
}
@@ -1279,7 +1307,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
// Even though it is an error for a mixin to declare a constructor,
// we still build elements for constructors, and resolve them.
@@ -1310,7 +1339,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.MIXIN_INSTANTIATE]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.MIXIN_INSTANTIATE]);
var creation = findNode.instanceCreation('M();');
var m = findElement.mixin('M');
@@ -1328,7 +1357,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
CompileTimeErrorCode.MIXIN_INSTANTIATE,
]);
@@ -1347,7 +1376,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_INSTANTIATE,
]);
@@ -1365,7 +1394,7 @@
var mathImport = findElement.import('dart:math');
var randomElement = mathImport.importedLibrary.getType('Random');
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS,
]);
@@ -1383,7 +1412,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS,
]);
@@ -1400,7 +1429,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
]);
@@ -1418,7 +1447,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
]);
@@ -1435,7 +1464,7 @@
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
ParserErrorCode.EXPECTED_TYPE_NAME,
]);
@@ -1467,7 +1496,7 @@
''');
await resolveTestFile();
CompileTimeErrorCode.IMPLEMENTS_REPEATED;
- assertTestErrors([CompileTimeErrorCode.ON_REPEATED]);
+ assertTestErrorsWithCodes([CompileTimeErrorCode.ON_REPEATED]);
}
test_error_undefinedSuperMethod() async {
@@ -1481,7 +1510,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
+ assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
var invocation = findNode.methodInvocation('foo(42)');
assertElementNull(invocation.methodName);
@@ -1562,7 +1591,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1578,7 +1607,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1594,7 +1623,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1610,7 +1639,7 @@
mixin M on A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1626,7 +1655,7 @@
mixin M on A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1642,7 +1671,7 @@
mixin M on A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
@@ -1658,7 +1687,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1674,7 +1703,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1690,7 +1719,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1706,7 +1735,7 @@
mixin M implements A, B {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
@@ -1726,7 +1755,7 @@
abstract class X extends A with U1, U2, M {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
@@ -1827,7 +1856,7 @@
mixin A implements B {}
mixin B implements A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1838,7 +1867,7 @@
mixin A on B {}
mixin B on A {}''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
]);
@@ -1849,7 +1878,7 @@
mixin A on A {}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_ON,
]);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart b/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
index 1b47f1e..820678a 100644
--- a/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
@@ -36,7 +36,7 @@
assertNoTestErrors();
assertType(findNode.typeName('int? a'), 'int?');
- assertType(findNode.typeName('int b'), 'int!');
+ assertType(findNode.typeName('int b'), 'int');
}
test_local_returnType_interfaceType() async {
@@ -50,7 +50,7 @@
assertNoTestErrors();
assertType(findNode.typeName('int? f'), 'int?');
- assertType(findNode.typeName('int g'), 'int!');
+ assertType(findNode.typeName('int g'), 'int');
}
@failingTest
@@ -80,7 +80,7 @@
assertNoTestErrors();
assertType(findNode.typeName('int? a'), 'int?');
- assertType(findNode.typeName('int b'), 'int!');
+ assertType(findNode.typeName('int b'), 'int');
}
test_local_variable_interfaceType_generic() async {
@@ -96,9 +96,9 @@
assertNoTestErrors();
assertType(findNode.typeName('List<int?>? a'), 'List<int?>?');
- assertType(findNode.typeName('List<int>? b'), 'List<int!>?');
- assertType(findNode.typeName('List<int?> c'), 'List<int?>!');
- assertType(findNode.typeName('List<int> d'), 'List<int!>!');
+ assertType(findNode.typeName('List<int>? b'), 'List<int>?');
+ assertType(findNode.typeName('List<int?> c'), 'List<int?>');
+ assertType(findNode.typeName('List<int> d'), 'List<int>');
}
test_local_variable_typeParameter() async {
@@ -112,10 +112,22 @@
await resolveTestFile();
assertNoTestErrors();
- assertType(findNode.typeName('T a'), 'T!');
+ assertType(findNode.typeName('T a'), 'T');
assertType(findNode.typeName('T? b'), 'T?');
}
+ test_null_assertion_operator_removes_nullability() async {
+ addTestFile('''
+main() {
+ Object? x = null;
+ x!;
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ assertType(findNode.postfix('x!'), 'Object');
+ }
+
test_typedef_classic() async {
addTestFile('''
typedef int? F(bool a, String? b);
@@ -127,7 +139,7 @@
await resolveTestFile();
assertNoTestErrors();
- assertType(findNode.typeName('F? a'), '(bool!, String?) → int??');
+ assertType(findNode.typeName('F? a'), '(bool, String?) → int??');
}
@failingTest
@@ -165,9 +177,9 @@
await resolveTestFile();
assertNoTestErrors();
- assertType(findNode.typeName('A {} // 1'), 'A!');
- assertType(findNode.typeName('A {} // 2'), 'A!');
- assertType(findNode.typeName('A {} // 3'), 'A!');
+ assertType(findNode.typeName('A {} // 1'), 'A');
+ assertType(findNode.typeName('A {} // 2'), 'A');
+ assertType(findNode.typeName('A {} // 3'), 'A');
}
test_classTypeAlias_hierarchy() async {
@@ -181,9 +193,9 @@
await resolveTestFile();
assertNoTestErrors();
- assertType(findNode.typeName('A with'), 'A!');
- assertType(findNode.typeName('B implements'), 'B!');
- assertType(findNode.typeName('C;'), 'C!');
+ assertType(findNode.typeName('A with'), 'A');
+ assertType(findNode.typeName('B implements'), 'B');
+ assertType(findNode.typeName('C;'), 'C');
}
test_local_variable_interfaceType_notMigrated() async {
@@ -194,7 +206,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([ParserErrorCode.EXPERIMENT_NOT_ENABLED]);
+ assertTestErrorsWithCodes([ParserErrorCode.EXPERIMENT_NOT_ENABLED]);
assertType(findNode.typeName('int? a'), 'int*');
assertType(findNode.typeName('int b'), 'int*');
@@ -210,7 +222,7 @@
await resolveTestFile();
assertNoTestErrors();
- assertType(findNode.typeName('A {} // 1'), 'A!');
- assertType(findNode.typeName('A {} // 2'), 'A!');
+ assertType(findNode.typeName('A {} // 1'), 'A');
+ assertType(findNode.typeName('A {} // 2'), 'A');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index 0723755..dcc2d69 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -28,7 +28,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
var access = findNode.propertyAccess('foo; // ref');
assertPropertyAccess(access, findElement.getter('foo', of: 'A'), 'int');
@@ -68,7 +69,8 @@
}
''');
await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertTestErrorsWithCodes(
+ [CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
var access = findNode.propertyAccess('foo = v; // ref');
assertPropertyAccess(
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 262e9cf..b713264 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -150,11 +150,28 @@
expect(element.enclosingElement, expectedEnclosing);
}
+ Future<void> assertErrorCodesInCode(
+ String code, List<ErrorCode> errors) async {
+ addTestFile(code);
+ await resolveTestFile();
+ assertTestErrorsWithCodes(errors);
+ }
+
+ Future<void> assertErrorsInCode(
+ String code, List<ExpectedError> expectedErrors) async {
+ addTestFile(code);
+ await resolveTestFile();
+
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ errorListener.addAll(result.errors);
+ errorListener.assertErrors(expectedErrors);
+ }
+
/**
* Assert that the number of error codes in reported [errors] matches the
* number of [expected] error codes. The order of errors is ignored.
*/
- void assertErrors(List<AnalysisError> errors,
+ void assertErrorsWithCodes(List<AnalysisError> errors,
[List<ErrorCode> expected = const <ErrorCode>[]]) {
var errorListener = new GatheringErrorListener();
for (AnalysisError error in result.errors) {
@@ -175,12 +192,6 @@
errorListener.assertErrorsWithCodes(expected);
}
- Future<void> assertErrorsInCode(String code, List<ErrorCode> errors) async {
- addTestFile(code);
- await resolveTestFile();
- assertTestErrors(errors);
- }
-
void assertHasTestErrors() {
expect(result.errors, isNotEmpty);
}
@@ -319,7 +330,7 @@
}
void assertNoTestErrors() {
- assertTestErrors(const <ErrorCode>[]);
+ assertTestErrorsWithCodes(const <ErrorCode>[]);
}
void assertPropertyAccess(
@@ -338,8 +349,8 @@
// assertTypeNull(superExpression);
}
- void assertTestErrors(List<ErrorCode> expected) {
- assertErrors(result.errors, expected);
+ void assertTestErrorsWithCodes(List<ErrorCode> expected) {
+ assertErrorsWithCodes(result.errors, expected);
}
void assertTopGetRef(String search, String name) {
@@ -392,6 +403,9 @@
expect(node.staticType, isNull);
}
+ ExpectedError error(ErrorCode code, int offset, int length) =>
+ new ExpectedError(code, offset, length);
+
Element getNodeElement(AstNode node) {
if (node is Annotation) {
return node.element;
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 9d08d0e..65de6ba 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -41,7 +41,7 @@
final b = new A().a;
''');
await resolveTestFile();
- assertTestErrors([StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+ assertTestErrorsWithCodes([StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
assertElementTypeDynamic(findElement.field('a').type);
assertElementTypeDynamic(findElement.topVar('b').type);
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_set_or_map_literal_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_set_or_map_literal_test.dart
index 8e95614..202c01bd 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_set_or_map_literal_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_set_or_map_literal_test.dart
@@ -30,7 +30,9 @@
Map<int, int> map;
Set<int> set;
var c = {...set, ...map};
-''', [CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH]);
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH, 41, 16),
+ ]);
}
}
@@ -48,6 +50,8 @@
var map;
var set;
var c = {...set, ...map};
-''', [CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER]);
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER, 26, 16),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index b40bc8e..28b285e 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -24,7 +24,9 @@
class A {
n(void f(int i)) {}
}
-''', [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+''', [
+ error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 7),
+ ]);
}
test_interfaceType() async {
@@ -34,6 +36,8 @@
n(i);
}
n(int i) {}
-''', [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+''', [
+ error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 24, 1),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/async_keyword_used_as_identifier_test.dart b/pkg/analyzer/test/src/diagnostics/async_keyword_used_as_identifier_test.dart
index 2e30543..28ab163 100644
--- a/pkg/analyzer/test/src/diagnostics/async_keyword_used_as_identifier_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/async_keyword_used_as_identifier_test.dart
@@ -23,7 +23,9 @@
g(@async x) {}
g(0);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 38, 5),
+ ]);
}
test_async_argumentLabel() async {
@@ -31,23 +33,33 @@
f(c) async {
c.g(async: 0);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 19, 5),
+ ]);
}
test_async_async() async {
await assertErrorsInCode('''
f() async {
var async = 1;
+ print(async);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 18, 5),
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 37, 5),
+ ]);
}
test_async_asyncStar() async {
await assertErrorsInCode('''
f() async* {
var async = 1;
+ print(async);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 19, 5),
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 38, 5),
+ ]);
}
test_async_break() async {
@@ -58,8 +70,8 @@
}
}
''', [
- ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
- CompileTimeErrorCode.LABEL_UNDEFINED
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 39, 5),
+ error(CompileTimeErrorCode.LABEL_UNDEFINED, 39, 5),
]);
}
@@ -71,7 +83,9 @@
g();
} catch (async) { }
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 47, 5),
+ ]);
}
test_async_catchStacktrace() async {
@@ -82,7 +96,10 @@
g();
} catch (e, async) { }
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 50, 5),
+ error(HintCode.UNUSED_CATCH_STACK, 50, 5),
+ ]);
}
test_async_continue() async {
@@ -93,8 +110,8 @@
}
}
''', [
- ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
- CompileTimeErrorCode.LABEL_UNDEFINED
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 42, 5),
+ error(CompileTimeErrorCode.LABEL_UNDEFINED, 42, 5),
]);
}
@@ -104,7 +121,9 @@
f() async {
for (async in []) {}
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 30, 5),
+ ]);
}
test_async_formalParameter() async {
@@ -113,7 +132,9 @@
g(int async) {}
g(0);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 20, 5),
+ ]);
}
test_async_getter() async {
@@ -124,7 +145,9 @@
f() async {
return new C().async;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 63, 5),
+ ]);
}
test_async_invocation() async {
@@ -135,7 +158,9 @@
f() async {
return new C().async();
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 61, 5),
+ ]);
}
test_async_invocation_cascaded() async {
@@ -146,7 +171,9 @@
f() async {
return new C()..async();
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 62, 5),
+ ]);
}
test_async_label() async {
@@ -155,15 +182,22 @@
async: g();
}
g() {}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, HintCode.UNUSED_LABEL]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 14, 5),
+ error(HintCode.UNUSED_LABEL, 14, 6),
+ ]);
}
test_async_localFunction() async {
await assertErrorsInCode('''
f() async {
int async() => null;
+ async();
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 18, 5),
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 37, 5),
+ ]);
}
test_async_prefix() async {
@@ -172,7 +206,9 @@
f() async {
return new async.Future.value(0);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 55, 5),
+ ]);
}
test_async_setter() async {
@@ -183,7 +219,9 @@
f() async {
new C().async = 1;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 61, 5),
+ ]);
}
test_async_setter_cascaded() async {
@@ -194,7 +232,9 @@
f() async {
return new C()..async = 1;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 69, 5),
+ ]);
}
test_async_stringInterpolation() async {
@@ -203,7 +243,9 @@
f() async {
return "$async";
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 38, 5),
+ ]);
}
test_async_suffix() async {
@@ -216,7 +258,9 @@
f() async {
return l.async;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 48, 5),
+ ]);
}
test_async_switchLabel() async {
@@ -226,15 +270,22 @@
async: case 0: break;
}
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, HintCode.UNUSED_LABEL]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 31, 5),
+ error(HintCode.UNUSED_LABEL, 31, 6),
+ ]);
}
test_async_syncStar() async {
await assertErrorsInCode('''
f() sync* {
var async = 1;
+ print(async);
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 18, 5),
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 37, 5),
+ ]);
}
test_await_async() async {
@@ -242,7 +293,10 @@
f() async {
var await = 1;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 18, 5),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 5),
+ ]);
}
test_await_asyncStar() async {
@@ -250,7 +304,10 @@
f() async* {
var await = 1;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 19, 5),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 19, 5),
+ ]);
}
test_await_syncStar() async {
@@ -258,6 +315,9 @@
f() sync* {
var await = 1;
}
-''', [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+''', [
+ error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 18, 5),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 5),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart b/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
index 3e9bddb..ee5b015 100644
--- a/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
@@ -20,7 +20,9 @@
m(x) {
x..a?.b.c;
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 10, 6),
+ ]);
}
test_beforeCascade() async {
@@ -28,7 +30,9 @@
m(x) {
x?.a..m();
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 4),
+ ]);
}
test_cascadeWithParenthesis() async {
@@ -36,7 +40,9 @@
m(x) {
(x?.a)..m();
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 6),
+ ]);
}
test_definedForNull() async {
@@ -73,7 +79,9 @@
m(x) {
x?.a.b();
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 4),
+ ]);
}
test_multipleInvocations() async {
@@ -83,7 +91,9 @@
..m()
..m();
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 4),
+ ]);
}
test_parenthesized() async {
@@ -91,7 +101,9 @@
m(x) {
(x?.a).b;
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 6),
+ ]);
}
test_propertyAccess() async {
@@ -99,6 +111,8 @@
m(x) {
x?.a.b;
}
-''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+''', [
+ error(HintCode.CAN_BE_NULL_AFTER_NULL_AWARE, 9, 4),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
index f8b4aec..662215a 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
@@ -26,7 +26,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
]);
@@ -43,7 +43,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
]);
}
@@ -85,7 +85,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
]);
@@ -102,7 +102,7 @@
}
''');
await resolveTestFile();
- assertTestErrors([
+ assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
index 47b2dd1..ba1168f 100644
--- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
@@ -14,6 +14,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(ConstEvalThrowsExceptionTest);
defineReflectiveTests(ConstEvalThrowsExceptionWithConstantUpdateTest);
+ defineReflectiveTests(ConstEvalThrowsExceptionWithUiAsCodeAndConstantsTest);
defineReflectiveTests(ConstEvalThrowsExceptionWithUIAsCodeTest);
});
}
@@ -152,6 +153,18 @@
}
@reflectiveTest
+class ConstEvalThrowsExceptionWithUiAsCodeAndConstantsTest
+ extends ConstEvalThrowsExceptionWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class ConstEvalThrowsExceptionWithUIAsCodeTest
extends ConstEvalThrowsExceptionTest {
@override
@@ -162,37 +175,66 @@
];
test_ifElement_false_thenNotEvaluated() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic nil = null;
const c = [if (1 < 0) nil + 1];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_ifElement_nonBoolCondition_list() async {
- assertErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
const dynamic nonBool = 3;
const c = const [if (nonBool) 'a'];
-''', [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]
+ : [
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+ CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT
+ ]);
}
test_ifElement_nonBoolCondition_map() async {
- assertErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
const dynamic nonBool = null;
const c = const {if (nonBool) 'a' : 1};
-''', [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]
+ : [
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_ifElement_nonBoolCondition_set() async {
- assertErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
const dynamic nonBool = 'a';
const c = const {if (nonBool) 3};
-''', [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]
+ : [
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT
+ ]);
}
test_ifElement_true_elseNotEvaluated() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic nil = null;
const c = [if (0 < 1) 3 else nil + 1];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/const_map_key_expression_type_implements_equals_test.dart b/pkg/analyzer/test/src/diagnostics/const_map_key_expression_type_implements_equals_test.dart
index 9822a85..0a03667 100644
--- a/pkg/analyzer/test/src/diagnostics/const_map_key_expression_type_implements_equals_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_map_key_expression_type_implements_equals_test.dart
@@ -34,7 +34,7 @@
}
test_constField() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
const {double.INFINITY: 0};
}
@@ -42,7 +42,7 @@
}
test_direct() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
@@ -58,7 +58,7 @@
// Note: static type of B.a is "dynamic", but actual type of the const
// object is A. We need to make sure we examine the actual type when
// deciding whether there is a problem with operator==.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
@@ -75,7 +75,7 @@
}
test_factory() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const factory A() = B;
}
@@ -92,7 +92,7 @@
}
test_super() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
diff --git a/pkg/analyzer/test/src/diagnostics/const_set_element_type_implements_equals_test.dart b/pkg/analyzer/test/src/diagnostics/const_set_element_type_implements_equals_test.dart
index 95fa251..ded7bfb 100644
--- a/pkg/analyzer/test/src/diagnostics/const_set_element_type_implements_equals_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_set_element_type_implements_equals_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -12,6 +13,8 @@
defineReflectiveSuite(() {
defineReflectiveTests(ConstSetElementTypeImplementsEqualsTest);
defineReflectiveTests(
+ ConstSetElementTypeImplementsEqualsWithUIAsCodeAndConstantsTest);
+ defineReflectiveTests(
ConstSetElementTypeImplementsEqualsWithUIAsCodeTest,
);
});
@@ -20,7 +23,7 @@
@reflectiveTest
class ConstSetElementTypeImplementsEqualsTest extends DriverResolutionTest {
test_constField() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
static const a = const A();
const A();
@@ -33,7 +36,7 @@
}
test_direct() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
@@ -48,7 +51,7 @@
// Note: static type of B.a is "dynamic", but actual type of the const
// object is A. We need to make sure we examine the actual type when
// deciding whether there is a problem with operator==.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
@@ -63,7 +66,7 @@
}
test_factory() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A { const factory A() = B; }
class B implements A {
@@ -79,7 +82,7 @@
}
test_super() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
const A();
operator ==(other) => false;
@@ -95,14 +98,30 @@
}
@reflectiveTest
+class ConstSetElementTypeImplementsEqualsWithUIAsCodeAndConstantsTest
+ extends ConstSetElementTypeImplementsEqualsWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class ConstSetElementTypeImplementsEqualsWithUIAsCodeTest
extends ConstSetElementTypeImplementsEqualsTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_spread_list() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
class A {
const A();
operator ==(other) => false;
@@ -111,11 +130,15 @@
main() {
const {...[A()]};
}
-''', [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_spread_set() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
class A {
const A();
operator ==(other) => false;
@@ -124,6 +147,12 @@
main() {
const {...{A()}};
}
-''', [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]
+ : [
+ CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS,
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/const_spread_expected_list_or_set_test.dart b/pkg/analyzer/test/src/diagnostics/const_spread_expected_list_or_set_test.dart
index 9c8d9f4..5863409 100644
--- a/pkg/analyzer/test/src/diagnostics/const_spread_expected_list_or_set_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_spread_expected_list_or_set_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConstSpreadExpectedListOrSetTest);
+ defineReflectiveTests(ConstSpreadExpectedListOrSetWithConstantsTest);
});
}
@@ -18,90 +20,141 @@
class ConstSpreadExpectedListOrSetTest extends DriverResolutionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_listInt() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 5;
var b = const <int>[...a];
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_listList() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = [5];
var b = const <int>[...a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_listMap() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int, int>{0: 1};
var b = const <int>[...a];
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_listNull() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = null;
var b = const <int>[...a];
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_listNull_nullable() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = null;
var b = const <int>[...?a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_listSet() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int>{5};
var b = const <int>[...a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_setInt() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 5;
var b = const <int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_setList() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int>[5];
var b = const <int>{...a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_setMap() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int, int>{1: 2};
var b = const <int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_setNull() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = null;
var b = const <int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_setNull_nullable() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = null;
var b = const <int>{...?a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_setSet() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int>{5};
var b = const <int>{...a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_nonConst_listInt() async {
@@ -118,3 +171,15 @@
''');
}
}
+
+@reflectiveTest
+class ConstSpreadExpectedListOrSetWithConstantsTest
+ extends ConstSpreadExpectedListOrSetTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
diff --git a/pkg/analyzer/test/src/diagnostics/const_spread_expected_map_test.dart b/pkg/analyzer/test/src/diagnostics/const_spread_expected_map_test.dart
index 405a700..93d86bb 100644
--- a/pkg/analyzer/test/src/diagnostics/const_spread_expected_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_spread_expected_map_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConstSpreadExpectedMapTest);
+ defineReflectiveTests(ConstSpreadExpectedMapWithConstantsTest);
});
}
@@ -18,20 +20,31 @@
class ConstSpreadExpectedMapTest extends DriverResolutionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_mapInt() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 5;
var b = const <int, int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_mapList() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int>[5];
var b = const <int, int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_mapMap() async {
@@ -42,10 +55,14 @@
}
test_const_mapNull() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = null;
var b = const <int, int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_mapNull_nullable() async {
@@ -56,10 +73,14 @@
}
test_const_mapSet() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = <int>{5};
var b = const <int, int>{...a};
-''', [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_nonConst_mapInt() async {
@@ -76,3 +97,15 @@
''');
}
}
+
+@reflectiveTest
+class ConstSpreadExpectedMapWithConstantsTest
+ extends ConstSpreadExpectedMapTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index f2f92f9..e97aa48 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -66,7 +66,7 @@
}
test_deadBlock_conditionalElse() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
true ? 1 : 2;
}''', [HintCode.DEAD_CODE]);
@@ -82,14 +82,14 @@
test_deadBlock_conditionalElse_nested() async {
// Test that a dead else-statement can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
true ? true : false && false;
}''', [HintCode.DEAD_CODE]);
}
test_deadBlock_conditionalIf() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
false ? 1 : 2;
}''', [HintCode.DEAD_CODE]);
@@ -105,14 +105,14 @@
test_deadBlock_conditionalIf_nested() async {
// Test that a dead then-statement can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
false ? false && false : true;
}''', [HintCode.DEAD_CODE]);
}
test_deadBlock_else() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
if(true) {} else {}
}''', [HintCode.DEAD_CODE]);
@@ -128,14 +128,14 @@
test_deadBlock_else_nested() async {
// Test that a dead else-statement can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
if(true) {} else {if (false) {}}
}''', [HintCode.DEAD_CODE]);
}
test_deadBlock_if() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
if(false) {}
}''', [HintCode.DEAD_CODE]);
@@ -189,14 +189,14 @@
test_deadBlock_if_nested() async {
// Test that a dead then-statement can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
if(false) {if(false) {}}
}''', [HintCode.DEAD_CODE]);
}
test_deadBlock_while() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
while(false) {}
}''', [HintCode.DEAD_CODE]);
@@ -212,14 +212,14 @@
test_deadBlock_while_nested() async {
// Test that a dead while body can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
while(false) {if(false) {}}
}''', [HintCode.DEAD_CODE]);
}
test_deadCatch_catchFollowingCatch() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f() {
try {} catch (e) {} catch (e) {}
@@ -228,7 +228,7 @@
test_deadCatch_catchFollowingCatch_nested() async {
// Test that a dead catch clause can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f() {
try {} catch (e) {} catch (e) {if(false) {}}
@@ -236,7 +236,7 @@
}
test_deadCatch_catchFollowingCatch_object() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
try {} on Object catch (e) {} catch (e) {}
}''', [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
@@ -244,14 +244,14 @@
test_deadCatch_catchFollowingCatch_object_nested() async {
// Test that a dead catch clause can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
try {} on Object catch (e) {} catch (e) {if(false) {}}
}''', [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
}
test_deadCatch_onCatchSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {}
f() {
@@ -261,7 +261,7 @@
test_deadCatch_onCatchSubtype_nested() async {
// Test that a dead catch clause can't generate additional violations.
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {}
f() {
@@ -296,7 +296,7 @@
}
test_deadFinalReturnInCase() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
switch (true) {
case true:
@@ -313,7 +313,7 @@
}
test_deadFinalStatementInCase() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
switch (true) {
case true:
@@ -330,7 +330,7 @@
}
test_deadOperandLHS_and() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
bool b = false && false;
}''', [HintCode.DEAD_CODE]);
@@ -345,14 +345,14 @@
}
test_deadOperandLHS_and_nested() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
bool b = false && (false && false);
}''', [HintCode.DEAD_CODE]);
}
test_deadOperandLHS_or() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
bool b = true || true;
}''', [HintCode.DEAD_CODE]);
@@ -367,7 +367,7 @@
}
test_deadOperandLHS_or_nested() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
bool b = true || (false && false);
}''', [HintCode.DEAD_CODE]);
@@ -375,7 +375,7 @@
test_statementAfterAlwaysThrowsFunction() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@alwaysThrows
@@ -393,7 +393,7 @@
@failingTest
test_statementAfterAlwaysThrowsGetter() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@@ -411,7 +411,7 @@
test_statementAfterAlwaysThrowsMethod() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@@ -429,7 +429,7 @@
}
test_statementAfterBreak_inDefaultCase() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(v) {
switch(v) {
case 1:
@@ -441,7 +441,7 @@
}
test_statementAfterBreak_inForEachStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var list;
for(var l in list) {
@@ -452,7 +452,7 @@
}
test_statementAfterBreak_inForStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
for(;;) {
break;
@@ -462,7 +462,7 @@
}
test_statementAfterBreak_inSwitchCase() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(v) {
switch(v) {
case 1:
@@ -473,7 +473,7 @@
}
test_statementAfterBreak_inWhileStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(v) {
while(v) {
break;
@@ -483,7 +483,7 @@
}
test_statementAfterContinue_inForEachStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var list;
for(var l in list) {
@@ -494,7 +494,7 @@
}
test_statementAfterContinue_inForStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
for(;;) {
continue;
@@ -504,7 +504,7 @@
}
test_statementAfterContinue_inWhileStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(v) {
while(v) {
continue;
@@ -514,7 +514,7 @@
}
test_statementAfterExitingIf_returns() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
if (1 > 2) {
return;
@@ -536,7 +536,7 @@
}
test_statementAfterRethrow() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
try {
var one = 1;
@@ -548,7 +548,7 @@
}
test_statementAfterReturn_function() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var one = 1;
return;
@@ -557,7 +557,7 @@
}
test_statementAfterReturn_ifStatement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(bool b) {
if(b) {
var one = 1;
@@ -568,7 +568,7 @@
}
test_statementAfterReturn_method() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
m() {
var one = 1;
@@ -579,7 +579,7 @@
}
test_statementAfterReturn_nested() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var one = 1;
return;
@@ -588,7 +588,7 @@
}
test_statementAfterReturn_twoReturns() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var one = 1;
return;
@@ -599,7 +599,7 @@
}
test_statementAfterThrow() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f() {
var one = 1;
throw 'Stop here';
@@ -614,8 +614,20 @@
AnalysisOptionsImpl get analysisOptions =>
AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+ test_nullCoalesce_dynamic() async {
+ await assertNoErrorsInCode(r'''
+@pragma('analyzer:non-nullable')
+library foo;
+
+m() {
+ dynamic x;
+ x ?? 1;
+}
+''');
+ }
+
test_nullCoalesce_nonNullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
@pragma('analyzer:non-nullable')
library foo;
@@ -638,8 +650,32 @@
''');
}
+ test_nullCoalesce_nullType() async {
+ await assertNoErrorsInCode(r'''
+@pragma('analyzer:non-nullable')
+library foo;
+
+m() {
+ Null x;
+ x ?? 1;
+}
+''');
+ }
+
+ test_nullCoalesceAssign_dynamic() async {
+ await assertNoErrorsInCode(r'''
+@pragma('analyzer:non-nullable')
+library foo;
+
+m() {
+ dynamic x;
+ x ??= 1;
+}
+''');
+ }
+
test_nullCoalesceAssign_nonNullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
@pragma('analyzer:non-nullable')
library foo;
diff --git a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart b/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
index eaadc2d..1ef1b7e 100644
--- a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
@@ -24,7 +24,7 @@
}
test_double() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(double x, double y) {
var v = (x / y).toInt();
}
@@ -40,7 +40,7 @@
}
test_int() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(int x, int y) {
var v = (x / y).toInt();
}
@@ -59,7 +59,7 @@
}
test_wrappedInParentheses() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(int x, int y) {
var v = (((x / y))).toInt();
}
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
index 428e9b2..d168502 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
@@ -28,7 +28,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.DUPLICATE_IMPORT]);
+ assertTestErrorsWithCodes([HintCode.DUPLICATE_IMPORT]);
}
test_importsHaveIdenticalShowHide() async {
@@ -45,7 +45,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.DUPLICATE_IMPORT]);
+ assertTestErrorsWithCodes([HintCode.DUPLICATE_IMPORT]);
}
test_oneImportHasHide() async {
@@ -114,7 +114,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
+ assertTestErrorsWithCodes(
+ [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
}
/// Resolve the test file at [path].
diff --git a/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart b/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
index 6d4a55f..91c8202f 100644
--- a/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/equal_elements_in_const_set_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(EqualElementsInConstSetTest);
+ defineReflectiveTests(EqualElementsInConstSetWithUIAsCodeAndConstantsTest);
defineReflectiveTests(EqualElementsInConstSetWithUIAsCodeTest);
});
}
@@ -19,13 +20,13 @@
@reflectiveTest
class EqualElementsInConstSetTest extends DriverResolutionTest {
test_const_entry() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = const {1, 2, 1};
''', [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]);
}
test_const_instanceCreation_equalTypeArgs() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<T> {
const A();
}
@@ -53,6 +54,18 @@
}
@reflectiveTest
+class EqualElementsInConstSetWithUIAsCodeAndConstantsTest
+ extends EqualElementsInConstSetWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class EqualElementsInConstSetWithUIAsCodeTest
extends EqualElementsInConstSetTest {
@override
@@ -63,50 +76,82 @@
];
test_const_ifElement_thenElseFalse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1, if (1 < 0) 2 else 1};
-''', [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseFalse_onlyElse() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {if (0 < 1) 1 else 1};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseTrue() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {1, if (0 < 1) 2 else 1};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseTrue_onlyThen() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {if (0 < 1) 1 else 1};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenFalse() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {2, if (1 < 0) 2};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenTrue() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1, if (0 < 1) 1};
-''', [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_spread__noDuplicate() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1, ...{2}};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_spread_hasDuplicate() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1, ...{1}};
-''', [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart b/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
index 3ba9ead..c4ff97b 100644
--- a/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/equal_keys_in_const_map_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(EqualKeysInConstMapTest);
+ defineReflectiveTests(EqualKeysInConstMapWithUIAsCodeAndConstantsTest);
defineReflectiveTests(EqualKeysInConstMapWithUIAsCodeTest);
});
}
@@ -19,13 +20,13 @@
@reflectiveTest
class EqualKeysInConstMapTest extends DriverResolutionTest {
test_const_entry() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = const {1: null, 2: null, 1: null};
''', [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]);
}
test_const_instanceCreation_equalTypeArgs() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A<T> {
const A();
}
@@ -53,6 +54,18 @@
}
@reflectiveTest
+class EqualKeysInConstMapWithUIAsCodeAndConstantsTest
+ extends EqualKeysInConstMapWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class EqualKeysInConstMapWithUIAsCodeTest extends EqualKeysInConstMapTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -62,50 +75,82 @@
];
test_const_ifElement_thenElseFalse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1: null, if (1 < 0) 2: null else 1: null};
-''', [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseFalse_onlyElse() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {if (0 < 1) 1: null else 1: null};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {1: null, if (0 < 1) 2: null else 1: null};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue_onlyThen() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {if (0 < 1) 1: null else 1: null};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse() async {
- assertNoErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
var c = const {2: null, if (1 < 0) 2: 2};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1: null, if (0 < 1) 1: null};
-''', [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread__noDuplicate() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1: null, ...{2: null}};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread_hasDuplicate() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var c = const {1: null, ...{1: null}};
-''', [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/expression_in_map_test.dart b/pkg/analyzer/test/src/diagnostics/expression_in_map_test.dart
index 613210f..b53dea9 100644
--- a/pkg/analyzer/test/src/diagnostics/expression_in_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/expression_in_map_test.dart
@@ -22,7 +22,7 @@
bool get isUiAsCode => analysisOptions.experimentStatus.spread_collections;
test_map() async {
- await assertErrorsInCode(
+ await assertErrorCodesInCode(
'''
var m = <String, int>{'a', 'b' : 2};
''',
@@ -38,7 +38,7 @@
}
test_map_const() async {
- await assertErrorsInCode(
+ await assertErrorCodesInCode(
'''
var m = <String, int>{'a', 'b' : 2};
''',
@@ -64,13 +64,13 @@
];
test_map() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var m = <String, int>{'a', 'b' : 2};
''', [CompileTimeErrorCode.EXPRESSION_IN_MAP]);
}
test_map_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var m = <String, int>{'a', 'b' : 2};
''', [CompileTimeErrorCode.EXPRESSION_IN_MAP]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
index 93e6065..6563a8a 100644
--- a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
@@ -28,7 +28,8 @@
await _resolveTestFile('/pkg1/lib/lib1.dart');
await _resolveTestFile('/pkg1/lib/lib2.dart');
- assertTestErrors([HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]);
+ assertTestErrorsWithCodes(
+ [HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]);
}
test_deferredImport_withoutLoadLibraryFunction() async {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index c67ce98..6e45cc9 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class InvalidAssignmentTest extends DriverResolutionTest {
test_instanceVariable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int x;
}
@@ -30,7 +30,7 @@
}
test_localVariable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(var y) {
if (y is String) {
int x = y;
@@ -58,7 +58,7 @@
}
test_staticVariable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
static int x;
}
@@ -71,7 +71,7 @@
}
test_typeParameterRecursion_regress35306() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {}
class C extends D {}
@@ -87,7 +87,7 @@
test_variableDeclaration() async {
// 17971
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class Point {
final num x, y;
Point(this.x, this.y);
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
index 7ea31a2..c60fc29 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
@@ -21,7 +21,7 @@
AnalysisOptionsImpl()..enabledExperiments = ['set-literals'];
test_listLiteral_const() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
const c = <B>[A()];
class A {
const A();
@@ -36,7 +36,7 @@
}
test_listLiteral_nonConst() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
var c = <B>[A()];
class A {
const A();
@@ -48,7 +48,7 @@
}
test_setLiteral_const() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
const c = <B>{A()};
class A {
const A();
@@ -63,7 +63,7 @@
}
test_setLiteral_nonConst() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
var c = <B>{A()};
class A {
const A();
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
index fc57260..d692547 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
@@ -19,7 +19,7 @@
with PackageMixin {
test_class() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@factory
class X {
@@ -29,7 +29,7 @@
test_field() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class X {
@factory
@@ -40,7 +40,7 @@
test_topLevelFunction() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@factory
main() { }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart
index 8ba3959..b685325 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart
@@ -31,7 +31,7 @@
test_badReturn() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class Stateful {
State _s = new State();
@@ -131,7 +131,7 @@
test_voidReturn() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class Stateful {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
index 85ee340e..f494f73 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
@@ -30,7 +30,7 @@
test_method() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@immutable
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
index c9a88ca..5a3c051 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
@@ -30,7 +30,7 @@
test_nonConstConstructor() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@literal
@@ -41,7 +41,7 @@
test_nonConstructor() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@literal
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
index 7b57b1e..867b204 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
@@ -58,7 +58,7 @@
test_equal_values_generic_undefined_value_base() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m({x = Undefined.value}) {}
}
@@ -74,7 +74,7 @@
test_equal_values_generic_undefined_value_both() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m({x = Undefined.value}) {}
}
@@ -92,7 +92,7 @@
test_equal_values_generic_undefined_value_derived() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m({x = 1}) {}
}
@@ -175,7 +175,7 @@
}
Future<void> _assertError(String code) async {
- await assertErrorsInCode(code, [
+ await assertErrorCodesInCode(code, [
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
index b3f03a6..d1421cb 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
@@ -58,7 +58,7 @@
test_equal_values_generic_undefined_value_base() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m([x = Undefined.value]) {}
}
@@ -74,7 +74,7 @@
test_equal_values_generic_undefined_value_both() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m([x = Undefined.value]) {}
}
@@ -92,7 +92,7 @@
test_equal_values_generic_undefined_value_derived() async {
// Note: we expect some errors due to the constant referring to undefined
// values, but there should not be any INVALID_OVERRIDE... error.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
m([x = 1]) {}
}
@@ -175,7 +175,7 @@
}
Future<void> _assertError(String code) async {
- await assertErrorsInCode(code, [
+ await assertErrorCodesInCode(code, [
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
index 96f6722c..2194b85 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
@@ -23,7 +23,7 @@
}
test_namedParameter_withDefault() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
m({@required a = 1}) => null;
@@ -31,7 +31,7 @@
}
test_positionalParameter_noDefault() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
m([@required a]) => null;
@@ -39,7 +39,7 @@
}
test_positionalParameter_withDefault() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
m([@required a = 1]) => null;
@@ -47,7 +47,7 @@
}
test_requiredParameter() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
m(@required a) => null;
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_sealed_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_sealed_annotation_test.dart
index 99876eb..428a164 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_sealed_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_sealed_annotation_test.dart
@@ -31,7 +31,7 @@
}
test_mixin() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@sealed mixin M {}
@@ -51,7 +51,7 @@
}
test_nonClass() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@sealed m({a = 1}) => null;
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
index 81c2a4c..0458e81 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
@@ -38,7 +38,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_extendingSubclass() async {
@@ -86,7 +86,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_field_subclassAndSameLibrary() async {
@@ -145,7 +145,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_function_sameLibrary() async {
@@ -208,7 +208,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_getter_subclass() async {
@@ -270,7 +270,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_method_subclass() async {
@@ -356,7 +356,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertTestErrorsWithCodes([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
}
test_setter_sameClass() async {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
index 71dde80..f14c277 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
@@ -52,7 +52,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
}
test_export() async {
@@ -91,7 +92,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
}
test_method_fromTemplate() async {
@@ -140,7 +142,7 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([
+ assertTestErrorsWithCodes([
HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER
]);
@@ -214,7 +216,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
}
/// Resolve the test file at [path].
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
index 5090d0d..984fbcf 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -37,7 +37,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
}
test_export() async {
@@ -116,7 +117,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
}
test_method() async {
@@ -137,7 +139,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
}
test_protectedAndForTesting_usedAsProtected() async {
@@ -203,7 +206,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
}
test_topLevelFunction() async {
@@ -222,7 +226,8 @@
await _resolveTestFile('/lib1.dart');
await _resolveTestFile('/lib2.dart');
- assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+ assertTestErrorsWithCodes(
+ [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
}
/// Resolve the test file at [path].
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart
index dd8ad78..b9523f5 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart
@@ -24,7 +24,7 @@
}
test_fields_multipleMixed() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@visibleForTesting int _a, b;
@@ -33,7 +33,7 @@
}
test_fields_multiplePrivate() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@visibleForTesting int _a, _b;
@@ -54,14 +54,14 @@
}
test_privateClass() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting class _C {}
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_privateConstructor() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@visibleForTesting C._() {}
@@ -70,14 +70,14 @@
}
test_privateEnum() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting enum _E {a, b, c}
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_privateField() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@visibleForTesting int _a;
@@ -86,7 +86,7 @@
}
test_privateMethod() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@visibleForTesting void _m() {}
@@ -95,42 +95,42 @@
}
test_privateMixin() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting mixin _M {}
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_privateTopLevelFunction() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting void _f() {}
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_privateTopLevelVariable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting final _a = 1;
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_privateTypedef() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting typedef _T = Function();
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_topLevelVariable_multipleMixed() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting final _a = 1, b = 2;
''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
}
test_topLevelVariable_multiplePrivate() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@visibleForTesting final _a = 1, _b = 2;
''', [
diff --git a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
index 98381f5..65a09dc 100644
--- a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,8 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ListElementTypeNotAssignableTest);
+ defineReflectiveTests(
+ ListElementTypeNotAssignableWithUIAsCodeAndConstantsTest);
defineReflectiveTests(ListElementTypeNotAssignableWithUIAsCodeTest);
});
}
@@ -18,13 +21,13 @@
@reflectiveTest
class ListElementTypeNotAssignableTest extends DriverResolutionTest {
test_const_stringInt() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String>[42];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
test_const_stringInt_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const dynamic x = 42;
var v = const <String>[x];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
@@ -50,7 +53,7 @@
}
test_nonConst_stringInt() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <String>[42];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
@@ -70,59 +73,105 @@
}
@reflectiveTest
+class ListElementTypeNotAssignableWithUIAsCodeAndConstantsTest
+ extends ListElementTypeNotAssignableWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class ListElementTypeNotAssignableWithUIAsCodeTest
extends ListElementTypeNotAssignableTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_ifElement_thenElseFalse_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 0;
var v = const <int>[if (1 < 0) a else b];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenElseFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 'b';
var v = const <int>[if (1 < 0) a else b];
-''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int>[if (1 < 0) 'a'];
-''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT
+ ]);
}
test_const_ifElement_thenFalse_intString_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int>[if (1 < 0) a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenTrue_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int>[if (true) a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenTrue_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int>[if (true) a];
-''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_spread_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int>[...[0, 1]];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_nonConst_ifElement_thenElseFalse_intDynamic() async {
@@ -142,7 +191,7 @@
}
test_nonConst_ifElement_thenFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int>[if (1 < 0) 'a'];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/map_entry_not_in_map_test.dart b/pkg/analyzer/test/src/diagnostics/map_entry_not_in_map_test.dart
index 673c83a..782e3e7 100644
--- a/pkg/analyzer/test/src/diagnostics/map_entry_not_in_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_entry_not_in_map_test.dart
@@ -22,7 +22,7 @@
bool get isUiAsCode => analysisOptions.experimentStatus.spread_collections;
test_set() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = <int>{1:2};
''', [
isUiAsCode
@@ -32,7 +32,7 @@
}
test_set_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = const <int>{1:2};
''', [
isUiAsCode
@@ -52,13 +52,13 @@
];
test_set() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = <int>{1:2};
''', [CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP]);
}
test_set_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var c = const <int>{1:2};
''', [CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
index 2ea6a69..e629629 100644
--- a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MapKeyTypeNotAssignableTest);
+ defineReflectiveTests(MapKeyTypeNotAssignableWithUIAsCodeAndConstantsTest);
defineReflectiveTests(MapKeyTypeNotAssignableWithUIAsCodeTest);
});
}
@@ -25,14 +27,14 @@
}
test_const_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const dynamic a = 'a';
var v = const <int, bool>{a : true};
''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
}
test_const_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <int, bool>{'a' : true};
''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
}
@@ -52,80 +54,137 @@
}
test_nonConst_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int, bool>{'a' : true};
''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
}
}
@reflectiveTest
+class MapKeyTypeNotAssignableWithUIAsCodeAndConstantsTest
+ extends MapKeyTypeNotAssignableWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class MapKeyTypeNotAssignableWithUIAsCodeTest
extends MapKeyTypeNotAssignableTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_ifElement_thenElseFalse_intInt_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 0;
var v = const <int, bool>{if (1 < 0) a: true else b: false};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseFalse_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 'b';
var v = const <int, bool>{if (1 < 0) a: true else b: false};
-''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_intString_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int, bool>{if (1 < 0) a: true};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int, bool>{if (1 < 0) 'a': true};
-''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_const_ifElement_thenTrue_intInt_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int, bool>{if (true) a: true};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int, bool>{if (true) a: true};
-''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_notConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final a = 0;
var v = const <int, bool>{if (1 < 2) a: true};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int, String>{...{1: 'a'}};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int, String>{...{a: 'a'}};
-''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_nonConst_ifElement_thenElseFalse_intInt_dynamic() async {
@@ -145,7 +204,7 @@
}
test_nonConst_ifElement_thenFalse_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int, bool>{if (1 < 0) 'a': true};
''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
}
@@ -177,7 +236,7 @@
}
test_nonConst_spread_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int, String>{...{'a': 'a'}};
''', [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
index 3a9bc4a..c5e15e3 100644
--- a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,8 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MapValueTypeNotAssignableTest);
+ defineReflectiveTests(
+ MapValueTypeNotAssignableWithUIAsCodeAndConstantsTest);
defineReflectiveTests(MapValueTypeNotAssignableWithUIAsCodeTest);
});
}
@@ -25,14 +28,14 @@
}
test_const_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const dynamic a = 'a';
var v = const <bool, int>{true: a};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
test_const_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <bool, int>{true: 'a'};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
@@ -52,80 +55,136 @@
}
test_nonConst_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <bool, int>{true: 'a'};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
}
@reflectiveTest
+class MapValueTypeNotAssignableWithUIAsCodeAndConstantsTest
+ extends MapValueTypeNotAssignableWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
+}
+
+@reflectiveTest
class MapValueTypeNotAssignableWithUIAsCodeTest
extends MapValueTypeNotAssignableTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_ifElement_thenElseFalse_intInt_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 0;
var v = const <bool, int>{if (1 < 0) true: a else false: b};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseFalse_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 'b';
var v = const <bool, int>{if (1 < 0) true: a else false: b};
-''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_intString_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <bool, int>{if (1 < 0) true: a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <bool, int>{if (1 < 0) true: 'a'};
-''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_const_ifElement_thenTrue_intInt_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <bool, int>{if (true) true: a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <bool, int>{if (true) true: a};
-''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_notConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final a = 0;
var v = const <bool, int>{if (1 < 2) true: a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <bool, int>{...{true: 1}};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_spread_intString_dynamic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <bool, int>{...{true: a}};
-''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_nonConst_ifElement_thenElseFalse_intInt_dynamic() async {
@@ -145,7 +204,7 @@
}
test_nonConst_ifElement_thenFalse_intString_value() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <bool, int>{if (1 < 0) true: 'a'};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
@@ -177,7 +236,7 @@
}
test_nonConst_spread_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <bool, int>{...{true: 'a'}};
''', [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
index d73c1e7..99866a3 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -33,7 +33,7 @@
test_constructorParam_missingArgument() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
C({@Required('must specify an `a`') int a}) {}
@@ -46,7 +46,7 @@
test_constructorParam_noReason() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@@ -61,7 +61,7 @@
test_constructorParam_nullReason() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@@ -76,7 +76,7 @@
test_constructorParam_redirectingConstructorCall() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
C({@required int x});
@@ -87,7 +87,7 @@
test_functionParam() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
void f({@Required('must specify an `a`') int a}) {}
@@ -100,7 +100,7 @@
test_methodParam() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
void m({@Required('must specify an `a`') int a}) {}
@@ -129,12 +129,12 @@
await _resolveTestFile('/a_lib.dart');
await _resolveTestFile('/test.dart');
- assertTestErrors([HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+ assertTestErrorsWithCodes([HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
}
test_requiredConstructor_paramSuperCall() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class C {
@@ -149,7 +149,7 @@
test_typedef_functionParam() async {
addMetaPackage();
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
String test(C c) => c.m()();
diff --git a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
index a83bb3a..41042fb 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
@@ -32,7 +32,7 @@
}
test_async() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'dart:async';
Future<int> f() async {}
''', [HintCode.MISSING_RETURN]);
@@ -66,7 +66,7 @@
}
test_factory() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
factory A() {}
}
@@ -74,20 +74,20 @@
}
test_function() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
int f() {}
''', [HintCode.MISSING_RETURN]);
}
test_method() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int m() {}
}''', [HintCode.MISSING_RETURN]);
}
test_method_inferred() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
abstract class A {
int m();
}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_on_sealed_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_on_sealed_class_test.dart
index ab64700..4d96004 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_on_sealed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_on_sealed_class_test.dart
@@ -30,7 +30,7 @@
mixin Bar on Foo {}
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.MIXIN_ON_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.MIXIN_ON_SEALED_CLASS]);
}
test_withinLibrary_OK() async {
diff --git a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
index 2e425d4..e907d2c 100644
--- a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
@@ -22,7 +22,7 @@
}
test_directAnnotation() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@immutable
class A {
@@ -32,7 +32,7 @@
}
test_directMixinAnnotation() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@immutable
mixin A {
@@ -42,7 +42,7 @@
}
test_extendsClassWithAnnotation() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@immutable
class A {}
@@ -64,7 +64,7 @@
}
test_fromMixinWithAnnotation() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@immutable
class A {}
@@ -76,7 +76,7 @@
}
test_mixinApplication() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
@immutable
class A {}
@@ -88,7 +88,7 @@
}
test_mixinApplicationBase() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
int x;
diff --git a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
index 5ef8e97..588df81 100644
--- a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
@@ -38,7 +38,7 @@
}
test_fromExtendingClass() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
@@ -67,7 +67,7 @@
}
test_indirectlyInherited() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@mustCallSuper
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
index 4865ced..3199d246 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
// defineReflectiveTests(NonBoolConditionTest);
+ defineReflectiveTests(NonBoolConditionWithUIAsCodeAndConstantsTest);
defineReflectiveTests(NonBoolConditionWithUIAsCodeTest);
});
}
@@ -20,6 +21,18 @@
class NonBoolConditionTest extends DriverResolutionTest {}
@reflectiveTest
+class NonBoolConditionWithUIAsCodeAndConstantsTest
+ extends NonBoolConditionWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonBoolConditionWithUIAsCodeTest extends NonBoolConditionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -29,8 +42,15 @@
];
test_ifElement() async {
- assertErrorsInCode('''
+ assertErrorCodesInCode(
+ '''
const c = [if (3) 1];
-''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticTypeWarningCode.NON_BOOL_CONDITION]
+ : [
+ StaticTypeWarningCode.NON_BOOL_CONDITION,
+ CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
index e4b8eab..3b24286 100644
--- a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
@@ -62,7 +62,7 @@
}
test_namedConstructor() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@literal
@@ -75,7 +75,7 @@
}
test_nonConstContext() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@literal
@@ -102,7 +102,7 @@
}
test_usingNew() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'package:meta/meta.dart';
class A {
@literal
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
index 2da7688..759b7de 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_if_element_condition_from_deferred_library_test.dart
@@ -28,14 +28,18 @@
test_inList_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const [if(a.c) 0];
-}''', [
- CompileTimeErrorCode
- .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_inList_nonConst() async {
@@ -51,24 +55,32 @@
test_inList_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const [if(a.c) 0];
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_inMap_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const {if(a.c) 0 : 0};
-}''', [
- CompileTimeErrorCode
- .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_inMap_notConst() async {
@@ -84,24 +96,32 @@
test_inMap_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const {if(a.c) 0 : 0};
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_inSet_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const {if(a.c) 0};
-}''', [
- CompileTimeErrorCode
- .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_IF_ELEMENT_CONDITION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_inSet_notConst() async {
@@ -117,10 +137,26 @@
test_inSet_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const bool c = true;''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const {if(a.c) 0};
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
}
+
+@reflectiveTest
+class NonConstantIfElementConditionFromDeferredLibraryWithConstantsTest
+ extends NonConstantIfElementConditionFromDeferredLibraryTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_list_element_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_list_element_from_deferred_library_test.dart
index 9a486ea..8359de2 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_list_element_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_list_element_from_deferred_library_test.dart
@@ -13,6 +13,8 @@
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantListElementFromDeferredLibraryTest);
defineReflectiveTests(
+ NonConstantListValueFromDeferredLibraryWithUiAsCodeAndConstantsTest);
+ defineReflectiveTests(
NonConstantListValueFromDeferredLibraryWithUiAsCodeTest);
});
}
@@ -23,7 +25,7 @@
test_const_topLevel_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const [a.c];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY]);
@@ -32,7 +34,7 @@
test_const_topLevel_deferred_nested() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const [a.c + 1];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY]);
@@ -40,6 +42,18 @@
}
@reflectiveTest
+class NonConstantListValueFromDeferredLibraryWithUiAsCodeAndConstantsTest
+ extends NonConstantListValueFromDeferredLibraryWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantListValueFromDeferredLibraryWithUiAsCodeTest
extends NonConstantListElementFromDeferredLibraryTest {
@override
@@ -54,7 +68,7 @@
// reports wrong error code (which is not crucial to fix)
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const [ if (cond) 'a' else a.c ];
@@ -64,10 +78,17 @@
test_const_ifElement_thenTrue_deferredThen() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const [ if (cond) a.c ];
-''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_list_element_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_list_element_test.dart
index 96fd900..aafeb85 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_list_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_list_element_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantListElementTest);
+ defineReflectiveTests(NonConstantListElementWithUiAsCodeAndConstantsTest);
defineReflectiveTests(NonConstantListElementWithUiAsCodeTest);
});
}
@@ -19,14 +20,14 @@
@reflectiveTest
class NonConstantListElementTest extends DriverResolutionTest {
test_const_topVar() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [a];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_topVar_nested() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
final dynamic a = 0;
var v = const [a + 1];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
@@ -41,6 +42,18 @@
}
@reflectiveTest
+class NonConstantListElementWithUiAsCodeAndConstantsTest
+ extends NonConstantListElementWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantListElementWithUiAsCodeTest
extends NonConstantListElementTest {
@override
@@ -51,63 +64,71 @@
];
test_const_forElement() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
const Set set = {};
var v = const [for(final x in set) x];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenElseFalse_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 < 0) 0 else a];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenElseFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 < 0) a else 0];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 > 0) 0 else a];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 > 0) a else 0];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenFalse_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const [if (1 < 0) a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 < 0) a];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenTrue_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const [if (1 > 0) a];
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_const_ifElement_thenTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const [if (1 > 0) a];
''', [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_map_element_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_map_element_test.dart
index ddff55a..692b49b 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_map_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_map_element_test.dart
@@ -11,6 +11,7 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(NonConstantMapElementWithUiAsCodeAndConstantTest);
defineReflectiveTests(NonConstantMapElementWithUiAsCodeTest);
defineReflectiveTests(NonConstantMapKeyTest);
defineReflectiveTests(NonConstantMapKeyWithUiAsCodeTest);
@@ -20,6 +21,18 @@
}
@reflectiveTest
+class NonConstantMapElementWithUiAsCodeAndConstantTest
+ extends NonConstantMapElementWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantMapElementWithUiAsCodeTest extends DriverResolutionTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -29,7 +42,7 @@
];
test_forElement_cannotBeConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
void main() {
const {1: null, for (final x in const []) null: null};
}
@@ -37,7 +50,7 @@
}
test_forElement_nested_cannotBeConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
void main() {
const {1: null, if (true) for (final x in const []) null: null};
}
@@ -54,23 +67,31 @@
}
test_ifElement_mayBeConst() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
void main() {
const {1: null, if (true) null: null};
}
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_ifElement_nested_mayBeConst() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
void main() {
const {1: null, if (true) if (true) null: null};
}
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_ifElement_notConstCondition() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
void main() {
bool notConst = true;
const {1: null, if (notConst) null: null};
@@ -79,24 +100,32 @@
}
test_ifElementWithElse_mayBeConst() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
void main() {
const isTrue = true;
const {1: null, if (isTrue) null: null else null: null};
}
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_spreadElement_mayBeConst() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
void main() {
const {1: null, ...{null: null}};
}
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_spreadElement_notConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
void main() {
var notConst = {};
const {1: null, ...notConst};
@@ -108,7 +137,7 @@
@reflectiveTest
class NonConstantMapKeyTest extends DriverResolutionTest {
test_const_topVar() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int, int>{a: 0};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
@@ -132,66 +161,98 @@
];
test_const_ifElement_thenElseFalse_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) 0: 0 else a: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) a: 0 else 0: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) 0: 0 else a: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) a: 0 else 0: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int, int>{if (1 < 0) a: 0};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) a: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int, int>{if (1 > 0) a: 0};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) a: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
@reflectiveTest
class NonConstantMapValueTest extends DriverResolutionTest {
test_const_topVar() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int, int>{0: a};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
@@ -215,58 +276,90 @@
];
test_const_ifElement_thenElseFalse_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) 0: 0 else 0: a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) 0: a else 0: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) 0: 0 else 0: a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) 0: a else 0: 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int, int>{if (1 < 0) 0: a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 < 0) 0: a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int, int>{if (1 > 0) 0: a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
final dynamic a = 0;
var v = const <int, int>{if (1 > 0) 0: a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_map_key_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_map_key_from_deferred_library_test.dart
index be77d50..43225c7 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_map_key_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_map_key_from_deferred_library_test.dart
@@ -12,6 +12,8 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantMapKeyFromDeferredLibraryTest);
+ defineReflectiveTests(
+ NonConstantMapKeyFromDeferredLibraryWithUiAsCodeAndConstantsTest);
defineReflectiveTests(NonConstantMapKeyFromDeferredLibraryWithUiAsCodeTest);
});
}
@@ -21,7 +23,7 @@
test_const_topLevel_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {a.c : 0};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY]);
@@ -30,7 +32,7 @@
test_const_topLevel_deferred_nested() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {a.c + 1 : 0};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY]);
@@ -38,6 +40,18 @@
}
@reflectiveTest
+class NonConstantMapKeyFromDeferredLibraryWithUiAsCodeAndConstantsTest
+ extends NonConstantMapKeyFromDeferredLibraryWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantMapKeyFromDeferredLibraryWithUiAsCodeTest
extends NonConstantMapKeyFromDeferredLibraryTest {
@override
@@ -52,7 +66,7 @@
// reports wrong error code
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const { if (cond) 0: 1 else a.c : 0};
@@ -62,10 +76,14 @@
test_const_ifElement_thenTrue_deferredThen() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const { if (cond) a.c : 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_map_key_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_map_key_test.dart
index 95ec677..48a454b 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_map_key_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_map_key_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantMapKeyTest);
+ defineReflectiveTests(NonConstantMapKeyWithUiAsCodeAndConstantsTest);
defineReflectiveTests(NonConstantMapKeyWithUiAsCodeTest);
});
}
@@ -19,7 +20,7 @@
@reflectiveTest
class NonConstantMapKeyTest extends DriverResolutionTest {
test_const_topLevel() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
final dynamic a = 0;
var v = const {a : 0};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
@@ -27,6 +28,18 @@
}
@reflectiveTest
+class NonConstantMapKeyWithUiAsCodeAndConstantsTest
+ extends NonConstantMapKeyWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantMapKeyWithUiAsCodeTest extends NonConstantMapKeyTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -36,18 +49,26 @@
];
test_const_ifElement_thenTrue_elseFinal() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
final dynamic a = 0;
const cond = true;
var v = const {if (cond) 0: 1 else a : 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_const_ifElement_thenTrue_thenFinal() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
final dynamic a = 0;
const cond = true;
var v = const {if (cond) a : 0};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_map_value_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_map_value_from_deferred_library_test.dart
index ce04f02..ddfde67 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_map_value_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_map_value_from_deferred_library_test.dart
@@ -13,6 +13,8 @@
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantMapValueFromDeferredLibraryTest);
defineReflectiveTests(
+ NonConstantMapValueFromDeferredLibraryWithUiAsCodeAndConstantsTest);
+ defineReflectiveTests(
NonConstantMapValueFromDeferredLibraryWithUiAsCodeTest);
});
}
@@ -22,7 +24,7 @@
test_const_topLevel_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {'a' : a.c};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY]);
@@ -31,7 +33,7 @@
test_const_topLevel_deferred_nested() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {'a' : a.c + 1};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY]);
@@ -39,6 +41,18 @@
}
@reflectiveTest
+class NonConstantMapValueFromDeferredLibraryWithUiAsCodeAndConstantsTest
+ extends NonConstantMapValueFromDeferredLibraryWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantMapValueFromDeferredLibraryWithUiAsCodeTest
extends NonConstantMapValueFromDeferredLibraryTest {
@override
@@ -53,7 +67,7 @@
// reports wrong error code
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const { if (cond) 'a': 'b' else 'c' : a.c};
@@ -63,10 +77,17 @@
test_const_ifElement_thenTrue_thenDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const { if (cond) 'a' : a.c};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_map_value_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_map_value_test.dart
index 75b20d5..a88a96d 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_map_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_map_value_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantMapValueTest);
+ defineReflectiveTests(NonConstantMapValueWithUiAsCodeAndConstantsTest);
defineReflectiveTests(NonConstantMapValueWithUiAsCodeTest);
});
}
@@ -19,7 +20,7 @@
@reflectiveTest
class NonConstantMapValueTest extends DriverResolutionTest {
test_const_topLevel() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
final dynamic a = 0;
var v = const {'a' : a};
''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
@@ -27,6 +28,18 @@
}
@reflectiveTest
+class NonConstantMapValueWithUiAsCodeAndConstantsTest
+ extends NonConstantMapValueWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantMapValueWithUiAsCodeTest extends NonConstantMapValueTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -36,18 +49,29 @@
];
test_const_ifTrue_elseFinal() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
final dynamic a = 0;
const cond = true;
var v = const {if (cond) 'a': 'b', 'c' : a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [
+ CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE,
+ CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT
+ ]);
}
test_const_ifTrue_thenFinal() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
final dynamic a = 0;
const cond = true;
var v = const {if (cond) 'a' : a};
-''', [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
index 59bdddb..7a2ea68 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_set_element_from_deferred_library_test.dart
@@ -13,6 +13,8 @@
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantSetElementFromDeferredLibraryTest);
defineReflectiveTests(
+ NonConstantSetElementFromDeferredLibraryWithUiAsCodeAndConstantsTest);
+ defineReflectiveTests(
NonConstantSetElementFromDeferredLibraryWithUiAsCodeTest);
});
}
@@ -23,7 +25,7 @@
test_const_topLevel_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {a.c};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY]);
@@ -32,7 +34,7 @@
test_const_topLevel_deferred_nested() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
var v = const {a.c + 1};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY]);
@@ -40,6 +42,18 @@
}
@reflectiveTest
+class NonConstantSetElementFromDeferredLibraryWithUiAsCodeAndConstantsTest
+ extends NonConstantSetElementFromDeferredLibraryWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantSetElementFromDeferredLibraryWithUiAsCodeTest
extends NonConstantSetElementFromDeferredLibraryTest {
@override
@@ -54,7 +68,7 @@
// reports wrong error code
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const {if (cond) null else a.c};
@@ -64,10 +78,17 @@
test_const_ifElement_thenTrue_thenDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const int c = 1;''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
const cond = true;
var v = const {if (cond) a.c};
-''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_set_element_test.dart
index ac0fdf9..753d602 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_set_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_set_element_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantSetElementTest);
+ defineReflectiveTests(NonConstantSetElementWithUiAsCodeAndConstantsTest);
defineReflectiveTests(NonConstantSetElementWithUiAsCodeTest);
});
}
@@ -19,14 +20,14 @@
@reflectiveTest
class NonConstantSetElementTest extends DriverResolutionTest {
test_const_parameter() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(a) {
return const {a};
}''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_topVar() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{a};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
@@ -41,6 +42,18 @@
}
@reflectiveTest
+class NonConstantSetElementWithUiAsCodeAndConstantsTest
+ extends NonConstantSetElementWithUiAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class NonConstantSetElementWithUiAsCodeTest extends NonConstantSetElementTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -50,63 +63,71 @@
];
test_const_ifElement_thenElseFalse_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 < 0) 0 else a};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 < 0) a else 0};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalElse() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 > 0) 0 else a};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 > 0) a else 0};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenFalse_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int>{if (1 < 0) a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenFalse_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 < 0) a};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenTrue_constThen() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int>{if (1 > 0) a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenTrue_finalThen() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
final dynamic a = 0;
var v = const <int>{if (1 > 0) a};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_spread_final() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
final Set x = null;
var v = const {...x};
''', [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
index c7f752bd..5d0e702 100644
--- a/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_constant_spread_expression_from_deferred_library_test.dart
@@ -12,6 +12,8 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NonConstantSpreadExpressionFromDeferredLibraryTest);
+ defineReflectiveTests(
+ NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest);
});
}
@@ -28,13 +30,18 @@
test_inList_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const List c = [];''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const [...a.c];
-}''', [
- CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_inList_deferred_notConst() async {
@@ -50,23 +57,32 @@
test_inList_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const List c = [];''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const [...a.c];
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
}
test_inMap_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const Map c = <int, int>{};''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const {...a.c};
-}''', [
- CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_inMap_notConst() async {
@@ -82,23 +98,32 @@
test_inMap_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const Map c = <int, int>{};''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const {...a.c};
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_MAP_ELEMENT]);
}
test_inSet_deferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const Set c = <int>{};''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' deferred as a;
f() {
return const {...a.c};
-}''', [
- CompileTimeErrorCode.NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
- ]);
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [
+ CompileTimeErrorCode
+ .NON_CONSTANT_SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY
+ ]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_inSet_notConst() async {
@@ -114,10 +139,26 @@
test_inSet_notDeferred() async {
newFile(convertPath('/test/lib/lib1.dart'), content: r'''
const Set c = <int>{};''');
- await assertNoErrorsInCode(r'''
+ await assertErrorCodesInCode(
+ r'''
import 'lib1.dart' as a;
f() {
return const {...a.c};
-}''');
+}''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
}
+
+@reflectiveTest
+class NonConstantSpreadExpressionFromDeferredLibraryWithConstantsTest
+ extends NonConstantSpreadExpressionFromDeferredLibraryTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
index f326006..08a4506 100644
--- a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
@@ -38,28 +38,28 @@
}
test_notIterable_direct() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = [...a];
''', [CompileTimeErrorCode.NOT_ITERABLE_SPREAD]);
}
test_notIterable_forElement() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = [for (var i in []) ...a];
''', [CompileTimeErrorCode.NOT_ITERABLE_SPREAD]);
}
test_notIterable_ifElement_else() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = [if (1 > 0) ...[] else ...a];
''', [CompileTimeErrorCode.NOT_ITERABLE_SPREAD]);
}
test_notIterable_ifElement_then() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = [if (1 > 0) ...a];
''', [CompileTimeErrorCode.NOT_ITERABLE_SPREAD]);
diff --git a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
index a9bf651..57031dd 100644
--- a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
@@ -38,28 +38,28 @@
}
test_notMap_direct() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = <int, int>{...a};
''', [CompileTimeErrorCode.NOT_MAP_SPREAD]);
}
test_notMap_forElement() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = <int, int>{for (var i in []) ...a};
''', [CompileTimeErrorCode.NOT_MAP_SPREAD]);
}
test_notMap_ifElement_else() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = <int, int>{if (1 > 0) ...<int, int>{} else ...a};
''', [CompileTimeErrorCode.NOT_MAP_SPREAD]);
}
test_notMap_ifElement_then() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var a = 0;
var v = <int, int>{if (1 > 0) ...a};
''', [CompileTimeErrorCode.NOT_MAP_SPREAD]);
diff --git a/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart
index 4a04ab2..45ffdf8 100644
--- a/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart
@@ -25,13 +25,13 @@
];
test_listLiteral_notNullAware_nullLiteral() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = [...null];
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
}
test_listLiteral_notNullAware_nullTyped() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
Null a = null;
var v = [...a];
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
@@ -51,13 +51,13 @@
}
test_mapLiteral_notNullAware_nullLiteral() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int, int>{...null};
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
}
test_mapLiteral_notNullAware_nullType() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
Null a = null;
var v = <int, int>{...a};
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
@@ -77,13 +77,13 @@
}
test_setLiteral_notNullAware_nullLiteral() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int>{...null};
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
}
test_setLiteral_notNullAware_nullTyped() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
Null a = null;
var v = <int>{...a};
''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
index 5505086..7f89a71 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
@@ -48,7 +48,7 @@
}
test_minus() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x?.a - '';
}
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
index 18bed78..89203f2 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class NullAwareInConditionTest extends DriverResolutionTest {
test_assert() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
assert (x?.a);
}
@@ -24,7 +24,7 @@
}
test_conditionalExpression() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
return x?.a ? 0 : 1;
}
@@ -32,7 +32,7 @@
}
test_do() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
do {} while (x?.a);
}
@@ -40,7 +40,7 @@
}
test_for() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
for (var v = x; v?.a; v = v.next) {}
}
@@ -48,7 +48,7 @@
}
test_if() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
if (x?.a) {}
}
@@ -56,7 +56,7 @@
}
test_if_parenthesized() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
if ((x?.a)) {}
}
@@ -64,7 +64,7 @@
}
test_while() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
while (x?.a) {}
}
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
index 05f7a5e..b60810e 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class NullAwareInLogicalOperatorTest extends DriverResolutionTest {
test_conditionalAnd_first() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x?.a && x.b;
}
@@ -24,7 +24,7 @@
}
test_conditionalAnd_second() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x.a && x?.b;
}
@@ -32,7 +32,7 @@
}
test_conditionalAnd_third() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x.a && x.b && x?.c;
}
@@ -40,7 +40,7 @@
}
test_conditionalOr_first() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x?.a || x.b;
}
@@ -48,7 +48,7 @@
}
test_conditionalOr_second() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x.a || x?.b;
}
@@ -56,7 +56,7 @@
}
test_conditionalOr_third() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
x.a || x.b || x?.c;
}
@@ -80,7 +80,7 @@
}
test_not() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(x) {
!x?.a;
}
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.dart
new file mode 100644
index 0000000..b500cd6
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_catch_clause_test.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.
+
+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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NullableTypeInCatchClauseTest);
+ });
+}
+
+@reflectiveTest
+class NullableTypeInCatchClauseTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_noOnClause() async {
+ assertNoErrorsInCode('''
+f() {
+ try {
+ } catch (e) {
+ }
+}
+''');
+ }
+
+ test_on_class() async {
+ assertErrorsInCode('''
+class A {}
+f() {
+ try {
+ } on A? {
+ }
+}
+''', [
+ error(CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 32, 2),
+ ]);
+ }
+
+ test_on_typeParameter() async {
+ assertErrorsInCode('''
+class A<B> {
+ m() {
+ try {
+ } on B {
+ }
+ }
+}
+''', [
+ error(CompileTimeErrorCode.NULLABLE_TYPE_IN_CATCH_CLAUSE, 40, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart
new file mode 100644
index 0000000..2478d79
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart
@@ -0,0 +1,69 @@
+// 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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NullableTypeInExtendsClauseTest);
+ });
+}
+
+@reflectiveTest
+class NullableTypeInExtendsClauseTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_class_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+class B extends A {}
+''');
+ }
+
+ test_class_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+class B extends A? {}
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE]);
+ }
+
+ test_classAlias_withClass_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+class B {}
+class C = A with B;
+''');
+ }
+
+ test_classAlias_withClass_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+class B {}
+class C = A? with B;
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE]);
+ }
+
+ test_classAlias_withMixin_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+mixin B {}
+class C = A with B;
+''');
+ }
+
+ test_classAlias_withMixin_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+mixin B {}
+class C = A? with B;
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart
new file mode 100644
index 0000000..ec81d73
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NullableTypeInImplementsClauseTest);
+ });
+}
+
+@reflectiveTest
+class NullableTypeInImplementsClauseTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_class_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+class B implements A {}
+''');
+ }
+
+ test_class_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+class B implements A? {}
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE]);
+ }
+
+ test_mixin_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+mixin B implements A {}
+''');
+ }
+
+ test_mixin_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+mixin B implements A? {}
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart
new file mode 100644
index 0000000..d9613ee
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NullableTypeInOnClauseTest);
+ });
+}
+
+@reflectiveTest
+class NullableTypeInOnClauseTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+mixin B on A {}
+''');
+ }
+
+ test_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+mixin B on A? {}
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart
new file mode 100644
index 0000000..d25ad1f
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart
@@ -0,0 +1,69 @@
+// 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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NullableTypeInWithClauseTest);
+ });
+}
+
+@reflectiveTest
+class NullableTypeInWithClauseTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+ test_class_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+class B with A {}
+''');
+ }
+
+ test_class_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+class B with A? {}
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE]);
+ }
+
+ test_classAlias_withClass_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+class B {}
+class C = A with B;
+''');
+ }
+
+ test_classAlias_withClass_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+class B {}
+class C = A with B?;
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE]);
+ }
+
+ test_classAlias_withMixin_nonNullable() async {
+ assertNoErrorsInCode('''
+class A {}
+mixin B {}
+class C = A with B;
+''');
+ }
+
+ test_classAlias_withMixin_nullable() async {
+ assertErrorCodesInCode('''
+class A {}
+mixin B {}
+class C = A with B?;
+''', [CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
index 898bbe1..7ecb535 100644
--- a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
@@ -25,7 +25,7 @@
@failingTest
test_overrideEquals_andNotHashCode() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
bool operator ==(x) {}
}''', [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
index 8bb0368..514ad99 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class OverrideOnNonOverridingFieldTest extends DriverResolutionTest {
test_inInterface() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int get a => 0;
void set b(_) {}
@@ -33,7 +33,7 @@
}
test_inSuperclass() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int get a => 0;
void set b(_) {}
@@ -50,7 +50,7 @@
}
test_invalid() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
}
class B extends A {
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
index c9b41a6..58dfef6 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
@@ -38,7 +38,7 @@
}
test_invalid() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
}
class B extends A {
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
index fb6038e..608295d 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
@@ -65,7 +65,7 @@
}
test_invalid() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
}
class B extends A {
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
index a9b4b62..0625741 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
@@ -38,7 +38,7 @@
}
test_invalid() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
}
class B extends A {
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
index 0624d6a..feb02f5 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_constraint_verifier_support.dart
@@ -17,6 +17,6 @@
driver.configure(
analysisOptions: analysisOptions
..sdkVersionConstraint = VersionConstraint.parse(version));
- await assertErrorsInCode(source, errorCodes ?? []);
+ await assertErrorCodesInCode(source, errorCodes ?? []);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
index 1296385..1a71c80 100644
--- a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/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';
@@ -11,6 +12,8 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SetElementTypeNotAssignableTest);
+ defineReflectiveTests(
+ SetElementTypeNotAssignableWithUiAsCodeAndConstantTest);
defineReflectiveTests(SetElementTypeNotAssignableWithUIAsCodeTest);
});
}
@@ -18,7 +21,7 @@
@reflectiveTest
class SetElementTypeNotAssignableTest extends DriverResolutionTest {
test_explicitTypeArgs_const() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = const <String>{42};
''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
@@ -31,73 +34,119 @@
}
test_explicitTypeArgs_const_actualTypeMismatch() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
const dynamic x = 42;
var v = const <String>{x};
''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
test_explicitTypeArgs_notConst() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <String>{42};
''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
}
@reflectiveTest
+class SetElementTypeNotAssignableWithUiAsCodeAndConstantTest
+ extends SetElementTypeNotAssignableWithUIAsCodeTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections,
+ EnableString.constant_update_2018
+ ];
+}
+
+@reflectiveTest
class SetElementTypeNotAssignableWithUIAsCodeTest
extends SetElementTypeNotAssignableTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
- ..enabledExperiments = ['control-flow-collections', 'spread-collections'];
+ ..enabledExperiments = [
+ EnableString.control_flow_collections,
+ EnableString.spread_collections
+ ];
test_const_ifElement_thenElseFalse_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 0;
var v = const <int>{if (1 < 0) a else b};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenElseFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
const dynamic b = 'b';
var v = const <int>{if (1 < 0) a else b};
-''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int>{if (1 < 0) 'a'};
-''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [
+ StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT
+ ]);
}
test_const_ifElement_thenFalse_intString_dynamic() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int>{if (1 < 0) a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenTrue_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 0;
var v = const <int>{if (true) a};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_ifElement_thenTrue_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
const dynamic a = 'a';
var v = const <int>{if (true) a};
-''', [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_const_spread_intInt() async {
- await assertNoErrorsInCode('''
+ await assertErrorCodesInCode(
+ '''
var v = const <int>{...[0, 1]};
-''');
+''',
+ analysisOptions.experimentStatus.constant_update_2018
+ ? []
+ : [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
}
test_nonConst_ifElement_thenElseFalse_intDynamic() async {
@@ -117,7 +166,7 @@
}
test_nonConst_ifElement_thenFalse_intString() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
var v = <int>[if (1 < 0) 'a'];
''', [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
index 6801637..ab27d78 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
@@ -30,7 +30,7 @@
class Bar extends Foo {}
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_implementingSealedClass() async {
@@ -46,7 +46,7 @@
class Bar implements Foo {}
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_mixinApplicationOfSealedClass() async {
@@ -63,7 +63,7 @@
class Bar2 = Bar1 with Foo;
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_mixinApplicationOfSealedMixin() async {
@@ -80,7 +80,7 @@
class Bar2 = Bar1 with Foo;
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_mixingInWithSealedMixin() async {
@@ -96,7 +96,7 @@
class Bar extends Object with Foo {}
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_mixinImplementsSealedClass() async {
@@ -112,7 +112,7 @@
mixin Bar implements Foo {}
''');
await _resolveTestFile('/pkg1/lib/lib1.dart');
- assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
+ assertTestErrorsWithCodes([HintCode.SUBTYPE_OF_SEALED_CLASS]);
}
test_withinLibrary_OK() async {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 7bf4d02..56a1409 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -86,6 +86,14 @@
import 'null_aware_in_condition_test.dart' as null_aware_in_condition;
import 'null_aware_in_logical_operator_test.dart'
as null_aware_in_logical_operator;
+import 'nullable_type_in_catch_clause_test.dart'
+ as nullable_type_in_catch_clause;
+import 'nullable_type_in_extends_clause_test.dart'
+ as nullable_type_in_extends_clause;
+import 'nullable_type_in_implements_clause_test.dart'
+ as nullable_type_in_implements_clause;
+import 'nullable_type_in_on_clause_test.dart' as nullable_type_in_on_clause;
+import 'nullable_type_in_with_clause_test.dart' as nullable_type_in_with_clause;
import 'override_equals_but_not_hashcode_test.dart'
as override_equals_but_not_hashcode;
import 'override_on_non_overriding_field_test.dart'
@@ -202,6 +210,11 @@
null_aware_before_operator.main();
null_aware_in_condition.main();
null_aware_in_logical_operator.main();
+ nullable_type_in_catch_clause.main();
+ nullable_type_in_extends_clause.main();
+ nullable_type_in_implements_clause.main();
+ nullable_type_in_on_clause.main();
+ nullable_type_in_with_clause.main();
override_equals_but_not_hashcode.main();
override_on_non_overriding_field.main();
override_on_non_overriding_getter.main();
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
index dae29d6..8427700 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
@@ -76,7 +76,7 @@
}
test_implicitlyTyped() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
get g => 0;
}
@@ -85,7 +85,7 @@
}
test_implicitlyTyped_call() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
get g => () => 0;
}
@@ -95,7 +95,7 @@
}
test_implicitlyTyped_field() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var g = 0;
}
@@ -104,7 +104,7 @@
}
test_implicitlyTyped_field_call() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var g = () => 0;
}
@@ -114,7 +114,7 @@
}
test_implicitlyTyped_field_prefixedIdentifier() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var g = 0;
}
@@ -126,7 +126,7 @@
test_implicitlyTyped_fn() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
// generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = 0;
}
@@ -178,7 +178,7 @@
test_implicitlyTyped_invoke() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
// closure is generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = 0;
}
@@ -214,7 +214,7 @@
test_implicitlyTyped_method() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
// generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = 0;
int f<T>(int x) => 0;
@@ -253,7 +253,7 @@
test_implicitlyTyped_new() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
// generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = 0;
}
@@ -316,7 +316,7 @@
test_implicitlyTyped_new_named() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
// generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = 0;
}
@@ -384,7 +384,7 @@
''');
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
// generic, so the type of a.x might affect the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
import 'lib1.dart' as foo;
class A {
var x = 0;
@@ -395,7 +395,7 @@
}
test_implicitlyTyped_prefixedIdentifier() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
get g => 0;
}
@@ -407,7 +407,7 @@
test_implicitlyTyped_propertyAccessLhs() async {
// The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
// of a.x affects the lookup of y, which in turn affects the type of b.
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
var x = new B();
int operator[](int value) => 0;
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
index 4e6dde5..221a7f0 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class TopLevelInstanceMethodTest extends DriverResolutionTest {
test_noParameter() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
f() => 0;
}
@@ -34,7 +34,7 @@
}
test_parameter_generic() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
int f<T>(v) => 0;
}
@@ -61,7 +61,7 @@
}
test_tearOff() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
f() => 0;
}
@@ -70,7 +70,7 @@
}
test_tearOff_parameter() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
class A {
int f(v) => 0;
}
diff --git a/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart b/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart
index a5d66af..9a473f0 100644
--- a/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class TypeCheckIsNotNullTest extends DriverResolutionTest {
test_not_Null() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
bool m(i) {
return i is! Null;
}
diff --git a/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart b/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart
index 4f50661..42d8555 100644
--- a/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class TypeCheckIsNullTest extends DriverResolutionTest {
test_is_Null() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
bool m(i) {
return i is Null;
}
diff --git a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
index 621b6b3..ce2c1f0 100644
--- a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
@@ -31,7 +31,7 @@
}
test_and_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
bool? x;
if(x && true) {}
@@ -76,7 +76,7 @@
}
test_cascade_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x..isEven;
@@ -103,7 +103,7 @@
}
test_forLoop_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
List? x;
for (var y in x) {}
@@ -121,7 +121,7 @@
}
test_if_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
bool? x;
if (x) {}
@@ -139,7 +139,7 @@
}
test_index_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
List? x;
x[0];
@@ -160,7 +160,7 @@
test_invoke_dynamicFunctionType_nullable() async {
// test is failing because nullable function invocations aren't being
// resolved correctly
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
Function? x;
x();
@@ -181,7 +181,7 @@
test_invoke_nullable() async {
// test is failing because nullable function invocations aren't being
// resolved correctly
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
Function()? x;
x();
@@ -226,7 +226,7 @@
}
test_member_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x.isEven;
@@ -244,7 +244,7 @@
}
test_member_parenthesized_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
(x).isEven;
@@ -298,7 +298,7 @@
}
test_method_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x.round();
@@ -334,7 +334,7 @@
}
test_minusEq_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x -= 1;
@@ -352,7 +352,7 @@
}
test_not_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
bool? x;
if(!x) {}
@@ -379,7 +379,7 @@
}
test_operatorMinus_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x - 3;
@@ -397,7 +397,7 @@
}
test_operatorPlus_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x + 3;
@@ -415,7 +415,7 @@
}
test_operatorPostfixDec_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x--;
@@ -433,7 +433,7 @@
}
test_operatorPostfixInc_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x++;
@@ -451,7 +451,7 @@
}
test_operatorPrefixDec_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
--x;
@@ -469,7 +469,7 @@
}
test_operatorPrefixInc_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
++x;
@@ -487,7 +487,7 @@
}
test_operatorUnaryMinus_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
-x;
@@ -505,7 +505,7 @@
}
test_or_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
bool? x;
if(x || false) {}
@@ -523,7 +523,7 @@
}
test_plusEq_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
int? x;
x += 1;
@@ -532,7 +532,7 @@
}
test_ternary_condition_nullable() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m() {
bool? x;
x ? 0 : 1;
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index 75f0359..e2ace47b 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -19,7 +19,7 @@
@reflectiveTest
class UndefinedGetterTest extends DriverResolutionTest {
test_ifStatement_notPromoted() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f(int x) {
if (x is String) {
x.length;
@@ -39,7 +39,7 @@
}
test_promotedTypeParameter_regress35305() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
void f<X extends num, Y extends X>(Y y) {
if (y is int) {
y.isEven;
@@ -57,7 +57,7 @@
..enabledExperiments = [EnableString.control_flow_collections];
test_ifElement_inList_notPromoted() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f(int x) {
return [if (x is String) x.length];
}
@@ -73,7 +73,7 @@
}
test_ifElement_inMap_notPromoted() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f(int x) {
return {if (x is String) x : x.length};
}
@@ -89,7 +89,7 @@
}
test_ifElement_inSet_notPromoted() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f(int x) {
return {if (x is String) x.length};
}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart
index 3391749..888721c 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart
@@ -17,14 +17,14 @@
class UndefinedHiddenNameTest extends DriverResolutionTest {
test_export() async {
newFile('/test/lib/lib1.dart');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
export 'lib1.dart' hide a;
''', [HintCode.UNDEFINED_HIDDEN_NAME]);
}
test_import() async {
newFile('/test/lib/lib1.dart');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' hide a;
''', [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_HIDDEN_NAME]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
index 2df536e..7b44210 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
@@ -29,7 +29,7 @@
}
test_forStatement_outsideBody() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() {
for (int x in []) {}
x;
@@ -54,7 +54,7 @@
}
test_forElement_inList_outsideElement() async {
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
f() {
return [for (int x in []) null, x];
}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
index b05ef9b..a10a3ee 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class UndefinedOperatorTest extends DriverResolutionTest {
test_binaryExpression() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f(var a) {
if (a is A) {
@@ -27,7 +27,7 @@
}
test_binaryExpression_inSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {
operator +(B b) {}
@@ -41,7 +41,7 @@
}
test_indexBoth() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f(var a) {
if (a is A) {
@@ -55,7 +55,7 @@
}
test_indexBoth_inSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {
operator [](int index) {}
@@ -72,7 +72,7 @@
}
test_indexGetter() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f(var a) {
if (a is A) {
@@ -83,7 +83,7 @@
}
test_indexGetter_inSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {
operator [](int index) {}
@@ -97,7 +97,7 @@
}
test_indexSetter() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f(var a) {
if (a is A) {
@@ -108,7 +108,7 @@
}
test_indexSetter_inSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {
operator []=(i, v) {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
index b6ba333..6de8429 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_prefixed_name_test.dart
@@ -17,7 +17,7 @@
class UndefinedPrefixedNameTest extends DriverResolutionTest {
test_getterContext() async {
newFile('/test/lib/lib.dart');
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
import 'lib.dart' as p;
f() => p.c;
''', [StaticTypeWarningCode.UNDEFINED_PREFIXED_NAME]);
@@ -25,7 +25,7 @@
test_setterContext() async {
newFile('/test/lib/lib.dart');
- await assertErrorsInCode('''
+ await assertErrorCodesInCode('''
import 'lib.dart' as p;
f() {
p.c = 0;
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index fd9bafd..7306c0e 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class UndefinedSetterTest extends DriverResolutionTest {
test_inSubtype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
class B extends A {
set b(x) {}
@@ -30,7 +30,7 @@
}
test_inType() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {}
f(var a) {
if(a is A) {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart
index 9bbc57a..3243bb2 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart
@@ -17,14 +17,14 @@
class UndefinedShownNameTest extends DriverResolutionTest {
test_export() async {
newFile('/test/lib/lib1.dart');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
export 'lib1.dart' show a;
''', [HintCode.UNDEFINED_SHOWN_NAME]);
}
test_import() async {
newFile('/test/lib/lib1.dart');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' show a;
''', [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_SHOWN_NAME]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
index 5459327..0d89796 100644
--- a/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
@@ -59,7 +59,7 @@
test_generics() async {
// dartbug.com/18953
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
import 'dart:async';
Future<int> f() => new Future.value(0);
void g(bool c) {
@@ -92,7 +92,7 @@
}
test_type_supertype() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(int i) {
var b = i as Object;
}
@@ -100,7 +100,7 @@
}
test_type_type() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(num i) {
var b = i as num;
}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart
index e6f36ad..0801ae0 100644
--- a/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class UnnecessaryNoSuchMethodTest extends DriverResolutionTest {
test_blockBody() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
noSuchMethod(x) => super.noSuchMethod(x);
}
@@ -59,7 +59,7 @@
}
test_expressionBody() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
noSuchMethod(x) => super.noSuchMethod(x);
}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart
index 6b48d25..e3316ad 100644
--- a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart
@@ -16,13 +16,13 @@
@reflectiveTest
class UnnecessaryTypeCheckFalseTest extends DriverResolutionTest {
test_null_not_Null() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
bool b = null is! Null;
''', [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
}
test_type_not_dynamic() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(i) {
bool b = i is! dynamic;
}
@@ -30,7 +30,7 @@
}
test_type_not_object() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(i) {
bool b = i is! Object;
}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart
index 44e96ea..269d39a 100644
--- a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart
@@ -16,13 +16,13 @@
@reflectiveTest
class UnnecessaryTypeCheckTrueTest extends DriverResolutionTest {
test_null_is_Null() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
bool b = null is Null;
''', [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
}
test_type_is_dynamic() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(i) {
bool b = i is dynamic;
}
@@ -30,7 +30,7 @@
}
test_type_is_object() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
m(i) {
bool b = i is Object;
}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart b/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
index 841f0df..de74c41 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
@@ -19,7 +19,7 @@
bool get enableUnusedLocalVariable => true;
test_on_unusedException() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
try {
} on String catch (exception) {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart b/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart
index 71bba94..84303fa 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart
@@ -19,7 +19,7 @@
bool get enableUnusedLocalVariable => true;
test_on_unusedStack() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
try {
} on String catch (exception, stackTrace) {
@@ -40,7 +40,7 @@
}
test_unusedStack() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
try {
} catch (exception, stackTrace) {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
index 871023a..8f16748 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -85,7 +85,7 @@
}
test_class_notUsed_inClassMember() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class _A {
static staticMethod() {
new _A();
@@ -98,7 +98,7 @@
}
test_class_notUsed_inConstructorName() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class _A {
_A() {}
_A.named() {}
@@ -107,7 +107,7 @@
}
test_class_notUsed_isExpression() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class _A {}
main(p) {
if (p is _A) {
@@ -117,7 +117,7 @@
}
test_class_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class _A {}
main() {
}
@@ -125,7 +125,7 @@
}
test_class_notUsed_variableDeclaration() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class _A {}
main() {
_A v;
@@ -145,7 +145,7 @@
}
test_enum_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
enum _MyEnum {A, B, C}
main() {
}
@@ -181,7 +181,7 @@
}
test_functionLocal_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
f() {}
}
@@ -189,7 +189,7 @@
}
test_functionLocal_notUsed_referenceFromItself() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
_f(int p) {
_f(p - 1);
@@ -218,7 +218,7 @@
}
test_functionTop_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
_f() {}
main() {
}
@@ -226,7 +226,7 @@
}
test_functionTop_notUsed_referenceFromItself() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
_f(int p) {
_f(p - 1);
}
@@ -274,7 +274,7 @@
}
test_functionTypeAlias_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
typedef _F(a, b);
main() {
}
@@ -315,7 +315,7 @@
}
test_getter_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
get _g => null;
}
@@ -323,7 +323,7 @@
}
test_getter_notUsed_referenceFromItself() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
get _g {
return _g;
@@ -477,7 +477,7 @@
}
test_method_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
static _m() {}
}
@@ -485,7 +485,7 @@
}
test_method_notUsed_referenceFromItself() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
static _m(int p) {
_m(p - 1);
@@ -528,7 +528,7 @@
}
test_setter_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
set _s(x) {}
}
@@ -536,7 +536,7 @@
}
test_setter_notUsed_referenceFromItself() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
set _s(int x) {
if (x > 5) {
@@ -567,7 +567,7 @@
}
test_topLevelVariable_notUsed() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
int _a = 1;
main() {
_a = 2;
diff --git a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
index 91c7082..a0dacdb 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
@@ -105,7 +105,7 @@
}
test_unusedField_notUsed_compoundAssign() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f;
main() {
@@ -116,7 +116,7 @@
}
test_unusedField_notUsed_constructorFieldInitializers() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f;
A() : _f = 0;
@@ -125,7 +125,7 @@
}
test_unusedField_notUsed_fieldFormalParameter() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f;
A(this._f);
@@ -134,7 +134,7 @@
}
test_unusedField_notUsed_noReference() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f;
}
@@ -154,7 +154,7 @@
}
test_unusedField_notUsed_postfixExpr() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f = 0;
main() {
@@ -165,7 +165,7 @@
}
test_unusedField_notUsed_prefixExpr() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f = 0;
main() {
@@ -176,7 +176,7 @@
}
test_unusedField_notUsed_simpleAssignment() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
int _f;
m() {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index f94815c..84ac848 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -31,7 +31,7 @@
newFile('/test/lib/lib1.dart', content: r'''
class A {}
''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart';
import 'lib1.dart' as one;
one.A a;
@@ -63,7 +63,7 @@
newFile('/test/lib/lib2.dart', content: r'''
class B {}
''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' as one;
import 'lib2.dart' as one;
one.A a;
@@ -131,7 +131,7 @@
newFile('/test/lib/lib1.dart', content: r'''
class A {}
''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart';
import 'lib1.dart' hide A;
A a;
@@ -200,7 +200,7 @@
class A {}
class B {}
''');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart' show A;
import 'lib1.dart' show B;
A a;
@@ -209,7 +209,7 @@
test_unusedImport() async {
newFile('/test/lib/lib1.dart');
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
import 'lib1.dart';
''', [HintCode.UNUSED_IMPORT]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_label_test.dart b/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
index 7d3a4f4..3322685 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class UnusedLabelTest extends DriverResolutionTest {
test_unused_inSwitch() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(x) {
switch (x) {
label: case 0:
@@ -29,7 +29,7 @@
}
test_unused_onWhile() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
f(condition()) {
label: while (condition()) {
break;
diff --git a/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart
index ef082c4..d4281bc 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart
@@ -31,7 +31,7 @@
}
test_inFunction() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
var v = 1;
v = 2;
@@ -40,7 +40,7 @@
}
test_inMethod() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
class A {
foo() {
var v = 1;
@@ -72,7 +72,7 @@
}
test_isRead_notUsed_compoundAssign() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
var v = 1;
v += 2;
@@ -81,7 +81,7 @@
}
test_isRead_notUsed_postfixExpr() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
var v = 1;
v++;
@@ -90,7 +90,7 @@
}
test_isRead_notUsed_prefixExpr() async {
- await assertErrorsInCode(r'''
+ await assertErrorCodesInCode(r'''
main() {
var v = 1;
++v;
diff --git a/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart b/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
index c798569..fd823b1 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
@@ -20,7 +20,7 @@
class A {}
class B {}
''');
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
import 'lib1.dart' show A, B;
A a;
''', [HintCode.UNUSED_SHOWN_NAME]);
@@ -31,7 +31,7 @@
class A {}
class B {}
''');
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
import 'lib1.dart' as p show A, B;
p.A a;
''', [HintCode.UNUSED_SHOWN_NAME]);
@@ -44,7 +44,7 @@
class C {}
class D {}
''');
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
import 'lib1.dart' show A, B;
import 'lib1.dart' show C, D;
A a;
@@ -59,7 +59,7 @@
const int var3 = 3;
const int var4 = 4;
''');
- assertErrorsInCode(r'''
+ assertErrorCodesInCode(r'''
import 'lib1.dart' show var1, var2;
import 'lib1.dart' show var3, var4;
int a = var1;
diff --git a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
index 00ffa49..e366f23 100644
--- a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
@@ -27,6 +27,7 @@
const double y = x;
''');
await resolveTestFile();
- assertTestErrors([CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+ assertTestErrorsWithCodes(
+ [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
}
}
diff --git a/pkg/analyzer/test/src/manifest/manifest_validator_test.dart b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
index 8cd846cc6..1388f40 100644
--- a/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
+++ b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
@@ -65,10 +65,42 @@
''', [ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE]);
}
+ test_screenOrientation_error() {
+ assertErrors('''
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <application android:label="@string/app_name">
+ <activity android:name="testActivity"
+ android:screenOrientation="landscape"
+ android:exported="false">
+ </activity>
+ </application>
+</manifest>
+''', [ManifestWarningCode.SETTING_ORIENTATION_ON_ACTIVITY]);
+ }
+
+ test_resizeableactivity_error() {
+ assertErrors('''
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <application android:label="@string/app_name">
+ <activity android:name="testActivity"
+ android:resizeableActivity="false"
+ android:exported="false">
+ </activity>
+ </application>
+</manifest>
+''', [ManifestWarningCode.NON_RESIZABLE_ACTIVITY]);
+ }
+
test_no_errors() {
assertErrors('''
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">
+ <activity android:name="testActivity"
+ android:resizeableActivity="true"
+ android:exported="false">
+ </activity>
</manifest>
''', []);
}
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index 206a034..dbf23a4 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -1097,6 +1097,7 @@
parameters: '()',
parameterTypes: [],
requiredParameterCount: 0,
+ returnType: 'C',
);
_assertDeclaration(
_getDeclaration(classDeclaration.children, 'a'),
@@ -1106,6 +1107,7 @@
parameters: '()',
parameterTypes: [],
requiredParameterCount: 0,
+ returnType: 'C',
);
_assertDeclaration(
_getDeclaration(classDeclaration.children, 'b'),
@@ -1116,6 +1118,7 @@
parameterNames: [],
parameterTypes: [],
requiredParameterCount: 0,
+ returnType: 'C',
);
_assertDeclaration(
_getDeclaration(classDeclaration.children, 'c'),
@@ -1127,6 +1130,7 @@
parameterNames: [],
parameterTypes: [],
requiredParameterCount: 0,
+ returnType: 'C',
);
_assertDeclaration(
_getDeclaration(classDeclaration.children, 'd'),
@@ -1138,6 +1142,7 @@
parameterNames: ['p1', 'p2', 'p3'],
parameterTypes: ['Map<String, int>', 'int', 'double'],
requiredParameterCount: 2,
+ returnType: 'C',
);
_assertDeclaration(
_getDeclaration(classDeclaration.children, 'e'),
@@ -1149,6 +1154,7 @@
parameterNames: ['f1', 'f2'],
parameterTypes: ['', ''],
requiredParameterCount: 2,
+ returnType: 'C',
);
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 16c94d1..7ec7d23 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -8,12 +8,12 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
-import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'resynthesize_common.dart';
@@ -28,141 +28,54 @@
@reflectiveTest
class ResynthesizeAst2Test extends ResynthesizeTestStrategyTwoPhase
with ResynthesizeTestCases {
+ /// The shared SDK bundle, computed once and shared among test invocations.
+ static LinkedNodeBundle _sdkBundle;
+
@override
bool get isAstBasedSummary => true;
+ LinkedNodeBundle get sdkBundle {
+ if (_sdkBundle != null) return _sdkBundle;
+
+ var inputLibraries = <LinkInputLibrary>[];
+ for (var sdkLibrary in sdk.sdkLibraries) {
+ var source = sourceFactory.resolveUri(null, sdkLibrary.shortName);
+ var text = getFile(source.fullName).readAsStringSync();
+ var unit = parseText(text);
+
+ var inputUnits = <LinkInputUnit>[];
+ _addLibraryUnits(source, unit, inputUnits);
+ inputLibraries.add(
+ LinkInputLibrary(source, inputUnits),
+ );
+ }
+
+ var sdkLinkResult = link(
+ AnalysisOptionsImpl(),
+ sourceFactory,
+ declaredVariables,
+ [],
+ inputLibraries,
+ );
+
+ var bytes = sdkLinkResult.bundle.toBuffer();
+ return _sdkBundle = LinkedNodeBundle.fromBuffer(bytes);
+ }
+
@override
Future<LibraryElementImpl> checkLibrary(String text,
{bool allowErrors = false, bool dumpSummaries = false}) async {
- var dartCoreSource = sourceFactory.forUri('dart:core');
- var dartAsyncSource = sourceFactory.forUri('dart:async');
- var dartMathSource = sourceFactory.forUri('dart:math');
-
- var dartCoreCode = getFile(dartCoreSource.fullName).readAsStringSync();
- dartCoreCode = r'''
-library dart.core;
-
-abstract class Comparable<T> {
- int compareTo(T other);
-}
-
-class Iterable<T> {}
-
-class Iterator<T> {}
-
-class List<T> {}
-
-class Map<K, V> {}
-
-abstract class Null {}
-
-class Object {
- const Object();
-}
-
-abstract class String {
- int get length;
- String operator +(String other);
-}
-
-class Set<T> {}
-
-abstract class Symbol {}
-
-abstract class Type {}
-
-abstract class bool {}
-
-abstract class double extends num {}
-
-abstract class int extends num {
- bool get isEven => false;
- bool get isNegative;
-
- int operator &(int other);
- int operator -();
- int operator <<(int shiftAmount);
- int operator >>(int shiftAmount);
- int operator ^(int other);
- int operator |(int other);
- int operator ~();
-}
-
-abstract class num implements Comparable<num> {
- bool operator <(num other);
- bool operator <=(num other);
- bool operator ==(Object other);
- bool operator >(num other);
- bool operator >=(num other);
-
- double operator /(num other);
- double toDouble();
-
- int operator <<(int other);
- int operator >>(int other);
- int operator ^(int other);
- int operator |(int other);
- int operator ~();
- int operator ~/(num other);
-
- int round();
- int toInt();
- num abs();
-
- num operator %(num other);
- num operator *(num other);
- num operator +(num other);
- num operator -();
- num operator -(num other);
-}
-''';
-
- var dartAsyncCode = r'''
-library dart.async;
-
-class Future<T> {}
-
-class FutureOr<T> {}
-
-class Stream<T> {}
-''';
-
- var dartMathCode = r'''
-library dart.math;
-
-const double E = 2.718281828459045;
-const double PI = 3.1415926535897932;
-const double LN10 = 2.302585092994046;
-
-T min<T extends num>(T a, T b) => null;
-T max<T extends num>(T a, T b) => null;
-''';
-
- var dartCoreResult = _link({
- dartCoreSource: dartCoreCode,
- dartAsyncSource: dartAsyncCode,
- dartMathSource: dartMathCode,
- });
-
var source = addTestSource(text);
- var unit = parseText(text, experimentStatus: experimentStatus);
- var libraryUnitMap = {
- source: _unitsOfLibrary(source, unit),
- };
-
- for (var otherLibrarySource in otherLibrarySources) {
- var text = getFile(otherLibrarySource.fullName).readAsStringSync();
- var unit = parseText(text, experimentStatus: experimentStatus);
- var unitMap = _unitsOfLibrary(otherLibrarySource, unit);
- libraryUnitMap[otherLibrarySource] = unitMap;
- }
+ var inputLibraries = <LinkInputLibrary>[];
+ _addNonDartLibraries(Set(), inputLibraries, source);
var linkResult = link(
AnalysisOptionsImpl(),
sourceFactory,
- [dartCoreResult.bundle],
- libraryUnitMap,
+ declaredVariables,
+ [sdkBundle],
+ inputLibraries,
);
var analysisContext = _FakeAnalysisContext(sourceFactory);
@@ -177,7 +90,7 @@
rootReference,
);
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, dartCoreResult.bundle),
+ LinkedBundleContext(elementFactory, sdkBundle),
);
elementFactory.addBundle(
LinkedBundleContext(elementFactory, linkResult.bundle),
@@ -191,937 +104,40 @@
analysisContext.typeProvider = typeProvider;
analysisContext.typeSystem = Dart2TypeSystem(typeProvider);
+ dartCore.createLoadLibraryFunction(typeProvider);
+ dartAsync.createLoadLibraryFunction(typeProvider);
+
return elementFactory.libraryOfUri('${source.uri}');
}
@override
@failingTest
- test_class_alias_notSimplyBounded_self() async {
- await super.test_class_alias_notSimplyBounded_self();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_circularity_via_typedef() async {
- await super.test_class_notSimplyBounded_circularity_via_typedef();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_complex_by_cycle() async {
- await super.test_class_notSimplyBounded_complex_by_cycle();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
- await super.test_class_notSimplyBounded_complex_by_reference_to_cycle();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_complex_by_use_of_parameter() async {
- await super.test_class_notSimplyBounded_complex_by_use_of_parameter();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_dependency_with_type_params() async {
- await super.test_class_notSimplyBounded_dependency_with_type_params();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async {
- await super
- .test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async {
- await super
- .test_class_notSimplyBounded_function_typed_bound_complex_via_return_type();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_refers_to_circular_typedef() async {
- await super.test_class_notSimplyBounded_refers_to_circular_typedef();
- }
-
- @override
- @failingTest
- test_class_notSimplyBounded_self() async {
- await super.test_class_notSimplyBounded_self();
- }
-
- @override
- @failingTest
- test_class_type_parameters_bound() async {
- await super.test_class_type_parameters_bound();
- }
-
- @override
- @failingTest
- test_class_type_parameters_f_bound_complex() async {
- await super.test_class_type_parameters_f_bound_complex();
- }
-
- @override
- @failingTest
- test_class_type_parameters_f_bound_simple() async {
- await super.test_class_type_parameters_f_bound_simple();
- }
-
- @override
- @failingTest
- test_closure_generic() async {
- await super.test_closure_generic();
- }
-
- @override
- @failingTest
- test_closure_in_variable_declaration_in_part() async {
- await super.test_closure_in_variable_declaration_in_part();
- }
-
- @override
- @failingTest
test_const_constructor_inferred_args() async {
await super.test_const_constructor_inferred_args();
}
@override
@failingTest
- test_const_finalField_hasConstConstructor() async {
- // TODO(scheglov) Needs initializer, because of const constructor.
- await super.test_const_finalField_hasConstConstructor();
- }
-
- @override
- @failingTest
- test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
- await super
- .test_const_parameterDefaultValue_initializingFormal_functionTyped();
- }
-
- @override
- @failingTest
- test_const_reference_topLevelFunction_generic() async {
- await super.test_const_reference_topLevelFunction_generic();
- }
-
- @override
- @failingTest
- test_const_reference_topLevelVariable_imported() async {
- await super.test_const_reference_topLevelVariable_imported();
- }
-
- @override
- @failingTest
- test_const_reference_topLevelVariable_imported_withPrefix() async {
- await super.test_const_reference_topLevelVariable_imported_withPrefix();
- }
-
- @override
- @failingTest
- test_const_topLevel_typedList_typedefArgument() async {
- await super.test_const_topLevel_typedList_typedefArgument();
- }
-
- @override
- @failingTest
- test_constExpr_pushReference_field_simpleIdentifier() async {
- await super.test_constExpr_pushReference_field_simpleIdentifier();
- }
-
- @override
- @failingTest
- test_constructor_initializers_assertInvocation() async {
- await super.test_constructor_initializers_assertInvocation();
- }
-
- @override
- @failingTest
- test_constructor_initializers_assertInvocation_message() async {
- await super.test_constructor_initializers_assertInvocation_message();
- }
-
- @override
- @failingTest
- test_constructor_initializers_field() async {
- await super.test_constructor_initializers_field();
- }
-
- @override
- @failingTest
- test_constructor_initializers_field_notConst() async {
- await super.test_constructor_initializers_field_notConst();
- }
-
- @override
- @failingTest
- test_constructor_initializers_field_withParameter() async {
- await super.test_constructor_initializers_field_withParameter();
- }
-
- @override
- @failingTest
- test_constructor_initializers_superInvocation_named() async {
- await super.test_constructor_initializers_superInvocation_named();
- }
-
- @override
- @failingTest
- test_constructor_initializers_superInvocation_named_underscore() async {
- await super
- .test_constructor_initializers_superInvocation_named_underscore();
- }
-
- @override
- @failingTest
- test_constructor_initializers_superInvocation_namedExpression() async {
- await super.test_constructor_initializers_superInvocation_namedExpression();
- }
-
- @override
- @failingTest
- test_constructor_initializers_superInvocation_unnamed() async {
- await super.test_constructor_initializers_superInvocation_unnamed();
- }
-
- @override
- @failingTest
- test_constructor_initializers_thisInvocation_named() async {
- await super.test_constructor_initializers_thisInvocation_named();
- }
-
- @override
- @failingTest
- test_constructor_initializers_thisInvocation_namedExpression() async {
- await super.test_constructor_initializers_thisInvocation_namedExpression();
- }
-
- @override
- @failingTest
- test_constructor_initializers_thisInvocation_unnamed() async {
- await super.test_constructor_initializers_thisInvocation_unnamed();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named() async {
- await super.test_constructor_redirected_factory_named();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named_generic() async {
- await super.test_constructor_redirected_factory_named_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named_imported() async {
- await super.test_constructor_redirected_factory_named_imported();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named_imported_generic() async {
- await super.test_constructor_redirected_factory_named_imported_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named_prefixed() async {
- await super.test_constructor_redirected_factory_named_prefixed();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_named_prefixed_generic() async {
- await super.test_constructor_redirected_factory_named_prefixed_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed() async {
- await super.test_constructor_redirected_factory_unnamed();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed_generic() async {
- await super.test_constructor_redirected_factory_unnamed_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed_imported() async {
- await super.test_constructor_redirected_factory_unnamed_imported();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed_imported_generic() async {
- await super.test_constructor_redirected_factory_unnamed_imported_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed_prefixed() async {
- await super.test_constructor_redirected_factory_unnamed_prefixed();
- }
-
- @override
- @failingTest
- test_constructor_redirected_factory_unnamed_prefixed_generic() async {
- await super.test_constructor_redirected_factory_unnamed_prefixed_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_thisInvocation_named() async {
- await super.test_constructor_redirected_thisInvocation_named();
- }
-
- @override
- @failingTest
- test_constructor_redirected_thisInvocation_named_generic() async {
- await super.test_constructor_redirected_thisInvocation_named_generic();
- }
-
- @override
- @failingTest
- test_constructor_redirected_thisInvocation_unnamed() async {
- await super.test_constructor_redirected_thisInvocation_unnamed();
- }
-
- @override
- @failingTest
- test_constructor_redirected_thisInvocation_unnamed_generic() async {
- await super.test_constructor_redirected_thisInvocation_unnamed_generic();
- }
-
- @override
- @failingTest
- test_constructor_withCycles_const() async {
- await super.test_constructor_withCycles_const();
- }
-
- @override
- @failingTest
- test_defaultValue_genericFunction() async {
- await super.test_defaultValue_genericFunction();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass() async {
- await super.test_defaultValue_refersToGenericClass();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_constructor() async {
- await super.test_defaultValue_refersToGenericClass_constructor();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_constructor2() async {
- await super.test_defaultValue_refersToGenericClass_constructor2();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_functionG() async {
- await super.test_defaultValue_refersToGenericClass_functionG();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_methodG() async {
- await super.test_defaultValue_refersToGenericClass_methodG();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_methodG_classG() async {
- await super.test_defaultValue_refersToGenericClass_methodG_classG();
- }
-
- @override
- @failingTest
- test_defaultValue_refersToGenericClass_methodNG() async {
- await super.test_defaultValue_refersToGenericClass_methodNG();
- }
-
- @override
- @failingTest
- test_export_class_type_alias() async {
- await super.test_export_class_type_alias();
- }
-
- @override
- @failingTest
- test_export_configurations_useFirst() async {
- await super.test_export_configurations_useFirst();
- }
-
- @override
- @failingTest
- test_export_configurations_useSecond() async {
- await super.test_export_configurations_useSecond();
- }
-
- @override
- @failingTest
- test_exportImport_configurations_useFirst() async {
- await super.test_exportImport_configurations_useFirst();
- }
-
- @override
- @failingTest
- test_field_formal_param_inferred_type_implicit() async {
- await super.test_field_formal_param_inferred_type_implicit();
- }
-
- @override
- @failingTest
- test_field_inferred_type_nonStatic_implicit_uninitialized() async {
- await super.test_field_inferred_type_nonStatic_implicit_uninitialized();
- }
-
- @override
- @failingTest
- test_field_propagatedType_final_dep_inLib() async {
- await super.test_field_propagatedType_final_dep_inLib();
- }
-
- @override
- @failingTest
- test_field_propagatedType_final_dep_inPart() async {
- await super.test_field_propagatedType_final_dep_inPart();
- }
-
- @override
- @failingTest
- test_futureOr_inferred() async {
- await super.test_futureOr_inferred();
- }
-
- @override
- @failingTest
- test_getter_inferred_type_nonStatic_implicit_return() async {
- await super.test_getter_inferred_type_nonStatic_implicit_return();
- }
-
- @override
- @failingTest
- test_implicitConstructor_named_const() async {
- await super.test_implicitConstructor_named_const();
- }
-
- @override
- @failingTest
- test_import_configurations_useFirst() async {
- await super.test_import_configurations_useFirst();
- }
-
- @override
- @failingTest
- test_import_invalidUri_metadata() async {
- await super.test_import_invalidUri_metadata();
- }
-
- @override
- @failingTest
- test_import_short_absolute() async {
- // TODO(scheglov) fails on Windows
- fail('test_import_short_absolute on Windows');
-// await super.test_import_short_absolute();
- }
-
- @override
- @failingTest
- test_infer_generic_typedef_complex() async {
- await super.test_infer_generic_typedef_complex();
- }
-
- @override
- @failingTest
- test_infer_generic_typedef_simple() async {
- await super.test_infer_generic_typedef_simple();
- }
-
- @override
- @failingTest
- test_inference_issue_32394() async {
- await super.test_inference_issue_32394();
- }
-
- @override
- @failingTest
- test_inference_map() async {
- await super.test_inference_map();
- }
-
- @override
- @failingTest
- test_inferred_type_is_typedef() async {
- await super.test_inferred_type_is_typedef();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_bound_type_param() async {
- await super.test_inferred_type_refers_to_bound_type_param();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_function_typed_param_of_typedef() async {
- await super.test_inferred_type_refers_to_function_typed_param_of_typedef();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async {
- await super
- .test_inferred_type_refers_to_function_typed_parameter_type_generic_class();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_function_typed_parameter_type_other_lib() async {
- await super
- .test_inferred_type_refers_to_function_typed_parameter_type_other_lib();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_method_function_typed_parameter_type() async {
- await super
- .test_inferred_type_refers_to_method_function_typed_parameter_type();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_nested_function_typed_param() async {
- await super.test_inferred_type_refers_to_nested_function_typed_param();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_nested_function_typed_param_named() async {
- await super
- .test_inferred_type_refers_to_nested_function_typed_param_named();
- }
-
- @override
- @failingTest
- test_inferred_type_refers_to_setter_function_typed_parameter_type() async {
- await super
- .test_inferred_type_refers_to_setter_function_typed_parameter_type();
- }
-
- @override
- @failingTest
- test_inferredType_definedInSdkLibraryPart() async {
- await super.test_inferredType_definedInSdkLibraryPart();
- }
-
- @override
- @failingTest
- test_inferredType_implicitCreation() async {
- await super.test_inferredType_implicitCreation();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure() async {
- await super.test_initializer_executable_with_return_type_from_closure();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure_await_dynamic() async {
- await super
- .test_initializer_executable_with_return_type_from_closure_await_dynamic();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure_await_future3_int() async {
- await super
- .test_initializer_executable_with_return_type_from_closure_await_future3_int();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure_await_future_int() async {
- await super
- .test_initializer_executable_with_return_type_from_closure_await_future_int();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure_await_future_noArg() async {
- await super
- .test_initializer_executable_with_return_type_from_closure_await_future_noArg();
- }
-
- @override
- @failingTest
- test_initializer_executable_with_return_type_from_closure_field() async {
- await super
- .test_initializer_executable_with_return_type_from_closure_field();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
- await super.test_instantiateToBounds_boundRefersToEarlierTypeArgument();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_boundRefersToItself() async {
- await super.test_instantiateToBounds_boundRefersToItself();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
- await super.test_instantiateToBounds_boundRefersToLaterTypeArgument();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_functionTypeAlias_reexported() async {
- await super.test_instantiateToBounds_functionTypeAlias_reexported();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_functionTypeAlias_simple() async {
- await super.test_instantiateToBounds_functionTypeAlias_simple();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_simple() async {
- await super.test_instantiateToBounds_simple();
- }
-
- @override
- @failingTest
- test_invalid_nameConflict_imported_exported() async {
- await super.test_invalid_nameConflict_imported_exported();
- }
-
- @override
- @failingTest
- test_invalid_nameConflict_local() async {
- await super.test_invalid_nameConflict_local();
- }
-
- @override
- @failingTest
- test_invalidUri_part_emptyUri() async {
- await super.test_invalidUri_part_emptyUri();
- }
-
- @override
- @failingTest
- test_invalidUris() async {
- await super.test_invalidUris();
- }
-
- @override
- @failingTest
- test_library_documented_lines() async {
- await super.test_library_documented_lines();
- }
-
- @override
- @failingTest
- test_library_documented_stars() async {
- await super.test_library_documented_stars();
- }
-
- @override
- @failingTest
- test_method_inferred_type_nonStatic_implicit_param() async {
- await super.test_method_inferred_type_nonStatic_implicit_param();
- }
-
- @override
- @failingTest
- test_method_inferred_type_nonStatic_implicit_return() async {
- await super.test_method_inferred_type_nonStatic_implicit_return();
- }
-
- @override
- @failingTest
- test_nameConflict_importWithRelativeUri_exportWithAbsolute() async {
- // TODO(scheglov) unexpectedly passes on Windows
- fail('unexpectedly passes on Windows');
-// await super.test_nameConflict_importWithRelativeUri_exportWithAbsolute();
- }
-
- @override
- @failingTest
- test_new_typedef_notSimplyBounded_self() async {
- await super.test_new_typedef_notSimplyBounded_self();
- }
-
- @override
- @failingTest
- test_old_typedef_notSimplyBounded_self() async {
- await super.test_old_typedef_notSimplyBounded_self();
- }
-
- @override
- @failingTest
- test_parameter_covariant() async {
- await super.test_parameter_covariant();
- }
-
- @override
- @failingTest
test_parameter_covariant_inherited() async {
await super.test_parameter_covariant_inherited();
}
@override
@failingTest
- test_parts_invalidUri_nullStringValue() async {
- await super.test_parts_invalidUri_nullStringValue();
- }
-
- @override
- @failingTest
- test_setter_covariant() async {
- await super.test_setter_covariant();
- }
-
- @override
- @failingTest
- test_setter_inferred_type_nonStatic_implicit_param() async {
- await super.test_setter_inferred_type_nonStatic_implicit_param();
- }
-
- @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();
}
- @override
- @failingTest
- test_syntheticFunctionType_inGenericClass() async {
- await super.test_syntheticFunctionType_inGenericClass();
- }
-
- @override
- @failingTest
- test_syntheticFunctionType_noArguments() async {
- await super.test_syntheticFunctionType_noArguments();
- }
-
- @override
- @failingTest
- test_syntheticFunctionType_withArguments() async {
- await super.test_syntheticFunctionType_withArguments();
- }
-
- @override
- @failingTest
- test_type_inference_based_on_loadLibrary() async {
- await super.test_type_inference_based_on_loadLibrary();
- }
-
- @override
- @failingTest
- test_type_inference_closure_with_function_typed_parameter() async {
- await super.test_type_inference_closure_with_function_typed_parameter();
- }
-
- @override
- @failingTest
- test_type_inference_closure_with_function_typed_parameter_new() async {
- await super.test_type_inference_closure_with_function_typed_parameter_new();
- }
-
- @override
- @failingTest
- test_type_inference_depends_on_exported_variable() async {
- await super.test_type_inference_depends_on_exported_variable();
- }
-
- @override
- @failingTest
- test_type_inference_nested_function() async {
- await super.test_type_inference_nested_function();
- }
-
- @override
- @failingTest
- test_type_inference_nested_function_with_parameter_types() async {
- await super.test_type_inference_nested_function_with_parameter_types();
- }
-
- @override
- @failingTest
- test_type_inference_of_closure_with_default_value() async {
- await super.test_type_inference_of_closure_with_default_value();
- }
-
- @override
- @failingTest
- test_typedef_generic() async {
- await super.test_typedef_generic();
- }
-
- @override
- @failingTest
- test_typedef_generic_asFieldType() async {
- await super.test_typedef_generic_asFieldType();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_param_type_old_style();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_return_type_new_style();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_return_type_old_style();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_bound() async {
- await super.test_typedef_type_parameters_bound();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_bound_recursive() async {
- await super.test_typedef_type_parameters_bound_recursive();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_bound_recursive2() async {
- await super.test_typedef_type_parameters_bound_recursive2();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_f_bound_complex() async {
- await super.test_typedef_type_parameters_f_bound_complex();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_f_bound_simple() async {
- await super.test_typedef_type_parameters_f_bound_simple();
- }
-
- @override
- @failingTest
- test_typedef_type_parameters_f_bound_simple_new_syntax() async {
- await super.test_typedef_type_parameters_f_bound_simple_new_syntax();
- }
-
- @override
- @failingTest
- test_unresolved_annotation_instanceCreation_argument_super() async {
- await super.test_unresolved_annotation_instanceCreation_argument_super();
- }
-
- @override
- @failingTest
- test_unresolved_export() async {
- await super.test_unresolved_export();
- }
-
- @override
- @failingTest
- test_unresolved_import() async {
- await super.test_unresolved_import();
- }
-
- @override
- @failingTest
- test_unused_type_parameter() async {
- await super.test_unused_type_parameter();
- }
-
- @override
- @failingTest
- test_variable_propagatedType_final_dep_inLib() async {
- await super.test_variable_propagatedType_final_dep_inLib();
- }
-
- @override
- @failingTest
- test_variable_propagatedType_final_dep_inPart() async {
- await super.test_variable_propagatedType_final_dep_inPart();
- }
-
- LinkResult _link(Map<Source, String> codeMap) {
- // TODO(scheglov) support for parts
- var libraryUnitMap = <Source, Map<Source, CompilationUnit>>{};
- for (var source in codeMap.keys) {
- var code = codeMap[source];
- var unit = parseText(code, experimentStatus: experimentStatus);
- libraryUnitMap[source] = {source: unit};
- }
-
- return link(
- AnalysisOptionsImpl(),
- sourceFactory,
- [],
- libraryUnitMap,
+ void _addLibraryUnits(
+ Source definingSource,
+ CompilationUnit definingUnit,
+ List<LinkInputUnit> units,
+ ) {
+ units.add(
+ LinkInputUnit(definingSource, definingUnit),
);
- }
-
- Map<Source, CompilationUnit> _unitsOfLibrary(
- Source definingSource, CompilationUnit definingUnit) {
- var result = <Source, CompilationUnit>{
- definingSource: definingUnit,
- };
for (var directive in definingUnit.directives) {
if (directive is PartDirective) {
var relativeUriStr = directive.uri.stringValue;
@@ -1131,19 +147,65 @@
relativeUriStr,
);
- String text;
- try {
- var partFile = resourceProvider.getFile(partSource.fullName);
- text = partFile.readAsStringSync();
- } catch (_) {
- text = '';
+ if (partSource != null) {
+ var text = _readSafely(partSource.fullName);
+ var unit = parseText(text, experimentStatus: experimentStatus);
+ units.add(
+ LinkInputUnit(partSource, unit),
+ );
+ } else {
+ var unit = parseText('', experimentStatus: experimentStatus);
+ units.add(
+ LinkInputUnit(partSource, unit),
+ );
}
-
- var partUnit = parseText(text, experimentStatus: experimentStatus);
- result[partSource] = partUnit;
}
}
- return result;
+ }
+
+ void _addNonDartLibraries(
+ Set<Source> addedLibraries,
+ List<LinkInputLibrary> libraries,
+ Source source,
+ ) {
+ if (source == null ||
+ source.uri.isScheme('dart') ||
+ !addedLibraries.add(source)) {
+ return;
+ }
+
+ var text = _readSafely(source.fullName);
+ var unit = parseText(text, experimentStatus: experimentStatus);
+
+ var units = <LinkInputUnit>[];
+ _addLibraryUnits(source, unit, units);
+ libraries.add(
+ LinkInputLibrary(source, units),
+ );
+
+ void addRelativeUriStr(StringLiteral uriNode) {
+ var uriStr = uriNode.stringValue;
+ var uriSource = sourceFactory.resolveUri(source, uriStr);
+ _addNonDartLibraries(addedLibraries, libraries, uriSource);
+ }
+
+ for (var directive in unit.directives) {
+ if (directive is NamespaceDirective) {
+ addRelativeUriStr(directive.uri);
+ for (var configuration in directive.configurations) {
+ addRelativeUriStr(configuration.uri);
+ }
+ }
+ }
+ }
+
+ String _readSafely(String path) {
+ try {
+ var file = resourceProvider.getFile(path);
+ return file.readAsStringSync();
+ } catch (_) {
+ return '';
+ }
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 40b6c41..70ecb30 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -46,6 +46,12 @@
@override
@failingTest
+ test_infer_generic_typedef_complex() async {
+ await super.test_infer_generic_typedef_complex();
+ }
+
+ @override
+ @failingTest
test_syntheticFunctionType_inGenericClass() async {
await super.test_syntheticFunctionType_inGenericClass();
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 77b78c1..b049e24 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -17,7 +17,6 @@
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../util/element_type_matchers.dart';
import 'element_text.dart';
@@ -1359,12 +1358,21 @@
typedef F(G value);
typedef G(F value);
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function(((dynamic) → dynamic) → dynamic value);
+notSimplyBounded typedef G = dynamic Function(((dynamic) → dynamic) → dynamic value);
+notSimplyBounded class C<T extends ((dynamic) → dynamic) → dynamic> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(((...) → dynamic) → dynamic value);
notSimplyBounded typedef G = dynamic Function(((...) → dynamic) → dynamic value);
notSimplyBounded class C<T extends ((...) → dynamic) → dynamic> {
}
''');
+ }
}
test_class_notSimplyBounded_self() async {
@@ -3868,11 +3876,21 @@
typedef int F(String id);
const v = const <F>[];
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+typedef F = int Function(String id);
+const List<(String) → int> v = const <
+ F/*location: test.dart;F*/>[];
+''');
+ } else {
+ // This is wrong.
+ // `F` must be the reference to `typedef F` element, not the type.
+ checkElementText(library, r'''
typedef F = int Function(String id);
const List<(String) → int> v = const <
null/*location: test.dart;F;-*/>[];
''');
+ }
}
test_const_topLevel_typedMap() async {
@@ -3988,7 +4006,16 @@
static const b = null;
}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+class C {
+ static const dynamic a =
+ b/*location: test.dart;C;b?*/;
+ static const dynamic b = null;
+}
+''');
+ } else {
+ checkElementText(library, r'''
class C {
static const dynamic a =
C/*location: test.dart;C*/.
@@ -3996,6 +4023,7 @@
static const dynamic b = null;
}
''');
+ }
}
test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
@@ -4589,6 +4617,38 @@
test_constructor_redirected_thisInvocation_named() async {
var library = await checkLibrary('''
class C {
+ const C.named();
+ const C() : this.named();
+}
+''');
+ checkElementText(library, r'''
+class C {
+ const C.named();
+ const C() = C.named : this.
+ named/*location: test.dart;C;named*/();
+}
+''');
+ }
+
+ test_constructor_redirected_thisInvocation_named_generic() async {
+ var library = await checkLibrary('''
+class C<T> {
+ const C.named();
+ const C() : this.named();
+}
+''');
+ checkElementText(library, r'''
+class C<T> {
+ const C.named();
+ const C() = C<T>.named : this.
+ named/*location: test.dart;C;named*/();
+}
+''');
+ }
+
+ test_constructor_redirected_thisInvocation_named_notConst() async {
+ var library = await checkLibrary('''
+class C {
C.named();
C() : this.named();
}
@@ -4597,8 +4657,7 @@
checkElementText(library, r'''
class C {
C.named();
- C() = C.named : this.
- named/*location: test.dart;C;named*/();
+ C();
}
''');
} else {
@@ -4611,32 +4670,37 @@
}
}
- test_constructor_redirected_thisInvocation_named_generic() async {
+ test_constructor_redirected_thisInvocation_unnamed() async {
var library = await checkLibrary('''
-class C<T> {
- C.named();
- C() : this.named();
+class C {
+ const C();
+ const C.named() : this();
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
-class C<T> {
- C.named();
- C() = C<T>.named : this.
- named/*location: test.dart;C;named*/();
+ checkElementText(library, r'''
+class C {
+ const C();
+ const C.named() = C : this();
}
''');
- } else {
- checkElementText(library, r'''
-class C<T> {
- C.named();
- C() = C<T>.named;
-}
-''');
- }
}
- test_constructor_redirected_thisInvocation_unnamed() async {
+ test_constructor_redirected_thisInvocation_unnamed_generic() async {
+ var library = await checkLibrary('''
+class C<T> {
+ const C();
+ const C.named() : this();
+}
+''');
+ checkElementText(library, r'''
+class C<T> {
+ const C();
+ const C.named() = C<T> : this();
+}
+''');
+ }
+
+ test_constructor_redirected_thisInvocation_unnamed_notConst() async {
var library = await checkLibrary('''
class C {
C();
@@ -4647,7 +4711,7 @@
checkElementText(library, r'''
class C {
C();
- C.named() = C : this();
+ C.named();
}
''');
} else {
@@ -4660,30 +4724,6 @@
}
}
- test_constructor_redirected_thisInvocation_unnamed_generic() async {
- var library = await checkLibrary('''
-class C<T> {
- C();
- C.named() : this();
-}
-''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
-class C<T> {
- C();
- C.named() = C<T> : this();
-}
-''');
- } else {
- checkElementText(library, r'''
-class C<T> {
- C();
- C.named() = C<T>;
-}
-''');
- }
- }
-
test_constructor_withCycles_const() async {
var library = await checkLibrary('''
class C {
@@ -6002,9 +6042,7 @@
''');
}
- @failingTest
test_implicitConstructor_named_const() async {
- // TODO(paulberry, scheglov): get this to pass
var library = await checkLibrary('''
class C {
final Object x;
@@ -6012,7 +6050,27 @@
}
const x = C.named(42);
''');
- checkElementText(library, 'TODO(paulberry, scheglov)');
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+class C {
+ final Object x;
+ const C.named(Object this.x);
+}
+const C x =
+ C/*location: test.dart;C*/.
+ named/*location: test.dart;C;named*/(42);
+''');
+ } else {
+ checkElementText(library, r'''
+class C {
+ final Object x;
+ const C.named(Object this.x);
+}
+const C x = const
+ C/*location: test.dart;C*/.
+ named/*location: test.dart;C;named*/(42);
+''');
+ }
}
test_implicitTopLevelVariable_getterFirst() async {
@@ -6221,9 +6279,7 @@
''');
}
- @failingTest
- void test_infer_generic_typedef_complex() async {
- // TODO(paulberry, scheglov): get this test to pass.
+ test_infer_generic_typedef_complex() async {
var library = await checkLibrary('''
typedef F<T> = D<T,U> Function<U>();
class C<V> {
@@ -6233,10 +6289,21 @@
D<int,U> f<U>() => null;
const x = const C(f);
''');
- checkElementText(library, '''TODO(paulberry, scheglov)''');
+ checkElementText(library, '''
+typedef F<T> = D<T, U> Function<U>();
+class C<V> {
+ const C(<U>() → D<V, U> f);
+}
+class D<T, U> {
+}
+const C<int> x = const
+ C/*location: test.dart;C*/(
+ f/*location: test.dart;f*/);
+D<int, U> f<U>() {}
+''');
}
- void test_infer_generic_typedef_simple() async {
+ test_infer_generic_typedef_simple() async {
var library = await checkLibrary('''
typedef F = D<T> Function<T>();
class C {
@@ -6316,7 +6383,7 @@
}
test_inference_issue_32394() async {
- // Test the type inference involed in dartbug.com/32394
+ // Test the type inference involved in dartbug.com/32394
var library = await checkLibrary('''
var x = y.map((a) => a.toString());
var y = [3];
@@ -6452,6 +6519,30 @@
''');
}
+ test_inferred_type_initializer_cycle() async {
+ var library = await checkLibrary(r'''
+var a = b + 1;
+var b = c + 2;
+var c = a + 3;
+var d = 4;
+''');
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+dynamic a;
+dynamic b;
+dynamic c;
+int d;
+''');
+ } else {
+ checkElementText(library, r'''
+dynamic a/*error: dependencyCycle*/;
+dynamic b/*error: dependencyCycle*/;
+dynamic c/*error: dependencyCycle*/;
+int d;
+''');
+ }
+ }
+
test_inferred_type_is_typedef() async {
var library = await checkLibrary('typedef int F(String s);'
' class C extends D { var v; }'
@@ -6650,19 +6741,11 @@
var a1 = foo.A();
var a2 = foo.A.named();
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
-import 'foo.dart' as foo;
-dynamic a1;
-dynamic a2;
-''');
- } else {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'foo.dart' as foo;
A a1;
A a2;
''');
- }
}
test_inferredType_usesSyntheticFunctionType_functionTypedParam() async {
@@ -9232,11 +9315,19 @@
typedef F = void Function(C c);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
@@ -9246,11 +9337,19 @@
typedef F = void Function(C);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> );
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> );
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
@@ -9260,11 +9359,19 @@
typedef void F(C c);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
@@ -9274,11 +9381,19 @@
typedef F = C Function();
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = C<dynamic> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = C<C<dynamic>> Function();
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
@@ -9288,11 +9403,19 @@
typedef C F();
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = C<dynamic> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = C<C<dynamic>> Function();
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_parameter_parameters() async {
@@ -9400,9 +9523,15 @@
test_typedef_type_parameters_bound_recursive2() async {
var library = await checkLibrary('typedef void F<T extends List<F>>();');
// Typedefs cannot reference themselves.
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F<T extends List<dynamic>> = void Function();
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F<T extends List<() → void>> = void Function();
''');
+ }
}
test_typedef_type_parameters_f_bound_complex() async {
@@ -9435,9 +9564,7 @@
''');
}
- @failingTest
test_unresolved_annotation_instanceCreation_argument_super() async {
- // TODO(scheglov) fix https://github.com/dart-lang/sdk/issues/28553
var library = await checkLibrary('''
class A {
const A(_);
@@ -9448,11 +9575,11 @@
''', allowErrors: true);
checkElementText(library, r'''
class A {
- A(_);
+ const A(dynamic _);
}
-
+@
+ A/*location: test.dart;A*/(super)
class C {
- synthetic C();
}
''');
}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 5aef022..11182d9 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -11,12 +11,14 @@
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/manifest/manifest_warning_code.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
@@ -234,6 +236,11 @@
removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD);
} else if (errorType == TodoCode) {
declaredNames.remove('TODO_REGEX');
+ } else if (errorType == ParserErrorCode) {
+ declaredNames.remove('CONST_AFTER_FACTORY');
+ } else if (errorType == ManifestWarningCode) {
+ declaredNames.remove('NON_RESIZABLE_ACTIVITY');
+ declaredNames.remove('SETTING_ORIENTATION_ON_ACTIVITY');
}
// Assert that all remaining declared names are in errorCodeValues
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 49432eb..f247d09 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3649,6 +3649,70 @@
''');
}
+ test_strictInference_collectionLiterals() async {
+ addFile(r'''
+main() {
+ var emptyList = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
+ var emptyMap = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{};
+
+ var upwardsInfersDynamicList = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[42 as dynamic];
+ var upwardsInfersDynamicSet = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{42 as dynamic};
+
+
+ dynamic d;
+ var upwardsInfersDynamicMap1 = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{d: 2};
+ var upwardsInfersDynamicMap2 = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{4: d};
+ var upwardsInfersDynamicMap3 = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{d: d};
+}
+ ''');
+ await check(strictInference: true);
+ }
+
+ test_strictInference_instanceCreation() async {
+ addFile(r'''
+class C<T> {
+ C([T t]);
+ C.of(T t);
+ factory C.from(Object e) => C();
+}
+
+main() {
+ // These should be allowed:
+ C<int> downwardsInferenceIsOK = C();
+ C<dynamic> downwardsInferenceDynamicIsOK = C();
+ var inferredFromConstructorParameterIsOK = C(42);
+ var explicitDynamicIsOK = C<dynamic>(42);
+
+ var rawConstructorCall = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C();
+ var upwardsInfersDynamic = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C(42 as dynamic);
+ var namedConstructor = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C.of(42 as dynamic);
+ var factoryConstructor = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C.from(42);
+}
+ ''');
+ await check(strictInference: true);
+ }
+
+ test_strictInference_instanceCreation_optionalTypeArgs() async {
+ addMetaPackage();
+ addFile(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {
+ C([T t]);
+ C.of(T t);
+ factory C.from(Object e) => C();
+}
+
+main() {
+ var rawConstructorCall = C();
+ var upwardsInfersDynamic = C(42 as dynamic);
+ var namedConstructor = C.of(42 as dynamic);
+ var factoryConstructor = C.from(42);
+}
+ ''');
+ await check(strictInference: true);
+ }
+
test_strictRawTypes_classes() async {
addFile(r'''
class C<T> {
@@ -3679,20 +3743,10 @@
main() {
{
- // These should be allowed:
- C<int> downwardsInferenceIsOK = C();
- C<dynamic> downwardsInferenceDynamicIsOK = C();
- var inferredFromConstructorParameterIsOK = C(42);
- var explicitDynamicIsOK = C<dynamic>(42);
-
ClassWithNumBound classWithNumBoundOK;
ClassWithObjectBound classWithObjectBoundOK;
/*info:STRICT_RAW_TYPE*/ClassWithDynamicBound classWithDynamicBound;
-
- var rawConstructorCall = /*info:STRICT_RAW_TYPE*/C();
/*info:STRICT_RAW_TYPE*/C rawConstructorCallFromType = C();
-
- var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/C(42 as dynamic);
}
{
@@ -3702,11 +3756,8 @@
var upwardsInferNonDynamicIsOK = [42];
var explicitDynamicIsOK = <dynamic>[42];
- var rawList = /*info:STRICT_RAW_TYPE*/[];
var rawListOfLists = </*info:STRICT_RAW_TYPE*/List>[];
/*info:STRICT_RAW_TYPE*/List rawListFromType = [];
-
- var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/[42 as dynamic];
}
{
@@ -3716,11 +3767,8 @@
var upwardsInferNonDynamicIsOK = [42];
var explicitDynamicIsOK = <dynamic>[42];
- var rawList = /*info:STRICT_RAW_TYPE*/[];
var rawListOfLists = </*info:STRICT_RAW_TYPE*/List>[];
/*info:STRICT_RAW_TYPE*/List rawListFromType = [];
-
- var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/[42 as dynamic];
}
{
@@ -3732,8 +3780,6 @@
var rawSetOfSets = </*info:STRICT_RAW_TYPE*/Set>{};
/*info:STRICT_RAW_TYPE*/Set rawSetFromType = {};
-
- var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/{42 as dynamic};
}
{
@@ -3748,11 +3794,6 @@
var rawMapOfMaps = </*info:STRICT_RAW_TYPE*/Map>{};
/*info:STRICT_RAW_TYPE*/Map rawMapFromType = {};
-
- dynamic d;
- var upwardsInfersDynamic1 = /*info:STRICT_RAW_TYPE*/{d: 2};
- var upwardsInfersDynamic2 = /*info:STRICT_RAW_TYPE*/{4: d};
- var upwardsInfersDynamic3 = /*info:STRICT_RAW_TYPE*/{d: d};
}
{
@@ -3815,15 +3856,6 @@
await check(strictRawTypes: true);
}
- test_strictRawTypes_emptyMap() async {
- addFile('''
-main() {
- var rawMap = /*info:STRICT_RAW_TYPE*/{};
-}
-''');
- await check(strictRawTypes: true);
- }
-
test_strictRawTypes_typedefs() async {
addFile(r'''
typedef T F1<T>(T _);
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 7ea6be3..03726eb 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -281,6 +280,7 @@
Future<CompilationUnit> check(
{bool implicitCasts: true,
bool implicitDynamic: true,
+ bool strictInference: false,
bool strictRawTypes: false}) async {
_checkCalled = true;
@@ -291,6 +291,7 @@
analysisOptions.strongModeHints = true;
analysisOptions.implicitCasts = implicitCasts;
analysisOptions.implicitDynamic = implicitDynamic;
+ analysisOptions.strictInference = strictInference;
analysisOptions.strictRawTypes = strictRawTypes;
analysisOptions.enabledExperiments = enabledExperiments;
@@ -331,9 +332,12 @@
code == TodoCode.TODO) {
return false;
}
- if (strictRawTypes) {
- // When testing strict-raw-types, ignore anything else.
+ if (strictInference || strictRawTypes) {
+ // When testing strict-inference or strict-raw-types, ignore anything
+ // else.
return code.errorSeverity.ordinal > ErrorSeverity.INFO.ordinal ||
+ code == HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL ||
+ code == HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION ||
code == HintCode.STRICT_RAW_TYPE;
}
return true;
@@ -344,6 +348,7 @@
LibraryElement mainLibrary =
resolutionMap.elementDeclaredByCompilationUnit(mainUnit).library;
Set<LibraryElement> allLibraries = _reachableLibraries(mainLibrary);
+
for (LibraryElement library in allLibraries) {
for (CompilationUnitElement unit in library.units) {
var source = unit.source;
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index ca4002a..b2e0dfb 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -312,18 +312,21 @@
}
}
+ ErrorSeverity severity;
+ if (options.buildSummaryOnly) {
+ severity = ErrorSeverity.NONE;
+ } else {
+ // Process errors.
+ await _printErrors(outputPath: options.buildAnalysisOutput);
+ severity = await _computeMaxSeverity();
+ }
+
if (dependencyTracker != null) {
io.File file = new io.File(dependencyTracker.outputPath);
file.writeAsStringSync(dependencyTracker.dependencies.join('\n'));
}
- if (options.buildSummaryOnly) {
- return ErrorSeverity.NONE;
- } else {
- // Process errors.
- await _printErrors(outputPath: options.buildAnalysisOutput);
- return await _computeMaxSeverity();
- }
+ return severity;
});
}
@@ -446,7 +449,9 @@
var sourceFactory = new SourceFactory(<UriResolver>[
new DartUriResolver(sdk),
- new InSummaryUriResolver(resourceProvider, summaryDataStore),
+ new TrackingInSummaryUriResolver(
+ new InSummaryUriResolver(resourceProvider, summaryDataStore),
+ dependencyTracker),
new ExplicitSourceResolver(uriToFileMap)
]);
@@ -739,3 +744,26 @@
return cache.get(inputs, path);
}
}
+
+/**
+ * Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
+ */
+class TrackingInSummaryUriResolver extends UriResolver {
+ // May be null.
+ final DependencyTracker dependencyTracker;
+ final InSummaryUriResolver inSummaryUriResolver;
+
+ TrackingInSummaryUriResolver(
+ this.inSummaryUriResolver, this.dependencyTracker);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ var source = inSummaryUriResolver.resolveAbsolute(uri, actualUri);
+ if (dependencyTracker != null &&
+ source != null &&
+ source is InSummarySource) {
+ dependencyTracker.record(source.summaryPath);
+ }
+ return source;
+ }
+}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 7e910dc..bd54543 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -24,6 +24,7 @@
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/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/path_filter.dart';
@@ -378,6 +379,25 @@
} catch (exception) {
// If the file cannot be analyzed, ignore it.
}
+ } else if (shortName == AnalysisEngine.ANDROID_MANIFEST_FILE) {
+ try {
+ File file = resourceProvider.getFile(path);
+ String content = file.readAsStringSync();
+ ManifestValidator validator =
+ new ManifestValidator(file.createSource());
+ LineInfo lineInfo = new LineInfo.fromContent(content);
+ List<AnalysisError> errors = validator.validate(
+ content, analysisDriver.analysisOptions.chromeOsManifestChecks);
+ formatter
+ .formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+ for (AnalysisError error in errors) {
+ ErrorSeverity severity = determineProcessedSeverity(
+ error, options, analysisDriver.analysisOptions);
+ allResult = allResult.max(severity);
+ }
+ } catch (exception) {
+ // If the file cannot be analyzed, ignore it.
+ }
} else {
dartFiles.add(path);
var file = analysisDriver.fsState.getFileForPath(path);
@@ -544,7 +564,8 @@
for (io.FileSystemEntity entry
in directory.listSync(recursive: true, followLinks: false)) {
String relative = path.relative(entry.path, from: directory.path);
- if (AnalysisEngine.isDartFileName(entry.path) &&
+ if ((AnalysisEngine.isDartFileName(entry.path) ||
+ AnalysisEngine.isManifestFileName(entry.path)) &&
entry is io.File &&
!pathFilter.ignored(entry.path) &&
!_isInHiddenDir(relative)) {
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index aa44888..385f323 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -806,6 +806,32 @@
expect(exitCode, 0);
});
}
+
+ test_manifestFileChecks() async {
+ await withTempDirAsync((tempDir) async {
+ String filePath =
+ path.join(tempDir, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ new File(filePath).writeAsStringSync('''
+analyzer:
+ optional-checks:
+ chrome-os-manifest-checks: true
+''');
+ String manifestPath =
+ path.join(tempDir, AnalysisEngine.ANDROID_MANIFEST_FILE);
+ new File(manifestPath).writeAsStringSync('''
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-feature android:name="android.software.home_screen" />
+</manifest>
+''');
+ await drive(manifestPath, options: filePath);
+ expect(
+ bulletToDash(outSink),
+ contains(
+ "warning - This hardware feature is not supported on Chrome OS"));
+ expect(exitCode, 0);
+ });
+ }
}
@reflectiveTest
diff --git a/pkg/build_integration/lib/file_system/multi_root.dart b/pkg/build_integration/lib/file_system/multi_root.dart
index ed1bb8c..b5edb1b 100644
--- a/pkg/build_integration/lib/file_system/multi_root.dart
+++ b/pkg/build_integration/lib/file_system/multi_root.dart
@@ -52,7 +52,11 @@
_delegate ??= await _resolveEntity();
Future<FileSystemEntity> _resolveEntity() async {
- if (uri.scheme == multiRootFileSystem.markerScheme && uri.isAbsolute) {
+ if (uri.scheme == multiRootFileSystem.markerScheme) {
+ if (!uri.isAbsolute) {
+ throw new FileSystemException(
+ uri, "This MultiRootFileSystem only handles absolutes URIs: $uri");
+ }
var original = multiRootFileSystem.original;
assert(uri.path.startsWith('/'));
var path = uri.path.substring(1);
@@ -60,6 +64,7 @@
var candidate = original.entityForUri(root.resolve(path));
if (await candidate.exists()) return candidate;
}
+ return MissingFileSystemEntity(uri);
}
return multiRootFileSystem.original.entityForUri(uri);
}
@@ -76,6 +81,24 @@
Future<String> readAsString() async => (await delegate).readAsString();
}
+class MissingFileSystemEntity implements FileSystemEntity {
+ @override
+ final Uri uri;
+
+ MissingFileSystemEntity(this.uri);
+
+ @override
+ Future<bool> exists() => Future.value(false);
+
+ @override
+ Future<List<int>> readAsBytes() =>
+ Future.error(FileSystemException(uri, 'File not found'));
+
+ @override
+ Future<String> readAsString() =>
+ Future.error(FileSystemException(uri, 'File not found'));
+}
+
Uri _normalize(root) {
Uri uri = root;
return uri.path.endsWith('/') ? uri : uri.replace(path: '${uri.path}/');
diff --git a/pkg/build_integration/pubspec.yaml b/pkg/build_integration/pubspec.yaml
index b746b5c..722a284 100644
--- a/pkg/build_integration/pubspec.yaml
+++ b/pkg/build_integration/pubspec.yaml
@@ -10,3 +10,6 @@
dependencies:
front_end: ^0.1.0
+
+dev_dependencies:
+ test: any
diff --git a/pkg/build_integration/test/file_system/multi_root_test.dart b/pkg/build_integration/test/file_system/multi_root_test.dart
index e86fc3f..e92249a 100644
--- a/pkg/build_integration/test/file_system/multi_root_test.dart
+++ b/pkg/build_integration/test/file_system/multi_root_test.dart
@@ -8,6 +8,7 @@
import 'package:build_integration/file_system/multi_root.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
+import 'package:front_end/src/api_prototype/file_system.dart';
import 'package:test/test.dart';
@@ -122,4 +123,17 @@
expect(await effectiveUriOf('multi-root:///../../A/B/a/8.dart'),
'multi-root:///A/B/a/8.dart');
});
+
+ test('multi-root handles all multi-root scheme uris, even if missing',
+ () async {
+ expect(await effectiveUriOf('multi-root:///doesnt/exist.dart'),
+ 'multi-root:///doesnt/exist.dart');
+ expect(await exists('multi-root:///doesnt/exist.dart'), isFalse);
+ expect(
+ read('multi-root:///doesnt/exist.dart'),
+ throwsA(const TypeMatcher<FileSystemException>()
+ .having((e) => e.message, 'message', 'File not found')
+ .having((e) => e.uri, 'uri',
+ equals(Uri.parse('multi-root:///doesnt/exist.dart')))));
+ });
}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 82b1fe8..576cfc4 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -41,6 +41,8 @@
static const String experimentCallInstrumentation =
'--experiment-call-instrumentation';
+ static const String experimentNewRti = '--experiment-new-rti';
+
static const String enableLanguageExperiments = '--enable-experiment';
static const String fastStartup = '--fast-startup';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 85abe2a..c829eaa 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -431,6 +431,7 @@
new OptionHandler(Flags.experimentStartupFunctions, passThrough),
new OptionHandler(Flags.experimentToBoolean, passThrough),
new OptionHandler(Flags.experimentCallInstrumentation, passThrough),
+ new OptionHandler(Flags.experimentNewRti, passThrough),
// The following three options must come last.
new OptionHandler('-D.+=.*', addInEnvironment),
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 7cb0278..f91b15b 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -314,6 +314,9 @@
/// called.
bool experimentCallInstrumentation = false;
+ /// Experimental use of the new (Q2 2019) RTI system.
+ bool experimentNewRti = false;
+
/// The path to the file that contains the profiled allocations.
///
/// The file must contain the Map that was produced by using
@@ -381,6 +384,7 @@
..experimentToBoolean = _hasOption(options, Flags.experimentToBoolean)
..experimentCallInstrumentation =
_hasOption(options, Flags.experimentCallInstrumentation)
+ ..experimentNewRti = _hasOption(options, Flags.experimentNewRti)
..generateCodeWithCompileTimeErrors =
_hasOption(options, Flags.generateCodeWithCompileTimeErrors)
..generateSourceMap = !_hasOption(options, Flags.noSourceMaps)
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index d8f8ff5..7070b01 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1525,15 +1525,18 @@
@override
void visitConstantExpression(ir.ConstantExpression node) {
ConstantValue value = _elementMap.getConstantValue(node);
+ SourceInformation sourceInformation =
+ _sourceInformationBuilder.buildGet(node);
if (!closedWorld.outputUnitData
.hasOnlyNonDeferredImportPathsToConstant(targetElement, value)) {
stack.add(graph.addDeferredConstant(
value,
closedWorld.outputUnitData.outputUnitForConstant(value),
- _sourceInformationBuilder.buildGet(node),
+ sourceInformation,
closedWorld));
} else {
- stack.add(graph.addConstant(value, closedWorld));
+ stack.add(graph.addConstant(value, closedWorld,
+ sourceInformation: sourceInformation));
}
}
@@ -3114,7 +3117,10 @@
sourceInformation));
}
} else {
- MemberEntity member = _elementMap.getMember(staticTarget);
+ // TODO(johnniwinther): This is a constant tear off, so we should have
+ // created a constant value instead. Remove this case when we use CFE
+ // constants.
+ FunctionEntity member = _elementMap.getMember(staticTarget);
push(new HStatic(member, _typeInferenceMap.getInferredTypeOf(member),
sourceInformation));
}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index fe5bbfd..c6e5a6d 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3077,8 +3077,12 @@
accept(HVisitor visitor) => visitor.visitThrow(this);
}
+// TODO(johnniwinther): Change this to a "HStaticLoad" of a field when we use
+// CFE constants. It has been used for static tear-offs even though these should
+// have been constants.
class HStatic extends HInstruction {
final MemberEntity element;
+
HStatic(this.element, AbstractValue type, SourceInformation sourceInformation)
: super(<HInstruction>[], type) {
assert(element != null);
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index fbe7114..1075043 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -56,6 +56,18 @@
ZoneSpecification(print: (self, parent, zone, message) {
output.writeln(message.toString());
}));
+
+ if (lastResult.crashed && context != null) {
+ // TODO(vsm): See https://github.com/dart-lang/sdk/issues/36644.
+ // If the CFE is crashing with previous state, then clear compilation
+ // state and try again.
+ output.clear();
+ lastResult = await runZoned(() => compile(args, previousResult: null),
+ zoneSpecification:
+ ZoneSpecification(print: (self, parent, zone, message) {
+ output.writeln(message.toString());
+ }));
+ }
return WorkResponse()
..exitCode = lastResult.success ? 0 : 1
..output = output.toString();
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 7a76be5..8591d9c 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -2449,12 +2449,12 @@
if (param.isOptional) {
JS.Expression defaultValue;
- if (paramNode != null) {
+ if (findAnnotation(param, isUndefinedAnnotation) != null) {
+ defaultValue = null;
+ } else if (paramNode != null) {
var paramDefault = (paramNode as DefaultFormalParameter).defaultValue;
if (paramDefault == null) {
defaultValue = JS.LiteralNull();
- } else if (_isJSUndefined(paramDefault)) {
- defaultValue = null;
} else {
defaultValue = _visitExpression(paramDefault);
}
@@ -2513,16 +2513,6 @@
(_classProperties?.covariantParameters?.contains(p) ?? false);
}
- bool _isJSUndefined(Expression expr) {
- expr = expr is AsExpression ? expr.expression : expr;
- if (expr is Identifier) {
- var element = expr.staticElement;
- return isSdkInternalRuntime(element.library) &&
- element.name == 'undefined';
- }
- return false;
- }
-
JS.Fun _emitNativeFunctionBody(MethodDeclaration node) {
String name = getAnnotationName(node.declaredElement, isJSAnnotation) ??
node.name.name;
@@ -4270,10 +4260,6 @@
List<VariableDeclaration> fields) {
var lazyFields = <VariableDeclaration>[];
for (var field in fields) {
- // Skip our magic undefined constant.
- var element = field.declaredElement as TopLevelVariableElement;
- if (element.name == 'undefined') continue;
-
var init = field.initializer;
if (init == null ||
init is Literal ||
diff --git a/pkg/dev_compiler/lib/src/analyzer/js_interop.dart b/pkg/dev_compiler/lib/src/analyzer/js_interop.dart
index 5d51b33..b1a29ae 100644
--- a/pkg/dev_compiler/lib/src/analyzer/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/js_interop.dart
@@ -65,6 +65,9 @@
bool isNullCheckAnnotation(DartObjectImpl value) =>
isBuiltinAnnotation(value, '_js_helper', '_NullCheck');
+bool isUndefinedAnnotation(DartObjectImpl value) =>
+ isBuiltinAnnotation(value, '_js_helper', '_Undefined');
+
/// 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.
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index c72b51a..d9270a2 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -234,33 +234,34 @@
/// Emits a private name JS Symbol for [name] scoped to the Dart [library].
///
/// If the same name is used in multiple libraries in the same module,
- /// distinct symbols will be used, so the names cannot be referenced outside
- /// of their library.
+ /// distinct symbols will be used, so each library will have distinct private
+ /// member names, that won't collide at runtime, as required by the Dart
+ /// language spec.
@protected
JS.TemporaryId emitPrivateNameSymbol(Library library, String name) {
- // TODO(jmesserly): fix this to support referring to private symbols from
- // libraries that aren't in the current module.
- //
- // This is needed for several uses cases:
- // - const instances of classes (which directly initialize fields via an
- // object literal).
- // - noSuchMethod stubs created when an interface is implemented that had
- // private members from another library.
- // - stateful hot reload, where we need the ability to patch private
- // class members.
- //
- // See https://github.com/dart-lang/sdk/issues/36252
- return _privateNames.putIfAbsent(library, () => HashMap()).putIfAbsent(name,
- () {
- var idName = name;
- if (idName.endsWith('=')) {
- idName = idName.replaceAll('=', '_');
- }
+ /// Initializes the JS `Symbol` for the private member [name] in [library].
+ ///
+ /// If the library is in the current JS module ([_libraries] contains it),
+ /// the private name will be created and exported. The exported symbol is
+ /// used for a few things:
+ ///
+ /// - private fields of constant objects
+ /// - stateful hot reload (not yet implemented)
+ /// - correct library scope in REPL (not yet implemented)
+ ///
+ /// If the library is imported, then the existing private name will be
+ /// retrieved from it. In both cases, we use the same `dart.privateName`
+ /// runtime call.
+ JS.TemporaryId initPrivateNameSymbol() {
+ var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
var id = JS.TemporaryId(idName);
- moduleItems.add(
- js.statement('const # = Symbol(#);', [id, js.string(name, "'")]));
+ moduleItems.add(js.statement('const # = #.privateName(#, #)',
+ [id, runtimeModule, emitLibraryName(library), js.string(name)]));
return id;
- });
+ }
+
+ var privateNames = _privateNames.putIfAbsent(library, () => HashMap());
+ return privateNames.putIfAbsent(name, initPrivateNameSymbol);
}
/// Emits an expression to set the property [nameExpr] on the class [className],
@@ -409,6 +410,23 @@
}
items.add(JS.ExportDeclaration(JS.ExportClause(exports)));
+
+ if (isBuildingSdk) {
+ // Initialize the private name function.
+ // To bootstrap the SDK, this needs to be emitted before other code.
+ var symbol = JS.TemporaryId('_privateNames');
+ items.add(js.statement('const # = Symbol("_privateNames")', symbol));
+ items.add(js.statement(r'''
+ #.privateName = function(library, name) {
+ let names = library[#];
+ if (names == null) names = library[#] = new Map();
+ let symbol = names.get(name);
+ if (symbol == null) names.set(name, symbol = Symbol(name));
+ return symbol;
+ }
+ ''', [runtimeModule, symbol, symbol]));
+ }
+
return items;
}
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 596b6e6..e9f2a3a 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -96,7 +96,23 @@
SharedCompilerOptions.addArguments(argParser);
var declaredVariables = parseAndRemoveDeclaredVariables(args);
- var argResults = argParser.parse(filterUnknownArguments(args, argParser));
+ ArgResults argResults;
+ try {
+ argResults = argParser.parse(filterUnknownArguments(args, argParser));
+ } on FormatException catch (error) {
+ print(error);
+ print(_usageMessage(argParser));
+ return CompilerResult(64);
+ }
+
+ var output = argResults['out'] as String;
+ if (output == null) {
+ print('Please specify the output file location. For example:\n'
+ ' -o PATH/TO/OUTPUT_FILE.js'
+ '');
+ print(_usageMessage(argParser));
+ return CompilerResult(64);
+ }
if (argResults['help'] as bool || args.isEmpty) {
print(_usageMessage(argParser));
@@ -230,7 +246,6 @@
List<Uri> inputSummaries = compilerState.options.inputSummaries;
- var output = argResults['out'] as String;
// TODO(jmesserly): is there a cleaner way to do this?
//
// Ideally we'd manage our own batch compilation caching rather than rely on
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 55f5c10..1c88754 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -8,7 +8,7 @@
import 'package:front_end/src/api_unstable/ddc.dart' show TypeSchemaEnvironment;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
-import 'package:kernel/kernel.dart';
+import 'package:kernel/kernel.dart' hide MapEntry;
import 'package:kernel/library_index.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
@@ -1808,7 +1808,7 @@
/// Emits a Dart factory constructor to a JS static method.
JS.Method _emitFactoryConstructor(Procedure node) {
- if (isUnsupportedFactoryConstructor(node)) return null;
+ if (node.isExternal || isUnsupportedFactoryConstructor(node)) return null;
var function = node.function;
@@ -1983,9 +1983,6 @@
var lazyFields = <Field>[];
var savedUri = _currentUri;
for (var field in fields) {
- // Skip our magic undefined constant.
- if (field.name.name == 'undefined') continue;
-
var init = field.initializer;
if (init == null ||
init is BasicLiteral ||
@@ -2954,23 +2951,15 @@
}
JS.Expression _defaultParamValue(VariableDeclaration p) {
- if (p.initializer != null) {
- var value = p.initializer;
- return _isJSUndefined(value) ? null : _visitExpression(value);
+ if (p.annotations.any(isUndefinedAnnotation)) {
+ return null;
+ } else if (p.initializer != null) {
+ return _visitExpression(p.initializer);
} else {
return JS.LiteralNull();
}
}
- bool _isJSUndefined(Expression expr) {
- expr = expr is AsExpression ? expr.operand : expr;
- if (expr is StaticGet) {
- var t = expr.target;
- return isSdkInternalRuntime(getLibrary(t)) && t.name.name == 'undefined';
- }
- return false;
- }
-
void _emitCovarianceBoundsCheck(
List<TypeParameter> typeFormals, List<JS.Statement> body) {
for (var t in typeFormals) {
@@ -3786,15 +3775,11 @@
}
@override
- visitStaticGet(StaticGet node) {
- var target = node.target;
+ visitStaticGet(StaticGet node) => _emitStaticGet(node.target);
+ JS.Expression _emitStaticGet(Member target) {
// TODO(vsm): Re-inline constants. See:
// https://github.com/dart-lang/sdk/issues/36285
-
- // TODO(markzipan): reifyTearOff check can be removed when we enable
- // front-end constant evaluation because static tear-offs will be
- // treated as constants and handled by visitTearOffConstant.
var result = _emitStaticTarget(target);
if (_reifyTearoff(target)) {
// TODO(jmesserly): we could tag static/top-level function types once
@@ -5092,13 +5077,8 @@
isBuiltinAnnotation(a, '_js_helper', 'ReifyFunctionTypes');
while (parent != null) {
var a = findAnnotation(parent, reifyFunctionTypes);
- if (a is ConstructorInvocation) {
- var args = a.arguments.positional;
- if (args.length == 1) {
- var arg = args[0];
- if (arg is BoolLiteral) return arg.value;
- }
- }
+ var value = _constants.getFieldValueFromAnnotation(a, 'value');
+ if (value is bool) return value;
parent = parent.parent;
}
return true;
@@ -5128,7 +5108,8 @@
///
/// Calls [findAnnotation] followed by [getNameFromAnnotation].
String getAnnotationName(NamedNode node, bool test(Expression value)) {
- return _constants.getNameFromAnnotation(findAnnotation(node, test));
+ return _constants.getFieldValueFromAnnotation(
+ findAnnotation(node, test), 'name');
}
JS.Expression visitConstant(Constant node) => node.accept(this);
@@ -5139,7 +5120,23 @@
@override
visitIntConstant(IntConstant node) => js.number(node.value);
@override
- visitDoubleConstant(DoubleConstant node) => js.number(node.value);
+ visitDoubleConstant(DoubleConstant node) {
+ var value = node.value;
+
+ // Emit the constant as an integer, if possible.
+ if (value.isFinite) {
+ var intValue = value.toInt();
+ const int _MIN_INT32 = -0x80000000;
+ const int _MAX_INT32 = 0x7FFFFFFF;
+ if (intValue.toDouble() == value &&
+ intValue >= _MIN_INT32 &&
+ intValue <= _MAX_INT32) {
+ return js.number(intValue);
+ }
+ }
+ return js.number(value);
+ }
+
@override
visitStringConstant(StringConstant node) => js.escapedString(node.value, '"');
@@ -5174,13 +5171,11 @@
@override
visitInstanceConstant(node) {
- entryToProperty(entry) {
- var field = entry.key.asField.name.name;
+ entryToProperty(MapEntry<Reference, Constant> entry) {
var constant = entry.value.accept(this);
var member = entry.key.asField;
- var result =
- JS.Property(_emitMemberName(field, member: member), constant);
- return result;
+ return JS.Property(
+ _emitMemberName(member.name.name, member: member), constant);
}
var type = visitInterfaceType(node.getType(types) as InterfaceType);
@@ -5192,14 +5187,7 @@
}
@override
- visitTearOffConstant(node) {
- var target = node.procedure;
- var result = _emitStaticTarget(target);
- // TODO(jmesserly): we could tag static/top-level function types once
- // in the module initialization, rather than at the point where they
- // escape.
- return _emitFunctionTagged(result, target.function.functionType);
- }
+ visitTearOffConstant(node) => _emitStaticGet(node.procedure);
@override
visitTypeLiteralConstant(node) => _emitTypeLiteral(node.type);
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
index 7f550cb..55885a5 100644
--- a/pkg/dev_compiler/lib/src/kernel/constants.dart
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -41,10 +41,10 @@
return result is UnevaluatedConstant ? null : result;
}
- /// If [node] is an annotation with a field named `name`, returns that field's
+ /// If [node] is an annotation with a field named [name], returns that field's
/// value.
///
- /// This assumes the `name` field is populated from a named argument `name:`
+ /// This assumes the field is populated from a named argument with that name,
/// or from the first positional argument.
///
/// For example:
@@ -59,36 +59,56 @@
/// main() { ... }
///
/// Given the node for `@MyAnnotation('FooBar')` this will return `'FooBar'`.
- String getNameFromAnnotation(ConstructorInvocation node) {
- if (node == null) return null;
+ Object getFieldValueFromAnnotation(Expression node, String name) {
+ node = unwrapUnevaluatedConstant(node);
+ if (node is ConstantExpression) {
+ var constant = node.constant;
+ if (constant is InstanceConstant) {
+ var value = constant.fieldValues.entries
+ .firstWhere((e) => e.key.asField.name.name == name,
+ orElse: () => null)
+ ?.value;
+ if (value is PrimitiveConstant) return value.value;
+ if (value is UnevaluatedConstant) {
+ return _evaluateAnnotationArgument(value.expression);
+ }
+ return null;
+ }
+ }
// TODO(jmesserly): this does not use the normal evaluation engine, because
// it won't work if we don't have the const constructor body available.
//
// We may need to address this in the kernel outline files.
- Expression first;
- var named = node.arguments.named;
- if (named.isNotEmpty) {
- first =
- named.firstWhere((n) => n.name == 'name', orElse: () => null)?.value;
- }
- var positional = node.arguments.positional;
- if (positional.isNotEmpty) first ??= positional[0];
- if (first != null) {
- first = _followConstFields(first);
- if (first is StringLiteral) return first.value;
+ if (node is ConstructorInvocation) {
+ Expression first;
+ var named = node.arguments.named;
+ if (named.isNotEmpty) {
+ first =
+ named.firstWhere((n) => n.name == name, orElse: () => null)?.value;
+ }
+ var positional = node.arguments.positional;
+ if (positional.isNotEmpty) first ??= positional[0];
+ if (first != null) {
+ return _evaluateAnnotationArgument(first);
+ }
}
return null;
}
- Expression _followConstFields(Expression expr) {
- if (expr is StaticGet) {
- var target = expr.target;
+ Object _evaluateAnnotationArgument(Expression node) {
+ node = unwrapUnevaluatedConstant(node);
+ if (node is ConstantExpression) {
+ var constant = node.constant;
+ if (constant is PrimitiveConstant) return constant.value;
+ }
+ if (node is StaticGet) {
+ var target = node.target;
if (target is Field) {
- return _followConstFields(target.initializer);
+ return _evaluateAnnotationArgument(target.initializer);
}
}
- return expr;
+ return node is BasicLiteral ? node.value : null;
}
}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
index 95145f6..6083925 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -17,13 +17,7 @@
}
bool _annotationIsFromJSLibrary(String expectedName, Expression value) {
- Class c;
- if (value is ConstructorInvocation) {
- c = value.target.enclosingClass;
- } else if (value is StaticGet) {
- var type = value.target.getterType;
- if (type is InterfaceType) c = type.classNode;
- }
+ var c = getAnnotationClass(value);
return c != null &&
c.name == expectedName &&
_isJSLibrary(c.enclosingLibrary);
@@ -48,22 +42,10 @@
bool _isJSAnonymousAnnotation(Expression value) =>
_annotationIsFromJSLibrary('_Anonymous', value);
-bool _isBuiltinAnnotation(
- Expression value, String libraryName, String annotationName) {
- if (value is ConstructorInvocation) {
- var c = value.target.enclosingClass;
- if (c.name == annotationName) {
- var uri = c.enclosingLibrary.importUri;
- return uri.scheme == 'dart' && uri.pathSegments[0] == libraryName;
- }
- }
- return false;
-}
-
/// Whether [value] is a `@JSExportName` (internal annotation used in SDK
/// instead of `@JS` from `package:js`).
bool isJSExportNameAnnotation(Expression value) =>
- _isBuiltinAnnotation(value, '_foreign_helper', 'JSExportName');
+ isBuiltinAnnotation(value, '_foreign_helper', 'JSExportName');
/// Whether [i] is a `spread` invocation (to be used on function arguments
/// to have them compiled as `...` spread args in ES6 outputs).
@@ -71,19 +53,24 @@
target.name.name == 'spread' && _isJSLibrary(target.enclosingLibrary);
bool isJSName(Expression value) =>
- _isBuiltinAnnotation(value, '_js_helper', 'JSName');
+ isBuiltinAnnotation(value, '_js_helper', 'JSName');
bool isJsPeerInterface(Expression value) =>
- _isBuiltinAnnotation(value, '_js_helper', 'JsPeerInterface');
+ isBuiltinAnnotation(value, '_js_helper', 'JsPeerInterface');
bool isNativeAnnotation(Expression value) =>
- _isBuiltinAnnotation(value, '_js_helper', 'Native');
+ isBuiltinAnnotation(value, '_js_helper', 'Native');
bool isJSAnonymousType(Class namedClass) {
- return hasJSInteropAnnotation(namedClass) &&
+ var hasJSInterop = hasJSInteropAnnotation(namedClass);
+ var isAnonymous =
findAnnotation(namedClass, _isJSAnonymousAnnotation) != null;
+ return hasJSInterop && isAnonymous;
}
+bool isUndefinedAnnotation(Expression value) =>
+ isBuiltinAnnotation(value, '_js_helper', '_Undefined');
+
/// Returns true iff the class has an `@JS(...)` annotation from `package:js`.
///
/// Note: usually [_usesJSInterop] should be used instead of this.
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 498bf51..bca5ea6 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -79,18 +79,54 @@
return annotations.firstWhere(test, orElse: () => null);
}
+/// Returns true if [value] represents an annotation for class [className] in
+/// "dart:" library [libraryName].
bool isBuiltinAnnotation(
- Expression value, String libraryName, String expectedName) {
- if (value is ConstructorInvocation) {
- var c = value.target.enclosingClass;
- if (c.name == expectedName) {
- var uri = c.enclosingLibrary.importUri;
- return uri.scheme == 'dart' && uri.path == libraryName;
- }
+ Expression value, String libraryName, String className) {
+ var c = getAnnotationClass(value);
+ if (c != null && c.name == className) {
+ var uri = c.enclosingLibrary.importUri;
+ return uri.scheme == 'dart' && uri.path == libraryName;
}
return false;
}
+/// Gets the class of the instance referred to by metadata annotation [node].
+///
+/// For example:
+///
+/// - `@JS()` would return the "JS" class in "package:js".
+/// - `@anonymous` would return the "_Anonymous" class in "package:js".
+///
+/// This function works regardless of whether the CFE is evaluating constants,
+/// or whether the constant is a field reference (such as "anonymous" above).
+Class getAnnotationClass(Expression node) {
+ node = unwrapUnevaluatedConstant(node);
+ if (node is ConstantExpression) {
+ var constant = node.constant;
+ if (constant is InstanceConstant) return constant.classNode;
+ } else if (node is ConstructorInvocation) {
+ return node.target.enclosingClass;
+ } else if (node is StaticGet) {
+ var type = node.target.getterType;
+ if (type is InterfaceType) return type.classNode;
+ }
+ return null;
+}
+
+Expression unwrapUnevaluatedConstant(Expression node) {
+ // TODO(jmesserly): see if we can configure CFE to preseve the original
+ // expression, rather than wrapping in an UnevaluatedConstant and then
+ // a ConstantExpression.
+ if (node is ConstantExpression) {
+ var constant = node.constant;
+ if (constant is UnevaluatedConstant) {
+ return constant.expression;
+ }
+ }
+ return node;
+}
+
/// Returns true if [name] is an operator method that is available on primitive
/// types (`int`, `double`, `num`, `String`, `bool`).
///
@@ -196,12 +232,10 @@
var expr = statement.expression;
if (expr is Throw) {
var error = expr.expression;
- if (error is ConstructorInvocation &&
- error.target.enclosingClass.name == 'UnsupportedError') {
- // HTML adds a lot of private constructors that are unreachable.
- // Skip these.
- return true;
- }
+
+ // HTML adds a lot of private constructors that are unreachable.
+ // Skip these.
+ return isBuiltinAnnotation(error, 'core', 'UnsupportedError');
}
}
}
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index 1daac64..99a2140 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -6,6 +6,7 @@
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'constants.dart';
+import 'kernel_helpers.dart';
/// Contains information about native JS types (those types provided by the
/// implementation) that are also provided by the Dart SDK.
@@ -125,25 +126,33 @@
/// referring to the JavaScript built-in `Array` type.
List<String> getNativePeers(Class c) {
if (c == coreTypes.objectClass) return ['Object'];
- var names = constants.getNameFromAnnotation(_getNativeAnnotation(c));
- if (names == null) return const [];
- // Omit the special name "!nonleaf" and any future hacks starting with "!"
- return names.split(',').where((peer) => !peer.startsWith("!")).toList();
+ for (var annotation in c.annotations) {
+ var names = _getNativeAnnotationName(annotation);
+ if (names != null) {
+ // Omit the special name "!nonleaf" and any future dart2js hacks
+ // starting with "!"
+ return names.split(',').where((peer) => !peer.startsWith("!")).toList();
+ }
+ }
+ return const [];
+ }
+
+ /// If this [annotation] is `@Native` or `@JsPeerInterface`, returns the "name"
+ /// field (which is also the constructor parameter).
+ String _getNativeAnnotationName(Expression annotation) {
+ if (!_isNativeAnnotation(annotation)) return null;
+ return constants.getFieldValueFromAnnotation(annotation, 'name');
}
}
-bool _isNative(Class c) => _getNativeAnnotation(c) != null;
+/// Whether class [c] has any `@Native` or `@JsPeerInterface` annotations.
+bool _isNative(Class c) => c.annotations.any(_isNativeAnnotation);
-ConstructorInvocation _getNativeAnnotation(Class c) {
- for (var annotation in c.annotations) {
- if (annotation is ConstructorInvocation) {
- var c = annotation.target.enclosingClass;
- if ((c.name == 'Native' || c.name == 'JsPeerInterface') &&
- c.enclosingLibrary.importUri.scheme == 'dart') {
- return annotation;
- }
- }
- }
- return null;
+/// Whether this [annotation] is `@Native` or `@JsPeerInterface`.
+bool _isNativeAnnotation(Expression annotation) {
+ var c = getAnnotationClass(annotation);
+ return c != null &&
+ (c.name == 'Native' || c.name == 'JsPeerInterface') &&
+ c.enclosingLibrary.importUri.scheme == 'dart';
}
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 1ecdfc0..185d3f0 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -242,24 +242,36 @@
visitInstantiation(Instantiation node) => false;
bool isNotNullAnnotation(Expression value) =>
- _isInternalAnnotationField(value, 'notNull');
+ _isInternalAnnotationField(value, 'notNull', '_NotNull');
bool isNullCheckAnnotation(Expression value) =>
- _isInternalAnnotationField(value, 'nullCheck');
+ _isInternalAnnotationField(value, 'nullCheck', '_NullCheck');
- bool _isInternalAnnotationField(Expression value, String name) {
- if (value is StaticGet) {
- var t = value.target;
- if (t is Field && t.name.name == name) {
- var uri = t.enclosingLibrary.importUri;
- return uri.scheme == 'dart' && uri.pathSegments[0] == '_js_helper' ||
- allowPackageMetaAnnotations &&
- uri.scheme == 'package' &&
- uri.pathSegments[0] == 'meta';
- }
+ bool _isInternalAnnotationField(
+ Expression node, String fieldName, String className) {
+ node = unwrapUnevaluatedConstant(node);
+ if (node is ConstantExpression) {
+ var constant = node.constant;
+ return constant is InstanceConstant &&
+ constant.classNode.name == className &&
+ _isInternalSdkAnnotation(constant.classNode.enclosingLibrary);
+ }
+ if (node is StaticGet) {
+ var t = node.target;
+ return t is Field &&
+ t.name.name == fieldName &&
+ _isInternalSdkAnnotation(t.enclosingLibrary);
}
return false;
}
+
+ bool _isInternalSdkAnnotation(Library library) {
+ var uri = library.importUri;
+ return uri.scheme == 'dart' && uri.pathSegments[0] == '_js_helper' ||
+ allowPackageMetaAnnotations &&
+ uri.scheme == 'package' &&
+ uri.pathSegments[0] == 'meta';
+ }
}
/// A visitor that determines which local variables cannot be null using
diff --git a/pkg/dev_compiler/test/worker/worker_test.dart b/pkg/dev_compiler/test/worker/worker_test.dart
index dd4b5cc..07c9dc9 100644
--- a/pkg/dev_compiler/test/worker/worker_test.dart
+++ b/pkg/dev_compiler/test/worker/worker_test.dart
@@ -10,28 +10,41 @@
// TODO(jakemac): Remove once this is a part of the testing library.
import 'package:bazel_worker/src/async_message_grouper.dart';
import 'package:bazel_worker/testing.dart';
-import 'package:path/path.dart' show join, joinAll;
+import 'package:path/path.dart' show dirname, join, joinAll;
import 'package:test/test.dart';
-File file(String path) => File(joinAll(path.split('/'))).absolute;
+Directory tmp = Directory.systemTemp.createTempSync('ddc_worker_test');
+File file(String path) => File(join(tmp.path, joinAll(path.split('/'))));
-main() {
- var dartdevc = join('bin', 'dartdevc.dart');
- group('Hello World', () {
- final argsFile = file('test/worker/hello_world.args');
- final inputDartFile = file('test/worker/hello_world.dart');
- final outputJsFile = file('test/worker/out/hello_world.js');
- final dartSdkSummary = file('gen/sdk/ddc_sdk.sum');
- final executableArgs = [dartdevc];
- final compilerArgs = [
- '--no-source-map',
- '--no-summarize',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- outputJsFile.path,
- inputDartFile.path,
- ];
+void main() {
+ runTests(false);
+ runTests(true);
+}
+
+void runTests(bool isKernel) {
+ String mode = isKernel ? 'DDK' : 'DDC';
+ List<String> baseArgs = isKernel ? ['-k'] : [];
+ String ext = isKernel ? 'dill' : 'sum';
+ final binDir = dirname(Platform.resolvedExecutable);
+ // Note, the bots use the dart binary in the top-level build directory.
+ // On windows, this is a .bat file.
+ final dartdevc = 'dartdevc${Platform.isWindows ? ".bat" : ""}';
+ final executable = binDir.endsWith('bin')
+ ? join(binDir, dartdevc)
+ : join(binDir, 'dart-sdk', 'bin', dartdevc);
+ final executableArgs = <String>[];
+ group('$mode: Hello World', () {
+ final argsFile = file('hello_world.args');
+ final inputDartFile = file('hello_world.dart');
+ final outputJsFile = file('out/hello_world.js');
+ final compilerArgs = baseArgs +
+ [
+ '--no-source-map',
+ '--no-summarize',
+ '-o',
+ outputJsFile.path,
+ inputDartFile.path,
+ ];
setUp(() {
inputDartFile.createSync();
@@ -48,7 +61,7 @@
test('can compile in worker mode', () async {
var args = executableArgs.toList()..add('--persistent_worker');
- var process = await Process.start(Platform.executable, args);
+ var process = await Process.start(executable, args);
var messageGrouper = AsyncMessageGrouper(process.stdout);
var request = WorkRequest();
@@ -71,6 +84,17 @@
expect(response.output, isEmpty);
expect(outputJsFile.readAsStringSync(), contains('goodbye world'));
+ // Try to compile an error.
+ inputDartFile.writeAsStringSync('main() { int x = "hello"; }');
+ process.stdin.add(protoToDelimitedBuffer(request));
+
+ response = await _readResponse(messageGrouper);
+ expect(response.exitCode, 1, reason: response.output);
+ expect(
+ response.output,
+ contains(
+ 'A value of type \'String\' can\'t be assigned to a variable of type \'int\'.'));
+
process.kill();
// TODO(jakemac): This shouldn't be necessary, but it is for the process
@@ -80,7 +104,7 @@
test('can compile in basic mode', () {
var args = executableArgs.toList()..addAll(compilerArgs);
- var result = Process.runSync(Platform.executable, args);
+ var result = Process.runSync(executable, args);
expect(result.exitCode, EXIT_CODE_OK);
expect(result.stdout, isEmpty);
@@ -92,7 +116,7 @@
var args = List<String>.from(executableArgs)
..add('--does-not-exist')
..addAll(compilerArgs);
- var result = Process.runSync(Platform.executable, args);
+ var result = Process.runSync(executable, args);
expect(result.exitCode, 64);
expect(result.stdout,
@@ -106,7 +130,7 @@
..add('--does-not-exist')
..add('--ignore-unrecognized-flags')
..addAll(compilerArgs);
- var result = Process.runSync(Platform.executable, args);
+ var result = Process.runSync(executable, args);
expect(result.exitCode, EXIT_CODE_OK);
expect(result.stdout, isEmpty);
@@ -118,7 +142,7 @@
argsFile.createSync();
argsFile.writeAsStringSync(compilerArgs.join('\n'));
var args = executableArgs.toList()..add('@${argsFile.path}');
- var process = await Process.start(Platform.executable, args);
+ var process = await Process.start(executable, args);
stderr.addStream(process.stderr);
var futureProcessOutput = process.stdout.map(utf8.decode).toList();
@@ -128,16 +152,16 @@
});
});
- group('Hello World with Summaries', () {
- final greetingDart = file('test/worker/greeting.dart');
- final helloDart = file('test/worker/hello.dart');
+ group('$mode: Hello World with Summaries', () {
+ final greetingDart = file('greeting.dart');
+ final helloDart = file('hello.dart');
- final greetingJS = file('test/worker/greeting.js');
- final greetingSummary = file('test/worker/greeting.api.ds');
- final helloJS = file('test/worker/hello_world.js');
+ final greetingJS = file('greeting.js');
+ final greetingSummary = file('greeting.$ext');
+ final helloJS = file('hello_world.js');
- final greeting2JS = file('test/worker/greeting2.js');
- final greeting2Summary = file('test/worker/greeting2.api.ds');
+ final greeting2JS = file('greeting2.js');
+ final greeting2Summary = file('greeting2.$ext');
setUp(() {
greetingDart.writeAsStringSync('String greeting = "hello";');
@@ -156,36 +180,35 @@
});
test('can compile in basic mode', () {
- final dartSdkSummary = file('gen/sdk/ddc_sdk.sum');
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--summary-extension=api.ds',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- greetingJS.path,
- greetingDart.path,
- ]);
- expect(result.exitCode, EXIT_CODE_OK);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '-o',
+ greetingJS.path,
+ greetingDart.path,
+ ]);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
+ expect(result.exitCode, EXIT_CODE_OK);
expect(greetingJS.existsSync(), isTrue);
expect(greetingSummary.existsSync(), isTrue);
- result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-source-map',
- '--no-summarize',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '--summary-extension=api.ds',
- '-s',
- greetingSummary.path,
- '-o',
- helloJS.path,
- helloDart.path,
- ]);
+ result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '--no-summarize',
+ '-s',
+ greetingSummary.path,
+ '-o',
+ helloJS.path,
+ helloDart.path,
+ ]);
expect(result.exitCode, EXIT_CODE_OK);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
@@ -193,54 +216,53 @@
});
test('reports error on overlapping summaries', () {
- final dartSdkSummary = file('gen/sdk/ddc_sdk.sum');
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--summary-extension=api.ds',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- greetingJS.path,
- greetingDart.path,
- ]);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '-o',
+ greetingJS.path,
+ greetingDart.path,
+ ]);
expect(result.exitCode, EXIT_CODE_OK);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
expect(greetingJS.existsSync(), isTrue);
expect(greetingSummary.existsSync(), isTrue);
- result = Process.runSync(Platform.executable, [
- dartdevc,
- '--summary-extension=api.ds',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- greeting2JS.path,
- greetingDart.path,
- ]);
+ result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '-o',
+ greeting2JS.path,
+ greetingDart.path,
+ ]);
expect(result.exitCode, EXIT_CODE_OK);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
expect(greeting2JS.existsSync(), isTrue);
expect(greeting2Summary.existsSync(), isTrue);
- result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-source-map',
- '--no-summarize',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '--summary-extension=api.ds',
- '-s',
- greetingSummary.path,
- '-s',
- greeting2Summary.path,
- '-o',
- helloJS.path,
- helloDart.path,
- ]);
+ result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '--no-summarize',
+ '-s',
+ greetingSummary.path,
+ '-s',
+ greeting2Summary.path,
+ '-o',
+ helloJS.path,
+ helloDart.path,
+ ]);
// TODO(vsm): Re-enable when we turn this check back on.
expect(result.exitCode, 0);
// expect(result.exitCode, 65);
@@ -250,10 +272,9 @@
});
});
- group('Error handling', () {
- final dartSdkSummary = file('gen/sdk/ddc_sdk.sum');
- final badFileDart = file('test/worker/bad.dart');
- final badFileJs = file('test/worker/bad.js');
+ group('$mode: Error handling', () {
+ final badFileDart = file('bad.dart');
+ final badFileJs = file('bad.js');
tearDown(() {
if (badFileDart.existsSync()) badFileDart.deleteSync();
@@ -261,40 +282,41 @@
});
test('incorrect usage', () {
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--dart-sdk-summary',
- dartSdkSummary.path,
- 'oops',
- ]);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ 'oops',
+ ]);
expect(result.exitCode, 64);
expect(
- result.stdout, contains('Please include the output file location.'));
+ result.stdout, contains('Please specify the output file location.'));
expect(result.stdout, isNot(contains('#0')));
});
test('compile errors', () {
badFileDart.writeAsStringSync('main() => "hello world"');
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- badFileJs.path,
- badFileDart.path,
- ]);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-source-map',
+ '-o',
+ badFileJs.path,
+ badFileDart.path,
+ ]);
expect(result.exitCode, 1);
- expect(result.stdout, contains("[error] Expected to find ';'"));
+ expect(result.stdout, contains(RegExp(r"Expected (to find )?\';\'")));
});
});
- group('Parts', () {
- final dartSdkSummary = file('gen/sdk/ddc_sdk.sum');
- final partFile = file('test/worker/greeting.dart');
- final libraryFile = file('test/worker/hello.dart');
+ group('$mode: Parts', () {
+ final partFile = file('greeting.dart');
+ final libraryFile = file('hello.dart');
- final outJS = file('test/worker/output.js');
+ final outJS = file('output.js');
setUp(() {
partFile.writeAsStringSync('part of hello;\n'
@@ -311,17 +333,18 @@
});
test('works if part and library supplied', () {
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-summarize',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- outJS.path,
- partFile.path,
- libraryFile.path,
- ]);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-summarize',
+ '--no-source-map',
+ '-o',
+ outJS.path,
+ partFile.path,
+ libraryFile.path,
+ ]);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
@@ -329,38 +352,43 @@
});
test('works if part is not supplied', () {
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-summarize',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- outJS.path,
- libraryFile.path,
- ]);
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-summarize',
+ '--no-source-map',
+ '-o',
+ outJS.path,
+ libraryFile.path,
+ ]);
expect(result.stdout, isEmpty);
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(outJS.existsSync(), isTrue);
});
- test('part without library is silently ignored', () {
- var result = Process.runSync(Platform.executable, [
- dartdevc,
- '--no-summarize',
- '--no-source-map',
- '--dart-sdk-summary',
- dartSdkSummary.path,
- '-o',
- outJS.path,
- partFile.path,
- ]);
- expect(result.stdout, isEmpty);
- expect(result.stderr, isEmpty);
- expect(result.exitCode, 0);
- expect(outJS.existsSync(), isTrue);
- });
+ if (!isKernel) {
+ // TODO(vsm): Consider dropping this test. Kernel behavior is better.
+ test('part without library is silently ignored', () {
+ var result = Process.runSync(
+ executable,
+ executableArgs +
+ baseArgs +
+ [
+ '--no-summarize',
+ '--no-source-map',
+ '-o',
+ outJS.path,
+ partFile.path,
+ ]);
+ expect(result.stdout, isEmpty);
+ expect(result.stderr, isEmpty);
+ expect(result.exitCode, 0);
+ expect(outJS.existsSync(), isTrue);
+ });
+ }
});
}
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 368d5e7..192b5f6 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -17,7 +17,8 @@
nullCheck,
Primitives,
PrivateSymbol,
- quoteStringForRegExp;
+ quoteStringForRegExp,
+ undefined;
import 'dart:_runtime' as dart;
import 'dart:_foreign_helper' show JS;
import 'dart:_native_typed_data' show NativeUint8List;
@@ -396,7 +397,7 @@
@patch
class List<E> {
@patch
- factory List([int _length = dart.undefined]) {
+ factory List([@undefined int _length]) {
dynamic list;
if (JS('bool', '# === void 0', _length)) {
list = JS('', '[]');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/annotations.dart b/pkg/dev_compiler/tool/input_sdk/private/annotations.dart
index 1693256..bc437da 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/annotations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/annotations.dart
@@ -43,6 +43,14 @@
const _NullCheck();
}
+/// Annotation indicating the parameter should default to the JavaScript
+/// undefined constant.
+const undefined = _Undefined();
+
+class _Undefined {
+ const _Undefined();
+}
+
/// Tells the development compiler to check a variable for null at its
/// declaration point, and then to assume that the variable is non-null
/// from that point forward.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index 6f67aa9..7ab4a81 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -97,7 +97,7 @@
// Warning: dload, dput, and dsend assume they are never called on methods
// implemented by the Object base class as those methods can always be
// statically resolved.
-dload(obj, field, [mirrors = undefined]) {
+dload(obj, field, [@undefined mirrors]) {
if (JS('!', 'typeof # == "function" && # == "call"', obj, field)) {
return obj;
}
@@ -136,7 +136,7 @@
dputRepl(obj, field, value) =>
dput(obj, replNameLookup(obj, field), value, false);
-dput(obj, field, value, [mirrors = undefined]) {
+dput(obj, field, value, [@undefined mirrors]) {
var f = _canonicalMember(obj, field);
trackCall(obj);
if (f != null) {
@@ -308,10 +308,10 @@
return callNSM();
})()''');
-dcall(f, args, [named = undefined]) =>
+dcall(f, args, [@undefined named]) =>
_checkAndCall(f, null, JS('', 'void 0'), null, args, named, 'call');
-dgcall(f, typeArgs, args, [named = undefined]) =>
+dgcall(f, typeArgs, args, [@undefined named]) =>
_checkAndCall(f, null, JS('', 'void 0'), typeArgs, args, named, 'call');
/// Helper for REPL dynamic invocation variants that make a best effort to
@@ -377,16 +377,16 @@
return _checkAndCall(f, ftype, obj, typeArgs, args, named, displayName);
}
-dsend(obj, method, args, [named = undefined]) =>
+dsend(obj, method, args, [@undefined named]) =>
callMethod(obj, method, null, args, named, method);
-dgsend(obj, typeArgs, method, args, [named = undefined]) =>
+dgsend(obj, typeArgs, method, args, [@undefined named]) =>
callMethod(obj, method, typeArgs, args, named, method);
-dsendRepl(obj, method, args, [named = undefined]) =>
+dsendRepl(obj, method, args, [@undefined named]) =>
callMethod(obj, replNameLookup(obj, method), null, args, named, method);
-dgsendRepl(obj, typeArgs, method, args, [named = undefined]) =>
+dgsendRepl(obj, typeArgs, method, args, [@undefined named]) =>
callMethod(obj, replNameLookup(obj, method), typeArgs, args, named, method);
dindex(obj, index) => callMethod(obj, '_get', null, [index], null, '[]');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
index 665aae3..e943f3e 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
@@ -24,7 +24,8 @@
PrivateSymbol,
ReifyFunctionTypes,
NoReifyGeneric,
- notNull;
+ notNull,
+ undefined;
export 'dart:_debugger' show getDynamicStats, clearDynamicStats, trackCall;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index 13d6f88..a5d6dd0 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -682,7 +682,7 @@
}
/// Create a function type.
-FunctionType fnType(returnType, List args, [extra = undefined]) =>
+FunctionType fnType(returnType, List args, [@undefined extra]) =>
FunctionType.create(returnType, args, extra);
/// Creates a generic function type.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
index 435d89e..8f9431d 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
@@ -8,11 +8,6 @@
/// by the Dart runtime.
// TODO(ochafik): Rewrite some of these in Dart when possible.
-/// The JavaScript undefined constant.
-///
-/// This is initialized by DDC to JS `void 0`.
-const undefined = null;
-
final Function(Object, Object, Object) defineProperty =
JS('', 'Object.defineProperty');
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 ac0217a..1d75bc5 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -134,6 +134,11 @@
/// unevaluated and can be evaluated by a constant evaluator later.
Map<String, String> environmentDefines = null;
+ /// Report an error if a constant could not be evaluated (either because it
+ /// is an environment constant and no environment was specified, or because
+ /// it refers to a constructor or variable initializer that is not available).
+ bool errorOnUnevaluatedConstant = false;
+
/// The target platform that will consume the compiled code.
///
/// Used to provide platform-specific details to the compiler like:
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 84dc067..d0615fd 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -27,7 +27,7 @@
const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
ExperimentalFlag.constantUpdate2018: false,
- ExperimentalFlag.controlFlowCollections: false,
+ ExperimentalFlag.controlFlowCollections: true,
ExperimentalFlag.setLiterals: true,
- ExperimentalFlag.spreadCollections: false,
+ ExperimentalFlag.spreadCollections: true,
};
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 79d7201..9cfba14 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -184,6 +184,8 @@
final Map<String, String> environmentDefines;
+ bool get errorOnUnevaluatedConstant => _raw.errorOnUnevaluatedConstant;
+
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
ProcessedOptions({CompilerOptions options, List<Uri> inputs, this.output})
: this._raw = options ?? new CompilerOptions(),
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 de4fb58..668da04 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -639,6 +639,30 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Token token)>
+ templateCantUseControlFlowOrSpreadAsConstant =
+ const Template<Message Function(Token token)>(
+ messageTemplate:
+ r"""'#lexeme' is not supported in constant expressions.""",
+ withArguments: _withArgumentsCantUseControlFlowOrSpreadAsConstant);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Token token)>
+ codeCantUseControlFlowOrSpreadAsConstant =
+ const Code<Message Function(Token token)>(
+ "CantUseControlFlowOrSpreadAsConstant",
+ templateCantUseControlFlowOrSpreadAsConstant,
+ analyzerCodes: <String>["NOT_CONSTANT_EXPRESSION"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantUseControlFlowOrSpreadAsConstant(Token token) {
+ String lexeme = token.lexeme;
+ return new Message(codeCantUseControlFlowOrSpreadAsConstant,
+ message: """'${lexeme}' is not supported in constant expressions.""",
+ arguments: {'token': token});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
Token
@@ -896,17 +920,6 @@
message: r"""This is the type variable.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeConstAfterFactory = messageConstAfterFactory;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageConstAfterFactory = const MessageCode(
- "ConstAfterFactory",
- index: 56,
- message:
- r"""The modifier 'const' should be before the modifier 'factory'.""",
- tip: r"""Try re-ordering the modifiers.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstAndCovariant = messageConstAndCovariant;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1635,6 +1648,14 @@
message: r"""Null value during constant evaluation.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalUnevaluated = messageConstEvalUnevaluated;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalUnevaluated = const MessageCode(
+ "ConstEvalUnevaluated",
+ message: r"""Could not evaluate constant expression.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String string,
@@ -3225,7 +3246,7 @@
string)> templateExperimentNotEnabled = const Template<
Message Function(String string)>(
messageTemplate:
- r"""This requires the --#string experiment to be enabled.""",
+ r"""This requires the '#string' experiment to be enabled.""",
tipTemplate:
r"""Try enabling this experiment by adding it to the command line when compiling and running.""",
withArguments: _withArgumentsExperimentNotEnabled);
@@ -3240,7 +3261,7 @@
Message _withArgumentsExperimentNotEnabled(String string) {
if (string.isEmpty) throw 'No string provided';
return new Message(codeExperimentNotEnabled,
- message: """This requires the --${string} experiment to be enabled.""",
+ message: """This requires the '${string}' experiment to be enabled.""",
tip:
"""Try enabling this experiment by adding it to the command line when compiling and running.""",
arguments: {'string': string});
@@ -6904,6 +6925,36 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String string,
+ String
+ string2)> templateModifierOutOfOrder = const Template<
+ Message Function(String string, String string2)>(
+ messageTemplate:
+ r"""The modifier '#string' should be before the modifier '#string2'.""",
+ tipTemplate: r"""Try re-ordering the modifiers.""",
+ withArguments: _withArgumentsModifierOutOfOrder);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string, String string2)>
+ codeModifierOutOfOrder =
+ const Code<Message Function(String string, String string2)>(
+ "ModifierOutOfOrder", templateModifierOutOfOrder,
+ index: 56);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsModifierOutOfOrder(String string, String string2) {
+ if (string.isEmpty) throw 'No string provided';
+ if (string2.isEmpty) throw 'No string provided';
+ return new Message(codeModifierOutOfOrder,
+ message:
+ """The modifier '${string}' should be before the modifier '${string2}'.""",
+ tip: """Try re-ordering the modifiers.""",
+ arguments: {'string': string, 'string2': string2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMoreThanOneSuperOrThisInitializer =
messageMoreThanOneSuperOrThisInitializer;
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 e360c2e..0430c9d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2316,6 +2316,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(forToken),
+ forToken,
+ forToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
List<VariableDeclaration> variables =
buildVariableDeclarations(variableOrExpression);
@@ -3718,6 +3730,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(ifToken),
+ ifToken,
+ ifToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
if (entry is MapEntry) {
push(forest.ifMapEntry(toValue(condition), entry, null, ifToken));
@@ -3744,6 +3768,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(ifToken),
+ ifToken,
+ ifToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
if (thenEntry is MapEntry) {
if (elseEntry is MapEntry) {
@@ -3804,6 +3840,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(spreadToken),
+ spreadToken,
+ spreadToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
push(forest.spreadElement(toValue(expression), spreadToken));
}
@@ -4115,6 +4163,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(forToken),
+ forToken,
+ forToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
VariableDeclaration variable = buildForInVariable(lvalue);
Expression problem = checkForInVariable(lvalue, variable, forToken);
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 e6c5630..b35550c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -45,6 +45,7 @@
messageConstEvalNotListOrSetInSpread,
messageConstEvalNotMapInSpread,
messageConstEvalNullValue,
+ messageConstEvalUnevaluated,
noLength,
templateConstEvalDeferredLibrary,
templateConstEvalDuplicateElement,
@@ -83,6 +84,7 @@
bool enableAsserts: false,
bool evaluateAnnotations: true,
bool desugarSets: false,
+ bool errorOnUnevaluatedConstant: false,
CoreTypes coreTypes,
ClassHierarchy hierarchy}) {
coreTypes ??= new CoreTypes(component);
@@ -95,6 +97,7 @@
keepFields: keepFields,
enableAsserts: enableAsserts,
desugarSets: desugarSets,
+ errorOnUnevaluatedConstant: errorOnUnevaluatedConstant,
evaluateAnnotations: evaluateAnnotations);
return component;
}
@@ -109,6 +112,7 @@
bool keepVariables: false,
bool evaluateAnnotations: true,
bool desugarSets: false,
+ bool errorOnUnevaluatedConstant: false,
bool enableAsserts: false}) {
final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
backend,
@@ -117,6 +121,7 @@
keepVariables,
evaluateAnnotations,
desugarSets,
+ errorOnUnevaluatedConstant,
typeEnvironment,
enableAsserts,
errorReporter);
@@ -150,6 +155,7 @@
final bool keepVariables;
final bool evaluateAnnotations;
final bool desugarSets;
+ final bool errorOnUnevaluatedConstant;
ConstantsTransformer(
ConstantsBackend backend,
@@ -158,12 +164,14 @@
this.keepVariables,
this.evaluateAnnotations,
this.desugarSets,
+ this.errorOnUnevaluatedConstant,
this.typeEnvironment,
bool enableAsserts,
ErrorReporter errorReporter)
: constantEvaluator = new ConstantEvaluator(backend, environmentDefines,
typeEnvironment, enableAsserts, errorReporter,
- desugarSets: desugarSets);
+ desugarSets: desugarSets,
+ errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
// Transform the library/class members:
@@ -309,7 +317,8 @@
// So the value of the variable is still available for debugging
// purposes we convert the constant variable to be a final variable
// initialized to the evaluated constant expression.
- node.initializer = makeConstantExpression(constant)..parent = node;
+ node.initializer = makeConstantExpression(constant, node.initializer)
+ ..parent = node;
node.isFinal = true;
node.isConst = false;
} else {
@@ -354,13 +363,13 @@
// Handle use-sites of constants (and "inline" constant expressions):
visitSymbolLiteral(SymbolLiteral node) {
- return makeConstantExpression(constantEvaluator.evaluate(node));
+ return makeConstantExpression(constantEvaluator.evaluate(node), node);
}
visitStaticGet(StaticGet node) {
final Member target = node.target;
if (target is Field && target.isConst) {
- return evaluateAndTransformWithContext(node, target.initializer);
+ return evaluateAndTransformWithContext(node, node);
} else if (target is Procedure && target.kind == ProcedureKind.Method) {
return evaluateAndTransformWithContext(node, node);
}
@@ -426,7 +435,7 @@
}
evaluateAndTransformWithContext(TreeNode treeContext, Expression node) {
- return makeConstantExpression(evaluateWithContext(treeContext, node));
+ return makeConstantExpression(evaluateWithContext(treeContext, node), node);
}
evaluateWithContext(TreeNode treeContext, Expression node) {
@@ -439,12 +448,13 @@
});
}
- Expression makeConstantExpression(Constant constant) {
+ Expression makeConstantExpression(Constant constant, Expression node) {
if (constant is UnevaluatedConstant &&
constant.expression is InvalidExpression) {
return constant.expression;
}
- return new ConstantExpression(constant);
+ return new ConstantExpression(constant, node.getStaticType(typeEnvironment))
+ ..fileOffset = node.fileOffset;
}
}
@@ -452,6 +462,7 @@
final ConstantsBackend backend;
final NumberSemantics numberSemantics;
Map<String, String> environmentDefines;
+ final bool errorOnUnevaluatedConstant;
final CoreTypes coreTypes;
final TypeEnvironment typeEnvironment;
final bool enableAsserts;
@@ -488,7 +499,7 @@
ConstantEvaluator(this.backend, this.environmentDefines, this.typeEnvironment,
this.enableAsserts, this.errorReporter,
- {this.desugarSets = false})
+ {this.desugarSets = false, this.errorOnUnevaluatedConstant = false})
: numberSemantics = backend.numberSemantics,
coreTypes = typeEnvironment.coreTypes,
canonicalizationCache = <Constant, Constant>{},
@@ -537,7 +548,11 @@
seenUnevaluatedChild = false;
lazyDepth = 0;
try {
- return _evaluateSubexpression(node);
+ Constant result = _evaluateSubexpression(node);
+ if (errorOnUnevaluatedConstant && result is UnevaluatedConstant) {
+ return report(node, messageConstEvalUnevaluated);
+ }
+ return result;
} on _AbortDueToError catch (e) {
final Uri uri = getFileUri(e.node);
final int fileOffset = getFileOffset(uri, e.node);
@@ -653,7 +668,12 @@
result = nodeCache[node] ?? report(node, messageConstEvalCircularity);
} else {
nodeCache[node] = null;
- result = nodeCache[node] = node.accept(this);
+ try {
+ result = nodeCache[node] = node.accept(this);
+ } catch (e) {
+ nodeCache.remove(node);
+ rethrow;
+ }
}
} else {
result = node.accept(this);
@@ -1931,6 +1951,9 @@
concatenated.add(new StringBuffer(value));
}
} else if (shouldBeUnevaluated) {
+ // The constant is either unevaluated or a non-primitive in an
+ // unevaluated context. In both cases we defer the evaluation and/or
+ // error reporting till later.
concatenated.add(constant);
} else {
return report(
@@ -1943,11 +1966,13 @@
final expressions = new List<Expression>(concatenated.length);
for (int i = 0; i < concatenated.length; i++) {
Object value = concatenated[i];
- if (value is UnevaluatedConstant) {
- expressions[i] = extract(value);
- } else {
+ if (value is StringBuffer) {
expressions[i] = new ConstantExpression(
canonicalize(new StringConstant(value.toString())));
+ } else {
+ // The value is either unevaluated constant or a non-primitive
+ // constant in an unevaluated expression.
+ expressions[i] = extract(value);
}
}
return unevaluated(node, new StringConcatenation(expressions));
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 d34ba34..484c95e 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
@@ -23,7 +23,6 @@
StringLiteral,
SuperInitializer,
ThisExpression,
- TreeNode,
VariableGet;
import 'kernel_shadow_ast.dart' show ShadowClass;
@@ -94,9 +93,10 @@
this.stringType,
LibraryBuilder parent,
int startCharOffset,
- int charOffset)
+ int charOffset,
+ int charEndOffset)
: super(metadata, 0, name, null, null, null, scope, constructors, parent,
- null, startCharOffset, charOffset, TreeNode.noOffset,
+ null, startCharOffset, charOffset, charEndOffset,
cls: cls);
factory KernelEnumBuilder(
@@ -105,6 +105,7 @@
String name,
List<EnumConstantInfo> enumConstantInfos,
KernelLibraryBuilder parent,
+ int startCharOffset,
int charOffset,
int charEndOffset) {
assert(enumConstantInfos == null || enumConstantInfos.isNotEmpty);
@@ -226,8 +227,8 @@
members[name] = fieldBuilder..next = existing;
}
}
- final int startCharOffset =
- metadata == null ? charOffset : metadata.first.charOffset;
+ final int startCharOffsetComputed =
+ metadata == null ? startCharOffset : metadata.first.charOffset;
KernelEnumBuilder enumBuilder = new KernelEnumBuilder.internal(
metadata,
name,
@@ -241,8 +242,9 @@
objectType,
stringType,
parent,
- startCharOffset,
- charOffset);
+ startCharOffsetComputed,
+ charOffset,
+ charEndOffset);
void setParent(String name, MemberBuilder builder) {
do {
builder.parent = enumBuilder;
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 a7fbd0a..eac2a4a 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
@@ -32,7 +32,6 @@
StaticInvocation,
StringLiteral,
Supertype,
- TreeNode,
Typedef,
TypeParameter,
TypeParameterType,
@@ -303,7 +302,8 @@
modifiers,
className,
typeVariables,
- applyMixins(supertype, charOffset, className, isMixinDeclaration,
+ applyMixins(supertype, startCharOffset, charOffset, charEndOffset,
+ className, isMixinDeclaration,
typeVariables: typeVariables),
interfaces,
classScope,
@@ -379,8 +379,13 @@
return typeVariablesByName;
}
- KernelTypeBuilder applyMixins(KernelTypeBuilder type, int charOffset,
- String subclassName, bool isMixinDeclaration,
+ KernelTypeBuilder applyMixins(
+ KernelTypeBuilder type,
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset,
+ String subclassName,
+ bool isMixinDeclaration,
{String documentationComment,
List<MetadataBuilder> metadata,
String name,
@@ -553,9 +558,9 @@
}
}
}
- final int startCharOffset =
+ final int computedStartCharOffset =
(isNamedMixinApplication ? metadata : null) == null
- ? charOffset
+ ? startCharOffset
: metadata.first.charOffset;
SourceClassBuilder application = new SourceClassBuilder(
isNamedMixinApplication ? metadata : null,
@@ -575,9 +580,9 @@
isModifiable: false),
this,
<ConstructorReferenceBuilder>[],
- startCharOffset,
+ computedStartCharOffset,
charOffset,
- TreeNode.noOffset,
+ charEndOffset,
mixedInType: isMixinDeclaration ? null : mixin);
if (isNamedMixinApplication) {
loader.target.metadataCollector?.setDocumentationComment(
@@ -605,11 +610,13 @@
int modifiers,
KernelTypeBuilder mixinApplication,
List<KernelTypeBuilder> interfaces,
- int charOffset) {
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset) {
// Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`.
endNestedDeclaration(name).resolveTypes(typeVariables, this);
- KernelNamedTypeBuilder supertype = applyMixins(
- mixinApplication, charOffset, name, false,
+ KernelNamedTypeBuilder supertype = applyMixins(mixinApplication,
+ startCharOffset, charOffset, charEndOffset, name, false,
documentationComment: documentationComment,
metadata: metadata,
name: name,
@@ -819,11 +826,19 @@
List<MetadataBuilder> metadata,
String name,
List<EnumConstantInfo> enumConstantInfos,
+ int startCharOffset,
int charOffset,
int charEndOffset) {
MetadataCollector metadataCollector = loader.target.metadataCollector;
- KernelEnumBuilder builder = new KernelEnumBuilder(metadataCollector,
- metadata, name, enumConstantInfos, this, charOffset, charEndOffset);
+ KernelEnumBuilder builder = new KernelEnumBuilder(
+ metadataCollector,
+ metadata,
+ name,
+ enumConstantInfos,
+ this,
+ startCharOffset,
+ charOffset,
+ charEndOffset);
addBuilder(name, builder, charOffset);
metadataCollector?.setDocumentationComment(
builder.target, documentationComment);
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 e2598abc..4533ae4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -70,7 +70,7 @@
templateMissingImplementationCause,
templateSuperclassHasNoDefaultConstructor;
-import '../problems.dart' show unhandled, unimplemented;
+import '../problems.dart' show unhandled;
import '../scope.dart' show AmbiguousBuilder;
@@ -136,6 +136,9 @@
final Map<String, String> environmentDefines =
CompilerContext.current.options.environmentDefines;
+ final bool errorOnUnevaluatedConstant =
+ CompilerContext.current.options.errorOnUnevaluatedConstant;
+
final bool enableAsserts = CompilerContext.current.options.enableAsserts;
final List<Object> clonedFormals = <Object>[];
@@ -777,7 +780,8 @@
environment,
new KernelConstantErrorReporter(loader),
enableAsserts: enableAsserts,
- desugarSets: !backendTarget.supportsSetLiterals);
+ desugarSets: !backendTarget.supportsSetLiterals,
+ errorOnUnevaluatedConstant: errorOnUnevaluatedConstant);
ticker.logMs("Evaluated constants");
}
backendTarget.performModularTransformationsOnLibraries(
@@ -790,10 +794,6 @@
}
void runProcedureTransformations(Procedure procedure) {
- if (loader.target.enableConstantUpdate2018) {
- unimplemented('constant evaluation during expression evaluation',
- procedure.fileOffset, procedure.fileUri);
- }
backendTarget.performTransformationsOnProcedure(
loader.coreTypes, loader.hierarchy, procedure,
logger: (String msg) => ticker.logMs(msg));
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 dfa8437..b63af14 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1142,6 +1142,11 @@
}
@override
+ void handleLanguageVersion(Token commentToken, int major, int minor) {
+ listener?.handleLanguageVersion(commentToken, major, minor);
+ }
+
+ @override
void handleLiteralBool(Token token) {
listener?.handleLiteralBool(token);
}
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index c59f7ea..0dd6638 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -6,7 +6,7 @@
import '../fasta_codes.dart' as fasta;
-import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN;
+import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN, STRING_TOKEN;
import 'identifier_context.dart';
@@ -624,7 +624,8 @@
// Recovery
if (isOneOfOrEof(identifier, const [';', '=', ',', '{', '}']) ||
- looksLikeStatementStart(identifier)) {
+ looksLikeStatementStart(identifier) ||
+ identifier.kind == STRING_TOKEN) {
identifier = parser.insertSyntheticIdentifier(token, this,
message: fasta.templateExpectedIdentifier.withArguments(identifier));
} else {
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 858b3b8..9cc581a 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1405,6 +1405,15 @@
logEvent("Script");
}
+ /// A language version comment was parsed of the form
+ /// // @dart = <major>.<minor>
+ ///
+ /// For more information, see
+ /// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/language-versioning.md#individual-library-language-version-override
+ void handleLanguageVersion(Token commentToken, int major, int minor) {
+ // TODO(danrubel): Update listeners to handle this
+ }
+
/// A type has been just parsed, and the parser noticed that the next token
/// has a type substitution comment /*=T*. So, the type that has been just
/// parsed should be discarded, and a new type should be parsed instead.
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 83d9a8d..3a5c8d1 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -240,7 +240,8 @@
varFinalOrConst = constToken = next;
if (afterFactory) {
- parser.reportRecoverableError(next, fasta.messageConstAfterFactory);
+ parser.reportRecoverableError(next,
+ fasta.templateModifierOutOfOrder.withArguments('const', 'factory'));
}
return next;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index e716b34..4a616ac 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -10,15 +10,17 @@
import '../scanner.dart' show ErrorToken, Token;
+import '../scanner/characters.dart' show $0, $9, $SPACE;
+
import '../../scanner/token.dart'
show
ASSIGNMENT_PRECEDENCE,
BeginToken,
CASCADE_PRECEDENCE,
+ CommentToken,
EQUALITY_PRECEDENCE,
Keyword,
POSTFIX_PRECEDENCE,
- PREFIX_PRECEDENCE,
RELATIONAL_PRECEDENCE,
SELECTOR_PRECEDENCE,
SyntheticBeginToken,
@@ -339,6 +341,7 @@
directiveState?.checkScriptTag(this, token.next);
token = parseScript(token);
}
+ parseLanguageVersionOpt(token);
while (!token.next.isEof) {
final Token start = token.next;
token = parseTopLevelDeclarationImpl(token, directiveState);
@@ -365,6 +368,74 @@
return token;
}
+ /// Parse the optional language version comment as specified in
+ /// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/language-versioning.md#individual-library-language-version-override
+ void parseLanguageVersionOpt(Token token) {
+ // TODO(danrubel): Handle @dart version multi-line comments and dartdoc
+ // or update the spec to exclude them.
+ token = token.next.precedingComments;
+ while (token is CommentToken) {
+ if (parseLanguageVersionText(token)) {
+ break;
+ }
+ token = token.next;
+ }
+ }
+
+ bool parseLanguageVersionText(CommentToken token) {
+ String text = token.lexeme;
+ if (text == null || !text.startsWith('//')) {
+ return false;
+ }
+ int index = _skipSpaces(text, 2);
+ if (!text.startsWith('@dart', index)) {
+ return false;
+ }
+ index = _skipSpaces(text, index + 5);
+ if (!text.startsWith('=', index)) {
+ return false;
+ }
+ int start = index = _skipSpaces(text, index + 1);
+ index = _skipDigits(text, start);
+ if (start == index) {
+ return false;
+ }
+ int major = int.parse(text.substring(start, index));
+ if (!text.startsWith('.', index)) {
+ return false;
+ }
+ start = index + 1;
+ index = _skipDigits(text, start);
+ if (start == index) {
+ return false;
+ }
+ int minor = int.parse(text.substring(start, index));
+ index = _skipSpaces(text, index);
+ if (index != text.length) {
+ return false;
+ }
+ listener.handleLanguageVersion(token, major, minor);
+ return true;
+ }
+
+ int _skipSpaces(String text, int index) {
+ while (index < text.length && text.codeUnitAt(index) == $SPACE) {
+ ++index;
+ }
+ return index;
+ }
+
+ int _skipDigits(String text, int index) {
+ while (index < text.length) {
+ int code = text.codeUnitAt(index);
+ if (code < $0 || code > $9) {
+ break;
+ }
+ ++index;
+ }
+ return index;
+ }
+
/// This method exists for analyzer compatibility only
/// and will be removed once analyzer/fasta integration is complete.
///
@@ -3798,7 +3869,7 @@
}
Token next = token.next;
TokenType type = next.type;
- int tokenLevel = type.precedence;
+ int tokenLevel = _computePrecedence(type);
for (int level = tokenLevel; level >= precedence; --level) {
int lastBinaryExpressionLevel = -1;
while (identical(tokenLevel, level)) {
@@ -3821,13 +3892,10 @@
(identical(type, TokenType.MINUS_MINUS))) {
listener.handleUnaryPostfixAssignmentExpression(token.next);
token = next;
+ } else if (identical(type, TokenType.BANG)) {
+ listener.handleNonNullAssertExpression(token.next);
+ token = next;
}
- } else if (identical(tokenLevel, PREFIX_PRECEDENCE) &&
- (identical(type, TokenType.BANG))) {
- // The '!' has prefix precedence but here it's being used as a
- // postfix operator to assert the expression has a non-null value.
- listener.handleNonNullAssertExpression(token.next);
- token = next;
} else if (identical(tokenLevel, SELECTOR_PRECEDENCE)) {
if (identical(type, TokenType.PERIOD) ||
identical(type, TokenType.QUESTION_PERIOD)) {
@@ -3882,12 +3950,22 @@
}
next = token.next;
type = next.type;
- tokenLevel = type.precedence;
+ tokenLevel = _computePrecedence(type);
}
}
return token;
}
+ int _computePrecedence(TokenType type) {
+ if (identical(type, TokenType.BANG)) {
+ // The '!' has prefix precedence but here it's being used as a
+ // postfix operator to assert the expression has a non-null value.
+ return POSTFIX_PRECEDENCE;
+ } else {
+ return type.precedence;
+ }
+ }
+
Token parseCascadeExpression(Token token) {
Token cascadeOperator = token = token.next;
assert(optional('..', cascadeOperator));
diff --git a/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart b/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
index 848b65d..fd3c030 100644
--- a/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/scanner_main.dart
@@ -8,22 +8,18 @@
import '../scanner.dart' show ErrorToken, Token, scan;
-scanAll(Map<Uri, List<int>> files) {
+scanAll(Map<Uri, List<int>> files, {bool verbose: false, bool verify: false}) {
Stopwatch sw = new Stopwatch()..start();
int byteCount = 0;
files.forEach((Uri uri, List<int> bytes) {
var token = scan(bytes).tokens;
- if (const bool.fromEnvironment("printTokens")) {
- printTokens(token);
- }
- if (const bool.fromEnvironment('verifyErrorTokens')) {
- verifyErrorTokens(token, uri);
- }
+ if (verbose) printTokens(token);
+ if (verify) verifyErrorTokens(token, uri);
byteCount += bytes.length - 1;
});
sw.stop();
print("Scanning files took: ${sw.elapsed}");
- print("Bytes/ms: ${byteCount/sw.elapsedMilliseconds}");
+ print("Bytes/ms: ${byteCount / sw.elapsedMilliseconds}");
}
void printTokens(Token token) {
@@ -78,12 +74,25 @@
mainEntryPoint(List<String> arguments) {
Map<Uri, List<int>> files = <Uri, List<int>>{};
Stopwatch sw = new Stopwatch()..start();
- for (String name in arguments) {
- Uri uri = Uri.base.resolve(name);
+ bool verbose = const bool.fromEnvironment("printTokens");
+ bool verify = const bool.fromEnvironment('verifyErrorTokens');
+ for (String arg in arguments) {
+ if (arg.startsWith('--')) {
+ if (arg == '--print-tokens') {
+ verbose = true;
+ } else if (arg == '--verify-error-tokens') {
+ verify = true;
+ } else {
+ print('Unrecognized option: $arg');
+ }
+ continue;
+ }
+
+ Uri uri = Uri.base.resolve(arg);
List<int> bytes = readBytesFromFileSync(uri);
files[uri] = bytes;
}
sw.stop();
print("Reading files took: ${sw.elapsed}");
- scanAll(files);
+ scanAll(files, verbose: verbose, verify: verify);
}
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 32a7071..0f4d72f 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -944,8 +944,20 @@
library.endNestedDeclaration("<syntax-error>");
return;
}
- library.addNamedMixinApplication(documentationComment, metadata, name,
- typeVariables, modifiers, mixinApplication, interfaces, charOffset);
+
+ int startCharOffset = beginToken.charOffset;
+ int charEndOffset = endToken.charOffset;
+ library.addNamedMixinApplication(
+ documentationComment,
+ metadata,
+ name,
+ typeVariables,
+ modifiers,
+ mixinApplication,
+ interfaces,
+ startCharOffset,
+ charOffset,
+ charEndOffset);
}
@override
@@ -1168,13 +1180,14 @@
String documentationComment = getDocumentationComment(enumKeyword);
List<EnumConstantInfo> enumConstantInfos =
const FixedNullableList<EnumConstantInfo>().pop(stack, count);
- int charOffset = pop();
+ int charOffset = pop(); // identifier char offset.
+ int startCharOffset = enumKeyword.charOffset;
Object name = pop();
List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
checkEmpty(enumKeyword.charOffset);
if (name is ParserRecovery) return;
library.addEnum(documentationComment, metadata, name, enumConstantInfos,
- charOffset, leftBrace?.endGroup?.charOffset);
+ startCharOffset, charOffset, leftBrace?.endGroup?.charOffset);
}
@override
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 7aadb95..8d2b369 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
@@ -378,7 +378,9 @@
int modifiers,
T mixinApplication,
List<T> interfaces,
- int charOffset);
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset);
void addField(
String documentationComment,
@@ -453,6 +455,7 @@
List<MetadataBuilder> metadata,
String name,
List<EnumConstantInfo> enumConstantInfos,
+ int startCharOffset,
int charOffset,
int charEndOffset);
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 97a0382..4c3b6c9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -239,6 +239,12 @@
case "dart:async":
return utf8.encode(defaultDartAsyncSource);
+ case "dart:collection":
+ return utf8.encode(defaultDartCollectionSource);
+
+ case "dart:_internal":
+ return utf8.encode(defaultDartInternalSource);
+
default:
return utf8.encode(message == null ? "" : "/* ${message.message} */");
}
@@ -1136,6 +1142,8 @@
class Symbol {}
+class Set {}
+
class Type {}
class _InvocationMirror {
@@ -1221,3 +1229,20 @@
cancel() {}
}
""";
+
+/// A minimal implementation of dart:collection that is sufficient to create an
+/// instance of [CoreTypes] and compile program.
+const String defaultDartCollectionSource = """
+class _UnmodifiableSet {
+ final Map _map;
+ const _UnmodifiableSet(this._map);
+}
+""";
+
+/// A minimal implementation of dart:_internel that is sufficient to create an
+/// instance of [CoreTypes] and compile program.
+const String defaultDartInternalSource = """
+class Symbol {
+ const Symbol(String name);
+}
+""";
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
index d596481..5c8dbfa 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -131,6 +131,7 @@
}
if (declaredMethod is SyntheticAccessor) {
declaredMethod._field.type = inferredType;
+ declaredMethod._field.initializer = null;
} else {
if (kind == ProcedureKind.Getter) {
declaredMethod.function.returnType = inferredType;
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 64141b8..844ba61 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -31,15 +31,14 @@
CannotReadSdkSpecification/example: Fail
CantDetermineConstness/analyzerCode: Fail
CantDisambiguateAmbiguousInformation/analyzerCode: Fail # There's no analyzer code for that error yet.
-CantDisambiguateAmbiguousInformation/script: Fail # Can't be tested until 'spread-collections' flag is on.
CantDisambiguateNotEnoughInformation/analyzerCode: Fail # There's no analyzer code for that error yet.
-CantDisambiguateNotEnoughInformation/script: Fail # Can't be tested until 'spread-collections' flag is on.
CantInferPackagesFromManyInputs/analyzerCode: Fail
CantInferPackagesFromManyInputs/example: Fail
CantInferPackagesFromPackageUri/analyzerCode: Fail
CantInferPackagesFromPackageUri/example: Fail
CantInferTypeDueToCircularity/example: Fail
CantInferTypeDueToInconsistentOverrides/example: Fail
+CantUseControlFlowOrSpreadAsConstant/example: Fail
CantUseSuperBoundedTypeForInstanceCreation/analyzerCode: Fail
CantUseSuperBoundedTypeForInstanceCreation/example: Fail
ColonInPlaceOfIn/example: Fail
@@ -51,7 +50,6 @@
ConflictsWithSetter/example: Fail
ConflictsWithSetterWarning/example: Fail
ConflictsWithTypeVariable/example: Fail
-ConstAfterFactory/script1: Fail
ConstAndCovariant/script2: Fail
ConstAndFinal/declaration3: Fail
ConstAndFinal/declaration4: Fail
@@ -93,6 +91,8 @@
ConstEvalNotListOrSetInSpread/example: Fail
ConstEvalNotMapInSpread/example: Fail
ConstEvalNullValue/example: Fail
+ConstEvalUnevaluated/analyzerCode: Fail
+ConstEvalUnevaluated/example: Fail
ConstEvalZeroDivisor/example: Fail
ConstFieldWithoutInitializer/example: Fail
ConstructorNotFound/example: Fail
@@ -275,6 +275,7 @@
MissingMain/example: Fail
MissingPrefixInDeferredImport/example: Fail
MixinInferenceNoMatchingClass/example: Fail
+ModifierOutOfOrder/script1: Fail
MultipleExtends/script: Fail
MultipleImplements/script: Fail
MultipleLibraryDirectives/example: Fail
@@ -291,7 +292,6 @@
NonConstFactory/example: Fail
NonInstanceTypeVariableUse/example: Fail
NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
-NonNullAwareSpreadIsNull/script: Fail # Can't be tested until 'spread-collections' flag is on.
NonPartOfDirectiveInPart/script1: Fail
NotAConstantExpression/example: Fail
NotAType/example: Fail
@@ -358,15 +358,8 @@
SourceBodySummary/example: Fail
SourceOutlineSummary/analyzerCode: Fail
SourceOutlineSummary/example: Fail
-SpreadElementTypeMismatch/script: Fail # Can't be tested until 'spread-collections' flag is on.
-SpreadMapEntryElementKeyTypeMismatch/script: Fail # Can't be tested until 'spread-collections' flag is on.
-SpreadMapEntryElementValueTypeMismatch/script: Fail # Can't be tested until 'spread-collections' flag is on.
SpreadMapEntryTypeMismatch/analyzerCode: Fail # There's no analyzer code for that error yet.
-SpreadMapEntryTypeMismatch/script1: Fail # Can't be tested until 'spread-collections' flag is on.
-SpreadMapEntryTypeMismatch/script2: Fail # Can't be tested until 'spread-collections' flag is on.
SpreadTypeMismatch/analyzerCode: Fail # There's no analyzer code for that error yet.
-SpreadTypeMismatch/script1: Fail # Can't be tested until 'spread-collections' flag is on.
-SpreadTypeMismatch/script2: Fail # Can't be tested until 'spread-collections' flag is on.
StackOverflow/example: Fail
StaticAfterConst/script1: Fail
SuperAsExpression/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index e633dfd..bc98cf9 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -193,6 +193,9 @@
template: "Iteration can't be used in a constant map."
analyzerCode: NON_CONSTANT_MAP_ELEMENT
+ConstEvalUnevaluated:
+ template: "Could not evaluate constant expression."
+
NotConstantExpression:
template: "#string is not a constant expression."
analyzerCode: NOT_CONSTANT_EXPRESSION
@@ -218,7 +221,7 @@
ExperimentNotEnabled:
index: 93
- template: "This requires the --#string experiment to be enabled."
+ template: "This requires the '#string' experiment to be enabled."
tip: "Try enabling this experiment by adding it to the command line when compiling and running."
analyzerCode: ParserErrorCode.EXPERIMENT_NOT_ENABLED
@@ -629,11 +632,11 @@
tip: "Try using a constructor or factory that is 'const'."
analyzerCode: NOT_CONSTANT_EXPRESSION
-ConstAfterFactory:
+ModifierOutOfOrder:
index: 56
- template: "The modifier 'const' should be before the modifier 'factory'."
+ template: "The modifier '#string' should be before the modifier '#string2'."
tip: "Try re-ordering the modifiers."
- analyzerCode: ParserErrorCode.CONST_AFTER_FACTORY
+ analyzerCode: ParserErrorCode.MODIFIER_OUT_OF_ORDER
script:
- "class C { factory const C() = prefix.B.foo; }"
@@ -3197,6 +3200,10 @@
prefix?.Object;
}
+CantUseControlFlowOrSpreadAsConstant:
+ template: "'#lexeme' is not supported in constant expressions."
+ analyzerCode: NOT_CONSTANT_EXPRESSION
+
CantUseDeferredPrefixAsConstant:
template: >
'#lexeme' can't be used in a constant expression because it's marked as
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 abdd2f2..16125c3 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -439,11 +439,15 @@
for (Library lib in component.libraries) {
for (Class c in lib.classes) {
for (Procedure p in c.procedures) {
- if (p.function.body is! EmptyStatement) throw "Got body";
+ if (p.function.body != null && p.function.body is! EmptyStatement) {
+ throw "Got body (${p.function.body.runtimeType})";
+ }
}
}
for (Procedure p in lib.procedures) {
- if (p.function.body is! EmptyStatement) throw "Got body";
+ if (p.function.body != null && p.function.body is! EmptyStatement) {
+ throw "Got body (${p.function.body.runtimeType})";
+ }
}
}
}
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
index 5167dc9..c660edf 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
index 5167dc9..c660edf 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
index 799a3cd..0a70d79 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
index 494d25e..b5040a5 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
index 908e7aa..e223280 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
index 908e7aa..e223280 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
index b570941..26b5b7d 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "dart:core" as core;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
index 1ea2a3f..1f4e6c8 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
index e9712c6..eebc07b 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
index 7f12556..989c4c4 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:async" as asy;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
index db0bb07..512b965 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
index 5ac3a08..7b3dfb1 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
index 2a8fcd5..3cf5bf4 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
index 2a8fcd5..3cf5bf4 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
index a4a8839..feb2112 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
index 2b6f45a..b755990 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
index d1bc459..169b56c 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
index d1bc459..169b56c 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
index cf5fce5..3fa478a 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
index a6a7f4a..40b7cc6 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
index 175fa7c..714d35c 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
index 175fa7c..714d35c 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
index 1af399d..500b9e9 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
index daa8674..1e9676c 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
index 60e13fd..01f9ffd 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
index 60e13fd..01f9ffd 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
index 90d44a4..a454d85 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
index ed7f244..c8d8259 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
index 3982934..8acc0bb 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
index 3982934..8acc0bb 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
index d62739e..413f2f6 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
index 747f240..363f918 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
index a054b09..5e32eae 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
index a054b09..5e32eae 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
index 6ee7c79..cf7b29c 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
index cfe8c33..0e05e8f 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
index 423412d..982cf85 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
@@ -9,7 +9,7 @@
// ^^^
//
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
index 423412d..982cf85 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
// ^^^
//
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
index 7693576..592059d 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
index 6be11a9..29b1b92 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
@@ -9,7 +9,7 @@
// ^^^
//
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
index 6be11a9..29b1b92 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
// ^^^
//
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
diff --git a/pkg/front_end/testcases/export_main.dart.legacy.expect b/pkg/front_end/testcases/export_main.dart.legacy.expect
index 1f4d73b..2ce3772 100644
--- a/pkg/front_end/testcases/export_main.dart.legacy.expect
+++ b/pkg/front_end/testcases/export_main.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./hello.dart" as hel;
+import "hello.dart" as hel;
additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect b/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
index 1f4d73b..2ce3772 100644
--- a/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./hello.dart" as hel;
+import "hello.dart" as hel;
additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_main.dart.outline.expect b/pkg/front_end/testcases/export_main.dart.outline.expect
index 349482d..ce25789 100644
--- a/pkg/front_end/testcases/export_main.dart.outline.expect
+++ b/pkg/front_end/testcases/export_main.dart.outline.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./hello.dart" as hel;
+import "hello.dart" as hel;
additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_main.dart.strong.expect b/pkg/front_end/testcases/export_main.dart.strong.expect
index 1f4d73b..2ce3772 100644
--- a/pkg/front_end/testcases/export_main.dart.strong.expect
+++ b/pkg/front_end/testcases/export_main.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./hello.dart" as hel;
+import "hello.dart" as hel;
additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_main.dart.strong.transformed.expect b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
index 1f4d73b..2ce3772 100644
--- a/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./hello.dart" as hel;
+import "hello.dart" as hel;
additionalExports = (hel::main)
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
new file mode 100644
index 0000000..0105f44
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
@@ -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.md file.
+
+# Compile an application with the option of only getting an outline.
+# This is a reproduction of http://dartbug.com/36498.
+
+type: newworld
+strong: true
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ abstract class Foo {
+ int get foo;
+ }
+
+ class Bar implements Foo {
+ static int _foo = 0;
+ final foo = _foo++;
+ }
+ outlineOnly: true
\ No newline at end of file
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
index 0998224..80d04c7 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as inf;
+import "infer_consts_transitively_2_a.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
@@ -15,8 +15,8 @@
library;
import self as inf;
-import "./infer_consts_transitively_2.dart" as self;
-import "./infer_consts_transitively_2_b.dart" as inf2;
+import "infer_consts_transitively_2.dart" as self;
+import "infer_consts_transitively_2_b.dart" as inf2;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
index 0998224..80d04c7 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as inf;
+import "infer_consts_transitively_2_a.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
@@ -15,8 +15,8 @@
library;
import self as inf;
-import "./infer_consts_transitively_2.dart" as self;
-import "./infer_consts_transitively_2_b.dart" as inf2;
+import "infer_consts_transitively_2.dart" as self;
+import "infer_consts_transitively_2_b.dart" as inf2;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
index 3530a86..d434a70 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as inf;
+import "infer_consts_transitively_2_a.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_consts_transitively_2.dart" as self;
-import "./infer_consts_transitively_2_b.dart" as inf2;
+import "infer_consts_transitively_2.dart" as self;
+import "infer_consts_transitively_2_b.dart" as inf2;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
index 3530a86..d434a70 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as inf;
+import "infer_consts_transitively_2_a.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_consts_transitively_2.dart" as self;
-import "./infer_consts_transitively_2_b.dart" as inf2;
+import "infer_consts_transitively_2.dart" as self;
+import "infer_consts_transitively_2_b.dart" as inf2;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
index c06662b..6fa0ac1 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
-import "./infer_consts_transitively_2.dart" as test;
-import "./infer_consts_transitively_2_b.dart" as inf;
+import "infer_consts_transitively_2.dart" as test;
+import "infer_consts_transitively_2_b.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
@@ -13,7 +13,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as self;
+import "infer_consts_transitively_2_a.dart" as self;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
index c06662b..6fa0ac1 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
-import "./infer_consts_transitively_2.dart" as test;
-import "./infer_consts_transitively_2_b.dart" as inf;
+import "infer_consts_transitively_2.dart" as test;
+import "infer_consts_transitively_2_b.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
@@ -13,7 +13,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as self;
+import "infer_consts_transitively_2_a.dart" as self;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
index cbafa8c..f548afe 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2.dart" as test;
-import "./infer_consts_transitively_2_b.dart" as inf;
+import "infer_consts_transitively_2.dart" as test;
+import "infer_consts_transitively_2_b.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
@@ -14,7 +14,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as self;
+import "infer_consts_transitively_2_a.dart" as self;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
index cbafa8c..f548afe 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_consts_transitively_2.dart" as test;
-import "./infer_consts_transitively_2_b.dart" as inf;
+import "infer_consts_transitively_2.dart" as test;
+import "infer_consts_transitively_2_b.dart" as inf;
import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
@@ -14,7 +14,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_consts_transitively_2_a.dart" as self;
+import "infer_consts_transitively_2_a.dart" as self;
import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
index 4ea1232..9c32726 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
@@ -24,7 +24,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
index 4ea1232..9c32726 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
@@ -24,7 +24,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
index c251bf8..3e157ba 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
@@ -25,7 +25,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
index c251bf8..3e157ba 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
@@ -25,7 +25,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
index 878a97d..11440fd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
index 878a97d..11440fd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
index 28ec8b4..d23de18 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
index 28ec8b4..d23de18 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
index 9af84b2..3f3d4f9 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
@@ -15,7 +15,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
index 9af84b2..3f3d4f9 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
index 5112e7e..1ace456 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
@@ -15,7 +15,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
index 5112e7e..1ace456 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
@@ -15,7 +15,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
index ad43ba3..12230fd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
@@ -9,7 +9,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
index ad43ba3..12230fd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
index f5cd011..f6fbc3e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
@@ -10,7 +10,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
index f5cd011..f6fbc3e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
library test;
import self as self2;
import "dart:core" as core;
-import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+import "infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
index d442d47..6e1db6f 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
@@ -1,6 +1,6 @@
library test;
import self as self;
-import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
index d442d47..6e1db6f 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library test;
import self as self;
-import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
index ebfe694..1499bf7 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
@@ -13,7 +13,7 @@
// ^
//
import self as self;
-import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
index ebfe694..1499bf7 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
@@ -13,7 +13,7 @@
// ^
//
import self as self;
-import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
index db58bcd..426906e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
index db58bcd..426906e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
index 2af44de..4d2b4b8 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
@@ -14,7 +14,7 @@
//
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
index 2af44de..4d2b4b8 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
//
import self as self;
import "dart:core" as core;
-import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+import "infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
index 094adfb..7e55b99 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf;
+import "infer_statics_transitively_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf2;
-import "./infer_statics_transitively.dart" as self;
+import "infer_statics_transitively_b.dart" as inf2;
+import "infer_statics_transitively.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
index 094adfb..7e55b99 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf;
+import "infer_statics_transitively_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf2;
-import "./infer_statics_transitively.dart" as self;
+import "infer_statics_transitively_b.dart" as inf2;
+import "infer_statics_transitively.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
index 7d3fd79..99c4846 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf;
+import "infer_statics_transitively_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf2;
-import "./infer_statics_transitively.dart" as self;
+import "infer_statics_transitively_b.dart" as inf2;
+import "infer_statics_transitively.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
index 7d3fd79..99c4846 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf;
+import "infer_statics_transitively_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -16,8 +16,8 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf2;
-import "./infer_statics_transitively.dart" as self;
+import "infer_statics_transitively_b.dart" as inf2;
+import "infer_statics_transitively.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
index c14e037..b5b71b0 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively3_a.dart" as inf;
+import "infer_statics_transitively3_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
index c14e037..b5b71b0 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively3_a.dart" as inf;
+import "infer_statics_transitively3_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
index 8554b53..d80f5c4 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively3_a.dart" as inf;
+import "infer_statics_transitively3_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
index 8554b53..d80f5c4 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively3_a.dart" as inf;
+import "infer_statics_transitively3_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
index 041ca29..4e48a93 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -21,7 +21,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf2;
+import "infer_statics_transitively_a.dart" as inf2;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -44,8 +44,8 @@
library;
import self as inf2;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
index 041ca29..4e48a93 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -21,7 +21,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf2;
+import "infer_statics_transitively_a.dart" as inf2;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -44,8 +44,8 @@
library;
import self as inf2;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
index 295510c..9891055 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -21,7 +21,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf2;
+import "infer_statics_transitively_a.dart" as inf2;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -45,8 +45,8 @@
library;
import self as inf2;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
index 295510c..9891055 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -21,7 +21,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as inf2;
+import "infer_statics_transitively_a.dart" as inf2;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
@@ -45,8 +45,8 @@
library;
import self as inf2;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
index e1f6bf9..7c8af8a 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -19,7 +19,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as self;
+import "infer_statics_transitively_a.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
index e1f6bf9..7c8af8a 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -19,7 +19,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as self;
+import "infer_statics_transitively_a.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
index e5c5eb0..aa6b4be 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -19,7 +19,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as self;
+import "infer_statics_transitively_a.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
index e5c5eb0..aa6b4be 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
@@ -1,8 +1,8 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_statics_transitively_b.dart" as inf;
-import "./infer_statics_transitively.dart" as test;
+import "infer_statics_transitively_b.dart" as inf;
+import "infer_statics_transitively.dart" as test;
import "org-dartlang-testcase:///infer_statics_transitively.dart";
import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
@@ -19,7 +19,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_statics_transitively_a.dart" as self;
+import "infer_statics_transitively_a.dart" as self;
import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
index cdad9fa..1303bcc 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_with_method_invocations_a.dart" as inf;
+import "infer_statics_with_method_invocations_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
index cdad9fa..1303bcc 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_with_method_invocations_a.dart" as inf;
+import "infer_statics_with_method_invocations_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
index cdad9fa..1303bcc 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_with_method_invocations_a.dart" as inf;
+import "infer_statics_with_method_invocations_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
index cdad9fa..1303bcc 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_statics_with_method_invocations_a.dart" as inf;
+import "infer_statics_with_method_invocations_a.dart" as inf;
import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
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 4302f4f..707d09d 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
@@ -1,6 +1,6 @@
library test;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
@@ -29,7 +29,7 @@
library;
import self as inf;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
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 4302f4f..707d09d 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
@@ -1,6 +1,6 @@
library test;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
@@ -29,7 +29,7 @@
library;
import self as inf;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
index 1f0fd34..ff10b61 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
@@ -8,7 +8,7 @@
// ^
//
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
@@ -40,7 +40,7 @@
library;
import self as inf;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
index 1f0fd34..ff10b61 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
// ^
//
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
@@ -40,7 +40,7 @@
library;
import self as inf;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
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 2e91f62..f32c8d5 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
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
@@ -13,7 +13,7 @@
library test;
import self as test;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
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 2e91f62..f32c8d5 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
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
@@ -13,7 +13,7 @@
library test;
import self as test;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
index fe03c30..9b49051 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
@@ -21,7 +21,7 @@
// ^
//
import self as test;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
index fe03c30..9b49051 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+import "infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
@@ -21,7 +21,7 @@
// ^
//
import self as test;
-import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
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 2f73c7b..ecee2c6 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
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
@@ -34,7 +34,7 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
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 2f73c7b..ecee2c6 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
@@ -1,7 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
@@ -34,7 +34,7 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
index af26f52..1f20b42 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
@@ -9,7 +9,7 @@
//
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
@@ -45,7 +45,7 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
index af26f52..1f20b42 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
//
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
@@ -45,7 +45,7 @@
library;
import self as inf;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
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 c8150f5..54ed9fa 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
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
@@ -16,7 +16,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
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 c8150f5..54ed9fa 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
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
@@ -16,7 +16,7 @@
library test;
import self as test;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
index 09436d7..a10bf88 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
@@ -24,7 +24,7 @@
//
import self as test;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
index 09436d7..a10bf88 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+import "infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
@@ -24,7 +24,7 @@
//
import self as test;
import "dart:core" as core;
-import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+import "infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
index 34e8860..aa682e0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
+import "non_simple_many_libs_same_name_cycle_lib.dart" as non;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
@@ -14,7 +14,7 @@
library non_simple_many_libs_same_name_cycle_lib;
import self as non;
-import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "non_simple_many_libs_same_name_cycle.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
index 34e8860..aa682e0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
+import "non_simple_many_libs_same_name_cycle_lib.dart" as non;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
@@ -14,7 +14,7 @@
library non_simple_many_libs_same_name_cycle_lib;
import self as non;
-import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "non_simple_many_libs_same_name_cycle.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
index 63b417d..8b8c4bb 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
+import "non_simple_many_libs_same_name_cycle_lib.dart" as non;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
@@ -14,7 +14,7 @@
library non_simple_many_libs_same_name_cycle_lib;
import self as non;
-import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "non_simple_many_libs_same_name_cycle.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
index aa390f4..5ed003d 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
@@ -27,7 +27,7 @@
library non_simple_many_libs_same_name_cycle_lib;
import self as self2;
-import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "non_simple_many_libs_same_name_cycle.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
index aa390f4..5ed003d 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
@@ -27,7 +27,7 @@
library non_simple_many_libs_same_name_cycle_lib;
import self as self2;
-import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "non_simple_many_libs_same_name_cycle.dart" as self;
import "dart:core" as core;
import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
index 214711b..3afff4b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
@@ -1,7 +1,7 @@
library private;
import self as self;
import "dart:core" as core;
-import "./private_module.dart" as pri;
+import "private_module.dart" as pri;
import "org-dartlang-testcase:///private_module.dart";
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
index 214711b..3afff4b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library private;
import self as self;
import "dart:core" as core;
-import "./private_module.dart" as pri;
+import "private_module.dart" as pri;
import "org-dartlang-testcase:///private_module.dart";
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
index 6270b7f..518a7f4 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
@@ -1,7 +1,7 @@
library private;
import self as self;
import "dart:core" as core;
-import "./private_module.dart" as pri;
+import "private_module.dart" as pri;
import "org-dartlang-testcase:///private_module.dart";
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
index 214711b..3afff4b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
@@ -1,7 +1,7 @@
library private;
import self as self;
import "dart:core" as core;
-import "./private_module.dart" as pri;
+import "private_module.dart" as pri;
import "org-dartlang-testcase:///private_module.dart";
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
index 214711b..3afff4b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library private;
import self as self;
import "dart:core" as core;
-import "./private_module.dart" as pri;
+import "private_module.dart" as pri;
import "org-dartlang-testcase:///private_module.dart";
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
index 52f88c4..a545e64 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./no_such_method_private_setter_lib.dart" as no_;
+import "no_such_method_private_setter_lib.dart" as no_;
import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
index 52f88c4..a545e64 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./no_such_method_private_setter_lib.dart" as no_;
+import "no_such_method_private_setter_lib.dart" as no_;
import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
index 78df3aa..099c2ab 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./no_such_method_private_setter_lib.dart" as no_;
+import "no_such_method_private_setter_lib.dart" as no_;
import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
index 52f88c4..a545e64 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./no_such_method_private_setter_lib.dart" as no_;
+import "no_such_method_private_setter_lib.dart" as no_;
import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
index 52f88c4..a545e64 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./no_such_method_private_setter_lib.dart" as no_;
+import "no_such_method_private_setter_lib.dart" as no_;
import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect b/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect
index a057f8b..b9dac32 100644
--- a/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect
+++ b/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect
@@ -17,7 +17,7 @@
library;
import self as self2;
-import "./part_not_part_of_lib1.dart" as par;
+import "part_not_part_of_lib1.dart" as par;
import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect
index a057f8b..b9dac32 100644
--- a/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect
@@ -17,7 +17,7 @@
library;
import self as self2;
-import "./part_not_part_of_lib1.dart" as par;
+import "part_not_part_of_lib1.dart" as par;
import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.strong.expect b/pkg/front_end/testcases/part_not_part_of.dart.strong.expect
index a057f8b..b9dac32 100644
--- a/pkg/front_end/testcases/part_not_part_of.dart.strong.expect
+++ b/pkg/front_end/testcases/part_not_part_of.dart.strong.expect
@@ -17,7 +17,7 @@
library;
import self as self2;
-import "./part_not_part_of_lib1.dart" as par;
+import "part_not_part_of_lib1.dart" as par;
import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect b/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect
index a057f8b..b9dac32 100644
--- a/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect
@@ -17,7 +17,7 @@
library;
import self as self2;
-import "./part_not_part_of_lib1.dart" as par;
+import "part_not_part_of_lib1.dart" as par;
import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
index 2355e10..3e521af 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./private_method_tearoff_lib.dart" as pri;
+import "private_method_tearoff_lib.dart" as pri;
import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
index 2355e10..3e521af 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./private_method_tearoff_lib.dart" as pri;
+import "private_method_tearoff_lib.dart" as pri;
import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect b/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
index d1c7b20..dc1a5ae 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./private_method_tearoff_lib.dart" as pri;
+import "private_method_tearoff_lib.dart" as pri;
import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect b/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
index cb76ba8..1422ece 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./private_method_tearoff_lib.dart" as pri;
+import "private_method_tearoff_lib.dart" as pri;
import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
index cb76ba8..1422ece 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./private_method_tearoff_lib.dart" as pri;
+import "private_method_tearoff_lib.dart" as pri;
import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
index f4aa6fe..4e942b2 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./public_method_tearoff_lib.dart" as pub;
+import "public_method_tearoff_lib.dart" as pub;
import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
index f4aa6fe..4e942b2 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./public_method_tearoff_lib.dart" as pub;
+import "public_method_tearoff_lib.dart" as pub;
import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect b/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
index 2df3cac..7648db6 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./public_method_tearoff_lib.dart" as pub;
+import "public_method_tearoff_lib.dart" as pub;
import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect b/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
index a7c45ab..32ce75e 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./public_method_tearoff_lib.dart" as pub;
+import "public_method_tearoff_lib.dart" as pub;
import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
index a7c45ab..32ce75e 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./public_method_tearoff_lib.dart" as pub;
+import "public_method_tearoff_lib.dart" as pub;
import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.expect b/pkg/front_end/testcases/qualified.dart.legacy.expect
index 9abbf6a..bd70509 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.expect
@@ -23,7 +23,7 @@
//
import self as self;
import "dart:core" as core;
-import "./qualified_lib.dart" as lib;
+import "qualified_lib.dart" as lib;
import "org-dartlang-testcase:///qualified_lib.dart" as lib;
@@ -73,7 +73,7 @@
library test.qualified.lib;
import self as lib;
import "dart:core" as core;
-import "./qualified.dart" as self;
+import "qualified.dart" as self;
import "org-dartlang-testcase:///qualified.dart" as main;
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
index 6f18b56..df06d18 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
@@ -23,7 +23,7 @@
//
import self as self;
import "dart:core" as core;
-import "./qualified_lib.dart" as lib;
+import "qualified_lib.dart" as lib;
import "org-dartlang-testcase:///qualified_lib.dart" as lib;
@@ -76,7 +76,7 @@
library test.qualified.lib;
import self as lib;
import "dart:core" as core;
-import "./qualified.dart" as self;
+import "qualified.dart" as self;
import "org-dartlang-testcase:///qualified.dart" as main;
diff --git a/pkg/front_end/testcases/qualified.dart.outline.expect b/pkg/front_end/testcases/qualified.dart.outline.expect
index a8b09cd..0fca5f9 100644
--- a/pkg/front_end/testcases/qualified.dart.outline.expect
+++ b/pkg/front_end/testcases/qualified.dart.outline.expect
@@ -23,7 +23,7 @@
//
import self as self;
import "dart:core" as core;
-import "./qualified_lib.dart" as lib;
+import "qualified_lib.dart" as lib;
import "org-dartlang-testcase:///qualified_lib.dart" as lib;
@@ -62,7 +62,7 @@
library test.qualified.lib;
import self as lib;
import "dart:core" as core;
-import "./qualified.dart" as self;
+import "qualified.dart" as self;
import "org-dartlang-testcase:///qualified.dart" as main;
diff --git a/pkg/front_end/testcases/qualified.dart.strong.expect b/pkg/front_end/testcases/qualified.dart.strong.expect
index 2844fc6..9bc943f 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.expect
@@ -23,7 +23,7 @@
//
import self as self;
import "dart:core" as core;
-import "./qualified_lib.dart" as lib;
+import "qualified_lib.dart" as lib;
import "org-dartlang-testcase:///qualified_lib.dart" as lib;
@@ -73,7 +73,7 @@
library test.qualified.lib;
import self as lib;
import "dart:core" as core;
-import "./qualified.dart" as self;
+import "qualified.dart" as self;
import "org-dartlang-testcase:///qualified.dart" as main;
diff --git a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
index 807fc74..197c0d8 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
@@ -23,7 +23,7 @@
//
import self as self;
import "dart:core" as core;
-import "./qualified_lib.dart" as lib;
+import "qualified_lib.dart" as lib;
import "org-dartlang-testcase:///qualified_lib.dart" as lib;
@@ -76,7 +76,7 @@
library test.qualified.lib;
import self as lib;
import "dart:core" as core;
-import "./qualified.dart" as self;
+import "qualified.dart" as self;
import "org-dartlang-testcase:///qualified.dart" as main;
diff --git a/pkg/front_end/testcases/rasta/export.dart.legacy.expect b/pkg/front_end/testcases/rasta/export.dart.legacy.expect
index 467d2a4..b0410f4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.legacy.expect
@@ -1,6 +1,6 @@
library export;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
index 467d2a4..b0410f4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library export;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/export.dart.outline.expect b/pkg/front_end/testcases/rasta/export.dart.outline.expect
index 7c8cd4d..2314e9e 100644
--- a/pkg/front_end/testcases/rasta/export.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.outline.expect
@@ -1,6 +1,6 @@
library export;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/export.dart.strong.expect b/pkg/front_end/testcases/rasta/export.dart.strong.expect
index 467d2a4..b0410f4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.strong.expect
@@ -1,6 +1,6 @@
library export;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
index 467d2a4..b0410f4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
@@ -1,6 +1,6 @@
library export;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect b/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
index 33c77ad..e4794e6 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
import "org-dartlang-testcase:///export.dart";
@@ -10,7 +10,7 @@
library export;
import self as self2;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
index 33c77ad..e4794e6 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
import "org-dartlang-testcase:///export.dart";
@@ -10,7 +10,7 @@
library export;
import self as self2;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.outline.expect b/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
index d1a411b..42bbbc3 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
@@ -8,7 +8,7 @@
library export;
import self as self2;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.strong.expect b/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
index 33c77ad..e4794e6 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
import "org-dartlang-testcase:///export.dart";
@@ -10,7 +10,7 @@
library export;
import self as self2;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
index 33c77ad..e4794e6 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
import "org-dartlang-testcase:///export.dart";
@@ -10,7 +10,7 @@
library export;
import self as self2;
-import "./foo.dart" as foo;
+import "foo.dart" as foo;
additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
index a4ac799..0a16b0d 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
index a4ac799..0a16b0d 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
index a4ac799..0a16b0d 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
@@ -1,6 +1,6 @@
library;
import self as self;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
index 52df70f..601cdae 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./deferred_lib.dart" as def;
+import "deferred_lib.dart" as def;
import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
index be09171..bbd2127 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./mixin_library.dart" as mix;
+import "mixin_library.dart" as mix;
import "org-dartlang-testcase:///mixin_library.dart";
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
index 3c31738..90e3685 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./mixin_library.dart" as mix;
+import "mixin_library.dart" as mix;
import "org-dartlang-testcase:///mixin_library.dart";
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
index 64b6bb0..f8efb4c 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./mixin_library.dart" as mix;
+import "mixin_library.dart" as mix;
import "org-dartlang-testcase:///mixin_library.dart";
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
index 5ecf3b5..aba8974 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./mixin_library.dart" as mix;
+import "mixin_library.dart" as mix;
import "org-dartlang-testcase:///mixin_library.dart";
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
index b75366e..16fd29e 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./issue_34291_lib.dart" as iss;
+import "issue_34291_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
index b75366e..16fd29e 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./issue_34291_lib.dart" as iss;
+import "issue_34291_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
index a72a23c..7e0d3a3 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
@@ -1,7 +1,7 @@
library;
import self as self;
import "dart:core" as core;
-import "./issue_34291_lib.dart" as iss;
+import "issue_34291_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
index 4bc0e99..6411f4c 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
@@ -84,7 +84,7 @@
//
import self as self;
import "dart:core" as core;
-import "./issue_34403_lib.dart" as iss;
+import "issue_34403_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
index 4bc0e99..6411f4c 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
@@ -84,7 +84,7 @@
//
import self as self;
import "dart:core" as core;
-import "./issue_34403_lib.dart" as iss;
+import "issue_34403_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
index 67776e6..ae029a9 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
@@ -84,7 +84,7 @@
//
import self as self;
import "dart:core" as core;
-import "./issue_34403_lib.dart" as iss;
+import "issue_34403_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
index 67776e6..ae029a9 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
@@ -84,7 +84,7 @@
//
import self as self;
import "dart:core" as core;
-import "./issue_34403_lib.dart" as iss;
+import "issue_34403_lib.dart" as iss;
import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 76c12be..d64034e 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -139,7 +139,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 23;
+ UInt32 formatVersion = 25;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@@ -238,8 +238,11 @@
List<Field> fields;
List<Procedure> procedures;
+ List<UInt> sourceReferences; // list of sources owned by library, indexes into UriSource on Component.
+
// Library index. Offsets are used to get start (inclusive) and end (exclusive) byte positions for
// a specific class or procedure. Note the "+1" to account for needing the end of the last entry.
+ UInt32 sourceReferencesOffset;
UInt32[classes.length + 1] classOffsets;
UInt32 classCount = classes.length;
UInt32[procedures.length + 1] procedureOffsets;
@@ -901,6 +904,13 @@
}
type ConstantExpression extends Expression {
+ Byte tag = 106;
+ FileOffset fileOffset;
+ DartType type;
+ ConstantReference constantReference;
+}
+
+type Deprecated_ConstantExpression extends Expression {
Byte tag = 107;
ConstantReference constantReference;
}
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 140a9e4..f8709b7 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -661,6 +661,10 @@
annotations.add(node);
node.parent = this;
}
+
+ Location _getLocationInEnclosingFile(int offset) {
+ return _getLocationInComponent(enclosingComponent, fileUri, offset);
+ }
}
/// The degree to which the contents of a class have been loaded into memory.
@@ -3756,22 +3760,25 @@
class ConstantExpression extends Expression {
Constant constant;
+ DartType type;
- ConstantExpression(this.constant) {
+ ConstantExpression(this.constant, [this.type = const DynamicType()]) {
assert(constant != null);
}
- DartType getStaticType(TypeEnvironment types) => constant.getType(types);
+ DartType getStaticType(TypeEnvironment types) => type;
accept(ExpressionVisitor v) => v.visitConstantExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitConstantExpression(this, arg);
visitChildren(Visitor v) {
constant?.acceptReference(v);
+ type?.accept(v);
}
transformChildren(Transformer v) {
constant = v.visitConstant(constant);
+ type = v.visitDartType(type);
}
}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index ad088c0..6526e31 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1656,7 +1656,10 @@
var typeArguments = readDartTypeList();
return new Instantiation(expression, typeArguments);
case Tag.ConstantExpression:
- return new ConstantExpression(readConstantReference());
+ int offset = readOffset();
+ DartType type = readDartType();
+ Constant constant = readConstantReference();
+ return new ConstantExpression(constant, type)..fileOffset = offset;
default:
throw fail('unexpected expression tag: $tag');
}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 2b9baba..4b3434c 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -25,6 +25,7 @@
final UriIndexer _sourceUriIndexer = new UriIndexer();
bool _currentlyInNonimplementation = false;
final List<bool> _sourcesFromRealImplementation = new List<bool>();
+ final List<bool> _sourcesFromRealImplementationInLibrary = new List<bool>();
Map<LibraryDependency, int> _libraryDependencyIndex =
<LibraryDependency, int>{};
@@ -263,16 +264,19 @@
}
// Returns the new active file uri.
- Uri writeUriReference(Uri uri) {
+ void writeUriReference(Uri uri) {
final int index = _sourceUriIndexer.put(uri);
writeUInt30(index);
if (!_currentlyInNonimplementation) {
+ if (_sourcesFromRealImplementationInLibrary.length <= index) {
+ _sourcesFromRealImplementationInLibrary.length = index + 1;
+ }
+ _sourcesFromRealImplementationInLibrary[index] = true;
if (_sourcesFromRealImplementation.length <= index) {
_sourcesFromRealImplementation.length = index + 1;
}
_sourcesFromRealImplementation[index] = true;
}
- return uri;
}
void writeList<T>(List<T> items, void writeItem(T x)) {
@@ -921,7 +925,26 @@
writeProcedureNodeList(node.procedures);
procedureOffsets.add(getBufferOffset());
+ // Dump all source-references used in this library; used by the VM.
+ int sourceReferencesOffset = getBufferOffset();
+ int sourceReferencesCount = 0;
+ // Note: We start at 1 because 0 is the null-entry and we don't want to
+ // include that.
+ for (int i = 1; i < _sourcesFromRealImplementationInLibrary.length; i++) {
+ if (_sourcesFromRealImplementationInLibrary[i] == true) {
+ sourceReferencesCount++;
+ }
+ }
+ writeUInt30(sourceReferencesCount);
+ for (int i = 1; i < _sourcesFromRealImplementationInLibrary.length; i++) {
+ if (_sourcesFromRealImplementationInLibrary[i] == true) {
+ writeUInt30(i);
+ _sourcesFromRealImplementationInLibrary[i] = false;
+ }
+ }
+
// Fixed-size ints at the end used as an index.
+ writeUInt32(sourceReferencesOffset);
assert(classOffsets.length > 0);
for (int i = 0; i < classOffsets.length; ++i) {
int offset = classOffsets[i];
@@ -1758,6 +1781,8 @@
@override
void visitConstantExpression(ConstantExpression node) {
writeByte(Tag.ConstantExpression);
+ writeOffset(node.fileOffset);
+ writeDartType(node.type);
writeConstantReference(node.constant);
}
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 42200e1..8e52b70 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -122,7 +122,10 @@
static const int ClassReference = 100;
static const int MemberReference = 101;
- static const int ConstantExpression = 107;
+ static const int ConstantExpression = 106;
+
+ // Tag is deprecated since version 24.
+ static const int Deprecated_ConstantExpression = 107;
/// 108 is occupied by [RedirectingFactoryConstructor] (member).
/// 109 is occupied by [SetLiteral] (expression).
@@ -147,7 +150,7 @@
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
- static const int BinaryFormatVersion = 23;
+ static const int BinaryFormatVersion = 25;
}
abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index fd3bb4d..d5f1940 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -276,7 +276,8 @@
}
visitConstantExpression(ConstantExpression node) {
- return new ConstantExpression(visitConstant(node.constant));
+ return new ConstantExpression(
+ visitConstant(node.constant), visitType(node.type));
}
visitStringLiteral(StringLiteral node) {
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
index ae2829c..f549933 100644
--- a/pkg/kernel/lib/import_table.dart
+++ b/pkg/kernel/lib/import_table.dart
@@ -4,7 +4,6 @@
library kernel.import_table;
import 'ast.dart';
-import 'package:path/path.dart' as path;
abstract class ImportTable {
int getImportIndex(Library library);
@@ -89,12 +88,8 @@
bool isTargetSchemeFileOrCustom = isFileOrCustomScheme(targetUri);
bool isReferenceSchemeFileOrCustom = isFileOrCustomScheme(referenceUri);
if (isTargetSchemeFileOrCustom && isReferenceSchemeFileOrCustom) {
- var targetDirectory = path.dirname(targetUri.path);
- var currentDirectory = path.dirname(referenceUri.path);
- var relativeDirectory =
- path.relative(targetDirectory, from: currentDirectory);
- var filename = path.basename(targetUri.path);
- table.addImport(target, '$relativeDirectory/$filename');
+ String relativeUri = relativeUriPath(targetUri, referenceUri);
+ table.addImport(target, relativeUri);
} else if (isTargetSchemeFileOrCustom) {
// Cannot import a file:URI from a dart:URI or package:URI.
// We may want to remove this restriction, but for now it's just a sanity
@@ -126,3 +121,36 @@
}
}
}
+
+String relativeUriPath(Uri target, Uri ref) {
+ List<String> targetSegments = target.pathSegments;
+ List<String> refSegments = ref.pathSegments;
+ int to = refSegments.length;
+ if (targetSegments.length < to) to = targetSegments.length;
+ to--; // The last entry is the filename, here we compare only directories.
+ int same = -1;
+ for (int i = 0; i < to; i++) {
+ if (targetSegments[i] == refSegments[i]) {
+ same = i;
+ } else {
+ break;
+ }
+ }
+ if (same == targetSegments.length - 2 &&
+ targetSegments.length == refSegments.length) {
+ // Both parts have the same number of segments,
+ // and they agree on all directories.
+ if (targetSegments.last == "") return ".";
+ return targetSegments.last;
+ }
+ List<String> path = new List<String>();
+ int oked = same + 1;
+ while (oked < refSegments.length - 1) {
+ path.add("..");
+ oked++;
+ }
+ path.addAll(targetSegments.skip(same + 1));
+
+ if (path.isEmpty) path.add(".");
+ return path.join("/");
+}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index a78a3ab..b599cdf 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -747,7 +747,8 @@
new VariableGet(iteratorVariable),
new Name('moveNext'),
new Arguments(<Expression>[]),
- helper.streamIteratorMoveNext));
+ helper.streamIteratorMoveNext))
+ ..fileOffset = stmt.fileOffset;
// _asyncStarMoveNextHelper(:stream)
var asyncStarMoveNextCall = new StaticInvocation(
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index f81ec66..8faae52 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -811,6 +811,11 @@
}
@override
+ visitConstantExpression(ConstantExpression node) {
+ return node.type;
+ }
+
+ @override
visitAssertStatement(AssertStatement node) {
visitExpression(node.condition);
if (node.message != null) {
@@ -1034,11 +1039,4 @@
@override
visitInvalidInitializer(InvalidInitializer node) {}
-
- @override
- visitConstantExpression(ConstantExpression node) {
- // Without explicitly running the "constants" transformation, we should
- // never get here!
- throw 'unreachable';
- }
}
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index d9d4a46..3cbab2e 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -8,14 +8,9 @@
environment:
sdk: '>=2.0.0-dev.48.0 <3.0.0'
dependencies:
- path: ^1.3.9
args: '>=0.13.4 <2.0.0'
dev_dependencies:
- expect:
- path: ../expect
- front_end:
- path: ../front_end
- test:
- path: ../../third_party/pkg/test
- testing:
- path: ../testing
+ expect: any
+ front_end: any
+ test: any
+ testing: any
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index c195192..469b603 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -111,7 +111,7 @@
_assertLibraryText(libWithB, '''
library test_b;
import self as self;
-import "./test.dart" as test;
+import "test.dart" as test;
class B extends test::A {}
''');
diff --git a/pkg/kernel/test/import_table_test.dart b/pkg/kernel/test/import_table_test.dart
new file mode 100644
index 0000000..d02207f
--- /dev/null
+++ b/pkg/kernel/test/import_table_test.dart
@@ -0,0 +1,35 @@
+import 'package:kernel/import_table.dart';
+
+main() {
+ List<String> paths = new List<String>();
+ paths.add("file://");
+ paths.add("file:///a");
+ paths.add("file:///a/b");
+ paths.add("file:///a/b/c");
+
+ int end = paths.length;
+ for (int i = 0; i < end; i++) {
+ paths.add(paths[i] + "/d.dart");
+ paths.add(paths[i] + "/e.dart");
+ paths.add(paths[i] + "/");
+ }
+ paths[0] = "file:///";
+ paths.sort();
+ for (int i = 0; i < paths.length; i++) {
+ for (int j = 0; j < paths.length; j++) {
+ check(paths[i], paths[j]);
+ }
+ }
+ check("", "");
+}
+
+void check(String target, String ref) {
+ Uri uriTarget = Uri.parse(target);
+ Uri uriRef = Uri.parse(ref);
+ String relative = relativeUriPath(uriTarget, uriRef);
+ if (Uri.base.resolveUri(uriTarget) !=
+ Uri.base.resolveUri(uriRef).resolve(relative)) {
+ throw "Failure on '$target' and '$ref': Got '$relative' which resolves to "
+ "${uriRef.resolve(relative)}";
+ }
+}
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 0686cd6..cfb843e 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -281,6 +281,11 @@
emitWord(_encodeAD(Opcode.kInterfaceCall, ra, rd));
}
+ void emitUncheckedInterfaceCall(int ra, int rd) {
+ emitSourcePosition();
+ emitWord(_encodeAD(Opcode.kUncheckedInterfaceCall, ra, rd));
+ }
+
void emitDynamicCall(int ra, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kDynamicCall, ra, rd));
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 8702add..730ee69 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,7 +10,7 @@
/// 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 = 4;
+const int currentBytecodeFormatVersion = 6;
/// Version of experimental / bleeding edge bytecode format.
/// Produced by bytecode generator when --use-future-bytecode-format
@@ -125,6 +125,20 @@
kDirectCall,
kAllocateClosure,
+
+ kUncheckedInterfaceCall,
+
+ // Double operations.
+ kNegateDouble,
+ kAddDouble,
+ kSubDouble,
+ kMulDouble,
+ kDivDouble,
+ kCompareDoubleEq,
+ kCompareDoubleGt,
+ kCompareDoubleLt,
+ kCompareDoubleGe,
+ kCompareDoubleLe,
}
enum Encoding {
@@ -304,6 +318,28 @@
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Opcode.kAllocateClosure: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kUncheckedInterfaceCall: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kNegateDouble: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kAddDouble: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSubDouble: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kMulDouble: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kDivDouble: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCompareDoubleEq: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCompareDoubleGt: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCompareDoubleLt: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCompareDoubleGe: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCompareDoubleLe: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
};
// Should match constant in runtime/vm/stack_frame_dbc.h.
@@ -322,6 +358,7 @@
switch (opcode) {
case Opcode.kIndirectStaticCall:
case Opcode.kInterfaceCall:
+ case Opcode.kUncheckedInterfaceCall:
case Opcode.kDynamicCall:
case Opcode.kNativeCall:
case Opcode.kDirectCall:
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 0e54ba3..f8ae346 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -33,7 +33,8 @@
getDefaultFunctionTypeArguments,
getInstantiatorTypeArguments,
hasFreeTypeParameters,
- hasInstantiatorTypeArguments;
+ hasInstantiatorTypeArguments,
+ isUncheckedCall;
import 'local_vars.dart' show LocalVariables;
import 'nullability_detector.dart' show NullabilityDetector;
import 'object_table.dart' show ObjectHandle, ObjectTable, NameAndType;
@@ -2252,6 +2253,7 @@
break;
case Opcode.kNegateInt:
+ case Opcode.kNegateDouble:
_generateNode(node.receiver);
break;
@@ -2270,6 +2272,15 @@
case Opcode.kCompareIntLt:
case Opcode.kCompareIntGe:
case Opcode.kCompareIntLe:
+ case Opcode.kAddDouble:
+ case Opcode.kSubDouble:
+ case Opcode.kMulDouble:
+ case Opcode.kDivDouble:
+ case Opcode.kCompareDoubleEq:
+ case Opcode.kCompareDoubleGt:
+ case Opcode.kCompareDoubleLt:
+ case Opcode.kCompareDoubleGe:
+ case Opcode.kCompareDoubleLe:
_generateNode(node.receiver);
_generateNode(node.arguments.positional.single);
break;
@@ -2281,9 +2292,13 @@
asm.emitBytecode0(opcode);
}
- void _genInstanceCall(int totalArgCount, int callCpIndex, bool isDynamic) {
+ void _genInstanceCall(
+ int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked) {
if (isDynamic) {
+ assert(!isUnchecked);
asm.emitDynamicCall(totalArgCount, callCpIndex);
+ } else if (isUnchecked) {
+ asm.emitUncheckedInterfaceCall(totalArgCount, callCpIndex);
} else {
asm.emitInterfaceCall(totalArgCount, callCpIndex);
}
@@ -2305,6 +2320,8 @@
interfaceTarget = null;
}
final isDynamic = interfaceTarget == null;
+ final isUnchecked =
+ isUncheckedCall(interfaceTarget, node.receiver, typeEnvironment);
_genArguments(node.receiver, args);
final argDesc =
objectTable.getArgDescHandleByArguments(args, hasReceiver: true);
@@ -2314,7 +2331,7 @@
args.named.length +
1 /* receiver */ +
(args.types.isNotEmpty ? 1 : 0) /* type arguments */;
- _genInstanceCall(totalArgCount, callCpIndex, isDynamic);
+ _genInstanceCall(totalArgCount, callCpIndex, isDynamic, isUnchecked);
}
@override
@@ -2324,7 +2341,7 @@
final argDesc = objectTable.getArgDescHandle(1);
final callCpIndex = cp.addInstanceCall(
InvocationKind.getter, node.interfaceTarget, node.name, argDesc);
- _genInstanceCall(1, callCpIndex, isDynamic);
+ _genInstanceCall(1, callCpIndex, isDynamic, /*isUnchecked=*/ false);
}
@override
@@ -2340,10 +2357,12 @@
}
final isDynamic = node.interfaceTarget == null;
+ final isUnchecked =
+ isUncheckedCall(node.interfaceTarget, node.receiver, typeEnvironment);
final argDesc = objectTable.getArgDescHandle(2);
final callCpIndex = cp.addInstanceCall(
InvocationKind.setter, node.interfaceTarget, node.name, argDesc);
- _genInstanceCall(2, callCpIndex, isDynamic);
+ _genInstanceCall(2, callCpIndex, isDynamic, isUnchecked);
asm.emitDrop1();
if (hasResult) {
diff --git a/pkg/vm/lib/bytecode/generics.dart b/pkg/vm/lib/bytecode/generics.dart
index 9382da6..4e795d6 100644
--- a/pkg/vm/lib/bytecode/generics.dart
+++ b/pkg/vm/lib/bytecode/generics.dart
@@ -7,7 +7,9 @@
import 'dart:math' show min;
import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
bool hasInstantiatorTypeArguments(Class c) {
for (; c != null; c = c.superclass) {
@@ -236,3 +238,81 @@
visit(node.returnType);
}
}
+
+/// Returns static type of [expr].
+DartType getStaticType(Expression expr, TypeEnvironment typeEnvironment) {
+ // TODO(dartbug.com/34496): Remove this try/catch once
+ // getStaticType() is reliable.
+ try {
+ return expr.getStaticType(typeEnvironment);
+ } catch (e) {
+ return const DynamicType();
+ }
+}
+
+/// Returns `true` if [type] cannot be extended in user code.
+bool isSealedType(DartType type, CoreTypes coreTypes) {
+ if (type is InterfaceType) {
+ final cls = type.classNode;
+ return cls == coreTypes.intClass ||
+ cls == coreTypes.doubleClass ||
+ cls == coreTypes.boolClass ||
+ cls == coreTypes.stringClass ||
+ cls == coreTypes.nullClass;
+ }
+ return false;
+}
+
+// Returns true if an instance call to [interfaceTarget] with given
+// [receiver] can omit argument type checks needed due to generic-covariant
+// parameters.
+bool isUncheckedCall(Member interfaceTarget, Expression receiver,
+ TypeEnvironment typeEnvironment) {
+ if (interfaceTarget == null) {
+ // Dynamic call cannot be unchecked.
+ return false;
+ }
+
+ if (!_hasGenericCovariantParameters(interfaceTarget)) {
+ // Unchecked call makes sense only if there are generic-covariant parameters.
+ return false;
+ }
+
+ // Calls via [this] do not require checks.
+ if (receiver is ThisExpression) {
+ return true;
+ }
+
+ DartType receiverStaticType = getStaticType(receiver, typeEnvironment);
+ if (receiverStaticType is InterfaceType) {
+ if (receiverStaticType.typeArguments.isEmpty) {
+ return true;
+ }
+
+ if (receiverStaticType.typeArguments
+ .every((t) => isSealedType(t, typeEnvironment.coreTypes))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool _hasGenericCovariantParameters(Member target) {
+ if (target is Field) {
+ return target.isGenericCovariantImpl;
+ } else if (target is Procedure) {
+ for (var param in target.function.positionalParameters) {
+ if (param.isGenericCovariantImpl) {
+ return true;
+ }
+ }
+ for (var param in target.function.namedParameters) {
+ if (param.isGenericCovariantImpl) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ throw 'Unexpected instance call target ${target.runtimeType} $target';
+ }
+}
diff --git a/pkg/vm/lib/bytecode/nullability_detector.dart b/pkg/vm/lib/bytecode/nullability_detector.dart
index 961dfef..414807b 100644
--- a/pkg/vm/lib/bytecode/nullability_detector.dart
+++ b/pkg/vm/lib/bytecode/nullability_detector.dart
@@ -129,4 +129,14 @@
Opcode.kCompareIntLt,
Opcode.kCompareIntGe,
Opcode.kCompareIntLe,
+ Opcode.kNegateDouble,
+ Opcode.kAddDouble,
+ Opcode.kSubDouble,
+ Opcode.kMulDouble,
+ Opcode.kDivDouble,
+ Opcode.kCompareDoubleEq,
+ Opcode.kCompareDoubleGt,
+ Opcode.kCompareDoubleLt,
+ Opcode.kCompareDoubleGe,
+ Opcode.kCompareDoubleLe,
]);
diff --git a/pkg/vm/lib/bytecode/recognized_methods.dart b/pkg/vm/lib/bytecode/recognized_methods.dart
index b658fdf..6b776cc 100644
--- a/pkg/vm/lib/bytecode/recognized_methods.dart
+++ b/pkg/vm/lib/bytecode/recognized_methods.dart
@@ -8,6 +8,7 @@
import 'package:kernel/type_environment.dart' show TypeEnvironment;
import 'dbc.dart';
+import 'generics.dart' show getStaticType;
class RecognizedMethods {
static const binaryIntOps = <String, Opcode>{
@@ -28,21 +29,27 @@
'<=': Opcode.kCompareIntLe,
};
+ static const binaryDoubleOps = <String, Opcode>{
+ '+': Opcode.kAddDouble,
+ '-': Opcode.kSubDouble,
+ '*': Opcode.kMulDouble,
+ '/': Opcode.kDivDouble,
+ '==': Opcode.kCompareDoubleEq,
+ '>': Opcode.kCompareDoubleGt,
+ '<': Opcode.kCompareDoubleLt,
+ '>=': Opcode.kCompareDoubleGe,
+ '<=': Opcode.kCompareDoubleLe,
+ };
+
final TypeEnvironment typeEnv;
RecognizedMethods(this.typeEnv);
- DartType staticType(Expression expr) {
- // TODO(dartbug.com/34496): Remove this ugly try/catch once
- // getStaticType() is reliable.
- try {
- return expr.getStaticType(typeEnv);
- } catch (e) {
- return const DynamicType();
- }
- }
+ DartType staticType(Expression expr) => getStaticType(expr, typeEnv);
- bool isInt(Expression expr) => staticType(expr) == typeEnv.intType;
+ bool isInt(DartType type) => type == typeEnv.intType;
+
+ bool isDouble(DartType type) => type == typeEnv.doubleType;
Opcode specializedBytecodeFor(MethodInvocation node) {
final args = node.arguments;
@@ -65,8 +72,13 @@
}
Opcode specializedBytecodeForUnaryOp(String selector, Expression arg) {
- if (selector == 'unary-' && isInt(arg)) {
- return Opcode.kNegateInt;
+ if (selector == 'unary-') {
+ final argType = staticType(arg);
+ if (isInt(argType)) {
+ return Opcode.kNegateInt;
+ } else if (isDouble(argType)) {
+ return Opcode.kNegateDouble;
+ }
}
return null;
@@ -78,10 +90,15 @@
return Opcode.kEqualsNull;
}
- if (isInt(a) && isInt(b)) {
+ final aType = staticType(a);
+ final bType = staticType(b);
+
+ if (isInt(aType) && isInt(bType)) {
return binaryIntOps[selector];
}
-
+ if (isDouble(aType) && isDouble(bType)) {
+ return binaryDoubleOps[selector];
+ }
return null;
}
}
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index ecd0c8e..6685160 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -34,6 +34,7 @@
convertFileOrUriArgumentToUri,
createFrontEndTarget,
createFrontEndFileSystem,
+ setVMEnvironmentDefines,
writeDepfile;
ArgParser argParser = new ArgParser(allowTrailingOptions: true)
@@ -331,6 +332,8 @@
Component component;
if (options['incremental']) {
_compilerOptions = compilerOptions;
+ setVMEnvironmentDefines(environmentDefines, _compilerOptions);
+
_compilerOptions.omitPlatform = false;
_generator =
generator ?? _createGenerator(new Uri.file(_initializeFromDill));
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index dfc4b67..452e2ca 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -297,28 +297,7 @@
new ErrorDetector(previousErrorHandler: options.onDiagnostic);
options.onDiagnostic = errorDetector;
- // TODO(alexmarkov): move this logic into VmTarget and call from front-end
- // in order to have the same defines when compiling platform.
- assert(environmentDefines != null);
- if (environmentDefines['dart.vm.product'] == 'true') {
- environmentDefines['dart.developer.causal_async_stacks'] = 'false';
- }
- environmentDefines['dart.isVM'] = 'true';
- // TODO(dartbug.com/36460): Derive dart.library.* definitions from platform.
- for (String library in options.target.extraRequiredLibraries) {
- Uri libraryUri = Uri.parse(library);
- if (libraryUri.scheme == 'dart') {
- final path = libraryUri.path;
- if (!path.startsWith('_')) {
- environmentDefines['dart.library.${path}'] = 'true';
- }
- }
- }
- // dart:core is not mentioned in Target.extraRequiredLibraries.
- environmentDefines['dart.library.core'] = 'true';
-
- options.environmentDefines = environmentDefines;
-
+ setVMEnvironmentDefines(environmentDefines, options);
final component = await kernelForProgram(source, options);
// Run global transformations only if component is correct.
@@ -355,6 +334,30 @@
return component;
}
+void setVMEnvironmentDefines(
+ Map<String, dynamic> environmentDefines, CompilerOptions options) {
+ // TODO(alexmarkov): move this logic into VmTarget and call from front-end
+ // in order to have the same defines when compiling platform.
+ assert(environmentDefines != null);
+ if (environmentDefines['dart.vm.product'] == 'true') {
+ environmentDefines['dart.developer.causal_async_stacks'] = 'false';
+ }
+ environmentDefines['dart.isVM'] = 'true';
+ // TODO(dartbug.com/36460): Derive dart.library.* definitions from platform.
+ for (String library in options.target.extraRequiredLibraries) {
+ Uri libraryUri = Uri.parse(library);
+ if (libraryUri.scheme == 'dart') {
+ final path = libraryUri.path;
+ if (!path.startsWith('_')) {
+ environmentDefines['dart.library.${path}'] = 'true';
+ }
+ }
+ }
+ // dart:core is not mentioned in Target.extraRequiredLibraries.
+ environmentDefines['dart.library.core'] = 'true';
+ options.environmentDefines = environmentDefines;
+}
+
Future _runGlobalTransformations(
Uri source,
CompilerOptions compilerOptions,
diff --git a/pkg/vm/lib/transformations/pragma.dart b/pkg/vm/lib/transformations/pragma.dart
index ff3431b..0fa7432 100644
--- a/pkg/vm/lib/transformations/pragma.dart
+++ b/pkg/vm/lib/transformations/pragma.dart
@@ -50,10 +50,14 @@
if (annotation is ConstantExpression) {
Constant constant = annotation.constant;
if (constant is InstanceConstant) {
- if (constant.classReference.node == coreTypes.pragmaClass) {
+ if (constant.classNode == coreTypes.pragmaClass) {
pragmaConstant = constant;
}
+ } else if (constant is UnevaluatedConstant) {
+ throw 'Error: unevaluated constant $constant';
}
+ } else {
+ throw 'Error: non-constant annotation $annotation';
}
if (pragmaConstant == null) return null;
diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
index ff23f2f..9a496a8 100644
--- a/pkg/vm/test/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -19,7 +19,11 @@
import 'package:vm/target/vm.dart' show VmTarget;
-const bool kDumpActualResult = const bool.fromEnvironment('dump.actual.result');
+/// Environment define to update expectation files on failures.
+const kUpdateExpectations = 'updateExpectations';
+
+/// Environment define to dump actual results alongside expectations.
+const kDumpActualResult = 'dump.actual.result';
class TestingVmTarget extends VmTarget {
TestingVmTarget(TargetFlags flags) : super(flags);
@@ -37,6 +41,7 @@
final options = new CompilerOptions()
..target = target
..linkedDependencies = <Uri>[platformKernel]
+ ..environmentDefines = <String, String>{}
..onDiagnostic = (DiagnosticMessage message) {
fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
};
@@ -81,14 +86,62 @@
new BinaryPrinter(new DevNullSink<List<int>>()).writeComponentFile(component);
}
+class Difference {
+ final int line;
+ final String actual;
+ final String expected;
+
+ Difference(this.line, this.actual, this.expected);
+}
+
+Difference findFirstDifference(String actual, String expected) {
+ final actualLines = actual.split('\n');
+ final expectedLines = expected.split('\n');
+ int i = 0;
+ for (; i < actualLines.length && i < expectedLines.length; ++i) {
+ if (actualLines[i] != expectedLines[i]) {
+ return new Difference(i + 1, actualLines[i], expectedLines[i]);
+ }
+ }
+ return new Difference(
+ i + 1,
+ i < actualLines.length ? actualLines[i] : '<END>',
+ i < expectedLines.length ? expectedLines[i] : '<END>');
+}
+
void compareResultWithExpectationsFile(Uri source, String actual) {
final expectFile = new File(source.toFilePath() + '.expect');
final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
if (actual != expected) {
- if (kDumpActualResult) {
- new File(source.toFilePath() + '.actual').writeAsStringSync(actual);
+ if (bool.fromEnvironment(kUpdateExpectations)) {
+ expectFile.writeAsStringSync(actual);
+ print(" Updated $expectFile");
+ } else {
+ if (bool.fromEnvironment(kDumpActualResult)) {
+ new File(source.toFilePath() + '.actual').writeAsStringSync(actual);
+ }
+ Difference diff = findFirstDifference(actual, expected);
+ fail("""
+
+Result is different for the test case $source
+
+The first difference is at line ${diff.line}.
+Actual: ${diff.actual}
+Expected: ${diff.expected}
+
+This failure can be caused by changes in the front-end if it starts generating
+different kernel AST for the same Dart programs.
+
+In order to re-generate expectations run tests with -D$kUpdateExpectations=true VM option:
+
+ tools/test.py -m release --vm-options -D$kUpdateExpectations=true pkg/vm
+
+In order to dump actual results into .actual files run tests with -D$kDumpActualResult=true VM option:
+
+ tools/test.py -m release --vm-options -D$kDumpActualResult=true pkg/vm
+
+""");
}
- expect(actual, equals(expected), reason: "Test case: $source");
}
}
diff --git a/pkg/vm/test/frontend_server_flutter.dart b/pkg/vm/test/frontend_server_flutter.dart
new file mode 100644
index 0000000..be1ee67
--- /dev/null
+++ b/pkg/vm/test/frontend_server_flutter.dart
@@ -0,0 +1,251 @@
+import 'dart:async' show StreamController;
+import 'dart:convert' show utf8, LineSplitter;
+import 'dart:io' show Directory, File, FileSystemEntity, IOSink, stdout;
+
+import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/kernel.dart' show loadComponentFromBytes;
+import 'package:kernel/verifier.dart' show verifyComponent;
+
+import '../lib/frontend_server.dart';
+
+main(List<String> args) async {
+ String flutterDir;
+ String flutterPlatformDir;
+ for (String arg in args) {
+ if (arg.startsWith("--flutterDir=")) {
+ flutterDir = arg.substring(13);
+ } else if (arg.startsWith("--flutterPlatformDir=")) {
+ flutterPlatformDir = arg.substring(21);
+ }
+ }
+ if (flutterDir == null || !(new Directory(flutterDir).existsSync())) {
+ throw "Didn't get a valid flutter directory to work with.";
+ }
+ Directory flutterDirectory = new Directory(flutterDir);
+ List<FileSystemEntity> allFlutterFiles =
+ flutterDirectory.listSync(recursive: true, followLinks: false);
+ Directory flutterPlatformDirectory;
+ if (flutterPlatformDir == null) {
+ List<File> platformFiles = new List<File>.from(allFlutterFiles.where((f) =>
+ f.uri
+ .toString()
+ .endsWith("/flutter_patched_sdk/platform_strong.dill")));
+ if (platformFiles.length < 1) {
+ throw "Expected to find a flutter platform file but didn't.";
+ }
+ flutterPlatformDirectory = platformFiles.first.parent;
+ } else {
+ flutterPlatformDirectory = Directory(flutterPlatformDir);
+ }
+ if (!flutterPlatformDirectory.existsSync()) {
+ throw "$flutterPlatformDirectory doesn't exist.";
+ }
+ if (!new File.fromUri(
+ flutterPlatformDirectory.uri.resolve("platform_strong.dill"))
+ .existsSync()) {
+ throw "$flutterPlatformDirectory doesn't contain a "
+ "platform_strong.dill file.";
+ }
+ print("Using $flutterPlatformDirectory as platform directory.");
+ List<File> dotPackagesFiles = new List<File>.from(allFlutterFiles.where((f) =>
+ (f.uri.toString().contains("/examples/") ||
+ f.uri.toString().contains("/packages/")) &&
+ f.uri.toString().endsWith("/.packages")));
+
+ for (File dotPackage in dotPackagesFiles) {
+ Directory tempDir;
+ Directory systemTempDir = Directory.systemTemp;
+ tempDir = systemTempDir.createTempSync('foo bar');
+ try {
+ Directory testDir =
+ new Directory.fromUri(dotPackage.parent.uri.resolve("test/"));
+ if (!testDir.existsSync()) continue;
+ print("Go for $testDir");
+ await attemptStuff(
+ tempDir, flutterPlatformDirectory, dotPackage, testDir);
+ } finally {
+ tempDir.delete(recursive: true);
+ }
+ }
+}
+
+void attemptStuff(Directory tempDir, Directory flutterPlatformDirectory,
+ File dotPackage, Directory testDir) async {
+ File dillFile = new File('${tempDir.path}/dill.dill');
+ if (dillFile.existsSync()) {
+ throw "$dillFile already exists.";
+ }
+ List<int> platformData = new File.fromUri(
+ flutterPlatformDirectory.uri.resolve("platform_strong.dill"))
+ .readAsBytesSync();
+ final List<String> args = <String>[
+ '--sdk-root',
+ flutterPlatformDirectory.path,
+ '--incremental',
+ '--strong',
+ '--target=flutter',
+ '--packages',
+ dotPackage.path,
+ '--output-dill=${dillFile.path}',
+ // '--unsafe-package-serialization',
+ ];
+
+ List<File> testFiles = new List<File>.from(testDir
+ .listSync(recursive: true)
+ .where((f) => f.path.endsWith("_test.dart")));
+ if (testFiles.isEmpty) return;
+
+ Stopwatch stopwatch = new Stopwatch()..start();
+
+ final StreamController<List<int>> inputStreamController =
+ new StreamController<List<int>>();
+ final StreamController<List<int>> stdoutStreamController =
+ new StreamController<List<int>>();
+ final IOSink ioSink = new IOSink(stdoutStreamController.sink);
+ StreamController<Result> receivedResults = new StreamController<Result>();
+
+ final outputParser = new OutputParser(receivedResults);
+ stdoutStreamController.stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen(outputParser.listener);
+
+ Iterator<File> testFileIterator = testFiles.iterator;
+ testFileIterator.moveNext();
+
+ final Future<int> result =
+ starter(args, input: inputStreamController.stream, output: ioSink);
+ String shortTestPath =
+ testFileIterator.current.path.substring(testDir.path.length);
+ stdout.write(" => $shortTestPath");
+ Stopwatch stopwatch2 = new Stopwatch()..start();
+ inputStreamController
+ .add('compile ${testFileIterator.current.path}\n'.codeUnits);
+ int compilations = 0;
+ receivedResults.stream.listen((Result compiledResult) {
+ stdout.write(" --- done in ${stopwatch2.elapsedMilliseconds} ms\n");
+ stopwatch2.reset();
+ compiledResult.expectNoErrors();
+
+ List<int> resultBytes = dillFile.readAsBytesSync();
+ Component component = loadComponentFromBytes(platformData);
+ component = loadComponentFromBytes(resultBytes, component);
+ verifyComponent(component);
+ print(" => verified in ${stopwatch2.elapsedMilliseconds} ms.");
+ stopwatch2.reset();
+
+ inputStreamController.add('accept\n'.codeUnits);
+ inputStreamController.add('reset\n'.codeUnits);
+ compilations++;
+
+ if (!testFileIterator.moveNext()) {
+ inputStreamController.add('quit\n'.codeUnits);
+ return;
+ }
+ String shortTestPath =
+ testFileIterator.current.path.substring(testDir.path.length);
+ stdout.write(" => $shortTestPath");
+ inputStreamController.add('recompile ${testFileIterator.current.path} abc\n'
+ '${testFileIterator.current.uri}\n'
+ 'abc\n'
+ .codeUnits);
+ });
+
+ int resultDone = await result;
+ if (resultDone != 0) {
+ throw "Got $resultDone, expected 0";
+ }
+
+ inputStreamController.close();
+
+ print("Did $compilations compilations and verifications in "
+ "${stopwatch.elapsedMilliseconds} ms.");
+}
+
+// The below is copied from incremental_compiler_test.dart,
+// but with expect stuff replaced with ifs and throws
+// (expect can only be used in tests via the test framework).
+
+class OutputParser {
+ OutputParser(this._receivedResults);
+ bool expectSources = true;
+
+ StreamController<Result> _receivedResults;
+ List<String> _receivedSources;
+
+ String _boundaryKey;
+ bool _readingSources;
+
+ void listener(String s) {
+ if (_boundaryKey == null) {
+ const String RESULT_OUTPUT_SPACE = 'result ';
+ if (s.startsWith(RESULT_OUTPUT_SPACE)) {
+ _boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
+ }
+ _readingSources = false;
+ _receivedSources?.clear();
+ return;
+ }
+
+ if (s.startsWith(_boundaryKey)) {
+ // First boundaryKey separates compiler output from list of sources
+ // (if we expect list of sources, which is indicated by receivedSources
+ // being not null)
+ if (expectSources && !_readingSources) {
+ _readingSources = true;
+ return;
+ }
+ // Second boundaryKey indicates end of frontend server response
+ expectSources = true;
+ _receivedResults.add(new Result(
+ s.length > _boundaryKey.length
+ ? s.substring(_boundaryKey.length + 1)
+ : null,
+ _receivedSources));
+ _boundaryKey = null;
+ } else {
+ if (_readingSources) {
+ if (_receivedSources == null) {
+ _receivedSources = <String>[];
+ }
+ _receivedSources.add(s);
+ }
+ }
+ }
+}
+
+class Result {
+ String status;
+ List<String> sources;
+
+ Result(this.status, this.sources);
+
+ void expectNoErrors({String filename}) {
+ CompilationResult result = new CompilationResult.parse(status);
+ if (result.errorsCount != 0) {
+ throw "Got ${result.errorsCount} errors. Expected 0.";
+ }
+ if (filename != null) {
+ if (result.filename != filename) {
+ throw "Got ${result.filename} errors. Expected $filename.";
+ }
+ }
+ }
+}
+
+class CompilationResult {
+ String filename;
+ int errorsCount;
+
+ CompilationResult.parse(String filenameAndErrorCount) {
+ if (filenameAndErrorCount == null) {
+ return;
+ }
+ int delim = filenameAndErrorCount.lastIndexOf(' ');
+ if (delim <= 0) {
+ throw "Expected $delim > 0...";
+ }
+ filename = filenameAndErrorCount.substring(0, delim);
+ errorsCount = int.parse(filenameAndErrorCount.substring(delim + 1).trim());
+ }
+}
diff --git a/pkg/vm/test/transformations/type_flow/annotation_matcher.dart b/pkg/vm/test/transformations/type_flow/annotation_matcher.dart
deleted file mode 100644
index 2b7f278..0000000
--- a/pkg/vm/test/transformations/type_flow/annotation_matcher.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart';
-import 'package:vm/transformations/type_flow/utils.dart';
-import 'package:vm/transformations/pragma.dart';
-
-// Since we don't run the constants transformation in this test, we can't
-// recognize all pragma annotations precisely. Instead, we pattern match on
-// annotations which look like a pragma and assume that their options field
-// evaluates to true.
-class ExpressionPragmaAnnotationParser extends PragmaAnnotationParser {
- final CoreTypes coreTypes;
-
- ExpressionPragmaAnnotationParser(this.coreTypes);
-
- ParsedPragma parsePragma(Expression annotation) {
- assertx(annotation is! ConstantExpression);
-
- String pragmaName;
- Expression options;
-
- if (annotation is ConstructorInvocation) {
- if (annotation.constructedType.classNode != coreTypes.pragmaClass) {
- return null;
- }
-
- if (annotation.arguments.types.length != 0 ||
- (annotation.arguments.positional.length != 1 &&
- annotation.arguments.positional.length != 2) ||
- annotation.arguments.named.length != 0) {
- throw "Cannot evaluate pragma annotation $annotation";
- }
-
- var arguments = annotation.arguments.positional;
- var nameArg = arguments[0];
- if (nameArg is StringLiteral) {
- pragmaName = nameArg.value;
- } else {
- return null;
- }
-
- options = arguments.length > 1 ? arguments[1] : new NullLiteral();
- }
-
- switch (pragmaName) {
- case kEntryPointPragmaName:
- // We ignore the option because we can't properly evaluate it, assume
- // it's true.
- return new ParsedEntryPointPragma(PragmaEntryPointType.Default);
- case kExactResultTypePragmaName:
- if (options is TypeLiteral) {
- return new ParsedResultTypeByTypePragma(options.type);
- } else if (options is StringLiteral) {
- return new ParsedResultTypeByPathPragma(options.value);
- }
- throw "Could not recognize option to $kExactResultTypePragmaName";
- default:
- return null;
- }
- }
-}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 022c7e1..4ab863b 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -9,10 +9,11 @@
import 'package:kernel/core_types.dart';
import 'package:kernel/type_environment.dart';
import 'package:test/test.dart';
+import 'package:vm/transformations/pragma.dart'
+ show ConstantPragmaAnnotationParser;
import 'package:vm/transformations/type_flow/native_code.dart';
import 'package:vm/transformations/type_flow/summary_collector.dart';
import 'package:vm/transformations/type_flow/analysis.dart';
-import 'annotation_matcher.dart';
import 'package:kernel/target/targets.dart';
import '../../common_test_utils.dart';
@@ -31,7 +32,7 @@
hierarchy,
new EmptyEntryPointsListener(),
new NativeCodeOracle(
- null, new ExpressionPragmaAnnotationParser(coreTypes)),
+ null, new ConstantPragmaAnnotationParser(coreTypes)),
new GenericInterfacesInfoImpl(hierarchy));
String print(TreeNode node) {
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index d031f10..4d1effb 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -11,7 +11,6 @@
import 'package:test/test.dart';
import 'package:vm/transformations/type_flow/transformer.dart'
show transformComponent;
-import 'annotation_matcher.dart';
import '../../common_test_utils.dart';
@@ -24,8 +23,7 @@
final coreTypes = new CoreTypes(component);
- component = transformComponent(target, coreTypes, component,
- new ExpressionPragmaAnnotationParser(coreTypes));
+ component = transformComponent(target, coreTypes, component);
final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index a71a37a..fe17198 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -479,11 +479,11 @@
constructor _() → #lib::_NamespaceImpl
: super dart.core::Object::•()
;
- @dart._internal::ExternalName::•("Namespace_Create")
+ @#C2
external static method _create(#lib::_NamespaceImpl namespace, dynamic n) → #lib::_NamespaceImpl;
- @dart._internal::ExternalName::•("Namespace_GetPointer")
+ @#C4
external static method _getPointer(#lib::_NamespaceImpl namespace) → dart.core::int;
- @dart._internal::ExternalName::•("Namespace_GetDefault")
+ @#C6
external static method _getDefault() → dart.core::int;
static method _setupNamespace(dynamic namespace) → void {
#lib::_NamespaceImpl::_cachedNamespace = #lib::_NamespaceImpl::_create(new #lib::_NamespaceImpl::_(), namespace);
@@ -823,13 +823,13 @@
static field dart.core::int _stderrFD = 2;
static field dart.core::String _rawScript;
static field #lib::Stdin _stdin;
- @dart._internal::ExternalName::•("Builtin_PrintString")
+ @#C8
external static method _printString(dart.core::String s) → void;
static method _print(dynamic arg) → void {
#lib::_printString(arg.{dart.core::Object::toString}());
}
static method _getPrintClosure() → dynamic
- return #lib::_print;
+ return #C9;
static method _setScheduleImmediateClosure((() → void) → void closure) → void {
#lib::_ScheduleImmediate::_closure = closure;
}
@@ -847,7 +847,7 @@
}
}
static method _setupHooks() → dynamic {
- #lib::VMLibraryHooks::platformScript = #lib::_scriptUri;
+ #lib::VMLibraryHooks::platformScript = #C10;
}
static get stdin() → #lib::Stdin {
#lib::_stdin.{dart.core::Object::==}(null) ?{#lib::Stdin} #lib::_stdin = #lib::_StdIOUtils::_getStdioInputStream(#lib::_stdinFD) : null;
@@ -855,3 +855,15 @@
}
static method main() → dynamic {}
}
+constants {
+ #C1 = "Namespace_Create"
+ #C2 = dart._internal::ExternalName {name: #C1}
+ #C3 = "Namespace_GetPointer"
+ #C4 = dart._internal::ExternalName {name: #C3}
+ #C5 = "Namespace_GetDefault"
+ #C6 = dart._internal::ExternalName {name: #C5}
+ #C7 = "Builtin_PrintString"
+ #C8 = dart._internal::ExternalName {name: #C7}
+ #C9 = TearOffConstant(#lib::_print)
+ #C10 = TearOffConstant(#lib::_scriptUri)
+}
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
index b122da6..1a25aa9 100644
--- a/pkg/vm/testcases/bytecode/field_initializers.dart.expect
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -270,7 +270,7 @@
] class B extends #lib::A {
field dart.core::int foo6 = 46;
static field dart.core::int foo7 = 47;
- static const field dart.core::int foo8 = 48;
+ static const field dart.core::int foo8 = #C1;
constructor •() → #lib::B
: super #lib::A::•(49)
;
@@ -280,3 +280,6 @@
}
static method main() → dynamic {}
}
+constants {
+ #C1 = 48
+}
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index b79b398..2a98dd2 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -710,7 +710,7 @@
constructor •(dynamic param) → #lib::I
: super dart.core::Object::•()
;
- static factory test_factory2({dynamic param = null}) → #lib::I
+ static factory test_factory2({dynamic param = #C1}) → #lib::I
return new #lib::I::•(param);
}
[@vm.bytecode=
@@ -738,7 +738,7 @@
}
] class J extends dart.core::Object {
- @dart._internal::ExternalName::•("agent_J")
+ @#C3
external static factory •() → #lib::J;
}
[@vm.bytecode=
@@ -835,3 +835,8 @@
#lib::foo3<dart.core::String>();
}
}
+constants {
+ #C1 = null
+ #C2 = "agent_J"
+ #C3 = dart._internal::ExternalName {name: #C2}
+}
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index bc4b45d..3449af2 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -557,11 +557,11 @@
] class A extends dart.core::Object {
final field dart.core::int index;
final field dart.core::String _name;
- static const field dart.core::List<#lib::A> values = const <#lib::A>[#lib::A::elem1, #lib::A::elem2, #lib::A::elem3, #lib::A::elem4];
- static const field #lib::A elem1 = const #lib::A::•(0, "A.elem1");
- static const field #lib::A elem2 = const #lib::A::•(1, "A.elem2");
- static const field #lib::A elem3 = const #lib::A::•(2, "A.elem3");
- static const field #lib::A elem4 = const #lib::A::•(3, "A.elem4");
+ static const field dart.core::List<#lib::A> values = #C13;
+ static const field #lib::A elem1 = #C3;
+ static const field #lib::A elem2 = #C6;
+ static const field #lib::A elem3 = #C9;
+ static const field #lib::A elem4 = #C12;
const constructor •(dart.core::int index, dart.core::String _name) → #lib::A
: #lib::A::index = index, #lib::A::_name = _name, super dart.core::Object::•()
;
@@ -701,7 +701,7 @@
] class D extends dart.core::Object {
final field dynamic x;
final field dynamic y;
- const constructor •(dynamic x, [dynamic y = null]) → #lib::D
+ const constructor •(dynamic x, [dynamic y = #C14]) → #lib::D
: #lib::D::x = x, #lib::D::y = y, super dart.core::Object::•()
;
}
@@ -769,26 +769,26 @@
: super #lib::E::•()
;
}
- static const field #lib::A c1 = #lib::A::elem3;
- static const field dart.core::String c2 = "hello!";
- static const field dart.core::int c3 = #lib::c2.{dart.core::String::length};
- static const field #lib::C c4 = const #lib::C::•(1, 2, 3);
- static const field #lib::D c5 = const #lib::D::•(const #lib::B::•(4));
+ static const field #lib::A c1 = #C9;
+ static const field dart.core::String c2 = #C15;
+ static const field dart.core::int c3 = #C16;
+ static const field #lib::C c4 = #C18;
+ static const field #lib::D c5 = #C21;
static field dart.core::double fieldWithDoubleLiteralInitializer = 1.0;
static method test_constants1() → void {
- dart.core::print(#lib::c1);
- dart.core::print(#lib::c2);
- dart.core::print(#lib::c3);
- dart.core::print(#lib::c4);
- dart.core::print(#lib::c5);
+ dart.core::print(#C9);
+ dart.core::print(#C15);
+ dart.core::print(#C16);
+ dart.core::print(#C18);
+ dart.core::print(#C21);
}
static method test_constants2() → void {
dart.core::print(42);
dart.core::print("foo");
- dart.core::print(#lib::A::elem2);
- dart.core::print(const <dart.core::Object>[42, "foo", dart.core::int]);
- dart.core::print(const <dart.core::String, #lib::A>{"E2": #lib::A::elem2, "E4": #lib::A::elem4});
- dart.core::print(const #lib::D::•(const #lib::C::•(4, 5, 6), const <dart.core::String, dart.core::Object>{"foo": 42, "bar": const #lib::B::•(#lib::c2.{dart.core::String::length})}));
+ dart.core::print(#C6);
+ dart.core::print(#C25);
+ dart.core::print(#C29);
+ dart.core::print(#C37);
}
static method test_list_literal(dart.core::int a) → void {
dart.core::print(<dart.core::int>[1, a, 3]);
@@ -801,18 +801,60 @@
dart.core::print(<#lib::test_map_literal::T, dart.core::int>{c: 4});
}
static method test_symbol() → void {
- dart.core::print(#test_symbol);
- dart.core::print(#_private_symbol);
+ dart.core::print(#C38);
+ dart.core::print(#C39);
}
static method test_type_literal<T extends dart.core::Object = dynamic>() → void {
dart.core::print(dart.core::String);
dart.core::print(#lib::test_type_literal::T);
}
static method testGenericConstInstance() → dynamic
- return const #lib::F::•<dart.core::int, dart.core::String>();
+ return #C40;
static method testGenericFunctionTypeLiteral() → dynamic
return <X extends dart.core::Object = dynamic>(X) → X;
static method testFieldWithDoubleLiteralInitializer() → dynamic
return #lib::fieldWithDoubleLiteralInitializer;
static method main() → dynamic {}
}
+constants {
+ #C1 = 0
+ #C2 = "A.elem1"
+ #C3 = #lib::A {index: #C1, #lib::_name: #C2}
+ #C4 = 1
+ #C5 = "A.elem2"
+ #C6 = #lib::A {index: #C4, #lib::_name: #C5}
+ #C7 = 2
+ #C8 = "A.elem3"
+ #C9 = #lib::A {index: #C7, #lib::_name: #C8}
+ #C10 = 3
+ #C11 = "A.elem4"
+ #C12 = #lib::A {index: #C10, #lib::_name: #C11}
+ #C13 = ListConstant<#lib::A>(#C3, #C6, #C9, #C12)
+ #C14 = null
+ #C15 = "hello!"
+ #C16 = 6
+ #C17 = 15
+ #C18 = #lib::C {j: #C10, i: #C17}
+ #C19 = 4
+ #C20 = #lib::B {i: #C19}
+ #C21 = #lib::D {x: #C20, y: #C14}
+ #C22 = 42
+ #C23 = "foo"
+ #C24 = TypeLiteralConstant(dart.core::int)
+ #C25 = ListConstant<dart.core::Object>(#C22, #C23, #C24)
+ #C26 = "E2"
+ #C27 = "E4"
+ #C28 = ListConstant<dynamic>(#C26, #C6, #C27, #C12)
+ #C29 = dart.core::_ImmutableMap<dart.core::String, #lib::A> {dart.core::_kvPairs: #C28}
+ #C30 = 9
+ #C31 = 30
+ #C32 = #lib::C {j: #C30, i: #C31}
+ #C33 = "bar"
+ #C34 = #lib::B {i: #C16}
+ #C35 = ListConstant<dynamic>(#C23, #C22, #C33, #C34)
+ #C36 = dart.core::_ImmutableMap<dart.core::String, dart.core::Object> {dart.core::_kvPairs: #C35}
+ #C37 = #lib::D {x: #C32, y: #C36}
+ #C38 = #test_symbol
+ #C39 = ##lib::_private_symbol
+ #C40 = #lib::F<dart.core::int, dart.core::String> {}
+}
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 3ff8087..4fcf451 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -271,19 +271,19 @@
}
]library #lib from "#lib" as #lib {
- static method foo1(dynamic x, [dynamic a = "default_a", dynamic b = "default_b"]) → void {
+ static method foo1(dynamic x, [dynamic a = #C1, dynamic b = #C2]) → void {
dart.core::print("x = ${x}");
dart.core::print("a = ${a}");
dart.core::print("b = ${b}");
}
- static method foo2(dynamic y, dynamic z, {dynamic c = "default_c", dynamic a = 42, dynamic b = const <dart.core::String>["default_b"]}) → void {
+ static method foo2(dynamic y, dynamic z, {dynamic c = #C3, dynamic a = #C4, dynamic b = #C5}) → void {
dart.core::print("y = ${y}");
dart.core::print("z = ${z}");
dart.core::print("a = ${a}");
dart.core::print("b = ${b}");
dart.core::print("c = ${c}");
}
- static method foo3<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic>(dynamic z, dynamic y, {dart.core::bool a = false, dart.core::Map<#lib::foo3::P, #lib::foo3::Q> b = null}) → void {
+ static method foo3<P extends dart.core::Object = dynamic, Q extends dart.core::Object = dynamic>(dynamic z, dynamic y, {dart.core::bool a = #C6, dart.core::Map<#lib::foo3::P, #lib::foo3::Q> b = #C7}) → void {
dart.core::print(#lib::foo3::P);
dart.core::print(y);
dart.core::print(b);
@@ -293,3 +293,12 @@
#lib::foo2("fixed_y", "fixed_z", a: "concrete_a");
}
}
+constants {
+ #C1 = "default_a"
+ #C2 = "default_b"
+ #C3 = "default_c"
+ #C4 = 42
+ #C5 = ListConstant<dart.core::String>(#C2)
+ #C6 = false
+ #C7 = null
+}
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index b7ca049..adea1f5a 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -198,19 +198,19 @@
#L1:
switch(x) {
#L2:
- case 1:
+ case #C1:
{
y = 11;
break #L1;
}
#L3:
- case 2:
+ case #C2:
{
y = 22;
break #L1;
}
#L4:
- case 3:
+ case #C3:
{
y = 33;
break #L1;
@@ -223,17 +223,17 @@
#L5:
switch(x) {
#L6:
- case 1:
- case 2:
- case 3:
+ case #C1:
+ case #C2:
+ case #C3:
{
y = 11;
break #L5;
}
#L7:
- case 4:
- case 5:
- case 6:
+ case #C4:
+ case #C5:
+ case #C6:
{
y = 22;
break #L5;
@@ -250,17 +250,17 @@
dart.core::int y;
switch(x) {
#L9:
- case 1:
- case 2:
- case 3:
+ case #C1:
+ case #C2:
+ case #C3:
{
y = 11;
continue #L10;
}
#L10:
- case 4:
- case 5:
- case 6:
+ case #C4:
+ case #C5:
+ case #C6:
{
y = 22;
return 42;
@@ -275,3 +275,11 @@
}
static method main() → dynamic {}
}
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 3
+ #C4 = 4
+ #C5 = 5
+ #C6 = 6
+}
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index 126eae9..b6575db 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -1119,7 +1119,7 @@
#L2:
switch(x) {
#L3:
- case 1:
+ case #C1:
{
try {
dart.core::print("before try 1");
@@ -1144,7 +1144,7 @@
break #L2;
}
#L4:
- case 2:
+ case #C2:
{
dart.core::print("case 2");
break #L2;
@@ -1191,3 +1191,7 @@
}
static method main() → dynamic {}
}
+constants {
+ #C1 = 1
+ #C2 = 2
+}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 6b29eac..22da680 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -285,7 +285,7 @@
PushNull
PushConstant CP#10
AssertAssignable 0, CP#11
- InterfaceCall 2, CP#12
+ UncheckedInterfaceCall 2, CP#12
Drop1
PushNull
ReturnTOS
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index ea11fc1..16476c9 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -2,44 +2,37 @@
import self as self;
import "dart:core" as core;
-@self::TypedefAnnotation::•(const <core::int>[1, 2, 3])
+@#C5
typedef SomeType<T extends core::Object = dynamic> = (core::List<T>) → void;
abstract class ClassAnnotation2 extends core::Object {
-[@vm.unreachable.metadata=] const constructor •() → self::ClassAnnotation2
- throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
}
abstract class MethodAnnotation extends core::Object {
-[@vm.unreachable.metadata=] const constructor •(core::int x) → self::MethodAnnotation
- throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+[@vm.unreachable.metadata=] final field core::int x;
}
abstract class TypedefAnnotation extends core::Object {
-[@vm.unreachable.metadata=] const constructor •(core::List<core::int> list) → self::TypedefAnnotation
- throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+[@vm.unreachable.metadata=] final field core::List<core::int> list;
}
abstract class VarAnnotation extends core::Object {
-[@vm.unreachable.metadata=] const constructor •() → self::VarAnnotation
- throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
}
abstract class ParametrizedAnnotation<T extends core::Object = dynamic> extends core::Object {
-[@vm.unreachable.metadata=] const constructor •(self::ParametrizedAnnotation::T foo) → self::ParametrizedAnnotation<self::ParametrizedAnnotation::T>
- throw "Attempt to execute method removed by Dart AOT compiler (TFA)";
+[@vm.unreachable.metadata=] final field self::ParametrizedAnnotation::T foo;
}
abstract class A extends core::Object {
static method staticMethod() → void {}
}
-@self::ClassAnnotation2::•()
+@#C6
class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] @self::MethodAnnotation::•(42)
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] @#C8
method instanceMethod() → void {}
}
static method foo([@vm.inferred-type.metadata=dart.core::Null?] (core::List<core::int>) → void a) → core::int {
- @self::VarAnnotation::•() core::int x = 2;
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int? (skip check)] x.{core::num::+}(2);
+ @#C9 core::int x = 2;
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2);
}
-@self::ParametrizedAnnotation::•<core::Null>(null)
+@#C11
static method main(core::List<core::String> args) → dynamic {
self::A::staticMethod();
[@vm.direct-call.metadata=#lib::B::instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
index ffdd14f..fa9c87b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
@@ -3,21 +3,21 @@
import "dart:core" as core;
import "dart:_internal" as _in;
-static method isPrime([@vm.inferred-type.metadata=int?] dynamic n) → core::bool {
- if(_in::unsafeCast<core::bool>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool] n.<(2)))
+static method isPrime([@vm.inferred-type.metadata=int] dynamic n) → core::bool {
+ if(_in::unsafeCast<core::bool>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool] n.<(2)))
return false;
- for (core::int i = 2; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<=??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart.core::_IntegerImplementation::*??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::*}(i).{core::num::<=}(_in::unsafeCast<core::num>(n)); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}(1)) {
- if([@vm.inferred-type.metadata=dart.core::bool] [@vm.direct-call.metadata=dart.core::_IntegerImplementation::%??] [@vm.inferred-type.metadata=int?] n.%(i).{core::Object::==}(0))
+ for (core::int i = 2; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<=] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart.core::_IntegerImplementation::*] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::*}(i).{core::num::<=}(_in::unsafeCast<core::num>(n)); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
+ if([@vm.direct-call.metadata=dart.core::_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.direct-call.metadata=dart.core::_IntegerImplementation::%] [@vm.inferred-type.metadata=int] n.%(i).{core::Object::==}(0))
return false;
}
return true;
}
static method nThPrimeNumber([@vm.inferred-type.metadata=dart.core::_Smi] core::int n) → core::int {
core::int counter = 0;
- for (core::int i = 1; ; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}(1)) {
+ for (core::int i = 1; ; i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
if([@vm.inferred-type.metadata=dart.core::bool] self::isPrime(i))
- counter = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] counter.{core::num::+}(1);
- if([@vm.inferred-type.metadata=dart.core::bool] counter.{core::num::==}(n)) {
+ counter = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] counter.{core::num::+}(1);
+ if([@vm.direct-call.metadata=dart.core::_IntegerImplementation::==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] counter.{core::num::==}(n)) {
return i;
}
}
@@ -31,7 +31,7 @@
}
static method main(core::List<core::String> args) → dynamic {
core::Stopwatch timer = let final core::Stopwatch #t1 = new core::Stopwatch::•() in let final dynamic #t2 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}() in #t1;
- for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}(1)) {
+ for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::run();
}
[@vm.direct-call.metadata=dart.core::Stopwatch::stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index fb2975e..7fa4e1f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -12,14 +12,14 @@
constructor •([@vm.inferred-type.metadata=dart.core::_Smi] core::int size) → self::_Vector
: self::_Vector::_offset = 0, self::_Vector::_length = size, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(size), super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasTearOffUses:false] operator [](core::int i) → core::double
- return [@vm.direct-call.metadata=dart.typed_data::_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_offset}));
+[@vm.procedure-attributes.metadata=hasTearOffUses:false] operator []([@vm.inferred-type.metadata=!] core::int i) → core::double
+ return [@vm.direct-call.metadata=dart.typed_data::_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_offset}));
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int i, core::double value) → void {
let dynamic #t1 = [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = i in let dynamic #t3 = [@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
}
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector a) → core::double {
core::double result = 0.0;
- for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}(1))
+ for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1))
result = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] result.{core::double::+}([@vm.direct-call.metadata=dart.core::_Double::*] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.direct-call.metadata=#lib::_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=#lib::_Vector::[]??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] a.{self::_Vector::[]}(i)));
return result;
}
@@ -28,7 +28,7 @@
[@vm.inferred-type.metadata=dart.core::_Double?]static field core::double x = 0.0;
static method main(core::List<core::String> args) → dynamic {
core::Stopwatch timer = let final core::Stopwatch #t4 = new core::Stopwatch::•() in let final dynamic #t5 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] [@vm.inferred-type.metadata=!? (skip check)] #t4.{core::Stopwatch::start}() in #t4;
- for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int? (skip check)] i.{core::num::+}(1)) {
+ for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::x = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=dart.core::_Double?] self::x.{core::double::+}([@vm.direct-call.metadata=#lib::_Vector::*??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=#lib::_Vector?] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector?] self::v));
}
[@vm.direct-call.metadata=dart.core::Stopwatch::stop] [@vm.inferred-type.metadata=!? (skip check)] timer.{core::Stopwatch::stop}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index aee6417..d508c60 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -42,7 +42,7 @@
static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A aa) → void {
[@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
-static method callerA3({[@vm.inferred-type.metadata=#lib::C] self::A aa = null}) → void {
+static method callerA3({[@vm.inferred-type.metadata=#lib::C] self::A aa = #C1}) → void {
[@vm.direct-call.metadata=#lib::C::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A aa) → void {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 999e779..1762eb3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -21,13 +21,13 @@
synthetic constructor •() → self::Stream
: super core::Object::•()
;
- abstract method foobar((dynamic) → void onData, {core::Function onError = null}) → self::StreamSubscription;
+ abstract method foobar((dynamic) → void onData, {core::Function onError = #C1}) → self::StreamSubscription;
}
abstract class _StreamImpl extends self::Stream {
synthetic constructor •() → self::_StreamImpl
: super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = #C1}) → self::StreamSubscription {
return [@vm.inferred-type.metadata=!] this.{self::_StreamImpl::_createSubscription}();
}
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false] method _createSubscription() → self::StreamSubscription {
@@ -52,7 +52,7 @@
constructor •([@vm.inferred-type.metadata=!] self::Stream stream) → self::StreamView
: self::StreamView::_stream = stream, super self::Stream::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false] method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false] method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = #C1}) → self::StreamSubscription {
return [@vm.direct-call.metadata=#lib::StreamView::_stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
}
}
@@ -66,7 +66,7 @@
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method super_foobar2([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData) → dynamic {
super.{self::StreamView::foobar}(onData);
}
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = #C1}) → dynamic {
super.{self::StreamView::foobar}(onData, onError: onError);
}
get super_stream() → self::Stream
@@ -80,23 +80,23 @@
static method round0() → void {
new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
}
-static method round1({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null}) → void {
+static method round1({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = #C1}) → void {
self::ByteStream x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
[@vm.direct-call.metadata=#lib::ByteStream::super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(onData);
}
-static method round2({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → void {
+static method round2({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = #C1}) → void {
new self::_ControllerStream::•();
self::Stream x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
x.{self::Stream::foobar}(onData, onError: onError);
}
-static method round3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → void {
+static method round3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = #C1}) → void {
self::Stream x = new self::_GeneratedStreamImpl::•();
x = new self::ByteStream::•(x);
x = new self::_ControllerStream::•();
x.{self::Stream::foobar}(onData, onError: onError);
}
-static method round4({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null}) → void {
+static method round4({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = #C1}) → void {
self::ByteStream x = new self::ByteStream::•(new self::_ControllerStream::•());
self::Stream y = [@vm.direct-call.metadata=#lib::ByteStream::super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
self::Stream z = [@vm.direct-call.metadata=#lib::StreamView::_stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index 5fc9b87..1b22241 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -39,27 +39,27 @@
;
abstract method foo() → dynamic;
abstract get bar() → dynamic;
- abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = null, dynamic a5 = null]) → dynamic;
+ abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = #C1, dynamic a5 = #C1]) → dynamic;
}
class B extends self::A {
synthetic constructor •() → self::B
: super self::A::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T1::•();
}
no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#bar, 1, const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method foo() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#bazz, 0, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = #C1]) → dynamic
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
}
abstract class C extends core::Object {
synthetic constructor •() → self::C
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T2::•();
}
}
@@ -68,27 +68,27 @@
: super self::C::•()
;
no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#bar, 1, const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method foo() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#bazz, 0, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = #C1]) → dynamic
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
}
class E extends core::Object implements self::A {
synthetic constructor •() → self::E
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T4::•();
}
no-such-method-forwarder get bar() → dynamic
- return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E::noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#bar, 1, const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+ return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E::noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol, dynamic>] core::Map::unmodifiable<core::Symbol, dynamic>(#C5))));
}
class F extends core::Object {
synthetic constructor •() → self::F
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T2::•();
}
}
@@ -96,7 +96,7 @@
synthetic constructor •() → self::G
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T5::•();
}
}
@@ -104,9 +104,9 @@
synthetic constructor •() → self::H
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method foo({[@vm.inferred-type.metadata=dart.core::_Smi] dynamic left = null, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic right = null}) → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method foo({[@vm.inferred-type.metadata=dart.core::_Smi] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic right = #C1}) → dynamic
return new self::T6::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false] method noSuchMethod(core::Invocation invocation) → dynamic {
return new self::T7::•();
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 472fbbd..7f64259 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -54,7 +54,7 @@
return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call(x);
static method main(core::List<core::String> args) → dynamic {
self::func1(self::getDynamic() as{TypeError} self::T0);
- self::use(self::func2);
+ self::use(#C1);
self::use(new self::A::•().{self::A::method1});
self::B bb = self::getDynamic() as{TypeError} self::B;
[@vm.direct-call.metadata=#lib::C::method2??] [@vm.inferred-type.metadata=!? (skip check)] bb.{self::B::method2}(self::getDynamic());
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index 0630a2a..36dbf0d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -19,7 +19,7 @@
synthetic constructor •() → self::A1
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A1::foo] this.{self::A1::foo} = _in::unsafeCast<self::T1>(a5);
}
}
@@ -42,7 +42,7 @@
synthetic constructor •() → self::A2
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A2::foo] this.{self::A2::foo} = a6;
}
}
@@ -75,7 +75,7 @@
synthetic constructor •() → self::A3
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A3::foo] this.{self::A3::foo} = a7;
}
}
@@ -98,7 +98,7 @@
synthetic constructor •() → self::A4
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = null, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
[@vm.direct-call.metadata=#lib::A4::foo] this.{self::A4::foo} = a8;
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 2c96882..3c1beb0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -12,7 +12,7 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false] method foo() → core::int
- return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=!? (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
+ return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=! (skip check)] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
}
class TearOffDynamicMethod extends core::Object {
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false] field dynamic bazz;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
index 66af620..ccb925f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -14,7 +14,7 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false] method foo() → core::int
- return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int? (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::bar] [@vm.inferred-type.metadata=dart.core::_Smi] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar())));
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::bar] [@vm.inferred-type.metadata=dart.core::_Smi] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar())));
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method bar() → core::int
return 3;
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index 950a81d..b147844 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -14,14 +14,14 @@
: super self::A::•()
;
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false] method foo() → core::int
- return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int? (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 1.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
}
abstract class Base extends core::Object {
synthetic constructor •() → self::Base
: super core::Object::•()
;
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false] method foo() → core::int
- return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int? (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
+ return _in::unsafeCast<core::int>([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false] method doCall(dynamic x) → core::int
return [@vm.call-site-attributes.metadata=receiverType:dynamic] x.call() as{TypeError} core::int;
}
diff --git a/pkg/vm/tool/gen_kernel b/pkg/vm/tool/gen_kernel
index a968d05..8174ed5 100755
--- a/pkg/vm/tool/gen_kernel
+++ b/pkg/vm/tool/gen_kernel
@@ -14,8 +14,8 @@
for arg in "$@"; do
case $arg in
- --abi-version=*)
- ABI_VERSION="$(echo "$arg" | sed "s|--abi-version=||")"
+ --use-abi-version=*)
+ ABI_VERSION="$(echo "$arg" | sed "s|--use-abi-version=||")"
;;
--platform*)
HAS_PLATFORM="TRUE"
diff --git a/runtime/bin/ffi_test_functions.cc b/runtime/bin/ffi_test_functions.cc
index c22939d..1f07257 100644
--- a/runtime/bin/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test_functions.cc
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <sys/types.h>
+#include "platform/assert.h"
#include "platform/globals.h"
#if defined(HOST_OS_WINDOWS)
#include <psapi.h>
@@ -469,6 +470,36 @@
return *reinterpret_cast<void**>(&origin);
}
+// Allocates 'count'-many Mint boxes, to stress-test GC during an FFI call.
+DART_EXPORT void AllocateMints(uint64_t count) {
+ Dart_EnterScope();
+ for (uint64_t i = 0; i < count; ++i) {
+ Dart_NewInteger(0x8000000000000001);
+ }
+ Dart_ExitScope();
+}
+
+// Calls a Dart function to allocate 'count' objects.
+// Used for stress-testing GC when re-entering the API.
+DART_EXPORT void AllocateThroughDart(uint64_t count) {
+ Dart_EnterScope();
+ Dart_Handle root = Dart_RootLibrary();
+ Dart_Handle arguments[1] = {Dart_NewIntegerFromUint64(count)};
+ Dart_Handle result = Dart_Invoke(
+ root, Dart_NewStringFromCString("testAllocationsInDartHelper"), 1,
+ arguments);
+ const char* error;
+ if (Dart_IsError(result)) {
+ Dart_StringToCString(Dart_ToString(result), &error);
+ fprintf(stderr, "Could not call 'testAllocationsInDartHelper': %s\n",
+ error);
+ Dart_DumpNativeStackTrace(nullptr);
+ Dart_PrepareToAbort();
+ abort();
+ }
+ Dart_ExitScope();
+}
+
#if !defined(_WIN32)
DART_EXPORT int RedirectStderr() {
char filename[256];
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2d09c17..d0916b9 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -511,7 +511,7 @@
// Load embedder specific bits and return.
if (!VmService::Setup(
Options::vm_service_server_ip(), Options::vm_service_server_port(),
- Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(),
+ Options::vm_service_dev_mode(), !Options::vm_service_auth_enabled(),
Options::trace_loading(), Options::deterministic())) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 8513fe3..414f309 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -34,12 +34,16 @@
// As STRING_OPTIONS_LIST but for boolean valued options. The default value is
// always false, and the presence of the flag switches the value to true.
+// TODO(bkonyi): enable_service_auth_codes is a temporary flag and will be
+// removed once auth codes are enabled by default. disable_service_auth_codes is
+// a no-op for now.
#define BOOL_OPTIONS_LIST(V) \
V(version, version_option) \
V(compile_all, compile_all) \
V(disable_service_origin_check, vm_service_dev_mode) \
V(disable_service_auth_codes, vm_service_auth_disabled) \
V(deterministic, deterministic) \
+ V(enable_service_auth_codes, vm_service_auth_enabled) \
V(trace_loading, trace_loading) \
V(short_socket_read, short_socket_read) \
V(short_socket_write, short_socket_write) \
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 0615daa..3680f23 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -589,10 +589,24 @@
return status;
}
+ // After reading the binary into a VMO, we need to mark it as executable,
+ // since the VMO returned by fdio_get_vmo_clone should be read-only.
+ status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo);
+ if (status != ZX_OK) {
+ close(exit_pipe_fds[0]);
+ close(exit_pipe_fds[1]);
+ *os_error_message_ = DartUtils::ScopedCopyCString(
+ "Failed to mark binary as executable for process start.");
+ return status;
+ }
+
fdio_spawn_action_t* actions;
const intptr_t actions_count = BuildSpawnActions(
namespc_->namespc()->fdio_ns(), &actions);
if (actions_count < 0) {
+ zx_handle_close(vmo);
+ close(exit_pipe_fds[0]);
+ close(exit_pipe_fds[1]);
*os_error_message_ = DartUtils::ScopedCopyCString(
"Failed to build spawn actions array.");
return ZX_ERR_IO;
@@ -605,10 +619,9 @@
zx_handle_t process = ZX_HANDLE_INVALID;
char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC;
- status =
- fdio_spawn_vmo(ZX_HANDLE_INVALID, flags, vmo, program_arguments_,
- program_environment_, actions_count, actions, &process,
- err_msg);
+ status = fdio_spawn_vmo(ZX_HANDLE_INVALID, flags, vmo, program_arguments_,
+ program_environment_, actions_count, actions,
+ &process, err_msg);
// Handles are consumed by fdio_spawn_vmo even if it fails.
delete[] actions;
if (status != ZX_OK) {
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 447d334..40d7def 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -307,7 +307,10 @@
final String path = _checkAuthTokenAndGetPath(request.uri);
if (path == null) {
- // Malformed.
+ // Either no authentication code was provided when one was expected or an
+ // incorrect authentication code was provided.
+ request.response.statusCode = HttpStatus.forbidden;
+ request.response.write("missing or invalid authentication code");
request.response.close();
return;
}
@@ -335,7 +338,7 @@
}
// HTTP based service request.
final client = new HttpRequestClient(request, _service);
- final message = new Message.fromUri(client, request.uri);
+ final message = new Message.fromUri(client, Uri.parse(path));
client.onRequest(message); // exception free, no need to try catch
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index be316ee..18714e5 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3372,4 +3372,10 @@
*/
DART_EXPORT void Dart_DumpNativeStackTrace(void* context);
+/**
+ * Indicate that the process is about to abort, and the Dart VM should not
+ * attempt to cleanup resources.
+ */
+DART_EXPORT void Dart_PrepareToAbort();
+
#endif /* INCLUDE_DART_API_H_ */ /* NOLINT */
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index d717fc9..7bdca63 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -230,15 +230,15 @@
CheckRange(argCount, 1, max_count, "count");
size_t size = compiler::ffi::ElementSizeInBytes(type_cid) * count;
- intptr_t memory = reinterpret_cast<intptr_t>(malloc(size));
+ uint64_t memory = reinterpret_cast<uint64_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::New(memory)));
+ RawPointer* result = Pointer::New(
+ type_arg, Integer::Handle(zone, Integer::NewFromUint64(memory)));
return result;
}
diff --git a/runtime/observatory/.packages b/runtime/observatory/.packages
index 914bffb..0b5a10a 100644
--- a/runtime/observatory/.packages
+++ b/runtime/observatory/.packages
@@ -22,6 +22,7 @@
matcher:../../third_party/pkg/matcher/lib
package_config:../../third_party/pkg_tested/package_config/lib
package_resolver:../../third_party/pkg_tested/package_resolver/lib
+pedantic:../../third_party/pkg/pedantic/lib
pool:../../third_party/pkg/pool/lib
pub_semver:../../third_party/pkg/pub_semver/lib
source_map_stack_trace:../../third_party/pkg/source_map_stack_trace/lib
@@ -30,6 +31,8 @@
stream_channel:../../third_party/pkg/stream_channel/lib
string_scanner:../../third_party/pkg/string_scanner/lib
term_glyph:../../third_party/pkg/term_glyph/lib
-test:../../third_party/pkg/test/lib
+test:../../third_party/pkg/test/pkgs/test/lib
+test_api:../../third_party/pkg/test/pkgs/test_api/lib
+test_core:../../third_party/pkg/test/pkgs/test_core/lib
typed_data:../../third_party/pkg/typed_data/lib
observatory_test_package:tests/service/observatory_test_package
diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart
index 3c32189..6b73ba8 100644
--- a/runtime/observatory/lib/src/elements/function_view.dart
+++ b/runtime/observatory/lib/src/elements/function_view.dart
@@ -428,10 +428,10 @@
return 'implicit setter';
case M.FunctionKind.implicitStaticFinalGetter:
return 'implicit static final getter';
+ case M.FunctionKind.staticFieldInitializer:
+ return 'field initializer';
case M.FunctionKind.irregexpFunction:
return 'irregexp function';
- case M.FunctionKind.staticInitializer:
- return 'static initializer';
case M.FunctionKind.methodExtractor:
return 'method extractor';
case M.FunctionKind.noSuchMethodDispatcher:
diff --git a/runtime/observatory/lib/src/models/objects/function.dart b/runtime/observatory/lib/src/models/objects/function.dart
index 541dcad..777f57d 100644
--- a/runtime/observatory/lib/src/models/objects/function.dart
+++ b/runtime/observatory/lib/src/models/objects/function.dart
@@ -14,8 +14,8 @@
implicitGetter,
implicitSetter,
implicitStaticFinalGetter,
+ staticFieldInitializer,
irregexpFunction,
- staticInitializer,
methodExtractor,
noSuchMethodDispatcher,
invokeFieldDispatcher,
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 7e828a1..99e84be 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -3022,10 +3022,10 @@
return M.FunctionKind.implicitSetter;
case 'ImplicitStaticFinalGetter':
return M.FunctionKind.implicitStaticFinalGetter;
+ case 'StaticFieldInitializer':
+ return M.FunctionKind.staticFieldInitializer;
case 'IrregexpFunction':
return M.FunctionKind.irregexpFunction;
- case 'StaticInitializer':
- return M.FunctionKind.staticInitializer;
case 'MethodExtractor':
return M.FunctionKind.methodExtractor;
case 'NoSuchMethodDispatcher':
diff --git a/runtime/observatory/tests/service/breakpoint_on_if_null_1_test.dart b/runtime/observatory/tests/service/breakpoint_on_if_null_1_test.dart
new file mode 100644
index 0000000..2d28590
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_on_if_null_1_test.dart
@@ -0,0 +1,50 @@
+// 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 breakpoint_in_parts_class;
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 18;
+const String file = "breakpoint_on_if_null_1_test.dart";
+
+code() {
+ foo(42);
+}
+
+foo(dynamic args) {
+ if (args == null) {
+ print("was null");
+ }
+ if (args != null) {
+ print("was not null");
+ }
+ if (args == 42) {
+ print("was 42!");
+ }
+}
+
+List<String> stops = [];
+
+List<String> expected = [
+ "$file:${LINE + 0}:12", // on '=='
+ "$file:${LINE + 3}:12", // on '!='
+ "$file:${LINE + 4}:5", // on 'print'
+ "$file:${LINE + 6}:12", // on '=='
+ "$file:${LINE + 7}:5", // on 'print'
+ "$file:${LINE + 9}:1", // on ending '}'
+];
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtUriAndLine(file, LINE),
+ runStepThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/breakpoint_on_if_null_2_test.dart b/runtime/observatory/tests/service/breakpoint_on_if_null_2_test.dart
new file mode 100644
index 0000000..5eb37e5
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_on_if_null_2_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library breakpoint_in_parts_class;
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 21;
+const String file = "breakpoint_on_if_null_2_test.dart";
+
+dynamic compareWithMe = 43;
+
+code() {
+ compareWithMe = null;
+ foo(42);
+}
+
+foo(dynamic args) {
+ if (args == compareWithMe) {
+ print("was null");
+ }
+ if (args != compareWithMe) {
+ print("was not null");
+ }
+ if (args == 42) {
+ print("was 42!");
+ }
+}
+
+List<String> stops = [];
+
+List<String> expected = [
+ "$file:${LINE + 0}:12", // on '=='
+ "$file:${LINE + 3}:12", // on '!='
+ "$file:${LINE + 4}:5", // on 'print'
+ "$file:${LINE + 6}:12", // on '=='
+ "$file:${LINE + 7}:5", // on 'print'
+ "$file:${LINE + 9}:1", // on ending '}'
+];
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtUriAndLine(file, LINE),
+ runStepThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/breakpoint_on_if_null_3_test.dart b/runtime/observatory/tests/service/breakpoint_on_if_null_3_test.dart
new file mode 100644
index 0000000..a4c1fde
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_on_if_null_3_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library breakpoint_in_parts_class;
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 17;
+const String file = "breakpoint_on_if_null_3_test.dart";
+
+code() {
+ foo(42);
+}
+
+foo(dynamic args) {
+ if (args == null) {
+ print("was null");
+ }
+ if (args != null) {
+ print("was not null");
+ }
+ if (args == 42) {
+ print("was 42!");
+ }
+}
+
+List<String> stops = [];
+
+List<String> expected = [
+ "$file:${LINE + 0}:13", // on 'args'
+ "$file:${LINE + 1}:12", // on '=='
+ "$file:${LINE + 4}:12", // on '!='
+ "$file:${LINE + 5}:5", // on 'print'
+ "$file:${LINE + 7}:12", // on '=='
+ "$file:${LINE + 8}:5", // on 'print'
+ "$file:${LINE + 10}:1", // on ending '}'
+];
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtUriAndLine(file, LINE),
+ runStepThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/breakpoint_on_if_null_4_test.dart b/runtime/observatory/tests/service/breakpoint_on_if_null_4_test.dart
new file mode 100644
index 0000000..7b9ffe1
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_on_if_null_4_test.dart
@@ -0,0 +1,54 @@
+// 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 breakpoint_in_parts_class;
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 20;
+const String file = "breakpoint_on_if_null_4_test.dart";
+
+dynamic compareWithMe = 43;
+
+code() {
+ compareWithMe = null;
+ foo(42);
+}
+
+foo(dynamic args) {
+ if (args == compareWithMe) {
+ print("was null");
+ }
+ if (args != compareWithMe) {
+ print("was not null");
+ }
+ if (args == 42) {
+ print("was 42!");
+ }
+}
+
+List<String> stops = [];
+
+List<String> expected = [
+ "$file:${LINE + 0}:13", // on 'args'
+ "$file:${LINE + 1}:12", // on '=='
+ "$file:${LINE + 4}:12", // on '!='
+ "$file:${LINE + 5}:5", // on 'print'
+ "$file:${LINE + 7}:12", // on '=='
+ "$file:${LINE + 8}:5", // on 'print'
+ "$file:${LINE + 10}:1", // on ending '}'
+];
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtUriAndLine(file, LINE),
+ runStepThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index eb8c14d..f859e6d 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -91,9 +91,7 @@
final numRanges = coverage['ranges'].length;
expect(coverage['type'], equals('SourceReport'));
- // Running in app_jitk mode will result in the number of ranges being 9
- // during the training run and 10 when running from the snapshot.
- expect(((numRanges == 9) || (numRanges == 10)), isTrue);
+ expect((numRanges == 12), isTrue);
expect(coverage['ranges'][0], equals(expectedRange));
expect(coverage['scripts'].length, 1);
expect(
@@ -108,7 +106,7 @@
};
coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
expect(coverage['type'], equals('SourceReport'));
- expect(coverage['ranges'].length, numRanges + 2);
+ expect(coverage['ranges'].length, numRanges);
expect(allRangesCompiled(coverage), isTrue);
// One function
diff --git a/runtime/observatory/tests/service/next_through_await_for_test.dart b/runtime/observatory/tests/service/next_through_await_for_test.dart
new file mode 100644
index 0000000..734c1f1
--- /dev/null
+++ b/runtime/observatory/tests/service/next_through_await_for_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 14;
+const String file = "next_through_await_for_test.dart";
+
+code() async {
+ int count = 0;
+ await for (var num in naturalsTo(2)) {
+ print(num);
+ count++;
+ }
+}
+
+Stream<int> naturalsTo(int n) async* {
+ int k = 0;
+ while (k < n) {
+ k++;
+ yield k;
+ }
+ yield 42;
+}
+
+List<String> stops = [];
+List<String> expected = [
+ "$file:${LINE + 0}:13", // on '='
+ "$file:${LINE + 1}:25", // on 'naturalsTo'
+
+ // Iteration #1
+ "$file:${LINE + 1}:3", // on 'await'
+ "$file:${LINE + 1}:40", // on '{'
+ "$file:${LINE + 2}:5", // on 'print'
+ "$file:${LINE + 3}:10", // on '++'
+
+ // Iteration #2
+ "$file:${LINE + 1}:3", // on 'await'
+ "$file:${LINE + 1}:40", // on '{'
+ "$file:${LINE + 2}:5", // on 'print'
+ "$file:${LINE + 3}:10", // on '++'
+
+ // Iteration #3
+ "$file:${LINE + 1}:3", // on 'await'
+ "$file:${LINE + 1}:40", // on '{'
+ "$file:${LINE + 2}:5", // on 'print'
+ "$file:${LINE + 3}:10", // on '++'
+
+ // Done
+ "$file:${LINE + 1}:3", // on 'await'
+ "$file:${LINE + 5}:1"
+];
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtLine(LINE),
+ runStepThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected,
+ debugPrint: true, debugPrintFile: file, debugPrintLine: LINE)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 05c37a1..f57bf4e 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -132,8 +132,8 @@
if (pause_on_exit) {
fullArgs.add('--pause-isolates-on-exit');
}
- if (!useAuthToken) {
- fullArgs.add('--disable-service-auth-codes');
+ if (useAuthToken) {
+ fullArgs.add('--enable-service-auth-codes');
}
if (pause_on_unhandled_exceptions) {
fullArgs.add('--pause-isolates-on-unhandled-exceptions');
diff --git a/runtime/platform/assert.h b/runtime/platform/assert.h
index 48d1443..ed56f3a 100644
--- a/runtime/platform/assert.h
+++ b/runtime/platform/assert.h
@@ -278,29 +278,7 @@
if (!(cond)) dart::Assert(__FILE__, __LINE__).Fail("expected: %s", #cond); \
} while (false)
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-// COMPILE_ASSERT(sizeof(foo) < 128);
-//
-
-template <bool>
-struct CompileAssert {};
-// Macro to concatenate two tokens. The helper is need to proper expansion
-// in case an argument is a macro itself.
-#if !defined(COMPILE_ASSERT)
-#define COMPILE_ASSERT_JOIN(a, b) COMPILE_ASSERT_JOIN_HELPER(a, b)
-#define COMPILE_ASSERT_JOIN_HELPER(a, b) a##b
-#define COMPILE_ASSERT(expr) \
- DART_UNUSED typedef CompileAssert<(static_cast<bool>(expr))> \
- COMPILE_ASSERT_JOIN(CompileAssertTypeDef, \
- __LINE__)[static_cast<bool>(expr) ? 1 : -1]
-#endif // !defined(COMPILE_ASSERT)
+#define COMPILE_ASSERT(expr) static_assert(expr, "")
#if defined(TESTING)
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index be43b30..7815569 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -352,6 +352,19 @@
#error Unknown architecture.
#endif
+// Determine whether HOST_ARCH equals TARGET_ARCH.
+#if defined(HOST_ARCH_ARM) && defined(TARGET_ARCH_ARM)
+#define HOST_ARCH_EQUALS_TARGET_ARCH 1
+#elif defined(HOST_ARCH_ARM64) && defined(TARGET_ARCH_ARM64)
+#define HOST_ARCH_EQUALS_TARGET_ARCH 1
+#elif defined(HOST_ARCH_IA32) && defined(TARGET_ARCH_IA32)
+#define HOST_ARCH_EQUALS_TARGET_ARCH 1
+#elif defined(HOST_ARCH_X64) && defined(TARGET_ARCH_X64)
+#define HOST_ARCH_EQUALS_TARGET_ARCH 1
+#else
+// HOST_ARCH != TARGET_ARCH.
+#endif
+
#if !defined(TARGET_OS_ANDROID) && !defined(TARGET_OS_FUCHSIA) && \
!defined(TARGET_OS_MACOS_IOS) && !defined(TARGET_OS_LINUX) && \
!defined(TARGET_OS_MACOS) && !defined(TARGET_OS_WINDOWS)
diff --git a/runtime/tests/vm/dart/regress_36590_test.dart b/runtime/tests/vm/dart/regress_36590_test.dart
new file mode 100644
index 0000000..645c45b
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_36590_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Regression test for https://github.com/dart-lang/sdk/issues/36590.
+//
+// This test verifies that compiler does not crash if OSR occurs at
+// CheckStack bytecode instruction which is not at the beginning of a join
+// block in bytecode (if the end of the "loop" body is unreachable and hence
+// there is no backward jump).
+//
+// VMOptions=--deterministic
+
+var var6 = [1, 2, 3];
+
+void bar() {}
+
+var cond_true = true;
+
+void foo() {
+ for (int i = 0; i < 9995; ++i) {
+ var6[0] += 1;
+ }
+ if (cond_true) {
+ var6[0] += 1;
+ for (var loc1 in var6) {
+ break;
+ }
+ }
+ if (cond_true) {
+ var6[0] += 1;
+ for (var loc1 in var6) {
+ break;
+ }
+ }
+ if (cond_true) {
+ var6[0] += 1;
+ for (var loc1 in var6) {
+ break;
+ }
+ }
+ if (cond_true) {
+ var6[0] += 1;
+ for (var loc1 in var6) {
+ break;
+ }
+ }
+ if (cond_true) {
+ var6[0] += 1;
+ for (var loc1 in var6) {
+ break;
+ }
+ }
+}
+
+main() {
+ foo();
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index b626857..195b548 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -41,6 +41,10 @@
dart/redirection_type_shuffling_test/none: RuntimeError
dart/snapshot_version_test: RuntimeError
+[ $hot_reload || $hot_reload_rollback ]
+dart/compilation_trace_test: Pass, Slow
+dart/type_feedback_test: Pass, Slow
+
[ $compiler != dartk || ($arch != x64 && $arch != simarm && $arch != arm) || $hot_reload || $hot_reload_rollback ]
dart/entrypoints/jit/*: SkipByDesign # Only supported in the Dart 2 JIT and AOT, and test optimizations - hence disabled on hotreload bots.
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 9f79e8a..879e669 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -13,7 +13,7 @@
// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
-const String version = '1.7';
+const String version = '1.9';
// Restriction on statement and expression depths.
const int stmtDepth = 2;
diff --git a/runtime/tools/dartfuzz/dartfuzz_api_table.dart b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
index 170f19d..787e324 100644
--- a/runtime/tools/dartfuzz/dartfuzz_api_table.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
@@ -171,9 +171,6 @@
DartLib('FileSystemEvent.all', 'Vv'),
DartLib('FileSystemEvent.ALL', 'Vv'),
DartLib('exitCode', 'Vv'),
- DartLib('pid', 'Vv'),
- DartLib('ProcessInfo.currentRss', 'Vv'),
- DartLib('ProcessInfo.maxRss', 'Vv'),
DartLib('RawSocketOption.levelSocket', 'Vv'),
DartLib('RawSocketOption.levelIPv4', 'Vv'),
DartLib('RawSocketOption.IPv4MulticastInterface', 'Vv'),
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart
index 768ba39..05a5000 100755
--- a/runtime/tools/dartfuzz/gen_api_table.dart
+++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -127,8 +127,8 @@
}
void visitClass(ClassElement classElement) {
- // Platform operations cause too many divergences.
- if (classElement.name == 'Platform') {
+ // Classes that cause too many false divergences.
+ if (classElement.name == 'ProcessInfo' || classElement.name == 'Platform') {
return;
}
// Every class element contains elements for the members, viz. `methods` visits
@@ -252,13 +252,14 @@
if (ret.contains('?') || proto.contains('?')) {
return;
}
- // Restrict parameters for a few hardcoded cases, for
- // example, to avoid excessive runtime or memory allocation
- // in the generated fuzzing program or to avoid obvious
- // divergences.
+ // Restrict parameters for a few hardcoded cases,
+ // for example, to avoid excessive runtime or memory
+ // allocation in the generated fuzzing program or to
+ // avoid false divergences.
if (name == 'padLeft' || name == 'padRight') {
proto = proto.replaceAll('I', 'i');
- } else if (name == 'Platform.executable' ||
+ } else if (name == 'pid' ||
+ name == 'Platform.executable' ||
name == 'Platform.resolvedExecutable') {
return;
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index ce2bac2..ba2dc60 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1181,6 +1181,14 @@
ASSERT(Thread::Current()->IsMutatorThread());
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
+ // 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);
+ }
ClassFinalizer::FinalizeClass(cls);
return Error::null();
} else {
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 213a394..5f0accb 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4685,12 +4685,12 @@
"<empty>");
AddBaseObject(Object::empty_exception_handlers().raw(), "ExceptionHandlers",
"<empty>");
- ASSERT(Object::implicit_getter_bytecode().raw() != Object::null());
AddBaseObject(Object::implicit_getter_bytecode().raw(), "Bytecode",
"<implicit getter>");
- ASSERT(Object::implicit_setter_bytecode().raw() != Object::null());
AddBaseObject(Object::implicit_setter_bytecode().raw(), "Bytecode",
"<implicit setter>");
+ AddBaseObject(Object::method_extractor_bytecode().raw(), "Bytecode",
+ "<method extractor>");
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i],
@@ -5148,6 +5148,7 @@
AddBaseObject(Object::empty_exception_handlers().raw());
AddBaseObject(Object::implicit_getter_bytecode().raw());
AddBaseObject(Object::implicit_setter_bytecode().raw());
+ AddBaseObject(Object::method_extractor_bytecode().raw());
for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) {
AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 4289942..58750f8 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -794,6 +794,8 @@
Z, Closure::Cast(instance).instantiator_type_arguments()));
AddTypeArguments(TypeArguments::Handle(
Z, Closure::Cast(instance).function_type_arguments()));
+ AddTypeArguments(TypeArguments::Handle(
+ Z, Closure::Cast(instance).delayed_type_arguments()));
return;
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index e5e6e5f..b3debf1 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -547,6 +547,90 @@
Emit(encoding);
}
+void Assembler::TransitionGeneratedToNative(Register destination_address,
+ Register addr,
+ Register state) {
+ // Save exit frame information to enable stack walking.
+ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
+
+ // Mark that the thread is executing native code.
+ StoreToOffset(kWord, destination_address, THR, Thread::vm_tag_offset());
+ LoadImmediate(state, compiler::target::Thread::native_execution_state());
+ StoreToOffset(kWord, state, THR, Thread::execution_state_offset());
+
+ if (TargetCPUFeatures::arm_version() == ARMv5TE) {
+ EnterSafepointSlowly();
+ } else {
+ Label slow_path, done, retry;
+ LoadImmediate(addr, compiler::target::Thread::safepoint_state_offset());
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldrex(state, addr);
+ cmp(state, Operand(Thread::safepoint_state_unacquired()));
+ b(&slow_path, NE);
+
+ mov(state, Operand(Thread::safepoint_state_acquired()));
+ strex(TMP, state, addr);
+ cmp(TMP, Operand(0)); // 0 means strex was successful.
+ b(&done, EQ);
+ b(&retry);
+
+ Bind(&slow_path);
+ EnterSafepointSlowly();
+
+ Bind(&done);
+ }
+}
+
+void Assembler::EnterSafepointSlowly() {
+ ldr(TMP,
+ Address(THR, compiler::target::Thread::enter_safepoint_stub_offset()));
+ ldr(TMP, FieldAddress(TMP, compiler::target::Code::entry_point_offset()));
+ blx(TMP);
+}
+
+void Assembler::TransitionNativeToGenerated(Register addr, Register state) {
+ if (TargetCPUFeatures::arm_version() == ARMv5TE) {
+ ExitSafepointSlowly();
+ } else {
+ Label slow_path, done, retry;
+ LoadImmediate(addr, compiler::target::Thread::safepoint_state_offset());
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldrex(state, addr);
+ cmp(state, Operand(Thread::safepoint_state_acquired()));
+ b(&slow_path, NE);
+
+ mov(state, Operand(Thread::safepoint_state_unacquired()));
+ strex(TMP, state, addr);
+ cmp(TMP, Operand(0)); // 0 means strex was successful.
+ b(&done, EQ);
+ b(&retry);
+
+ Bind(&slow_path);
+ ExitSafepointSlowly();
+
+ Bind(&done);
+ }
+
+ // Mark that the thread is executing Dart code.
+ LoadImmediate(state, compiler::target::Thread::vm_tag_compiled_id());
+ StoreToOffset(kWord, state, THR, Thread::vm_tag_offset());
+ LoadImmediate(state, compiler::target::Thread::generated_execution_state());
+ StoreToOffset(kWord, state, THR, Thread::execution_state_offset());
+
+ // Reset exit frame information in Isolate structure.
+ LoadImmediate(state, 0);
+ StoreToOffset(kWord, state, THR, Thread::top_exit_frame_info_offset());
+}
+
+void Assembler::ExitSafepointSlowly() {
+ ldr(TMP,
+ Address(THR, compiler::target::Thread::exit_safepoint_stub_offset()));
+ ldr(TMP, FieldAddress(TMP, compiler::target::Code::entry_point_offset()));
+ blx(TMP);
+}
+
void Assembler::clrex() {
ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE);
int32_t encoding = (kSpecialCondition << kConditionShift) | B26 | B24 | B22 |
@@ -3158,8 +3242,6 @@
}
}
- LoadPoolPointer();
-
ReserveAlignedFrameSpace(frame_space);
}
@@ -3202,7 +3284,7 @@
entry.Call(this, argument_count);
}
-void Assembler::EnterDartFrame(intptr_t frame_size) {
+void Assembler::EnterDartFrame(intptr_t frame_size, bool load_pool_pointer) {
ASSERT(!constant_pool_allowed());
// Registers are pushed in descending order: R5 | R6 | R7/R11 | R14.
@@ -3214,7 +3296,7 @@
EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);
// Setup pool pointer for this dart function.
- LoadPoolPointer();
+ if (load_pool_pointer) LoadPoolPointer();
} else {
EnterFrame((1 << FP) | (1 << LR), 0);
}
@@ -3595,28 +3677,6 @@
strb(tmp, Address(addr, 3));
}
-static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc",
-};
-
-const char* Assembler::RegisterName(Register reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
- return cpu_reg_names[reg];
-}
-
-static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
- "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
-#if defined(VFPv3_D32)
- "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
-#endif
-};
-
-const char* Assembler::FpuRegisterName(FpuRegister reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
- return fpu_reg_names[reg];
-}
-
} // namespace compiler
} // namespace dart
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index cef1ff6..3f37cbd6 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -379,10 +379,6 @@
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
- static const char* RegisterName(Register reg);
-
- static const char* FpuRegisterName(FpuRegister reg);
-
// Data-processing instructions.
void and_(Register rd, Register rn, Operand o, Condition cond = AL);
@@ -514,6 +510,13 @@
void ldrex(Register rd, Register rn, Condition cond = AL);
void strex(Register rd, Register rt, Register rn, Condition cond = AL);
+ // Requires two temporary registers 'scratch0' and 'scratch1' (in addition to
+ // TMP).
+ void TransitionGeneratedToNative(Register destination_address,
+ Register scratch0,
+ Register scratch1);
+ void TransitionNativeToGenerated(Register scratch0, Register scratch1);
+
// Miscellaneous instructions.
void clrex();
void nop(Condition cond = AL);
@@ -1014,7 +1017,7 @@
// Set up a Dart frame on entry with a frame pointer and PC information to
// enable easy access to the RawInstruction object of code corresponding
// to this frame.
- void EnterDartFrame(intptr_t frame_size);
+ void EnterDartFrame(intptr_t frame_size, bool load_pool_pointer = true);
void LeaveDartFrame();
@@ -1295,6 +1298,9 @@
CanBeSmi can_be_smi,
BarrierFilterMode barrier_filter_mode);
+ void EnterSafepointSlowly();
+ void ExitSafepointSlowly();
+
friend class dart::FlowGraphCompiler;
std::function<void(Condition, Register)>
generate_invoke_write_barrier_wrapper_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index b466c6b..c88687fc 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -68,28 +68,6 @@
buffer_.Emit<int32_t>(value);
}
-static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
- "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
- "r22", "r23", "r24", "ip0", "ip1", "pp", "ctx", "fp", "lr", "r31",
-};
-
-const char* Assembler::RegisterName(Register reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
- return cpu_reg_names[reg];
-}
-
-static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
- "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10",
- "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
- "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
-};
-
-const char* Assembler::FpuRegisterName(FpuRegister reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
- return fpu_reg_names[reg];
-}
-
int32_t Assembler::BindImm19Branch(int64_t position, int64_t dest) {
if (use_far_branches() && !CanEncodeImm19BranchOffset(dest)) {
// Far branches are enabled, and we can't encode the branch offset in
@@ -1327,9 +1305,82 @@
LeaveFrame();
}
+void Assembler::TransitionGeneratedToNative(Register destination,
+ Register state) {
+ Register addr = TMP2;
+
+ // Save exit frame information to enable stack walking.
+ StoreToOffset(FPREG, THR,
+ compiler::target::Thread::top_exit_frame_info_offset());
+
+ // Mark that the thread is executing native code.
+ StoreToOffset(destination, THR, compiler::target::Thread::vm_tag_offset());
+ LoadImmediate(state, Thread::native_execution_state());
+ StoreToOffset(state, THR, compiler::target::Thread::execution_state_offset());
+
+ Label slow_path, done, retry;
+ movz(addr, Immediate(compiler::target::Thread::safepoint_state_offset()), 0);
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldxr(state, addr);
+ cmp(state, Operand(Thread::safepoint_state_unacquired()));
+ b(&slow_path, NE);
+
+ movz(state, Immediate(Thread::safepoint_state_acquired()), 0);
+ stxr(TMP, state, addr);
+ cbz(&done, TMP); // 0 means stxr was successful.
+ b(&retry);
+
+ Bind(&slow_path);
+ ldr(addr,
+ Address(THR, compiler::target::Thread::enter_safepoint_stub_offset()));
+ ldr(addr, FieldAddress(addr, compiler::target::Code::entry_point_offset()));
+ blr(addr);
+
+ Bind(&done);
+}
+
+void Assembler::TransitionNativeToGenerated(Register state) {
+ Register addr = TMP2;
+
+ Label slow_path, done, retry;
+ movz(addr, Immediate(compiler::target::Thread::safepoint_state_offset()), 0);
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldxr(state, addr);
+ cmp(state, Operand(Thread::safepoint_state_acquired()));
+ b(&slow_path, NE);
+
+ movz(state, Immediate(Thread::safepoint_state_unacquired()), 0);
+ stxr(TMP, state, addr);
+ cbz(&done, TMP); // 0 means stxr was successful.
+ b(&retry);
+
+ Bind(&slow_path);
+ ldr(addr,
+ Address(THR, compiler::target::Thread::exit_safepoint_stub_offset()));
+ ldr(addr, FieldAddress(TMP, compiler::target::Code::entry_point_offset()));
+ blr(addr);
+
+ Bind(&done);
+
+ // Mark that the thread is executing Dart code.
+ LoadImmediate(state, compiler::target::Thread::vm_tag_compiled_id());
+ StoreToOffset(state, THR, compiler::target::Thread::vm_tag_offset());
+ LoadImmediate(state, compiler::target::Thread::generated_execution_state());
+ StoreToOffset(state, THR, compiler::target::Thread::execution_state_offset());
+
+ // Reset exit frame information in Isolate structure.
+ StoreToOffset(ZR, THR,
+ compiler::target::Thread::top_exit_frame_info_offset());
+}
+
void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
Comment("EnterCallRuntimeFrame");
- EnterStubFrame();
+ EnterFrame(0);
+ if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+ TagAndPushPPAndPcMarker(); // Save PP and PC marker.
+ }
// Store fpu registers with the lowest register number at the lowest
// address.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index de51436..1ff5ac9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -473,10 +473,6 @@
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
- static const char* RegisterName(Register reg);
-
- static const char* FpuRegisterName(FpuRegister reg);
-
void SetPrologueOffset() {
if (prologue_offset_ == -1) {
prologue_offset_ = CodeSize();
@@ -1265,11 +1261,9 @@
ldr(reg, Address(SP, 1 * target::kWordSize, Address::PostIndex));
}
void PushPair(Register low, Register high) {
- ASSERT((low != PP) && (high != PP));
stp(low, high, Address(SP, -2 * target::kWordSize, Address::PairPreIndex));
}
void PopPair(Register low, Register high) {
- ASSERT((low != PP) && (high != PP));
ldp(low, high, Address(SP, 2 * target::kWordSize, Address::PairPostIndex));
}
void PushFloat(VRegister reg) {
@@ -1533,6 +1527,12 @@
void LeaveFrame();
void Ret() { ret(LR); }
+ // These require that CSP and SP are equal and aligned.
+ // These require a scratch register (in addition to TMP/TMP2).
+ void TransitionGeneratedToNative(Register destination_address,
+ Register scratch);
+ void TransitionNativeToGenerated(Register scratch);
+
void CheckCodePointer();
void RestoreCodePointer();
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.cc b/runtime/vm/compiler/assembler/assembler_dbc.cc
index 141c36a..fe6f47f 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.cc
+++ b/runtime/vm/compiler/assembler/assembler_dbc.cc
@@ -71,14 +71,6 @@
buffer_.Emit<int32_t>(value);
}
-const char* Assembler::RegisterName(Register reg) {
- return ThreadState::Current()->zone()->PrintToString("R%d", reg);
-}
-
-const char* Assembler::FpuRegisterName(FpuRegister reg) {
- return ThreadState::Current()->zone()->PrintToString("F%d", reg);
-}
-
static int32_t EncodeJump(int32_t relative_pc) {
return SimulatorBytecode::kJump | (relative_pc << 8);
}
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.h b/runtime/vm/compiler/assembler/assembler_dbc.h
index 3c57878..253fdc1 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.h
+++ b/runtime/vm/compiler/assembler/assembler_dbc.h
@@ -44,10 +44,6 @@
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
- static const char* RegisterName(Register reg);
-
- static const char* FpuRegisterName(FpuRegister reg);
-
static uword GetBreakInstructionFiller() { return SimulatorBytecode::kTrap; }
static bool IsSafe(const Object& value) { return true; }
diff --git a/runtime/vm/compiler/assembler/assembler_dbc_test.cc b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
index d577eec..1b192b5 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
@@ -1681,6 +1681,70 @@
EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
}
+ASSEMBLER_TEST_GENERATE(IfEqNullTOSNotNull, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(-1)));
+ __ IfEqNullTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfEqNullTOSNotNull, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+ASSEMBLER_TEST_GENERATE(IfEqNullTOSIsNull, assembler) {
+ Label branch_taken;
+ __ PushConstant(Object::null_object());
+ __ IfEqNullTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfEqNullTOSIsNull, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+ASSEMBLER_TEST_GENERATE(IfNeNullTOSNotNull, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(-1)));
+ __ IfNeNullTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfNeNullTOSNotNull, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+ASSEMBLER_TEST_GENERATE(IfNeNullTOSIsNull, assembler) {
+ Label branch_taken;
+ __ PushConstant(Object::null_object());
+ __ IfNeNullTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfNeNullTOSIsNull, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
// - If<Cond> rA, rD
//
// Cond is Le, Lt, Ge, Gt, unsigned variants ULe, ULt, UGe, UGt, and
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 5df8760..4ca49e3 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2078,6 +2078,72 @@
}
}
+void Assembler::TransitionGeneratedToNative(Register destination_address,
+ Register scratch) {
+ // Save exit frame information to enable stack walking.
+ movl(Address(THR, Thread::top_exit_frame_info_offset()), FPREG);
+
+ // Mark that the thread is executing native code.
+ movl(VMTagAddress(), destination_address);
+ movl(Address(THR, Thread::execution_state_offset()),
+ Immediate(compiler::target::Thread::native_execution_state()));
+
+ // Compare and swap the value at Thread::safepoint_state from unacquired to
+ // acquired. On success, jump to 'success'; otherwise, fallthrough.
+ pushl(EAX);
+ movl(EAX, Immediate(Thread::safepoint_state_unacquired()));
+ movl(scratch, Immediate(Thread::safepoint_state_acquired()));
+ LockCmpxchgl(Address(THR, Thread::safepoint_state_offset()), scratch);
+ movl(scratch, EAX);
+ popl(EAX);
+ cmpl(scratch, Immediate(Thread::safepoint_state_unacquired()));
+
+ Label done;
+ j(EQUAL, &done);
+
+ movl(scratch,
+ Address(THR, compiler::target::Thread::enter_safepoint_stub_offset()));
+ movl(scratch,
+ FieldAddress(scratch, compiler::target::Code::entry_point_offset()));
+ call(scratch);
+
+ Bind(&done);
+}
+
+void Assembler::TransitionNativeToGenerated(Register scratch) {
+ // Compare and swap the value at Thread::safepoint_state from acquired to
+ // unacquired. On success, jump to 'success'; otherwise, fallthrough.
+ pushl(EAX);
+ movl(EAX, Immediate(compiler::target::Thread::safepoint_state_acquired()));
+ movl(scratch,
+ Immediate(compiler::target::Thread::safepoint_state_unacquired()));
+ LockCmpxchgl(Address(THR, compiler::target::Thread::safepoint_state_offset()),
+ scratch);
+ movl(scratch, EAX);
+ popl(EAX);
+ cmpl(scratch, Immediate(Thread::safepoint_state_acquired()));
+
+ Label done;
+ j(EQUAL, &done);
+
+ movl(scratch,
+ Address(THR, compiler::target::Thread::exit_safepoint_stub_offset()));
+ movl(scratch,
+ FieldAddress(scratch, compiler::target::Code::entry_point_offset()));
+ call(scratch);
+
+ Bind(&done);
+
+ // Mark that the thread is executing Dart code.
+ movl(Assembler::VMTagAddress(),
+ Immediate(compiler::target::Thread::vm_tag_compiled_id()));
+ movl(Address(THR, Thread::execution_state_offset()),
+ Immediate(compiler::target::Thread::generated_execution_state()));
+
+ // Reset exit frame information in Isolate structure.
+ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
+}
+
static const intptr_t kNumberOfVolatileCpuRegisters = 3;
static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = {
EAX, ECX, EDX};
@@ -2594,24 +2660,6 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-// Used by disassembler, so it is declared outside of
-// !defined(DART_PRECOMPILED_RUNTIME) section.
-static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
- "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
-
-const char* Assembler::RegisterName(Register reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
- return cpu_reg_names[reg];
-}
-
-static const char* xmm_reg_names[kNumberOfXmmRegisters] = {
- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
-
-const char* Assembler::FpuRegisterName(FpuRegister reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
- return xmm_reg_names[reg];
-}
-
} // namespace compiler
} // namespace dart
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 1ec4248..91fa1c2 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -645,6 +645,12 @@
void LeaveFrame();
void ReserveAlignedFrameSpace(intptr_t frame_space);
+ // Require a temporary register 'tmp'.
+ // Clobber all non-CPU registers (e.g. XMM registers and the "FPU stack").
+ void TransitionGeneratedToNative(Register destination_address,
+ Register scratch);
+ void TransitionNativeToGenerated(Register scratch);
+
// Create a frame for calling into runtime that preserves all volatile
// registers. Frame's RSP is guaranteed to be correctly aligned and
// frame_space bytes are reserved under it.
@@ -811,9 +817,6 @@
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
- static const char* RegisterName(Register reg);
- static const char* FpuRegisterName(FpuRegister reg);
-
// Check if the given value is an integer value that can be directly
// emdedded into the code without additional XORing with jit_cookie.
// We consider 16-bit integers, powers of two and corresponding masks
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 0889448..64f3d7ed 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -164,6 +164,63 @@
EmitUint8(0xC0 + (dst & 0x07));
}
+void Assembler::TransitionGeneratedToNative(Register destination_address) {
+ // Save exit frame information to enable stack walking.
+ movq(Address(THR, Thread::top_exit_frame_info_offset()), FPREG);
+
+ movq(Assembler::VMTagAddress(), destination_address);
+ movq(Address(THR, compiler::target::Thread::execution_state_offset()),
+ Immediate(compiler::target::Thread::native_execution_state()));
+
+ // Compare and swap the value at Thread::safepoint_state from unacquired to
+ // acquired. If the CAS fails, go to a slow-path stub.
+ Label done;
+ pushq(RAX);
+ movq(RAX, Immediate(Thread::safepoint_state_unacquired()));
+ movq(TMP, Immediate(Thread::safepoint_state_acquired()));
+ LockCmpxchgq(Address(THR, Thread::safepoint_state_offset()), TMP);
+ movq(TMP, RAX);
+ popq(RAX);
+ cmpq(TMP, Immediate(Thread::safepoint_state_unacquired()));
+ j(EQUAL, &done);
+
+ movq(TMP,
+ Address(THR, compiler::target::Thread::enter_safepoint_stub_offset()));
+ movq(TMP, FieldAddress(TMP, compiler::target::Code::entry_point_offset()));
+ CallCFunction(TMP);
+
+ Bind(&done);
+}
+
+void Assembler::TransitionNativeToGenerated() {
+ // Compare and swap the value at Thread::safepoint_state from acquired to
+ // unacquired. On success, jump to 'success'; otherwise, fallthrough.
+ Label done;
+ pushq(RAX);
+ movq(RAX, Immediate(Thread::safepoint_state_acquired()));
+ movq(TMP, Immediate(Thread::safepoint_state_unacquired()));
+ LockCmpxchgq(Address(THR, Thread::safepoint_state_offset()), TMP);
+ movq(TMP, RAX);
+ popq(RAX);
+ cmpq(TMP, Immediate(Thread::safepoint_state_acquired()));
+ j(EQUAL, &done);
+
+ movq(TMP,
+ Address(THR, compiler::target::Thread::exit_safepoint_stub_offset()));
+ movq(TMP, FieldAddress(TMP, compiler::target::Code::entry_point_offset()));
+ CallCFunction(TMP);
+
+ Bind(&done);
+
+ movq(Assembler::VMTagAddress(),
+ Immediate(compiler::target::Thread::vm_tag_compiled_id()));
+ movq(Address(THR, Thread::execution_state_offset()),
+ Immediate(compiler::target::Thread::generated_execution_state()));
+
+ // Reset exit frame information in Isolate structure.
+ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
+}
+
void Assembler::EmitQ(int reg,
const Address& address,
int opcode,
@@ -1527,7 +1584,11 @@
void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
Comment("EnterCallRuntimeFrame");
- EnterStubFrame();
+ EnterFrame(0);
+ if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+ pushq(CODE_REG);
+ pushq(PP);
+ }
// TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
PushRegisters(CallingConventions::kVolatileCpuRegisters,
@@ -2133,26 +2194,6 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
-static const char* xmm_reg_names[kNumberOfXmmRegisters] = {
- "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
-
-const char* Assembler::FpuRegisterName(FpuRegister reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
- return xmm_reg_names[reg];
-}
-
-static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
- "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "thr", "pp"};
-
-// Used by disassembler, so it is declared outside of
-// !defined(DART_PRECOMPILED_RUNTIME) section.
-const char* Assembler::RegisterName(Register reg) {
- ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
- return cpu_reg_names[reg];
-}
-
} // namespace compiler
} // namespace dart
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 2df4c31..0ef1efe 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -306,6 +306,9 @@
void setcc(Condition condition, ByteRegister dst);
+ void TransitionGeneratedToNative(Register destination_address);
+ void TransitionNativeToGenerated();
+
// Register-register, register-address and address-register instructions.
#define RR(width, name, ...) \
void name(Register dst, Register src) { Emit##width(dst, src, __VA_ARGS__); }
@@ -929,10 +932,6 @@
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
- static const char* RegisterName(Register reg);
-
- static const char* FpuRegisterName(FpuRegister reg);
-
static Address ElementAddressForIntIndex(bool is_external,
intptr_t cid,
intptr_t index_scale,
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index e0c7f8a..c0b9538 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -215,6 +215,7 @@
case KernelBytecode::kPushConstant:
case KernelBytecode::kIndirectStaticCall:
case KernelBytecode::kInterfaceCall:
+ case KernelBytecode::kUncheckedInterfaceCall:
case KernelBytecode::kDynamicCall:
case KernelBytecode::kStoreStaticTOS:
case KernelBytecode::kPushStatic:
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index 9d9b45e..756e5d4 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -308,7 +308,7 @@
}
const char* NameOfCPURegister(int reg) const {
- return compiler::Assembler::RegisterName(static_cast<Register>(reg));
+ return RegisterNames::RegisterName(static_cast<Register>(reg));
}
const char* NameOfByteCPURegister(int reg) const {
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 0337556..22557d7 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -28,13 +28,15 @@
return def;
}
- Definition* AddDefinition(Definition* def) {
+ template <typename T>
+ T* AddDefinition(T* def) {
def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
AddInstruction(def);
return def;
}
- Instruction* AddInstruction(Instruction* instr) {
+ template <typename T>
+ T* AddInstruction(T* instr) {
if (instr->ComputeCanDeoptimize()) {
// All instructions that can deoptimize must have an environment attached
// to them.
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index a33c17b..d27b6e2 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -1326,6 +1326,10 @@
SetValue(instr, non_constant_);
}
+void ConstantPropagator::VisitBitCast(BitCastInstr* instr) {
+ SetValue(instr, non_constant_);
+}
+
void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
// TODO(kmillikin): Handle unary operations.
SetValue(instr, non_constant_);
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index e4e02d5..40eac02 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -497,10 +497,6 @@
// If the receiver can have the null value, exclude any method
// that is actually valid on a null receiver.
if (receiver_maybe_null) {
-#ifdef TARGET_ARCH_DBC
- // TODO(ajcbik): DBC does not support null check at all yet.
- return ToCheck::kCheckCid;
-#else
const Class& null_class =
Class::Handle(zone(), isolate()->object_store()->null_class());
const Function& target = Function::Handle(
@@ -509,7 +505,6 @@
if (!target.IsNull()) {
return ToCheck::kCheckCid;
}
-#endif
}
// Use CHA to determine if the method is not overridden by any subclass
@@ -1053,6 +1048,8 @@
}
}
+ const intptr_t var_length =
+ IsCompiledForOsr() ? osr_variable_count() : variable_count();
while (!worklist.is_empty()) {
BlockEntryInstr* current = worklist.RemoveLast();
// Ensure a phi for each block in the dominance frontier of current.
@@ -1063,7 +1060,7 @@
BlockEntryInstr* block = preorder[index];
ASSERT(block->IsJoinEntry());
PhiInstr* phi =
- block->AsJoinEntry()->InsertPhi(var_index, variable_count());
+ block->AsJoinEntry()->InsertPhi(var_index, var_length);
if (always_live) {
phi->mark_alive();
live_phis->Add(phi);
@@ -1079,17 +1076,26 @@
}
}
+void FlowGraph::CreateCommonConstants() {
+ constant_null_ = GetConstant(Object::ZoneHandle());
+ constant_dead_ = GetConstant(Symbols::OptimizedOut());
+}
+
void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
VariableLivenessAnalysis* variable_liveness,
ZoneGrowableArray<Definition*>* inlining_parameters) {
GraphEntryInstr* entry = graph_entry();
// Add global constants to the initial definitions.
- constant_null_ = GetConstant(Object::ZoneHandle());
- constant_dead_ = GetConstant(Symbols::OptimizedOut());
+ CreateCommonConstants();
+ // During regular execution, only the direct parameters appear in
+ // the fixed part of the environment. During OSR, however, all
+ // variables and possibly a non-empty stack are passed as
+ // parameters. The latter mimics the incoming expression stack
+ // that was set up prior to triggering OSR.
const intptr_t parameter_count =
- IsCompiledForOsr() ? variable_count() : num_direct_parameters_;
+ IsCompiledForOsr() ? osr_variable_count() : num_direct_parameters_;
// Initial renaming environment.
GrowableArray<Definition*> env(parameter_count + num_stack_locals());
@@ -1107,7 +1113,6 @@
ASSERT(entry->unchecked_entry() != nullptr ? entry->SuccessorCount() == 2
: entry->SuccessorCount() == 1);
}
-
RenameRecursive(entry, &env, live_phis, variable_liveness,
inlining_parameters);
}
@@ -1125,6 +1130,7 @@
const intptr_t inlined_type_args_param =
((inlining_parameters != NULL) && function().IsGeneric()) ? 1 : 0;
+ ASSERT(parameter_count <= env->length());
for (intptr_t i = 0; i < parameter_count; i++) {
ParameterInstr* param = new (zone()) ParameterInstr(i, function_entry);
param->set_ssa_temp_index(alloc_ssa_temp_index());
@@ -1182,13 +1188,26 @@
OsrEntryInstr* osr_entry,
GrowableArray<Definition*>* env) {
ASSERT(IsCompiledForOsr());
- const intptr_t parameter_count = variable_count();
+ const intptr_t parameter_count = osr_variable_count();
+ // Initialize the initial enviroment.
+ ASSERT(parameter_count <= env->length());
for (intptr_t i = 0; i < parameter_count; i++) {
ParameterInstr* param = new (zone()) ParameterInstr(i, osr_entry);
param->set_ssa_temp_index(alloc_ssa_temp_index());
AddToInitialDefinitions(osr_entry, param);
(*env)[i] = param;
}
+ // For OSR on a non-emtpy stack, insert synthetic phis on the joining entry.
+ // These phis are synthetic since they are not driven by live variable
+ // analysis, but merely serve the purpose of merging stack slots from
+ // parameters and other predecessors at the block in which OSR occurred.
+ JoinEntryInstr* join =
+ osr_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
+ ASSERT(join != nullptr);
+ for (intptr_t i = variable_count(); i < parameter_count; i++) {
+ PhiInstr* phi = join->InsertPhi(i, parameter_count);
+ phi->mark_alive();
+ }
}
void FlowGraph::PopulateEnvironmentFromCatchEntry(
@@ -1204,7 +1223,8 @@
: -1;
// Add real definitions for all locals and parameters.
- for (intptr_t i = 0; i < variable_count(); ++i) {
+ ASSERT(variable_count() <= env->length());
+ for (intptr_t i = 0, n = variable_count(); i < n; ++i) {
// Replace usages of the raw exception/stacktrace variables with
// [SpecialParameterInstr]s.
Definition* param = nullptr;
@@ -1247,10 +1267,13 @@
ZoneGrowableArray<Definition*>* inlining_parameters) {
// 1. Process phis first.
if (auto join = block_entry->AsJoinEntry()) {
- if (join->phis() != NULL) {
- for (intptr_t i = 0; i < join->phis()->length(); ++i) {
+ if (join->phis() != nullptr) {
+ const intptr_t var_length =
+ IsCompiledForOsr() ? osr_variable_count() : variable_count();
+ ASSERT(join->phis()->length() == var_length);
+ for (intptr_t i = 0; i < var_length; ++i) {
PhiInstr* phi = (*join->phis())[i];
- if (phi != NULL) {
+ if (phi != nullptr) {
(*env)[i] = phi;
AllocateSSAIndexes(phi); // New SSA temp.
if (block_entry->InsideTryBlock() && !phi->is_alive()) {
@@ -1290,7 +1313,6 @@
}
}
-
// Attach environment to the block entry.
AttachEnvironment(block_entry, env);
@@ -1334,7 +1356,6 @@
Value* v = current->InputAt(i);
// Update expression stack.
ASSERT(env->length() > variable_count());
-
Definition* reaching_defn = env->RemoveLast();
Definition* input_defn = v->definition();
if (input_defn != reaching_defn) {
@@ -1350,12 +1371,37 @@
input_defn->AddInputUse(v);
}
- // Drop pushed arguments for calls.
- for (intptr_t j = 0; j < current->ArgumentCount(); j++) {
- env->RemoveLast();
+ // 2b. Handle arguments. Usually this just consists of popping
+ // all consumed parameters from the expression stack. However,
+ // during OSR with a non-empty stack, PushArguments may have
+ // been lost (since the defining value resides in the now
+ // removed original entry).
+ Instruction* insert_at = current; // keeps push arguments in order
+ for (intptr_t i = current->ArgumentCount() - 1; i >= 0; --i) {
+ // Update expression stack.
+ ASSERT(env->length() > variable_count());
+ Definition* reaching_defn = env->RemoveLast();
+ if (reaching_defn->IsPushArgument()) {
+ insert_at = reaching_defn;
+ } else {
+ // We lost the PushArgument! This situation can only happen
+ // during OSR with a non-empty stack: replace the argument
+ // with the incoming parameter that mimics the stack slot.
+ ASSERT(IsCompiledForOsr());
+ PushArgumentInstr* push_arg = current->PushArgumentAt(i);
+ ASSERT(push_arg->IsPushArgument());
+ ASSERT(reaching_defn->ssa_temp_index() != -1);
+ ASSERT(reaching_defn->IsPhi());
+ push_arg->previous()->LinkTo(push_arg->next());
+ push_arg->set_previous(nullptr);
+ push_arg->set_next(nullptr);
+ push_arg->value()->set_definition(reaching_defn);
+ InsertBefore(insert_at, push_arg, nullptr, FlowGraph::kEffect);
+ insert_at = push_arg;
+ }
}
- // 2b. Handle LoadLocal/StoreLocal/MakeTemp/DropTemps/Constant and
+ // 2c. Handle LoadLocal/StoreLocal/MakeTemp/DropTemps/Constant and
// PushArgument specially. Other definitions are just pushed
// to the environment directly.
Definition* result = NULL;
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 48f4ff0..67f47ce 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -120,6 +120,13 @@
return num_direct_parameters_ + parsed_function_.num_stack_locals();
}
+ // The number of variables during OSR, which may include stack slots
+ // that pass in initial contents for the expression stack.
+ intptr_t osr_variable_count() const {
+ ASSERT(IsCompiledForOsr());
+ return variable_count() + graph_entry()->osr_entry()->stack_depth();
+ }
+
// The number of variables (or boxes) inside the functions frame - meaning
// below the frame pointer. This does not include the expression stack.
intptr_t num_stack_locals() const {
@@ -415,6 +422,8 @@
// SSA transformation methods and fields.
void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier);
+ void CreateCommonConstants();
+
private:
friend class FlowGraphCompiler; // TODO(ajcbik): restructure
friend class FlowGraphChecker;
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index a07ed6d..3b9481f 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -119,6 +119,7 @@
}
// Visit regular instructions.
Instruction* last = block->last_instruction();
+ ASSERT((last == block) == block->IsGraphEntry());
Instruction* prev = block;
ASSERT(prev->previous() == nullptr);
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 54f1e50..9e5377b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -81,7 +81,8 @@
it.CurrentValue()->definition()->IsPushArgument()) {
it.SetCurrentLocation(Location::StackSlot(
compiler::target::frame_layout.FrameSlotForVariableIndex(
- -*stack_height)));
+ -*stack_height),
+ FPREG));
(*stack_height)++;
}
}
@@ -559,6 +560,14 @@
StatsEnd(entry);
pending_deoptimization_env_ = NULL;
EndCodeSourceRange(entry->token_pos());
+
+ // The function was fully intrinsified, so there's no need to generate any
+ // more code.
+ if (fully_intrinsified_) {
+ ASSERT(entry == flow_graph().graph_entry()->normal_entry());
+ break;
+ }
+
// Compile all successors until an exit, branch, or a block entry.
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Instruction* instr = it.Current();
@@ -614,6 +623,14 @@
}
}
+intptr_t FlowGraphCompiler::ExtraStackSlotsOnOsrEntry() const {
+ ASSERT(flow_graph().IsCompiledForOsr());
+ const intptr_t stack_depth =
+ flow_graph().graph_entry()->osr_entry()->stack_depth();
+ const intptr_t num_stack_locals = flow_graph().num_stack_locals();
+ return StackSize() - stack_depth - num_stack_locals;
+}
+
Label* FlowGraphCompiler::GetJumpLabel(BlockEntryInstr* block_entry) const {
const intptr_t block_index = block_entry->postorder_number();
return block_info_[block_index]->jump_label();
@@ -952,8 +969,8 @@
for (Environment::DeepIterator it(env); !it.Done(); it.Advance()) {
Location loc = it.CurrentLocation();
Value* value = it.CurrentValue();
- it.SetCurrentLocation(loc.RemapForSlowPath(value->definition(),
- cpu_reg_slots, fpu_reg_slots));
+ it.SetCurrentLocation(LocationRemapForSlowPath(
+ loc, value->definition(), cpu_reg_slots, fpu_reg_slots));
}
return env;
@@ -1154,6 +1171,14 @@
// Returns 'true' if regular code generation should be skipped.
bool FlowGraphCompiler::TryIntrinsify() {
+ if (TryIntrinsifyHelper()) {
+ fully_intrinsified_ = true;
+ return true;
+ }
+ return false;
+}
+
+bool FlowGraphCompiler::TryIntrinsifyHelper() {
Label exit;
set_intrinsic_slow_path_label(&exit);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 8cfee57..56046747 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -243,8 +243,6 @@
}
};
-#if !defined(TARGET_ARCH_DBC)
-
// Slow path code which calls runtime entry to throw an exception.
class ThrowErrorSlowPathCode : public TemplateSlowPathCode<Instruction> {
public:
@@ -298,8 +296,6 @@
}
};
-#endif // !defined(TARGET_ARCH_DBC)
-
class FlowGraphCompiler : public ValueObject {
private:
class BlockInfo : public ZoneAllocated {
@@ -639,8 +635,15 @@
void EmitComment(Instruction* instr);
+ // Returns stack size (number of variables on stack for unoptimized
+ // code, or number of spill slots for optimized code).
intptr_t StackSize() const;
+ // Returns the number of extra stack slots used during an Osr entry
+ // (values for all [ParameterInstr]s, representing local variables
+ // and expression stack values, are already on the stack).
+ intptr_t ExtraStackSlotsOnOsrEntry() const;
+
// Returns assembler label associated with the given block entry.
Label* GetJumpLabel(BlockEntryInstr* block_entry) const;
bool WasCompacted(BlockEntryInstr* block_entry) const;
@@ -814,6 +817,7 @@
void EmitFrameEntry();
+ bool TryIntrinsifyHelper();
void AddPcRelativeCallTarget(const Function& function,
Code::EntryKind entry_kind);
void AddPcRelativeCallStubTarget(const Code& stub_code);
@@ -1027,6 +1031,7 @@
// True while emitting intrinsic code.
bool intrinsic_mode_;
Label* intrinsic_slow_path_label_ = nullptr;
+ bool fully_intrinsified_ = false;
CodeStatistics* stats_;
const Class& double_class_;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 47ba86e..04a4a85 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -886,7 +886,7 @@
}
__ Comment("Enter frame");
if (flow_graph().IsCompiledForOsr()) {
- intptr_t extra_slots = StackSize() - flow_graph().num_stack_locals();
+ const intptr_t extra_slots = ExtraStackSlotsOnOsrEntry();
ASSERT(extra_slots >= 0);
__ EnterOsrFrame(extra_slots * kWordSize);
} else {
@@ -943,8 +943,11 @@
VisitBlocks();
__ bkpt(0);
- ASSERT(assembler()->constant_pool_allowed());
- GenerateDeferredCode();
+
+ if (!fully_intrinsified_) {
+ ASSERT(assembler()->constant_pool_allowed());
+ GenerateDeferredCode();
+ }
}
void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index fe52d41..943aaec 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -870,7 +870,7 @@
}
__ Comment("Enter frame");
if (flow_graph().IsCompiledForOsr()) {
- intptr_t extra_slots = StackSize() - flow_graph().num_stack_locals();
+ const intptr_t extra_slots = ExtraStackSlotsOnOsrEntry();
ASSERT(extra_slots >= 0);
__ EnterOsrFrame(extra_slots * kWordSize, new_pp);
} else {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
index 09c490bd..892cdb5 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
@@ -113,7 +113,8 @@
NULL,
Location::StackSlot(
compiler::target::frame_layout.FrameSlotForVariableIndex(
- -stack_height)),
+ -stack_height),
+ FPREG),
slot_ix++);
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index b1c4671..dfa2fc7 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -727,7 +727,7 @@
__ PushObject(value.constant());
} else {
ASSERT(value.IsStackSlot());
- __ pushl(value.ToStackSlotAddress());
+ __ pushl(LocationToStackSlotAddress(value));
}
}
}
@@ -779,7 +779,7 @@
}
__ Comment("Enter frame");
if (flow_graph().IsCompiledForOsr()) {
- intptr_t extra_slots = StackSize() - flow_graph().num_stack_locals();
+ intptr_t extra_slots = ExtraStackSlotsOnOsrEntry();
ASSERT(extra_slots >= 0);
__ EnterOsrFrame(extra_slots * kWordSize);
} else {
@@ -990,8 +990,8 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos,
- RawPcDescriptors::kOther, locs, function);
+ GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ function);
__ Drop(count_with_type_args);
}
@@ -1182,15 +1182,15 @@
__ movl(destination.reg(), source.reg());
} else {
ASSERT(destination.IsStackSlot());
- __ movl(destination.ToStackSlotAddress(), source.reg());
+ __ movl(LocationToStackSlotAddress(destination), source.reg());
}
} else if (source.IsStackSlot()) {
if (destination.IsRegister()) {
- __ movl(destination.reg(), source.ToStackSlotAddress());
+ __ movl(destination.reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsStackSlot());
- MoveMemoryToMemory(destination.ToStackSlotAddress(),
- source.ToStackSlotAddress());
+ MoveMemoryToMemory(LocationToStackSlotAddress(destination),
+ LocationToStackSlotAddress(source));
}
} else if (source.IsFpuRegister()) {
if (destination.IsFpuRegister()) {
@@ -1199,27 +1199,27 @@
__ movaps(destination.fpu_reg(), source.fpu_reg());
} else {
if (destination.IsDoubleStackSlot()) {
- __ movsd(destination.ToStackSlotAddress(), source.fpu_reg());
+ __ movsd(LocationToStackSlotAddress(destination), source.fpu_reg());
} else {
ASSERT(destination.IsQuadStackSlot());
- __ movups(destination.ToStackSlotAddress(), source.fpu_reg());
+ __ movups(LocationToStackSlotAddress(destination), source.fpu_reg());
}
}
} else if (source.IsDoubleStackSlot()) {
if (destination.IsFpuRegister()) {
- __ movsd(destination.fpu_reg(), source.ToStackSlotAddress());
+ __ movsd(destination.fpu_reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsDoubleStackSlot());
- __ movsd(XMM0, source.ToStackSlotAddress());
- __ movsd(destination.ToStackSlotAddress(), XMM0);
+ __ movsd(XMM0, LocationToStackSlotAddress(source));
+ __ movsd(LocationToStackSlotAddress(destination), XMM0);
}
} else if (source.IsQuadStackSlot()) {
if (destination.IsFpuRegister()) {
- __ movups(destination.fpu_reg(), source.ToStackSlotAddress());
+ __ movups(destination.fpu_reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsQuadStackSlot());
- __ movups(XMM0, source.ToStackSlotAddress());
- __ movups(destination.ToStackSlotAddress(), XMM0);
+ __ movups(XMM0, LocationToStackSlotAddress(source));
+ __ movups(LocationToStackSlotAddress(destination), XMM0);
}
} else {
ASSERT(source.IsConstant());
@@ -1237,11 +1237,12 @@
if (source.IsRegister() && destination.IsRegister()) {
__ xchgl(destination.reg(), source.reg());
} else if (source.IsRegister() && destination.IsStackSlot()) {
- Exchange(source.reg(), destination.ToStackSlotAddress());
+ Exchange(source.reg(), LocationToStackSlotAddress(destination));
} else if (source.IsStackSlot() && destination.IsRegister()) {
- Exchange(destination.reg(), source.ToStackSlotAddress());
+ Exchange(destination.reg(), LocationToStackSlotAddress(source));
} else if (source.IsStackSlot() && destination.IsStackSlot()) {
- Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
+ Exchange(LocationToStackSlotAddress(destination),
+ LocationToStackSlotAddress(source));
} else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
__ movaps(XMM0, source.fpu_reg());
__ movaps(source.fpu_reg(), destination.fpu_reg());
@@ -1254,8 +1255,8 @@
XmmRegister reg =
source.IsFpuRegister() ? source.fpu_reg() : destination.fpu_reg();
const Address& slot_address = source.IsFpuRegister()
- ? destination.ToStackSlotAddress()
- : source.ToStackSlotAddress();
+ ? LocationToStackSlotAddress(destination)
+ : LocationToStackSlotAddress(source);
if (double_width) {
__ movsd(XMM0, slot_address);
@@ -1266,8 +1267,9 @@
}
__ movaps(reg, XMM0);
} else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
- const Address& source_slot_address = source.ToStackSlotAddress();
- const Address& destination_slot_address = destination.ToStackSlotAddress();
+ const Address& source_slot_address = LocationToStackSlotAddress(source);
+ const Address& destination_slot_address =
+ LocationToStackSlotAddress(destination);
ScratchFpuRegisterScope ensure_scratch(this, XMM0);
__ movsd(XMM0, source_slot_address);
@@ -1275,8 +1277,9 @@
__ movsd(destination_slot_address, XMM0);
__ movsd(source_slot_address, ensure_scratch.reg());
} else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
- const Address& source_slot_address = source.ToStackSlotAddress();
- const Address& destination_slot_address = destination.ToStackSlotAddress();
+ const Address& source_slot_address = LocationToStackSlotAddress(source);
+ const Address& destination_slot_address =
+ LocationToStackSlotAddress(destination);
ScratchFpuRegisterScope ensure_scratch(this, XMM0);
__ movups(XMM0, source_slot_address);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 1a1a007..192a903 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -648,11 +648,11 @@
Label done;
if (!test_cache.IsNull()) {
// Generate runtime call.
- __ PushObject(Object::null_object()); // Make room for the result.
- __ pushq(RAX); // Push the instance.
- __ PushObject(type); // Push the type.
- __ pushq(RDX); // Instantiator type arguments.
- __ pushq(RCX); // Function type arguments.
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ pushq(RAX); // Push the instance.
+ __ PushObject(type); // Push the type.
+ __ pushq(RDX); // Instantiator type arguments.
+ __ pushq(RCX); // Function type arguments.
__ LoadUniqueObject(RAX, test_cache);
__ pushq(RAX);
GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
@@ -787,7 +787,7 @@
__ PushObject(value.constant());
} else {
ASSERT(value.IsStackSlot());
- __ pushq(value.ToStackSlotAddress());
+ __ pushq(LocationToStackSlotAddress(value));
}
}
}
@@ -854,7 +854,7 @@
// needs to be updated to match.
void FlowGraphCompiler::EmitFrameEntry() {
if (flow_graph().IsCompiledForOsr()) {
- intptr_t extra_slots = StackSize() - flow_graph().num_stack_locals();
+ const intptr_t extra_slots = ExtraStackSlotsOnOsrEntry();
ASSERT(extra_slots >= 0);
__ EnterOsrFrame(extra_slots * kWordSize);
} else {
@@ -932,8 +932,11 @@
VisitBlocks();
__ int3();
- ASSERT(assembler()->constant_pool_allowed());
- GenerateDeferredCode();
+
+ if (!fully_intrinsified_) {
+ ASSERT(assembler()->constant_pool_allowed());
+ GenerateDeferredCode();
+ }
}
void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
@@ -1151,8 +1154,8 @@
}
// Do not use the code from the function, but let the code be patched so that
// we can record the outgoing edges to other code.
- GenerateStaticDartCall(deopt_id, token_pos,
- RawPcDescriptors::kOther, locs, function, entry_kind);
+ GenerateStaticDartCall(deopt_id, token_pos, RawPcDescriptors::kOther, locs,
+ function, entry_kind);
__ Drop(count_with_type_args, RCX);
}
@@ -1308,18 +1311,18 @@
ASSERT((destination.base_reg() != FPREG) ||
((-compiler::target::frame_layout.VariableIndexForFrameSlot(
destination.stack_index())) < compiler_->StackSize()));
- __ movq(destination.ToStackSlotAddress(), source.reg());
+ __ movq(LocationToStackSlotAddress(destination), source.reg());
}
} else if (source.IsStackSlot()) {
ASSERT((source.base_reg() != FPREG) ||
((-compiler::target::frame_layout.VariableIndexForFrameSlot(
source.stack_index())) < compiler_->StackSize()));
if (destination.IsRegister()) {
- __ movq(destination.reg(), source.ToStackSlotAddress());
+ __ movq(destination.reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsStackSlot());
- MoveMemoryToMemory(destination.ToStackSlotAddress(),
- source.ToStackSlotAddress());
+ MoveMemoryToMemory(LocationToStackSlotAddress(destination),
+ LocationToStackSlotAddress(source));
}
} else if (source.IsFpuRegister()) {
if (destination.IsFpuRegister()) {
@@ -1328,27 +1331,27 @@
__ movaps(destination.fpu_reg(), source.fpu_reg());
} else {
if (destination.IsDoubleStackSlot()) {
- __ movsd(destination.ToStackSlotAddress(), source.fpu_reg());
+ __ movsd(LocationToStackSlotAddress(destination), source.fpu_reg());
} else {
ASSERT(destination.IsQuadStackSlot());
- __ movups(destination.ToStackSlotAddress(), source.fpu_reg());
+ __ movups(LocationToStackSlotAddress(destination), source.fpu_reg());
}
}
} else if (source.IsDoubleStackSlot()) {
if (destination.IsFpuRegister()) {
- __ movsd(destination.fpu_reg(), source.ToStackSlotAddress());
+ __ movsd(destination.fpu_reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsDoubleStackSlot());
- __ movsd(XMM0, source.ToStackSlotAddress());
- __ movsd(destination.ToStackSlotAddress(), XMM0);
+ __ movsd(XMM0, LocationToStackSlotAddress(source));
+ __ movsd(LocationToStackSlotAddress(destination), XMM0);
}
} else if (source.IsQuadStackSlot()) {
if (destination.IsFpuRegister()) {
- __ movups(destination.fpu_reg(), source.ToStackSlotAddress());
+ __ movups(destination.fpu_reg(), LocationToStackSlotAddress(source));
} else {
ASSERT(destination.IsQuadStackSlot());
- __ movups(XMM0, source.ToStackSlotAddress());
- __ movups(destination.ToStackSlotAddress(), XMM0);
+ __ movups(XMM0, LocationToStackSlotAddress(source));
+ __ movups(LocationToStackSlotAddress(destination), XMM0);
}
} else {
ASSERT(source.IsConstant());
@@ -1372,11 +1375,12 @@
if (source.IsRegister() && destination.IsRegister()) {
__ xchgq(destination.reg(), source.reg());
} else if (source.IsRegister() && destination.IsStackSlot()) {
- Exchange(source.reg(), destination.ToStackSlotAddress());
+ Exchange(source.reg(), LocationToStackSlotAddress(destination));
} else if (source.IsStackSlot() && destination.IsRegister()) {
- Exchange(destination.reg(), source.ToStackSlotAddress());
+ Exchange(destination.reg(), LocationToStackSlotAddress(source));
} else if (source.IsStackSlot() && destination.IsStackSlot()) {
- Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
+ Exchange(LocationToStackSlotAddress(destination),
+ LocationToStackSlotAddress(source));
} else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
__ movaps(XMM0, source.fpu_reg());
__ movaps(source.fpu_reg(), destination.fpu_reg());
@@ -1389,8 +1393,8 @@
XmmRegister reg =
source.IsFpuRegister() ? source.fpu_reg() : destination.fpu_reg();
Address slot_address = source.IsFpuRegister()
- ? destination.ToStackSlotAddress()
- : source.ToStackSlotAddress();
+ ? LocationToStackSlotAddress(destination)
+ : LocationToStackSlotAddress(source);
if (double_width) {
__ movsd(XMM0, slot_address);
@@ -1401,8 +1405,9 @@
}
__ movaps(reg, XMM0);
} else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
- const Address& source_slot_address = source.ToStackSlotAddress();
- const Address& destination_slot_address = destination.ToStackSlotAddress();
+ const Address& source_slot_address = LocationToStackSlotAddress(source);
+ const Address& destination_slot_address =
+ LocationToStackSlotAddress(destination);
ScratchFpuRegisterScope ensure_scratch(this, XMM0);
__ movsd(XMM0, source_slot_address);
@@ -1410,8 +1415,9 @@
__ movsd(destination_slot_address, XMM0);
__ movsd(source_slot_address, ensure_scratch.reg());
} else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
- const Address& source_slot_address = source.ToStackSlotAddress();
- const Address& destination_slot_address = destination.ToStackSlotAddress();
+ const Address& source_slot_address = LocationToStackSlotAddress(source);
+ const Address& destination_slot_address =
+ LocationToStackSlotAddress(destination);
ScratchFpuRegisterScope ensure_scratch(this, XMM0);
__ movups(XMM0, source_slot_address);
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 6c2c344..92b725f 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -494,24 +494,33 @@
Definition* Definition::OriginalDefinition() {
Definition* defn = this;
- while (true) {
- if (auto redefinition = defn->AsRedefinition()) {
- defn = redefinition->value()->definition();
- } else if (auto assert_assignable = defn->AsAssertAssignable()) {
- defn = assert_assignable->value()->definition();
- } else if (auto check_array_bound = defn->AsCheckArrayBound()) {
- defn = check_array_bound->index()->definition();
- } else if (auto check_bound = defn->AsGenericCheckBound()) {
- defn = check_bound->index()->definition();
- } else if (auto check_null = defn->AsCheckNull()) {
- defn = check_null->value()->definition();
- } else {
- break;
- }
+ Value* unwrapped;
+ while ((unwrapped = defn->RedefinedValue()) != nullptr) {
+ defn = unwrapped->definition();
}
return defn;
}
+Value* Definition::RedefinedValue() const {
+ return nullptr;
+}
+
+Value* RedefinitionInstr::RedefinedValue() const {
+ return value();
+}
+
+Value* AssertAssignableInstr::RedefinedValue() const {
+ return value();
+}
+
+Value* CheckBoundBase::RedefinedValue() const {
+ return index();
+}
+
+Value* CheckNullInstr::RedefinedValue() const {
+ return value();
+}
+
Definition* Definition::OriginalDefinitionIgnoreBoxingAndConstraints() {
Definition* def = this;
while (true) {
@@ -1514,10 +1523,11 @@
// we can simply jump to the beginning of the block.
ASSERT(instr->previous() == this);
+ const intptr_t stack_depth = instr->AsCheckStackOverflow()->stack_depth();
auto normal_entry = graph_entry->normal_entry();
auto osr_entry = new OsrEntryInstr(graph_entry, normal_entry->block_id(),
normal_entry->try_index(),
- normal_entry->deopt_id());
+ normal_entry->deopt_id(), stack_depth);
auto goto_join = new GotoInstr(AsJoinEntry(),
CompilerState::Current().GetNextDeoptId());
@@ -2407,13 +2417,21 @@
} else if (rhs == 0) {
return right()->definition();
} else if (rhs == 2) {
+ const int64_t shift_1 = 1;
ConstantInstr* constant_1 =
- flow_graph->GetConstant(Smi::Handle(Smi::New(1)));
+ flow_graph->GetConstant(Smi::Handle(Smi::New(shift_1)));
BinaryIntegerOpInstr* shift = BinaryIntegerOpInstr::Make(
representation(), Token::kSHL, left()->CopyWithType(),
new Value(constant_1), GetDeoptId(), can_overflow(),
is_truncating(), range(), speculative_mode());
- if (shift != NULL) {
+ if (shift != nullptr) {
+ // Assign a range to the shift factor, just in case range
+ // analysis no longer runs after this rewriting.
+ if (auto shift_with_range = shift->AsShiftIntegerOp()) {
+ shift_with_range->set_shift_range(
+ new Range(RangeBoundary::FromConstant(shift_1),
+ RangeBoundary::FromConstant(shift_1)));
+ }
flow_graph->InsertBefore(this, shift, env(), FlowGraph::kValue);
return shift;
}
@@ -2542,8 +2560,7 @@
if (!HasUses() && !flow_graph->is_licm_allowed()) {
return NULL;
}
- if ((constrained_type() != NULL) &&
- Type()->IsEqualTo(value()->definition()->Type())) {
+ if ((constrained_type() != nullptr) && Type()->IsEqualTo(value()->Type())) {
return value()->definition();
}
return this;
@@ -3765,14 +3782,11 @@
compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
}
}
- // NOTE: Because in JIT X64/ARM mode the graph can have multiple
- // entrypoints, so we generate several times the same intrinsification &
- // frame setup. That's why we cannot rely on the constant pool being
- // `false` when we come in here.
+ // NOTE: Because in X64/ARM mode the graph can have multiple entrypoints, we
+ // generate several times the same intrinsification & frame setup. That's why
+ // we cannot rely on the constant pool being `false` when we come in here.
__ set_constant_pool_allowed(false);
- // TODO(#34162): Don't emit more code if 'TryIntrinsify' returns 'true'
- // (meaning the function was fully intrinsified).
- compiler->TryIntrinsify();
+ if (compiler->TryIntrinsify()) return;
compiler->EmitPrologue();
ASSERT(__ constant_pool_allowed());
#endif
@@ -3951,8 +3965,8 @@
registers_remapped_ = true;
for (intptr_t i = 0; i < InputCount(); i++) {
- locations_[i] = LocationAt(i).RemapForSlowPath(
- InputAt(i)->definition(), cpu_reg_slots, fpu_reg_slots);
+ locations_[i] = LocationRemapForSlowPath(
+ LocationAt(i), InputAt(i)->definition(), cpu_reg_slots, fpu_reg_slots);
}
}
@@ -4600,7 +4614,8 @@
return locs;
}
-#if !defined(TARGET_ARCH_DBC)
+#endif // !defined(TARGET_ARCH_DBC)
+
void CheckNullInstr::AddMetadataForRuntimeCall(CheckNullInstr* check_null,
FlowGraphCompiler* compiler) {
const String& function_name = check_null->function_name();
@@ -4609,7 +4624,8 @@
compiler->AddNullCheck(compiler->assembler()->CodeSize(),
check_null->token_pos(), name_index);
}
-#endif // !defined(TARGET_ARCH_DBC)
+
+#if !defined(TARGET_ARCH_DBC)
void UnboxInstr::EmitLoadFromBoxWithDeopt(FlowGraphCompiler* compiler) {
const intptr_t box_cid = BoxCid();
@@ -5199,8 +5215,19 @@
set_native_c_function(native_function);
}
-#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \
- defined(TARGET_ARCH_IA32)
+#if !defined(TARGET_ARCH_ARM)
+
+LocationSummary* BitCastInstr::MakeLocationSummary(Zone* zone, bool opt) const {
+ UNREACHABLE();
+}
+
+void BitCastInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ UNREACHABLE();
+}
+
+#endif // defined(TARGET_ARCH_ARM)
+
+#if !defined(TARGET_ARCH_DBC)
#define Z zone_
@@ -5219,7 +5246,8 @@
ASSERT(((1 << CallingConventions::kFirstCalleeSavedCpuReg) &
CallingConventions::kArgumentRegisters) == 0);
-#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_IA32)
+#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_IA32) || \
+ defined(TARGET_ARCH_ARM)
constexpr intptr_t kNumTemps = 2;
#else
constexpr intptr_t kNumTemps = 1;
@@ -5234,7 +5262,8 @@
CallingConventions::kFirstNonArgumentRegister));
summary->set_temp(0, Location::RegisterLocation(
CallingConventions::kSecondNonArgumentRegister));
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM64)
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM64) || \
+ defined(TARGET_ARCH_ARM)
summary->set_temp(1, Location::RegisterLocation(
CallingConventions::kFirstCalleeSavedCpuReg));
#endif
@@ -5246,8 +5275,15 @@
// register or a contiguous 64-bit slot on the stack. Unboxed 64-bit integer
// values, in contrast, can be split between any two registers on a 32-bit
// system.
+ //
+ // There is an exception for iOS and Android 32-bit ARM, where
+ // floating-point values are treated as integers as far as the calling
+ // convention is concerned. However, the representation of these arguments
+ // are set to kUnboxedInt32 or kUnboxedInt64 already, so we don't have to
+ // account for that here.
const bool is_atomic = arg_representations_[i] == kUnboxedFloat ||
arg_representations_[i] == kUnboxedDouble;
+
// Since we have to move this input down to the stack, there's no point in
// pinning it to any specific register.
summary->set_in(i, UnallocateStackSlots(arg_locations_[i], is_atomic));
@@ -5293,7 +5329,7 @@
UNREACHABLE();
}
-#endif
+#endif // !defined(TARGET_ARCH_DBC)
// SIMD
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 3440130..3ce025c 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -453,6 +453,7 @@
M(BoxInt32, _) \
M(UnboxInt32, kNoGC) \
M(IntConverter, _) \
+ M(BitCast, _) \
M(UnboxedWidthExtender, _) \
M(Deoptimize, kNoGC) \
M(SimdOp, kNoGC)
@@ -1621,8 +1622,10 @@
OsrEntryInstr(GraphEntryInstr* graph_entry,
intptr_t block_id,
intptr_t try_index,
- intptr_t deopt_id)
+ intptr_t deopt_id,
+ intptr_t stack_depth)
: BlockEntryWithInitialDefs(block_id, try_index, deopt_id),
+ stack_depth_(stack_depth),
graph_entry_(graph_entry) {}
DECLARE_INSTRUCTION(OsrEntry)
@@ -1635,6 +1638,7 @@
return graph_entry_;
}
+ intptr_t stack_depth() const { return stack_depth_; }
GraphEntryInstr* graph_entry() const { return graph_entry_; }
PRINT_TO_SUPPORT
@@ -1646,6 +1650,7 @@
graph_entry_ = predecessor->AsGraphEntry();
}
+ const intptr_t stack_depth_;
GraphEntryInstr* graph_entry_;
DISALLOW_COPY_AND_ASSIGN(OsrEntryInstr);
@@ -1959,6 +1964,12 @@
// redefinition and check instructions.
Definition* OriginalDefinition();
+ // If this definition is a redefinition (in a broad sense, this includes
+ // CheckArrayBound and CheckNull instructions) return [Value] corresponding
+ // to the input which is being redefined.
+ // Otherwise return [nullptr].
+ virtual Value* RedefinedValue() const;
+
// Find the original definition of [this].
//
// This is an extension of [OriginalDefinition] which also follows through any
@@ -2801,6 +2812,8 @@
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool HasUnknownSideEffects() const { return false; }
+ virtual Value* RedefinedValue() const;
+
PRINT_OPERANDS_TO_SUPPORT
private:
@@ -3026,6 +3039,8 @@
virtual bool AttributesEqual(Instruction* other) const;
+ virtual Value* RedefinedValue() const;
+
PRINT_OPERANDS_TO_SUPPORT
private:
@@ -5120,7 +5135,11 @@
if (!length.IsSmi()) return false;
const intptr_t value = Smi::Cast(length).Value();
if (value < 0) return false;
- return !Array::UseCardMarkingForAllocation(value);
+ return WillAllocateNewOrRemembered(value);
+ }
+
+ static bool WillAllocateNewOrRemembered(const intptr_t length) {
+ return !Array::UseCardMarkingForAllocation(length);
}
private:
@@ -6606,6 +6625,9 @@
Range* shift_range() const { return shift_range_; }
+ // Set the range directly (takes ownership).
+ void set_shift_range(Range* shift_range) { shift_range_ = shift_range; }
+
virtual void InferRange(RangeAnalysis* analysis, Range* range);
DEFINE_INSTRUCTION_TYPE_CHECK(ShiftIntegerOp)
@@ -6806,11 +6828,13 @@
};
CheckStackOverflowInstr(TokenPosition token_pos,
+ intptr_t stack_depth,
intptr_t loop_depth,
intptr_t deopt_id,
- Kind kind = kOsrAndPreemption)
+ Kind kind)
: TemplateInstruction(deopt_id),
token_pos_(token_pos),
+ stack_depth_(stack_depth),
loop_depth_(loop_depth),
kind_(kind) {
ASSERT(kind != kOsrOnly || loop_depth > 0);
@@ -6818,6 +6842,7 @@
virtual TokenPosition token_pos() const { return token_pos_; }
bool in_loop() const { return loop_depth_ > 0; }
+ intptr_t stack_depth() const { return stack_depth_; }
intptr_t loop_depth() const { return loop_depth_; }
DECLARE_INSTRUCTION(CheckStackOverflow)
@@ -6836,6 +6861,7 @@
private:
const TokenPosition token_pos_;
+ const intptr_t stack_depth_;
const intptr_t loop_depth_;
const Kind kind_;
@@ -7381,6 +7407,8 @@
static void AddMetadataForRuntimeCall(CheckNullInstr* check_null,
FlowGraphCompiler* compiler);
+ virtual Value* RedefinedValue() const;
+
private:
const TokenPosition token_pos_;
const String& function_name_;
@@ -7434,6 +7462,7 @@
virtual bool IsCheckBoundBase() { return true; }
virtual CheckBoundBase* AsCheckBoundBase() { return this; }
+ virtual Value* RedefinedValue() const;
// Give a name to the location/input indices.
enum { kLengthPos = 0, kIndexPos = 1 };
@@ -7621,6 +7650,56 @@
DISALLOW_COPY_AND_ASSIGN(IntConverterInstr);
};
+// Moves a floating-point value between CPU and FPU registers. Used to implement
+// "softfp" calling conventions, where FPU arguments/return values are passed in
+// normal CPU registers.
+class BitCastInstr : public TemplateDefinition<1, NoThrow, Pure> {
+ public:
+ BitCastInstr(Representation from, Representation to, Value* value)
+ : TemplateDefinition(DeoptId::kNone),
+ from_representation_(from),
+ to_representation_(to) {
+ ASSERT(from != to);
+ ASSERT(to == kUnboxedInt32 && from == kUnboxedFloat ||
+ to == kUnboxedFloat && from == kUnboxedInt32 ||
+ to == kUnboxedInt64 && from == kUnboxedDouble ||
+ to == kUnboxedDouble && from == kUnboxedInt64);
+ SetInputAt(0, value);
+ }
+
+ Value* value() const { return inputs_[0]; }
+
+ Representation from() const { return from_representation_; }
+ Representation to() const { return to_representation_; }
+
+ virtual bool ComputeCanDeoptimize() const { return false; }
+
+ virtual Representation representation() const { return to(); }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ ASSERT(idx == 0);
+ return from();
+ }
+
+ virtual bool AttributesEqual(Instruction* other) const {
+ ASSERT(other->IsBitCast());
+ BitCastInstr* converter = other->AsBitCast();
+ return converter->from() == from() && converter->to() == to();
+ }
+
+ virtual CompileType ComputeType() const { return CompileType::Dynamic(); }
+
+ DECLARE_INSTRUCTION(BitCast);
+
+ PRINT_OPERANDS_TO_SUPPORT
+
+ private:
+ const Representation from_representation_;
+ const Representation to_representation_;
+
+ DISALLOW_COPY_AND_ASSIGN(BitCastInstr);
+};
+
// Sign- or zero-extends an integer in unboxed 32-bit representation.
//
// The choice between sign- and zero- extension is made based on the whether the
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index dd332867..d7dc61d 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -79,7 +79,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::AnyOrConstant(value()));
+ locs->set_in(0, LocationAnyOrConstant(value()));
return locs;
}
@@ -558,12 +558,12 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -794,7 +794,7 @@
locs->set_in(0, Location::RequiresRegister());
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
- locs->set_in(1, Location::RegisterOrConstant(right()));
+ locs->set_in(1, LocationRegisterOrConstant(right()));
return locs;
}
@@ -894,12 +894,12 @@
ASSERT(operation_cid() == kSmiCid);
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RegisterOrConstant(left()));
+ summary->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
summary->set_in(1, summary->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -983,7 +983,97 @@
}
void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNREACHABLE();
+ const Register saved_fp = locs()->temp(0).reg();
+ const Register branch = locs()->in(TargetAddressIndex()).reg();
+
+ // Save frame pointer because we're going to update it when we enter the exit
+ // frame.
+ __ mov(saved_fp, Operand(FPREG));
+
+ // Make a space to put the return address.
+ __ PushImmediate(0);
+
+ // We need to create a dummy "exit frame". It will have a null code object.
+ __ LoadObject(CODE_REG, Object::null_object());
+ __ set_constant_pool_allowed(false);
+ __ EnterDartFrame(0, /*load_pool_pointer=*/false);
+
+ // Reserve space for arguments and align frame before entering C++ world.
+ __ ReserveAlignedFrameSpace(compiler::ffi::NumStackSlots(arg_locations_) *
+ kWordSize);
+
+ // Load a 32-bit argument, or a 32-bit component of a 64-bit argument.
+ auto load_single_slot = [&](Location from, Location to) {
+ if (!to.IsStackSlot()) return;
+ if (from.IsRegister()) {
+ __ str(from.reg(), LocationToStackSlotAddress(to));
+ } else if (from.IsFpuRegister()) {
+ __ vstrs(EvenSRegisterOf(EvenDRegisterOf(from.fpu_reg())),
+ LocationToStackSlotAddress(to));
+ } else if (from.IsStackSlot() || from.IsDoubleStackSlot()) {
+ ASSERT(from.base_reg() == FPREG);
+ __ ldr(TMP, Address(saved_fp, from.ToStackSlotOffset()));
+ __ str(TMP, LocationToStackSlotAddress(to));
+ } else {
+ UNREACHABLE();
+ }
+ };
+
+ for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
+ Location origin = locs()->in(i);
+ Location target = arg_locations_[i];
+
+ if (target.IsStackSlot()) {
+ load_single_slot(origin, target);
+ } else if (target.IsDoubleStackSlot()) {
+ if (origin.IsFpuRegister()) {
+ __ vstrd(EvenDRegisterOf(origin.fpu_reg()),
+ LocationToStackSlotAddress(target));
+ } else {
+ ASSERT(origin.IsDoubleStackSlot() && origin.base_reg() == FPREG);
+ __ vldrd(DTMP, Address(saved_fp, origin.ToStackSlotOffset()));
+ __ vstrd(DTMP, LocationToStackSlotAddress(target));
+ }
+ } else if (target.IsPairLocation()) {
+ ASSERT(origin.IsPairLocation());
+ load_single_slot(origin.AsPairLocation()->At(0),
+ target.AsPairLocation()->At(0));
+ load_single_slot(origin.AsPairLocation()->At(1),
+ target.AsPairLocation()->At(1));
+ }
+ }
+
+ // We need to copy the return address up into the dummy stack frame so the
+ // stack walker will know which safepoint to use.
+ __ mov(TMP, Operand(PC));
+ __ str(TMP, Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize));
+
+ // For historical reasons, the PC on ARM points 8 bytes past the current
+ // instruction. Therefore we emit the metadata here, 8 bytes (2 instructions)
+ // after the original mov.
+ compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
+ RawPcDescriptors::Kind::kOther, locs());
+
+ // Update information in the thread object and enter a safepoint.
+ __ TransitionGeneratedToNative(branch, saved_fp, locs()->temp(1).reg());
+
+ __ blx(branch);
+
+ // Update information in the thread object and leave the safepoint.
+ __ TransitionNativeToGenerated(saved_fp, locs()->temp(1).reg());
+
+ // Restore the global object pool after returning from runtime (old space is
+ // moving, so the GOP could have been relocated).
+ if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+ __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
+ }
+
+ // Leave dummy exit frame.
+ __ LeaveDartFrame();
+ __ set_constant_pool_allowed(true);
+
+ // Instead of returning to the "fake" return address, we just pop it.
+ __ PopRegister(TMP);
}
LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
@@ -1521,7 +1611,7 @@
case kArrayCid:
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
if (ShouldEmitStoreBarrier()) {
locs->set_in(0, Location::RegisterLocation(kWriteBarrierObjectReg));
locs->set_temp(0, Location::RegisterLocation(kWriteBarrierSlotReg));
@@ -2210,7 +2300,7 @@
} else {
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
}
return summary;
}
@@ -3524,7 +3614,7 @@
return summary;
}
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
if (((op_kind() == Token::kSHL) && can_overflow()) ||
(op_kind() == Token::kSHR)) {
summary->set_temp(0, Location::RequiresRegister());
@@ -3836,7 +3926,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, num_temps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
if (((op_kind() == Token::kSHL) && can_overflow()) ||
(op_kind() == Token::kSHR)) {
summary->set_temp(0, Location::RequiresRegister());
@@ -5867,8 +5957,8 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
- locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
+ locs->set_in(kLengthPos, LocationRegisterOrSmiConstant(length()));
+ locs->set_in(kIndexPos, LocationRegisterOrSmiConstant(index()));
return locs;
}
@@ -6234,7 +6324,7 @@
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::Pair(Location::RequiresRegister(),
Location::RequiresRegister()));
- summary->set_in(1, Location::WritableRegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationWritableRegisterOrSmiConstant(right()));
summary->set_out(0, Location::Pair(Location::RequiresRegister(),
Location::RequiresRegister()));
return summary;
@@ -6369,7 +6459,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
summary->set_temp(0, Location::RequiresRegister());
summary->set_out(0, Location::RequiresRegister());
return summary;
@@ -6647,6 +6737,83 @@
}
}
+LocationSummary* BitCastInstr::MakeLocationSummary(Zone* zone, bool opt) const {
+ LocationSummary* summary =
+ new (zone) LocationSummary(zone, /*num_inputs=*/InputCount(),
+ /*num_temps=*/0, LocationSummary::kNoCall);
+ switch (from()) {
+ case kUnboxedInt32:
+ summary->set_in(0, Location::RequiresRegister());
+ break;
+ case kUnboxedInt64:
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(),
+ Location::RequiresRegister()));
+ break;
+ case kUnboxedFloat:
+ case kUnboxedDouble:
+ summary->set_in(0, Location::RequiresFpuRegister());
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (to()) {
+ case kUnboxedInt32:
+ summary->set_out(0, Location::RequiresRegister());
+ break;
+ case kUnboxedInt64:
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(),
+ Location::RequiresRegister()));
+ break;
+ case kUnboxedFloat:
+ case kUnboxedDouble:
+ summary->set_out(0, Location::RequiresFpuRegister());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return summary;
+}
+
+void BitCastInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ switch (from()) {
+ case kUnboxedInt32: {
+ ASSERT(to() == kUnboxedFloat);
+ const Register from_reg = locs()->in(0).reg();
+ const FpuRegister to_reg = locs()->out(0).fpu_reg();
+ __ vmovsr(EvenSRegisterOf(EvenDRegisterOf(to_reg)), from_reg);
+ break;
+ }
+ case kUnboxedFloat: {
+ ASSERT(to() == kUnboxedInt32);
+ const FpuRegister from_reg = locs()->in(0).fpu_reg();
+ const Register to_reg = locs()->out(0).reg();
+ __ vmovrs(to_reg, EvenSRegisterOf(EvenDRegisterOf(from_reg)));
+ break;
+ }
+ case kUnboxedInt64: {
+ ASSERT(to() == kUnboxedDouble);
+ const Register from_lo = locs()->in(0).AsPairLocation()->At(0).reg();
+ const Register from_hi = locs()->in(0).AsPairLocation()->At(1).reg();
+ const FpuRegister to_reg = locs()->out(0).fpu_reg();
+ __ vmovsr(EvenSRegisterOf(EvenDRegisterOf(to_reg)), from_lo);
+ __ vmovsr(OddSRegisterOf(EvenDRegisterOf(to_reg)), from_hi);
+ break;
+ }
+ case kUnboxedDouble: {
+ ASSERT(to() == kUnboxedInt64);
+ const FpuRegister from_reg = locs()->in(0).fpu_reg();
+ const Register to_lo = locs()->out(0).AsPairLocation()->At(0).reg();
+ const Register to_hi = locs()->out(0).AsPairLocation()->At(1).reg();
+ __ vmovrs(to_lo, EvenSRegisterOf(EvenDRegisterOf(from_reg)));
+ __ vmovrs(to_hi, OddSRegisterOf(EvenDRegisterOf(from_reg)));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+}
+
LocationSummary* ThrowInstr::MakeLocationSummary(Zone* zone, bool opt) const {
return new (zone) LocationSummary(zone, 0, 0, LocationSummary::kCall);
}
@@ -6763,7 +6930,7 @@
if ((constant != NULL) && !left()->IsSingleUse()) {
locs->set_in(0, Location::RequiresRegister());
} else {
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
}
constant = right()->definition()->AsConstant();
@@ -6774,7 +6941,7 @@
// one is a constant.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
}
locs->set_out(0, Location::RequiresRegister());
return locs;
@@ -6875,10 +7042,14 @@
}
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#ifdef PRODUCT
+ UNREACHABLE();
+#else
ASSERT(!compiler->is_optimizing());
__ BranchLinkPatchable(StubCode::DebugStepCheck());
compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
compiler->RecordSafepoint(locs());
+#endif
}
} // namespace dart
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 67e080b..5ba37ca 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -79,7 +79,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::AnyOrConstant(value()));
+ locs->set_in(0, LocationAnyOrConstant(value()));
return locs;
}
@@ -627,13 +627,13 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
// Only right can be a stack slot.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -695,7 +695,7 @@
locs->set_in(0, Location::RequiresRegister());
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
- locs->set_in(1, Location::RegisterOrConstant(right()));
+ locs->set_in(1, LocationRegisterOrConstant(right()));
return locs;
}
@@ -783,12 +783,12 @@
if (operation_cid() == kSmiCid || operation_cid() == kMintCid) {
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RegisterOrConstant(left()));
+ summary->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
summary->set_in(1, summary->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -887,10 +887,8 @@
__ set_constant_pool_allowed(false);
__ EnterDartFrame(0, PP);
- // Save exit frame information to enable stack walking as we are about
- // to transition to Dart VM C++ code.
- __ StoreToOffset(FPREG, THR,
- compiler::target::Thread::top_exit_frame_info_offset());
+ // Save the stack limit address.
+ __ PushRegister(CSP);
// Make space for arguments and align the frame.
__ ReserveAlignedFrameSpace(compiler::ffi::NumStackSlots(arg_locations_) *
@@ -916,43 +914,29 @@
}
}
- // Mark that the thread is executing VM code.
- __ StoreToOffset(branch, THR, compiler::target::Thread::vm_tag_offset());
-
- // We need to copy the return address up into the dummy stack frame so the
+ // We need to copy a dummy return address up into the dummy stack frame so the
// stack walker will know which safepoint to use.
- const intptr_t call_sequence_start = __ CodeSize();
-
- // 5 instructions, 4 bytes each.
- constexpr intptr_t kCallSequenceLength = 5 * 4;
-
- __ adr(temp, Immediate(kCallSequenceLength));
- __ StoreToOffset(temp, FPREG, kSavedCallerPcSlotFromFp * kWordSize);
-
- // We are entering runtime code, so the C stack pointer must be restored from
- // the stack limit to the top of the stack. We cache the stack limit address
- // in a callee-saved register.
- __ mov(temp, CSP);
- __ mov(CSP, SP);
-
- __ blr(branch);
-
- ASSERT(__ CodeSize() - call_sequence_start == kCallSequenceLength);
-
- // Restore the Dart stack pointer and the saved C stack pointer.
- __ mov(SP, CSP);
- __ mov(CSP, temp);
-
+ __ adr(temp, Immediate(0));
compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
RawPcDescriptors::Kind::kOther, locs());
- // Mark that the thread is executing Dart code.
- __ LoadImmediate(temp, VMTag::kDartCompiledTagId);
- __ StoreToOffset(temp, THR, compiler::target::Thread::vm_tag_offset());
+ __ StoreToOffset(temp, FPREG, kSavedCallerPcSlotFromFp * kWordSize);
- // Reset exit frame information in Isolate structure.
- __ StoreToOffset(ZR, THR,
- compiler::target::Thread::top_exit_frame_info_offset());
+ // We are entering runtime code, so the C stack pointer must be restored from
+ // the stack limit to the top of the stack.
+ __ mov(CSP, SP);
+
+ // Update information in the thread object and enter a safepoint.
+ __ TransitionGeneratedToNative(branch, temp);
+
+ __ blr(branch);
+
+ // Update information in the thread object and leave the safepoint.
+ __ TransitionNativeToGenerated(temp);
+
+ // Restore the Dart stack pointer and the saved C stack pointer.
+ __ mov(SP, CSP);
+ __ LoadFromOffset(CSP, FPREG, kFirstLocalSlotFromFp * kWordSize);
// Refresh write barrier mask.
__ ldr(BARRIER_MASK,
@@ -1465,7 +1449,7 @@
case kArrayCid:
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
if (ShouldEmitStoreBarrier()) {
locs->set_in(0, Location::RegisterLocation(kWriteBarrierObjectReg));
locs->set_temp(0, Location::RegisterLocation(kWriteBarrierSlotReg));
@@ -2015,7 +1999,7 @@
} else {
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
}
return summary;
}
@@ -3301,7 +3285,7 @@
return summary;
}
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
if (((op_kind() == Token::kSHL) && can_overflow()) ||
(op_kind() == Token::kSHR)) {
summary->set_temp(0, Location::RequiresRegister());
@@ -5135,8 +5119,8 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
- locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
+ locs->set_in(kLengthPos, LocationRegisterOrSmiConstant(length()));
+ locs->set_in(kIndexPos, LocationRegisterOrSmiConstant(index()));
return locs;
}
@@ -5337,7 +5321,7 @@
LocationSummary* summary = new (zone) LocationSummary(
zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrConstant(right()));
+ summary->set_in(1, LocationRegisterOrConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -5553,7 +5537,7 @@
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, RangeUtils::IsPositive(shift_range())
- ? Location::RegisterOrConstant(right())
+ ? LocationRegisterOrConstant(right())
: Location::RequiresRegister());
summary->set_out(0, Location::RequiresRegister());
return summary;
@@ -5597,7 +5581,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -5664,7 +5648,7 @@
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, RangeUtils::IsPositive(shift_range())
- ? Location::RegisterOrConstant(right())
+ ? LocationRegisterOrConstant(right())
: Location::RequiresRegister());
summary->set_out(0, Location::RequiresRegister());
return summary;
@@ -5710,7 +5694,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -6102,12 +6086,12 @@
}
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one of the inputs can be a constant. Choose register if the first one
// is a constant.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -6201,10 +6185,14 @@
}
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#ifdef PRODUCT
+ UNREACHABLE();
+#else
ASSERT(!compiler->is_optimizing());
__ BranchLinkPatchable(StubCode::DebugStepCheck());
compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
compiler->RecordSafepoint(locs());
+#endif
}
} // namespace dart
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 421954b..e75bfef 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -58,7 +58,6 @@
#define FOR_EACH_UNREACHABLE_INSTRUCTION(M) \
M(CaseInsensitiveCompareUC16) \
M(GenericCheckBound) \
- M(CheckNull) \
M(IndirectGoto) \
M(Int64ToDouble) \
M(BinaryInt64Op) \
@@ -1318,8 +1317,12 @@
}
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#ifdef PRODUCT
+ UNREACHABLE();
+#else
__ DebugStep();
compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
+#endif
}
void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1575,6 +1578,17 @@
licm_hoisted_ ? ICData::kHoisted : 0);
}
+EMIT_NATIVE_CODE(CheckNull, 1) {
+ if (compiler->is_optimizing()) {
+ const Register value = locs()->in(0).reg();
+ __ IfEqNull(value);
+ } else {
+ __ IfEqNullTOS();
+ }
+ __ NullError();
+ CheckNullInstr::AddMetadataForRuntimeCall(this, compiler);
+}
+
EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) {
if (compiler->is_optimizing()) {
const Register left = locs()->in(0).reg();
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 19983a1..88ce5ba 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -73,7 +73,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::AnyOrConstant(value()));
+ locs->set_in(0, LocationAnyOrConstant(value()));
return locs;
}
@@ -88,7 +88,7 @@
__ PushObject(value.constant());
} else {
ASSERT(value.IsStackSlot());
- __ pushl(value.ToStackSlotAddress());
+ __ pushl(LocationToStackSlotAddress(value));
}
}
}
@@ -140,7 +140,7 @@
const intptr_t stack_index =
compiler::target::frame_layout.FrameSlotForVariable(&local());
return LocationSummary::Make(zone, kNumInputs,
- Location::StackSlot(stack_index),
+ Location::StackSlot(stack_index, FPREG),
LocationSummary::kNoCall);
}
@@ -224,20 +224,20 @@
} else {
__ movsd(XMM0, Address::Absolute(addr));
}
- __ movsd(destination.ToStackSlotAddress(), XMM0);
+ __ movsd(LocationToStackSlotAddress(destination), XMM0);
} else {
ASSERT(destination.IsStackSlot());
if (value_.IsSmi() && representation() == kUnboxedInt32) {
- __ movl(destination.ToStackSlotAddress(),
+ __ movl(LocationToStackSlotAddress(destination),
Immediate(Smi::Cast(value_).Value()));
} else {
if (Assembler::IsSafeSmi(value_) || value_.IsNull()) {
- __ movl(destination.ToStackSlotAddress(),
+ __ movl(LocationToStackSlotAddress(destination),
Immediate(reinterpret_cast<int32_t>(value_.raw())));
} else {
__ pushl(EAX);
__ LoadObjectSafely(EAX, value_);
- __ movl(destination.ToStackSlotAddress(), EAX);
+ __ movl(LocationToStackSlotAddress(destination), EAX);
__ popl(EAX);
}
}
@@ -381,13 +381,13 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
// Only right can be a stack slot.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -507,7 +507,7 @@
} else if (right.IsConstant()) {
__ CompareObject(left.reg(), right.constant());
} else if (right.IsStackSlot()) {
- __ cmpl(left.reg(), right.ToStackSlotAddress());
+ __ cmpl(left.reg(), LocationToStackSlotAddress(right));
} else {
__ cmpl(left.reg(), right.reg());
}
@@ -682,7 +682,7 @@
locs->set_in(0, Location::RequiresRegister());
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
- locs->set_in(1, Location::RegisterOrConstant(right()));
+ locs->set_in(1, LocationRegisterOrConstant(right()));
return locs;
}
@@ -781,12 +781,12 @@
ASSERT(operation_cid() == kSmiCid);
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RegisterOrConstant(left()));
+ summary->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
summary->set_in(1, summary->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -846,9 +846,9 @@
}
void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- Register saved_fp = locs()->temp(0).reg();
+ Register saved_fp = locs()->temp(0).reg(); // volatile
Register branch = locs()->in(TargetAddressIndex()).reg();
- Register tmp = locs()->temp(1).reg();
+ Register tmp = locs()->temp(1).reg(); // callee-saved
// Save frame pointer because we're going to update it when we enter the exit
// frame.
@@ -861,10 +861,6 @@
__ LoadObject(CODE_REG, Object::null_object());
__ EnterDartFrame(compiler::ffi::NumStackSlots(arg_locations_) * kWordSize);
- // Save exit frame information to enable stack walking as we are about
- // to transition to Dart VM C++ code.
- __ movl(Address(THR, Thread::top_exit_frame_info_offset()), FPREG);
-
// Align frame before entering C++ world.
if (OS::ActivationFrameAlignment() > 1) {
__ andl(SPREG, Immediate(~(OS::ActivationFrameAlignment() - 1)));
@@ -874,13 +870,13 @@
auto load_single_slot = [&](Location from, Location to) {
ASSERT(to.IsStackSlot());
if (from.IsRegister()) {
- __ movl(to.ToStackSlotAddress(), from.reg());
+ __ movl(LocationToStackSlotAddress(to), from.reg());
} else if (from.IsFpuRegister()) {
- __ movss(to.ToStackSlotAddress(), from.fpu_reg());
+ __ movss(LocationToStackSlotAddress(to), from.fpu_reg());
} else if (from.IsStackSlot() || from.IsDoubleStackSlot()) {
ASSERT(from.base_reg() == FPREG);
__ movl(tmp, Address(saved_fp, from.ToStackSlotOffset()));
- __ movl(to.ToStackSlotAddress(), tmp);
+ __ movl(LocationToStackSlotAddress(to), tmp);
} else {
UNREACHABLE();
}
@@ -894,11 +890,11 @@
load_single_slot(origin, target);
} else if (target.IsDoubleStackSlot()) {
if (origin.IsFpuRegister()) {
- __ movsd(target.ToStackSlotAddress(), origin.fpu_reg());
+ __ movsd(LocationToStackSlotAddress(target), origin.fpu_reg());
} else {
ASSERT(origin.IsDoubleStackSlot() && origin.base_reg() == FPREG);
__ movl(tmp, Address(saved_fp, origin.ToStackSlotOffset()));
- __ movl(target.ToStackSlotAddress(), tmp);
+ __ movl(LocationToStackSlotAddress(target), tmp);
__ movl(tmp, Address(saved_fp, origin.ToStackSlotOffset() + 4));
__ movl(Address(SPREG, target.ToStackSlotOffset() + 4), tmp);
}
@@ -911,33 +907,34 @@
}
}
- // Mark that the thread is executing VM code.
- __ movl(Assembler::VMTagAddress(), branch);
-
- // We need to copy the return address up into the dummy stack frame so the
+ // We need to copy a dummy return address up into the dummy stack frame so the
// stack walker will know which safepoint to use. Unlike X64, there's no
// PC-relative 'leaq' available, so we have do a trick with 'call'.
- constexpr intptr_t kCallSequenceLength = 6;
-
Label get_pc;
__ call(&get_pc);
- __ Bind(&get_pc);
-
- const intptr_t call_sequence_start = __ CodeSize();
-
- __ popl(tmp);
- __ movl(Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), tmp);
- __ call(branch);
-
- ASSERT(__ CodeSize() - call_sequence_start == kCallSequenceLength);
-
compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
RawPcDescriptors::Kind::kOther, locs());
+ __ Bind(&get_pc);
+ __ popl(tmp);
+ __ movl(Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), tmp);
+
+ __ TransitionGeneratedToNative(branch, tmp);
+ __ call(branch);
// The x86 calling convention requires floating point values to be returned on
// the "floating-point stack" (aka. register ST0). We don't use the
// floating-point stack in Dart, so we need to move the return value back into
// an XMM register.
+ if (representation() == kUnboxedDouble || representation() == kUnboxedFloat) {
+ __ subl(SPREG, Immediate(8));
+ __ fstpl(Address(SPREG, 0));
+ __ TransitionNativeToGenerated(tmp);
+ __ fldl(Address(SPREG, 0));
+ __ addl(SPREG, Immediate(8));
+ } else {
+ __ TransitionNativeToGenerated(tmp);
+ }
+
if (representation() == kUnboxedDouble) {
__ subl(SPREG, Immediate(8));
__ fstpl(Address(SPREG, 0));
@@ -948,12 +945,6 @@
__ movss(XMM0, Address(SPREG, 0));
}
- // Mark that the thread is executing Dart code.
- __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
- // Reset exit frame information in Isolate structure.
- __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
// Leave dummy exit frame.
__ LeaveFrame();
@@ -1392,7 +1383,7 @@
case kArrayCid:
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::WritableRegister()
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
if (ShouldEmitStoreBarrier()) {
locs->set_in(0, Location::RegisterLocation(kWriteBarrierObjectReg));
locs->set_temp(0, Location::RegisterLocation(kWriteBarrierSlotReg));
@@ -1406,7 +1397,7 @@
case kOneByteStringCid:
// TODO(fschneider): Add location constraint for byte registers (EAX,
// EBX, ECX, EDX) instead of using a fixed register.
- locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
+ locs->set_in(2, LocationFixedRegisterOrSmiConstant(value(), EAX));
break;
case kTypedDataInt16ArrayCid:
case kTypedDataUint16ArrayCid:
@@ -1907,7 +1898,7 @@
} else {
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::WritableRegister()
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
}
return summary;
}
@@ -2962,7 +2953,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
@@ -2974,7 +2965,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
if (kNumTemps == 1) {
summary->set_temp(0, Location::RequiresRegister());
}
@@ -2987,7 +2978,7 @@
summary->set_in(0, Location::RequiresRegister());
ConstantInstr* constant = right()->definition()->AsConstant();
if (constant != NULL) {
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
} else {
summary->set_in(1, Location::PrefersRegister());
}
@@ -3096,7 +3087,7 @@
} // if locs()->in(1).IsConstant()
if (locs()->in(1).IsStackSlot()) {
- const Address& right = locs()->in(1).ToStackSlotAddress();
+ const Address& right = LocationToStackSlotAddress(locs()->in(1));
if (op_kind() == Token::kMUL) {
__ SmiUntag(left);
}
@@ -3243,7 +3234,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
@@ -3251,7 +3242,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
if (can_overflow()) {
summary->set_temp(0, Location::RequiresRegister());
}
@@ -3264,7 +3255,7 @@
summary->set_in(0, Location::RequiresRegister());
ConstantInstr* constant = right()->definition()->AsConstant();
if (constant != NULL) {
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
} else {
summary->set_in(1, Location::PrefersRegister());
}
@@ -3353,7 +3344,7 @@
} // if locs()->in(1).IsConstant()
if (locs()->in(1).IsStackSlot()) {
- const Address& right = locs()->in(1).ToStackSlotAddress();
+ const Address& right = LocationToStackSlotAddress(locs()->in(1));
EmitIntegerArithmetic(compiler, op_kind(), left, right, deopt);
return;
} // if locs()->in(1).IsStackSlot.
@@ -5301,11 +5292,11 @@
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
if (length()->definition()->IsConstant()) {
- locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
+ locs->set_in(kLengthPos, LocationRegisterOrSmiConstant(length()));
} else {
locs->set_in(kLengthPos, Location::PrefersRegister());
}
- locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
+ locs->set_in(kIndexPos, LocationRegisterOrSmiConstant(index()));
return locs;
}
@@ -5345,7 +5336,7 @@
} else if (index_loc.IsConstant()) {
const Smi& index = Smi::Cast(index_loc.constant());
if (length_loc.IsStackSlot()) {
- const Address& length = length_loc.ToStackSlotAddress();
+ const Address& length = LocationToStackSlotAddress(length_loc);
__ cmpl(length, Immediate(reinterpret_cast<int32_t>(index.raw())));
} else {
Register length = length_loc.reg();
@@ -5354,7 +5345,7 @@
__ j(BELOW_EQUAL, deopt);
} else if (length_loc.IsStackSlot()) {
Register index = index_loc.reg();
- const Address& length = length_loc.ToStackSlotAddress();
+ const Address& length = LocationToStackSlotAddress(length_loc);
if (index_cid != kSmiCid) {
__ BranchIfNotSmi(index, deopt);
}
@@ -5722,7 +5713,7 @@
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::Pair(Location::RequiresRegister(),
Location::RequiresRegister()));
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
}
@@ -5859,7 +5850,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), ECX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
}
@@ -6229,12 +6220,12 @@
}
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one of the inputs can be a constant. Choose register if the first one
// is a constant.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -6393,10 +6384,14 @@
}
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#ifdef PRODUCT
+ UNREACHABLE();
+#else
ASSERT(!compiler->is_optimizing());
__ Call(StubCode::DebugStepCheck());
compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
compiler->RecordSafepoint(locs());
+#endif
}
} // namespace dart
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 85d77dc..19b2aed 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -1006,6 +1006,12 @@
Definition::PrintOperandsTo(f);
}
+void BitCastInstr::PrintOperandsTo(BufferFormatter* f) const {
+ Definition::PrintOperandsTo(f);
+ f->Print(" (%s -> %s)", RepresentationToCString(from()),
+ RepresentationToCString(to()));
+}
+
void ParameterInstr::PrintOperandsTo(BufferFormatter* f) const {
f->Print("%" Pd, index());
}
@@ -1022,7 +1028,7 @@
}
void CheckStackOverflowInstr::PrintOperandsTo(BufferFormatter* f) const {
- if (in_loop()) f->Print("depth %" Pd, loop_depth());
+ f->Print("stack=%" Pd ", loop=%" Pd, stack_depth(), loop_depth());
}
void TargetEntryInstr::PrintTo(BufferFormatter* f) const {
@@ -1039,7 +1045,8 @@
}
void OsrEntryInstr::PrintTo(BufferFormatter* f) const {
- f->Print("B%" Pd "[osr entry]:%" Pd, block_id(), GetDeoptId());
+ f->Print("B%" Pd "[osr entry]:%" Pd " stack_depth=%" Pd, block_id(),
+ GetDeoptId(), stack_depth());
if (HasParallelMove()) {
f->Print("\n");
parallel_move()->PrintTo(f);
@@ -1068,13 +1075,13 @@
}
void LoadIndexedUnsafeInstr::PrintOperandsTo(BufferFormatter* f) const {
- f->Print("%s[", Assembler::RegisterName(base_reg()));
+ f->Print("%s[", RegisterNames::RegisterName(base_reg()));
index()->PrintTo(f);
f->Print(" + %" Pd "]", offset());
}
void StoreIndexedUnsafeInstr::PrintOperandsTo(BufferFormatter* f) const {
- f->Print("%s[", Assembler::RegisterName(base_reg()));
+ f->Print("%s[", RegisterNames::RegisterName(base_reg()));
index()->PrintTo(f);
f->Print(" + %" Pd "], ", offset());
value()->PrintTo(f);
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 84d7acf..dc6385d 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -5,14 +5,17 @@
#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
#define RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
+#include <utility>
#include <vector>
#include "include/dart_api.h"
#include "platform/allocation.h"
+#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/compiler/compiler_state.h"
+#include "vm/compiler/jit/compiler.h"
#include "vm/unit_test.h"
// The helpers in this file make it easier to write C++ unit tests which assert
@@ -190,6 +193,127 @@
bool trace_;
};
+#if !defined(PRODUCT)
+#define ENTITY_TOCSTRING(v) ((v)->ToCString())
+#else
+#define ENTITY_TOCSTRING(v) "<?>"
+#endif
+
+// Helper to check various IL and object properties and informative error
+// messages if check fails. [entity] should be a pointer to a value.
+// [property] should be an expression which can refer to [entity] using
+// variable named [it].
+// [entity] is expected to have a ToCString() method in non-PRODUCT builds.
+#define EXPECT_PROPERTY(entity, property) \
+ do { \
+ auto& it = *entity; \
+ if (!(property)) { \
+ dart::Expect(__FILE__, __LINE__) \
+ .Fail("expected " #property " for " #entity " which is %s.\n", \
+ ENTITY_TOCSTRING(entity)); \
+ } \
+ } while (0)
+
+class FlowGraphBuilderHelper {
+ public:
+ FlowGraphBuilderHelper()
+ : state_(CompilerState::Current()),
+ flow_graph_(MakeDummyGraph(Thread::Current())) {
+ flow_graph_.CreateCommonConstants();
+ }
+
+ TargetEntryInstr* TargetEntry(intptr_t try_index = kInvalidTryIndex) const {
+ return new TargetEntryInstr(flow_graph_.allocate_block_id(), try_index,
+ state_.GetNextDeoptId());
+ }
+
+ JoinEntryInstr* JoinEntry(intptr_t try_index = kInvalidTryIndex) const {
+ return new JoinEntryInstr(flow_graph_.allocate_block_id(), try_index,
+ state_.GetNextDeoptId());
+ }
+
+ ConstantInstr* IntConstant(int64_t value) const {
+ return flow_graph_.GetConstant(
+ Integer::Handle(Integer::New(value, Heap::kOld)));
+ }
+
+ ConstantInstr* DoubleConstant(double value) {
+ return flow_graph_.GetConstant(
+ Double::Handle(Double::New(value, Heap::kOld)));
+ }
+
+ PhiInstr* Phi(JoinEntryInstr* join,
+ std::initializer_list<std::pair<BlockEntryInstr*, Definition*>>
+ incomming) {
+ auto phi = new PhiInstr(join, incomming.size());
+ for (size_t i = 0; i < incomming.size(); i++) {
+ auto input = new Value(flow_graph_.constant_dead());
+ phi->SetInputAt(i, input);
+ input->definition()->AddInputUse(input);
+ }
+ for (auto pair : incomming) {
+ pending_phis_.Add({phi, pair.first, pair.second});
+ }
+ return phi;
+ }
+
+ void FinishGraph() {
+ flow_graph_.DiscoverBlocks();
+ GrowableArray<BitVector*> dominance_frontier;
+ flow_graph_.ComputeDominators(&dominance_frontier);
+
+ for (auto& pending : pending_phis_) {
+ auto join = pending.phi->block();
+ EXPECT(pending.phi->InputCount() == join->PredecessorCount());
+ auto pred_index = join->IndexOfPredecessor(pending.pred);
+ EXPECT(pred_index != -1);
+ pending.phi->InputAt(pred_index)->BindTo(pending.defn);
+ }
+ }
+
+ FlowGraph* flow_graph() { return &flow_graph_; }
+
+ private:
+ static FlowGraph& MakeDummyGraph(Thread* thread) {
+ const Function& func = Function::ZoneHandle(Function::New(
+ String::Handle(Symbols::New(thread, "dummy")),
+ RawFunction::kRegularFunction,
+ /*is_static=*/true,
+ /*is_const=*/false,
+ /*is_abstract=*/false,
+ /*is_external=*/false,
+ /*is_native=*/true,
+ Class::Handle(thread->isolate()->object_store()->object_class()),
+ TokenPosition::kNoSource));
+
+ Zone* zone = thread->zone();
+ ParsedFunction* parsed_function = new (zone) ParsedFunction(thread, func);
+
+ parsed_function->SetNodeSequence(new SequenceNode(
+ TokenPosition::kNoSource, new LocalScope(nullptr, 0, 0)));
+
+ auto graph_entry =
+ new GraphEntryInstr(*parsed_function, Compiler::kNoOSRDeoptId);
+
+ const intptr_t block_id = 1; // 0 is GraphEntry.
+ graph_entry->set_normal_entry(
+ new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex,
+ CompilerState::Current().GetNextDeoptId()));
+ return *new FlowGraph(*parsed_function, graph_entry, block_id,
+ PrologueInfo{-1, -1});
+ }
+
+ CompilerState& state_;
+ FlowGraph& flow_graph_;
+
+ struct PendingPhiInput {
+ PhiInstr* phi;
+ BlockEntryInstr* pred;
+ Definition* defn;
+ };
+ GrowableArray<PendingPhiInput> pending_phis_;
+};
+
} // namespace dart
#endif // RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 6947e3c..af182c4 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -74,7 +74,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::AnyOrConstant(value()));
+ locs->set_in(0, LocationAnyOrConstant(value()));
return locs;
}
@@ -89,7 +89,7 @@
__ PushObject(value.constant());
} else {
ASSERT(value.IsStackSlot());
- __ pushq(value.ToStackSlotAddress());
+ __ pushq(LocationToStackSlotAddress(value));
}
}
}
@@ -243,7 +243,7 @@
const intptr_t stack_index =
compiler::target::frame_layout.FrameSlotForVariable(&local());
return LocationSummary::Make(zone, kNumInputs,
- Location::StackSlot(stack_index),
+ Location::StackSlot(stack_index, FPREG),
LocationSummary::kNoCall);
}
@@ -321,16 +321,16 @@
__ LoadObject(tmp, value_);
__ movsd(XMM0, FieldAddress(tmp, Double::value_offset()));
}
- __ movsd(destination.ToStackSlotAddress(), XMM0);
+ __ movsd(LocationToStackSlotAddress(destination), XMM0);
} else {
ASSERT(destination.IsStackSlot());
if (representation() == kUnboxedInt32 ||
representation() == kUnboxedInt64) {
const int64_t value = Integer::Cast(value_).AsInt64Value();
- __ movq(destination.ToStackSlotAddress(), Immediate(value));
+ __ movq(LocationToStackSlotAddress(destination), Immediate(value));
} else {
ASSERT(representation() == kTagged);
- __ StoreObject(destination.ToStackSlotAddress(), value_);
+ __ StoreObject(LocationToStackSlotAddress(destination), value_);
}
}
}
@@ -525,13 +525,13 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
// Only right can be a stack slot.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -632,7 +632,7 @@
__ CompareObject(left.reg(), right.constant());
}
} else if (right.IsStackSlot()) {
- __ cmpq(left.reg(), right.ToStackSlotAddress());
+ __ cmpq(left.reg(), LocationToStackSlotAddress(right));
} else {
__ cmpq(left.reg(), right.reg());
}
@@ -720,7 +720,7 @@
locs->set_in(0, Location::RequiresRegister());
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
- locs->set_in(1, Location::RegisterOrConstant(right()));
+ locs->set_in(1, LocationRegisterOrConstant(right()));
return locs;
}
@@ -808,12 +808,12 @@
if (operation_cid() == kSmiCid || operation_cid() == kMintCid) {
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- summary->set_in(0, Location::RegisterOrConstant(left()));
+ summary->set_in(0, LocationRegisterOrConstant(left()));
// Only one input can be a constant operand. The case of two constant
// operands should be handled by constant propagation.
summary->set_in(1, summary->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
summary->set_out(0, Location::RequiresRegister());
return summary;
}
@@ -897,10 +897,6 @@
__ EnterDartFrame(compiler::ffi::NumStackSlots(arg_locations_) * kWordSize,
PP);
- // Save exit frame information to enable stack walking as we are about to
- // transition to Dart VM C++ code.
- __ movq(Address(THR, Thread::top_exit_frame_info_offset()), FPREG);
-
// Align frame before entering C++ world.
if (OS::ActivationFrameAlignment() > 1) {
__ andq(SPREG, Immediate(~(OS::ActivationFrameAlignment() - 1)));
@@ -912,50 +908,37 @@
if (target.IsStackSlot()) {
if (origin.IsRegister()) {
- __ movq(target.ToStackSlotAddress(), origin.reg());
+ __ movq(LocationToStackSlotAddress(target), origin.reg());
} else if (origin.IsFpuRegister()) {
__ movq(TMP, origin.fpu_reg());
- __ movq(target.ToStackSlotAddress(), TMP);
+ __ movq(LocationToStackSlotAddress(target), TMP);
} else if (origin.IsStackSlot() || origin.IsDoubleStackSlot()) {
// The base register cannot be SPREG because we've moved it.
ASSERT(origin.base_reg() == FPREG);
__ movq(TMP, Address(saved_fp, origin.ToStackSlotOffset()));
- __ movq(target.ToStackSlotAddress(), TMP);
+ __ movq(LocationToStackSlotAddress(target), TMP);
}
} else {
ASSERT(origin.Equals(target));
}
}
- // Mark that the thread is executing VM code.
- __ movq(Assembler::VMTagAddress(), target_address);
-
-// We need to copy the return address up into the dummy stack frame so the
-// stack walker will know which safepoint to use.
-#if defined(TARGET_OS_WINDOWS)
- constexpr intptr_t kCallSequenceLength = 10;
-#else
- constexpr intptr_t kCallSequenceLength = 6;
-#endif
-
- // RIP points to the *next* instruction, so 'AddressRIPRelative' loads the
- // address of the following 'movq'.
- __ leaq(TMP, Address::AddressRIPRelative(kCallSequenceLength));
-
- const intptr_t call_sequence_start = __ CodeSize();
- __ movq(Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), TMP);
- __ CallCFunction(target_address);
-
- ASSERT(__ CodeSize() - call_sequence_start == kCallSequenceLength);
-
+ // We need to copy a dummy return address up into the dummy stack frame so the
+ // stack walker will know which safepoint to use. RIP points to the *next*
+ // instruction, so 'AddressRIPRelative' loads the address of the following
+ // 'movq'.
+ __ leaq(TMP, Address::AddressRIPRelative(0));
compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
RawPcDescriptors::Kind::kOther, locs());
+ __ movq(Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), TMP);
- // Mark that the thread is executing Dart code.
- __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+ // Update information in the thread object and enter a safepoint.
+ __ TransitionGeneratedToNative(target_address);
- // Reset exit frame information in Isolate structure.
- __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
+ __ CallCFunction(target_address);
+
+ // Update information in the thread object and leave the safepoint.
+ __ TransitionNativeToGenerated();
// Although PP is a callee-saved register, it may have been moved by the GC.
__ LeaveDartFrame(compiler::kRestoreCallerPP);
@@ -1498,7 +1481,7 @@
case kArrayCid:
locs->set_in(2, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
if (ShouldEmitStoreBarrier()) {
locs->set_in(0, Location::RegisterLocation(kWriteBarrierObjectReg));
locs->set_temp(0, Location::RegisterLocation(kWriteBarrierSlotReg));
@@ -1512,7 +1495,7 @@
case kOneByteStringCid:
// TODO(fschneider): Add location constraint for byte registers (RAX,
// RBX, RCX, RDX) instead of using a fixed register.
- locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
+ locs->set_in(2, LocationFixedRegisterOrSmiConstant(value(), RAX));
break;
case kTypedDataInt16ArrayCid:
case kTypedDataUint16ArrayCid:
@@ -2019,7 +2002,7 @@
} else {
summary->set_in(1, ShouldEmitStoreBarrier()
? Location::RegisterLocation(kWriteBarrierValueReg)
- : Location::RegisterOrConstant(value()));
+ : LocationRegisterOrConstant(value()));
}
return summary;
}
@@ -3375,7 +3358,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
@@ -3386,7 +3369,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX));
if (kNumTemps == 1) {
summary->set_temp(0, Location::RequiresRegister());
}
@@ -3399,7 +3382,7 @@
summary->set_in(0, Location::RequiresRegister());
ConstantInstr* constant = right()->definition()->AsConstant();
if (constant != NULL) {
- summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ summary->set_in(1, LocationRegisterOrSmiConstant(right()));
} else {
summary->set_in(1, Location::PrefersRegister());
}
@@ -3499,7 +3482,7 @@
} // locs()->in(1).IsConstant().
if (locs()->in(1).IsStackSlot()) {
- const Address& right = locs()->in(1).ToStackSlotAddress();
+ const Address& right = LocationToStackSlotAddress(locs()->in(1));
switch (op_kind()) {
case Token::kADD: {
__ addq(left, right);
@@ -5385,8 +5368,8 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
- locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index()));
+ locs->set_in(kLengthPos, LocationRegisterOrSmiConstant(length()));
+ locs->set_in(kIndexPos, LocationRegisterOrSmiConstant(index()));
return locs;
}
@@ -5669,7 +5652,7 @@
LocationSummary* summary = new (zone) LocationSummary(
zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::RegisterOrConstant(right()));
+ summary->set_in(1, LocationRegisterOrConstant(right()));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
}
@@ -5856,7 +5839,7 @@
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, RangeUtils::IsPositive(shift_range())
- ? Location::FixedRegisterOrConstant(right(), RCX)
+ ? LocationFixedRegisterOrConstant(right(), RCX)
: Location::RegisterLocation(RCX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
@@ -5902,7 +5885,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
}
@@ -5976,7 +5959,7 @@
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, RangeUtils::IsPositive(shift_range())
- ? Location::FixedRegisterOrConstant(right(), RCX)
+ ? LocationFixedRegisterOrConstant(right(), RCX)
: Location::RegisterLocation(RCX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
@@ -6021,7 +6004,7 @@
LocationSummary* summary = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
- summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
+ summary->set_in(1, LocationFixedRegisterOrSmiConstant(right(), RCX));
summary->set_out(0, Location::SameAsFirstInput());
return summary;
}
@@ -6391,12 +6374,12 @@
}
LocationSummary* locs = new (zone)
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
+ locs->set_in(0, LocationRegisterOrConstant(left()));
// Only one of the inputs can be a constant. Choose register if the first one
// is a constant.
locs->set_in(1, locs->in(0).IsConstant()
? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ : LocationRegisterOrConstant(right()));
locs->set_out(0, Location::RequiresRegister());
return locs;
}
@@ -6498,10 +6481,14 @@
}
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#ifdef PRODUCT
+ UNREACHABLE();
+#else
ASSERT(!compiler->is_optimizing());
__ CallPatchable(StubCode::DebugStepCheck());
compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos());
compiler->RecordSafepoint(locs());
+#endif
}
} // namespace dart
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 8d34ae8..8a7550f 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -10,6 +10,7 @@
#include "vm/compiler/aot/precompiler.h"
#include "vm/compiler/backend/block_scheduler.h"
#include "vm/compiler/backend/branch_optimizer.h"
+#include "vm/compiler/backend/flow_graph_checker.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/type_propagator.h"
@@ -1062,6 +1063,10 @@
{
callee_graph = builder.BuildGraph();
+#if defined(DEBUG)
+ FlowGraphChecker(callee_graph).Check();
+#endif
+
CalleeGraphValidator::Validate(callee_graph);
}
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 9c7d766..4f5473c 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -675,10 +675,10 @@
Location loc;
switch (param->kind()) {
case SpecialParameterInstr::kException:
- loc = Location::ExceptionLocation();
+ loc = LocationExceptionLocation();
break;
case SpecialParameterInstr::kStackTrace:
- loc = Location::StackTraceLocation();
+ loc = LocationStackTraceLocation();
break;
default:
UNREACHABLE();
@@ -764,7 +764,7 @@
ASSERT(param->kind() == SpecialParameterInstr::kArgDescriptor);
Location loc;
#if defined(TARGET_ARCH_DBC)
- loc = Location::ArgumentsDescriptorLocation();
+ loc = LocationArgumentsDescriptorLocation();
#else
loc = Location::RegisterLocation(ARGS_DESC_REG);
#endif // defined(TARGET_ARCH_DBC)
@@ -2049,7 +2049,7 @@
if (register_kind_ == Location::kRegister) {
const intptr_t slot_index =
compiler::target::frame_layout.FrameSlotForVariableIndex(-idx);
- range->set_spill_slot(Location::StackSlot(slot_index));
+ range->set_spill_slot(Location::StackSlot(slot_index, FPREG));
} else {
// We use the index of the slot with the lowest address as an index for the
// FPU register spill slot. In terms of indexes this relation is inverted:
@@ -2064,11 +2064,11 @@
(range->representation() == kUnboxedInt32x4) ||
(range->representation() == kUnboxedFloat64x2)) {
ASSERT(need_quad);
- location = Location::QuadStackSlot(slot_idx);
+ location = Location::QuadStackSlot(slot_idx, FPREG);
} else {
ASSERT(range->representation() == kUnboxedFloat ||
range->representation() == kUnboxedDouble);
- location = Location::DoubleStackSlot(slot_idx);
+ location = Location::DoubleStackSlot(slot_idx, FPREG);
}
range->set_spill_slot(location);
}
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index e549879..f705a15 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -27,7 +27,7 @@
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
Register r = static_cast<Register>(i);
if (ContainsRegister(r)) {
- THR_Print("%s %s\n", Assembler::RegisterName(r),
+ THR_Print("%s %s\n", RegisterNames::RegisterName(r),
IsTagged(r) ? "tagged" : "untagged");
}
}
@@ -35,7 +35,7 @@
for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
FpuRegister r = static_cast<FpuRegister>(i);
if (ContainsFpuRegister(r)) {
- THR_Print("%s\n", Assembler::FpuRegisterName(r));
+ THR_Print("%s\n", RegisterNames::FpuRegisterName(r));
}
}
}
@@ -70,56 +70,66 @@
return summary;
}
-Location Location::Pair(Location first, Location second) {
- PairLocation* pair_location = new PairLocation();
+template <class Register, class FpuRegister>
+TemplateLocation<Register, FpuRegister>
+TemplateLocation<Register, FpuRegister>::Pair(
+ TemplateLocation<Register, FpuRegister> first,
+ TemplateLocation<Register, FpuRegister> second) {
+ TemplatePairLocation<TemplateLocation<Register, FpuRegister>>* pair_location =
+ new TemplatePairLocation<TemplateLocation<Register, FpuRegister>>();
ASSERT((reinterpret_cast<intptr_t>(pair_location) & kLocationTagMask) == 0);
pair_location->SetAt(0, first);
pair_location->SetAt(1, second);
- Location loc(reinterpret_cast<uword>(pair_location) | kPairLocationTag);
+ TemplateLocation<Register, FpuRegister> loc(
+ reinterpret_cast<uword>(pair_location) | kPairLocationTag);
return loc;
}
-PairLocation* Location::AsPairLocation() const {
+template <class Register, class FpuRegister>
+TemplatePairLocation<TemplateLocation<Register, FpuRegister>>*
+TemplateLocation<Register, FpuRegister>::AsPairLocation() const {
ASSERT(IsPairLocation());
- return reinterpret_cast<PairLocation*>(value_ & ~kLocationTagMask);
+ return reinterpret_cast<
+ TemplatePairLocation<TemplateLocation<Register, FpuRegister>>*>(
+ value_ & ~kLocationTagMask);
}
-Location Location::RegisterOrConstant(Value* value) {
+Location LocationRegisterOrConstant(Value* value) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafe(constant->value()))
? Location::Constant(constant)
: Location::RequiresRegister();
}
-Location Location::RegisterOrSmiConstant(Value* value) {
+Location LocationRegisterOrSmiConstant(Value* value) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafeSmi(constant->value()))
? Location::Constant(constant)
: Location::RequiresRegister();
}
-Location Location::WritableRegisterOrSmiConstant(Value* value) {
+Location LocationWritableRegisterOrSmiConstant(Value* value) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafeSmi(constant->value()))
? Location::Constant(constant)
: Location::WritableRegister();
}
-Location Location::FixedRegisterOrConstant(Value* value, Register reg) {
+Location LocationFixedRegisterOrConstant(Value* value, Register reg) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafe(constant->value()))
? Location::Constant(constant)
: Location::RegisterLocation(reg);
}
-Location Location::FixedRegisterOrSmiConstant(Value* value, Register reg) {
+Location LocationFixedRegisterOrSmiConstant(Value* value, Register reg) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafeSmi(constant->value()))
? Location::Constant(constant)
: Location::RegisterLocation(reg);
}
-Location Location::AnyOrConstant(Value* value) {
+Location LocationAnyOrConstant(Value* value) {
ConstantInstr* constant = value->definition()->AsConstant();
return ((constant != NULL) && Assembler::IsSafe(constant->value()))
? Location::Constant(constant)
@@ -128,27 +138,30 @@
// DBC does not have an notion of 'address' in its instruction set.
#if !defined(TARGET_ARCH_DBC)
-Address Location::ToStackSlotAddress() const {
- return Address(base_reg(), ToStackSlotOffset());
+Address LocationToStackSlotAddress(Location loc) {
+ return Address(loc.base_reg(), loc.ToStackSlotOffset());
}
#endif
-intptr_t Location::ToStackSlotOffset() const {
+template <class Register, class FpuRegister>
+intptr_t TemplateLocation<Register, FpuRegister>::ToStackSlotOffset() const {
return stack_index() * kWordSize;
}
-const Object& Location::constant() const {
+template <class Register, class FpuRegister>
+const Object& TemplateLocation<Register, FpuRegister>::constant() const {
return constant_instruction()->value();
}
-const char* Location::Name() const {
+template <class Register, class FpuRegister>
+const char* TemplateLocation<Register, FpuRegister>::Name() const {
switch (kind()) {
case kInvalid:
return "?";
case kRegister:
- return Assembler::RegisterName(reg());
+ return RegisterNames::RegisterName(reg());
case kFpuRegister:
- return Assembler::FpuRegisterName(fpu_reg());
+ return RegisterNames::FpuRegisterName(fpu_reg());
case kStackSlot:
return "S";
case kDoubleStackSlot:
@@ -195,7 +208,9 @@
return "?";
}
-void Location::PrintTo(BufferFormatter* f) const {
+template <class Register, class FpuRegister>
+void TemplateLocation<Register, FpuRegister>::PrintTo(
+ BufferFormatter* f) const {
if (!FLAG_support_il_printer) {
return;
}
@@ -216,14 +231,16 @@
}
}
-const char* Location::ToCString() const {
+template <class Register, class FpuRegister>
+const char* TemplateLocation<Register, FpuRegister>::ToCString() const {
char buffer[1024];
BufferFormatter bf(buffer, 1024);
PrintTo(&bf);
return Thread::Current()->zone()->MakeCopyOfString(buffer);
}
-void Location::Print() const {
+template <class Register, class FpuRegister>
+void TemplateLocation<Register, FpuRegister>::Print() const {
if (kind() == kStackSlot) {
THR_Print("S%+" Pd "", stack_index());
} else {
@@ -231,46 +248,77 @@
}
}
-Location Location::Copy() const {
+template <class Register, class FpuRegister>
+TemplateLocation<Register, FpuRegister>
+TemplateLocation<Register, FpuRegister>::Copy() const {
if (IsPairLocation()) {
- PairLocation* pair = AsPairLocation();
+ TemplatePairLocation<TemplateLocation<Register, FpuRegister>>* pair =
+ AsPairLocation();
ASSERT(!pair->At(0).IsPairLocation());
ASSERT(!pair->At(1).IsPairLocation());
- return Location::Pair(pair->At(0).Copy(), pair->At(1).Copy());
+ return TemplateLocation::Pair(pair->At(0).Copy(), pair->At(1).Copy());
} else {
// Copy by value.
return *this;
}
}
-Location Location::RemapForSlowPath(Definition* def,
- intptr_t* cpu_reg_slots,
- intptr_t* fpu_reg_slots) const {
- if (IsRegister()) {
- intptr_t index = cpu_reg_slots[reg()];
+Location LocationArgumentsDescriptorLocation() {
+#ifdef TARGET_ARCH_DBC
+ return Location(Location::kSpecialDbcRegister, Location::kArgsDescriptorReg);
+#else
+ return Location::RegisterLocation(ARGS_DESC_REG);
+#endif
+}
+
+Location LocationExceptionLocation() {
+#ifdef TARGET_ARCH_DBC
+ return Location(Location::kSpecialDbcRegister, Location::kExceptionReg);
+#else
+ return Location::RegisterLocation(kExceptionObjectReg);
+#endif
+}
+
+Location LocationStackTraceLocation() {
+#ifdef TARGET_ARCH_DBC
+ return Location(Location::kSpecialDbcRegister, Location::kStackTraceReg);
+#else
+ return Location::RegisterLocation(kStackTraceObjectReg);
+#endif
+}
+
+Location LocationRemapForSlowPath(Location loc,
+ Definition* def,
+ intptr_t* cpu_reg_slots,
+ intptr_t* fpu_reg_slots) {
+ if (loc.IsRegister()) {
+ intptr_t index = cpu_reg_slots[loc.reg()];
ASSERT(index >= 0);
return Location::StackSlot(
- compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
- } else if (IsFpuRegister()) {
- intptr_t index = fpu_reg_slots[fpu_reg()];
+ compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
+ FPREG);
+ } else if (loc.IsFpuRegister()) {
+ intptr_t index = fpu_reg_slots[loc.fpu_reg()];
ASSERT(index >= 0);
switch (def->representation()) {
case kUnboxedDouble:
return Location::DoubleStackSlot(
- compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
+ compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
+ FPREG);
case kUnboxedFloat32x4:
case kUnboxedInt32x4:
case kUnboxedFloat64x2:
return Location::QuadStackSlot(
- compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
+ compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
+ FPREG);
default:
UNREACHABLE();
}
- } else if (IsPairLocation()) {
+ } else if (loc.IsPairLocation()) {
ASSERT(def->representation() == kUnboxedInt64);
- PairLocation* value_pair = AsPairLocation();
+ PairLocation* value_pair = loc.AsPairLocation();
intptr_t index_lo;
intptr_t index_hi;
@@ -290,14 +338,14 @@
index_hi = value_pair->At(1).stack_index();
}
- return Location::Pair(Location::StackSlot(index_lo),
- Location::StackSlot(index_hi));
- } else if (IsInvalid() && def->IsMaterializeObject()) {
+ return Location::Pair(Location::StackSlot(index_lo, FPREG),
+ Location::StackSlot(index_hi, FPREG));
+ } else if (loc.IsInvalid() && def->IsMaterializeObject()) {
def->AsMaterializeObject()->RemapRegisters(cpu_reg_slots, fpu_reg_slots);
- return *this;
+ return loc;
}
- return *this;
+ return loc;
}
void LocationSummary::PrintTo(BufferFormatter* f) const {
@@ -358,6 +406,14 @@
}
#endif
+template class TemplateLocation<dart::Register, dart::FpuRegister>;
+template class TemplatePairLocation<Location>;
+
+#if !defined(HOST_ARCH_EQUALS_TARGET_ARCH)
+template class TemplateLocation<dart::host::Register, dart::host::FpuRegister>;
+template class TemplatePairLocation<HostLocation>;
+#endif // !defined(HOST_ARCH_EQUALS_TARGET_ARCH)
+
} // namespace dart
#endif // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index a14d8a0..513d61b 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -9,15 +9,18 @@
#include "vm/bitfield.h"
#include "vm/bitmap.h"
#include "vm/compiler/assembler/assembler.h"
+#include "vm/constants.h"
namespace dart {
class BufferFormatter;
class ConstantInstr;
class Definition;
-class PairLocation;
class Value;
+template <class Location>
+class TemplatePairLocation;
+
enum Representation {
kNoRepresentation,
kTagged,
@@ -62,7 +65,8 @@
// are bitwise unequal then these two locations are guaranteed to be disjoint.
// Properties like representation belong to the value that is stored in
// the location not to the location itself.
-class Location : public ValueObject {
+template <class Register, class FpuRegister>
+class TemplateLocation : public ValueObject {
private:
enum {
// Number of bits required to encode Kind value.
@@ -128,7 +132,7 @@
#endif
};
- Location() : value_(kInvalidLocation) {
+ TemplateLocation() : value_(kInvalidLocation) {
// Verify that non-tagged location kinds do not interfere with location tags
// (kConstantTag and kPairLocationTag).
COMPILE_ASSERT((kInvalid & kLocationTagMask) != kConstantTag);
@@ -166,9 +170,10 @@
ASSERT(IsInvalid());
}
- Location(const Location& other) : ValueObject(), value_(other.value_) {}
+ TemplateLocation(const TemplateLocation& other)
+ : ValueObject(), value_(other.value_) {}
- Location& operator=(const Location& other) {
+ TemplateLocation& operator=(const TemplateLocation& other) {
value_ = other.value_;
return *this;
}
@@ -180,8 +185,8 @@
return (value_ & kLocationTagMask) == kConstantTag;
}
- static Location Constant(const ConstantInstr* obj) {
- Location loc(reinterpret_cast<uword>(obj) | kConstantTag);
+ static TemplateLocation Constant(const ConstantInstr* obj) {
+ TemplateLocation loc(reinterpret_cast<uword>(obj) | kConstantTag);
ASSERT(obj == loc.constant_instruction());
return loc;
}
@@ -197,9 +202,10 @@
return (value_ & kLocationTagMask) == kPairLocationTag;
}
- static Location Pair(Location first, Location second);
+ static TemplateLocation Pair(TemplateLocation first, TemplateLocation second);
- PairLocation* AsPairLocation() const;
+ TemplatePairLocation<TemplateLocation<Register, FpuRegister>>*
+ AsPairLocation() const;
// Unallocated locations.
enum Policy {
@@ -215,37 +221,37 @@
bool IsRegisterBeneficial() { return !Equals(Any()); }
- static Location UnallocatedLocation(Policy policy) {
- return Location(kUnallocated, PolicyField::encode(policy));
+ static TemplateLocation UnallocatedLocation(Policy policy) {
+ return TemplateLocation(kUnallocated, PolicyField::encode(policy));
}
// Any free register is suitable to replace this unallocated location.
- static Location Any() { return UnallocatedLocation(kAny); }
+ static TemplateLocation Any() { return UnallocatedLocation(kAny); }
- static Location PrefersRegister() {
+ static TemplateLocation PrefersRegister() {
return UnallocatedLocation(kPrefersRegister);
}
- static Location RequiresRegister() {
+ static TemplateLocation RequiresRegister() {
return UnallocatedLocation(kRequiresRegister);
}
- static Location RequiresFpuRegister() {
+ static TemplateLocation RequiresFpuRegister() {
return UnallocatedLocation(kRequiresFpuRegister);
}
- static Location WritableRegister() {
+ static TemplateLocation WritableRegister() {
return UnallocatedLocation(kWritableRegister);
}
// The location of the first input to the instruction will be
// used to replace this unallocated location.
- static Location SameAsFirstInput() {
+ static TemplateLocation SameAsFirstInput() {
return UnallocatedLocation(kSameAsFirstInput);
}
// Empty location. Used if there the location should be ignored.
- static Location NoLocation() { return Location(); }
+ static TemplateLocation NoLocation() { return TemplateLocation(); }
Policy policy() const {
ASSERT(IsUnallocated());
@@ -253,8 +259,8 @@
}
// Register locations.
- static Location RegisterLocation(Register reg) {
- return Location(kRegister, reg);
+ static TemplateLocation RegisterLocation(Register reg) {
+ return TemplateLocation(kRegister, reg);
}
bool IsRegister() const { return kind() == kRegister; }
@@ -265,36 +271,12 @@
}
// FpuRegister locations.
- static Location FpuRegisterLocation(FpuRegister reg) {
- return Location(kFpuRegister, reg);
+ static TemplateLocation FpuRegisterLocation(FpuRegister reg) {
+ return TemplateLocation(kFpuRegister, reg);
}
bool IsFpuRegister() const { return kind() == kFpuRegister; }
- static Location ArgumentsDescriptorLocation() {
-#ifdef TARGET_ARCH_DBC
- return Location(kSpecialDbcRegister, kArgsDescriptorReg);
-#else
- return Location::RegisterLocation(ARGS_DESC_REG);
-#endif
- }
-
- static Location ExceptionLocation() {
-#ifdef TARGET_ARCH_DBC
- return Location(kSpecialDbcRegister, kExceptionReg);
-#else
- return Location::RegisterLocation(kExceptionObjectReg);
-#endif
- }
-
- static Location StackTraceLocation() {
-#ifdef TARGET_ARCH_DBC
- return Location(kSpecialDbcRegister, kStackTraceReg);
-#else
- return Location::RegisterLocation(kStackTraceObjectReg);
-#endif
- }
-
#ifdef TARGET_ARCH_DBC
bool IsArgsDescRegister() const {
return IsSpecialDbcRegister(kArgsDescriptorReg);
@@ -320,7 +302,7 @@
return (kind == kRegister) || (kind == kFpuRegister);
}
- static Location MachineRegisterLocation(Kind kind, intptr_t reg) {
+ static TemplateLocation MachineRegisterLocation(Kind kind, intptr_t reg) {
if (kind == kRegister) {
return RegisterLocation(static_cast<Register>(reg));
} else {
@@ -342,10 +324,10 @@
return static_cast<uword>(kStackIndexBias + stack_index);
}
- static Location StackSlot(intptr_t stack_index, Register base = FPREG) {
+ static TemplateLocation StackSlot(intptr_t stack_index, Register base) {
uword payload = StackSlotBaseField::encode(base) |
StackIndexField::encode(EncodeStackIndex(stack_index));
- Location loc(kStackSlot, payload);
+ TemplateLocation loc(kStackSlot, payload);
// Ensure that sign is preserved.
ASSERT(loc.stack_index() == stack_index);
return loc;
@@ -353,10 +335,10 @@
bool IsStackSlot() const { return kind() == kStackSlot; }
- static Location DoubleStackSlot(intptr_t stack_index, Register base = FPREG) {
+ static TemplateLocation DoubleStackSlot(intptr_t stack_index, Register base) {
uword payload = StackSlotBaseField::encode(base) |
StackIndexField::encode(EncodeStackIndex(stack_index));
- Location loc(kDoubleStackSlot, payload);
+ TemplateLocation loc(kDoubleStackSlot, payload);
// Ensure that sign is preserved.
ASSERT(loc.stack_index() == stack_index);
return loc;
@@ -364,10 +346,10 @@
bool IsDoubleStackSlot() const { return kind() == kDoubleStackSlot; }
- static Location QuadStackSlot(intptr_t stack_index) {
- uword payload = StackSlotBaseField::encode(FPREG) |
+ static TemplateLocation QuadStackSlot(intptr_t stack_index, Register base) {
+ uword payload = StackSlotBaseField::encode(base) |
StackIndexField::encode(EncodeStackIndex(stack_index));
- Location loc(kQuadStackSlot, payload);
+ TemplateLocation loc(kQuadStackSlot, payload);
// Ensure that sign is preserved.
ASSERT(loc.stack_index() == stack_index);
return loc;
@@ -390,45 +372,27 @@
return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot();
}
-// DBC does not have an notion of 'address' in its instruction set.
-#if !defined(TARGET_ARCH_DBC)
- // Return a memory operand for stack slot locations.
- Address ToStackSlotAddress() const;
-#endif
-
// Returns the offset from the frame pointer for stack slot locations.
intptr_t ToStackSlotOffset() const;
- // Constants.
- static Location RegisterOrConstant(Value* value);
- static Location RegisterOrSmiConstant(Value* value);
- static Location WritableRegisterOrSmiConstant(Value* value);
- static Location FixedRegisterOrConstant(Value* value, Register reg);
- static Location FixedRegisterOrSmiConstant(Value* value, Register reg);
- static Location AnyOrConstant(Value* value);
-
const char* Name() const;
void PrintTo(BufferFormatter* f) const;
void Print() const;
const char* ToCString() const;
// Compare two locations.
- bool Equals(Location other) const { return value_ == other.value_; }
+ bool Equals(TemplateLocation other) const { return value_ == other.value_; }
// If current location is constant might return something that
// is not equal to any Kind.
Kind kind() const { return KindField::decode(value_); }
- Location Copy() const;
-
- Location RemapForSlowPath(Definition* def,
- intptr_t* cpu_reg_slots,
- intptr_t* fpu_reg_slots) const;
+ TemplateLocation Copy() const;
private:
- explicit Location(uword value) : value_(value) {}
+ explicit TemplateLocation(uword value) : value_(value) {}
- Location(Kind kind, uword payload)
+ TemplateLocation(Kind kind, uword payload)
: value_(KindField::encode(kind) | PayloadField::encode(payload)) {}
uword payload() const { return PayloadField::decode(value_); }
@@ -462,11 +426,48 @@
// a constant locations. Values of enumeration Kind are selected in such a
// way that none of them can be interpreted as a kConstant tag.
uword value_;
+
+ // The following functions are only defined for Location, not for
+ // HostLocation, but they do need access to private fields or constructors.
+ friend TemplateLocation<dart::Register, dart::FpuRegister>
+ LocationArgumentsDescriptorLocation();
+ friend TemplateLocation<dart::Register, dart::FpuRegister>
+ LocationExceptionLocation();
+ friend TemplateLocation<dart::Register, dart::FpuRegister>
+ LocationStackTraceLocation();
};
-class PairLocation : public ZoneAllocated {
+using Location = TemplateLocation<dart::Register, dart::FpuRegister>;
+using HostLocation =
+ TemplateLocation<dart::host::Register, dart::host::FpuRegister>;
+
+// The following functions are only defined for Location, not for HostLocation.
+Location LocationArgumentsDescriptorLocation();
+Location LocationExceptionLocation();
+Location LocationStackTraceLocation();
+// Constants.
+Location LocationRegisterOrConstant(Value* value);
+Location LocationRegisterOrSmiConstant(Value* value);
+Location LocationWritableRegisterOrSmiConstant(Value* value);
+Location LocationFixedRegisterOrConstant(Value* value, Register reg);
+Location LocationFixedRegisterOrSmiConstant(Value* value, Register reg);
+Location LocationAnyOrConstant(Value* value);
+
+Location LocationRemapForSlowPath(Location loc,
+ Definition* def,
+ intptr_t* cpu_reg_slots,
+ intptr_t* fpu_reg_slots);
+
+// DBC does not have an notion of 'address' in its instruction set.
+#if !defined(TARGET_ARCH_DBC)
+// Return a memory operand for stack slot locations.
+Address LocationToStackSlotAddress(Location loc);
+#endif
+
+template <class Location>
+class TemplatePairLocation : public ZoneAllocated {
public:
- PairLocation() {
+ TemplatePairLocation() {
for (intptr_t i = 0; i < kPairLength; i++) {
ASSERT(locations_[i].IsInvalid());
}
@@ -497,6 +498,9 @@
Location locations_[kPairLength];
};
+using PairLocation = TemplatePairLocation<Location>;
+using HostPairLocation = TemplatePairLocation<HostLocation>;
+
template <typename T>
class SmallSet {
public:
@@ -544,6 +548,25 @@
}
}
+ // Adds all registers which don't have a special purpose (e.g. FP, SP, PC,
+ // CSP, etc.).
+ void AddAllGeneralRegisters() {
+ for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
+ Register reg = static_cast<Register>(i);
+ if (reg == FPREG || reg == SPREG) continue;
+#if defined(TARGET_ARCH_ARM)
+ if (reg == PC) continue;
+#elif defined(TARGET_ARCH_ARM64)
+ if (reg == R31) continue;
+#endif
+ Add(Location::RegisterLocation(reg));
+ }
+
+ for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
+ Add(Location::FpuRegisterLocation(static_cast<FpuRegister>(i)));
+ }
+ }
+
void Add(Location loc, Representation rep = kTagged) {
if (loc.IsRegister()) {
cpu_registers_.Add(loc.reg());
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index abb9f5a..f29815c 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -951,8 +951,8 @@
for (Value* use = defn->input_use_list(); use != NULL;
use = use->next_use()) {
Instruction* instr = use->instruction();
- if ((instr->IsRedefinition() || instr->IsAssertAssignable()) &&
- HasLoadsFromPlace(instr->AsDefinition(), place)) {
+ if (UseIsARedefinition(use) &&
+ HasLoadsFromPlace(instr->Cast<Definition>(), place)) {
return true;
}
bool is_load = false, is_store;
@@ -966,6 +966,14 @@
return false;
}
+ // Returns true if the given [use] is a redefinition (e.g. RedefinitionInstr,
+ // CheckNull, CheckArrayBound, etc).
+ static bool UseIsARedefinition(Value* use) {
+ Instruction* instr = use->instruction();
+ return instr->IsDefinition() &&
+ (instr->Cast<Definition>()->RedefinedValue() == use);
+ }
+
// Check if any use of the definition can create an alias.
// Can add more objects into aliasing_worklist_.
bool AnyUseCreatesAlias(Definition* defn) {
@@ -978,8 +986,8 @@
(use->use_index() == StoreIndexedInstr::kValuePos)) ||
instr->IsStoreStaticField() || instr->IsPhi()) {
return true;
- } else if ((instr->IsAssertAssignable() || instr->IsRedefinition()) &&
- AnyUseCreatesAlias(instr->AsDefinition())) {
+ } else if (UseIsARedefinition(use) &&
+ AnyUseCreatesAlias(instr->Cast<Definition>())) {
return true;
} else if ((instr->IsStoreInstanceField() &&
(use->use_index() !=
@@ -1017,15 +1025,14 @@
// Find all stores into this object.
for (Value* use = defn->input_use_list(); use != NULL;
use = use->next_use()) {
- if (use->instruction()->IsRedefinition() ||
- use->instruction()->IsAssertAssignable()) {
- MarkStoredValuesEscaping(use->instruction()->AsDefinition());
+ auto instr = use->instruction();
+ if (UseIsARedefinition(use)) {
+ MarkStoredValuesEscaping(instr->AsDefinition());
continue;
}
if ((use->use_index() == StoreInstanceFieldInstr::kInstancePos) &&
- use->instruction()->IsStoreInstanceField()) {
- StoreInstanceFieldInstr* store =
- use->instruction()->AsStoreInstanceField();
+ instr->IsStoreInstanceField()) {
+ StoreInstanceFieldInstr* store = instr->AsStoreInstanceField();
Definition* value = store->value()->definition()->OriginalDefinition();
if (value->Identity().IsNotAliased()) {
value->SetIdentity(AliasIdentity::Aliased());
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 21e63d8..e06aca3 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -3,6 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/compiler/backend/redundancy_elimination.h"
+
+#include <functional>
+
+#include "vm/compiler/backend/block_builder.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/backend/inliner.h"
@@ -194,4 +198,357 @@
TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{"a", "b", "i"});
}
+// LoadOptimizer tests
+
+// This family of tests verifies behavior of load forwarding when alias for an
+// allocation A is created by creating a redefinition for it and then
+// letting redefinition escape.
+static void TestAliasingViaRedefinition(
+ Thread* thread,
+ bool make_it_escape,
+ std::function<Definition*(CompilerState* S, FlowGraph*, Definition*)>
+ make_redefinition) {
+ const char* script_chars = R"(
+ dynamic blackhole([a, b, c, d, e, f]) native 'BlackholeNative';
+ class K {
+ var field;
+ }
+ )";
+ const Library& lib =
+ Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
+
+ const Class& cls = Class::Handle(
+ lib.LookupLocalClass(String::Handle(Symbols::New(thread, "K"))));
+ const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
+ EXPECT(err.IsNull());
+
+ const Field& field = Field::Handle(
+ cls.LookupField(String::Handle(Symbols::New(thread, "field"))));
+ EXPECT(!field.IsNull());
+
+ const Function& blackhole =
+ Function::ZoneHandle(GetFunction(lib, "blackhole"));
+
+ using compiler::BlockBuilder;
+ CompilerState S(thread);
+ FlowGraphBuilderHelper H;
+
+ // We are going to build the following graph:
+ //
+ // B0[graph_entry]
+ // B1[function_entry]:
+ // v0 <- AllocateObject(class K)
+ // v1 <- LoadField(v0, K.field)
+ // v2 <- make_redefinition(v0)
+ // PushArgument(v1)
+ // #if make_it_escape
+ // PushArgument(v2)
+ // #endif
+ // v3 <- StaticCall(blackhole, v1, v2)
+ // v4 <- LoadField(v2, K.field)
+ // Return v4
+
+ auto b1 = H.flow_graph()->graph_entry()->normal_entry();
+ AllocateObjectInstr* v0;
+ LoadFieldInstr* v1;
+ PushArgumentInstr* push_v1;
+ LoadFieldInstr* v4;
+ ReturnInstr* ret;
+
+ {
+ BlockBuilder builder(H.flow_graph(), b1);
+ auto& slot = Slot::Get(field, &H.flow_graph()->parsed_function());
+ v0 = builder.AddDefinition(new AllocateObjectInstr(
+ TokenPosition::kNoSource, cls, new PushArgumentsArray(0)));
+ v1 = builder.AddDefinition(
+ new LoadFieldInstr(new Value(v0), slot, TokenPosition::kNoSource));
+ auto v2 = builder.AddDefinition(make_redefinition(&S, H.flow_graph(), v0));
+ auto args = new PushArgumentsArray(2);
+ push_v1 = builder.AddInstruction(new PushArgumentInstr(new Value(v1)));
+ args->Add(push_v1);
+ if (make_it_escape) {
+ auto push_v2 =
+ builder.AddInstruction(new PushArgumentInstr(new Value(v2)));
+ args->Add(push_v2);
+ }
+ builder.AddInstruction(new StaticCallInstr(
+ TokenPosition::kNoSource, blackhole, 0, Array::empty_array(), args,
+ S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
+ v4 = builder.AddDefinition(
+ new LoadFieldInstr(new Value(v2), slot, TokenPosition::kNoSource));
+ ret = builder.AddInstruction(new ReturnInstr(
+ TokenPosition::kNoSource, new Value(v4), S.GetNextDeoptId()));
+ }
+ H.FinishGraph();
+ DominatorBasedCSE::Optimize(H.flow_graph());
+
+ if (make_it_escape) {
+ // Allocation must be considered aliased.
+ EXPECT_PROPERTY(v0, !it.Identity().IsNotAliased());
+ } else {
+ // Allocation must be considered not-aliased.
+ EXPECT_PROPERTY(v0, it.Identity().IsNotAliased());
+ }
+
+ // v1 should have been removed from the graph and replaced with constant_null.
+ EXPECT_PROPERTY(v1, it.next() == nullptr && it.previous() == nullptr);
+ EXPECT_PROPERTY(push_v1,
+ it.value()->definition() == H.flow_graph()->constant_null());
+
+ if (make_it_escape) {
+ // v4 however should not be removed from the graph, because v0 escapes into
+ // blackhole.
+ EXPECT_PROPERTY(v4, it.next() != nullptr && it.previous() != nullptr);
+ EXPECT_PROPERTY(ret, it.value()->definition() == v4);
+ } else {
+ // If v0 it not aliased then v4 should also be removed from the graph.
+ EXPECT_PROPERTY(v4, it.next() == nullptr && it.previous() == nullptr);
+ EXPECT_PROPERTY(
+ ret, it.value()->definition() == H.flow_graph()->constant_null());
+ }
+}
+
+static Definition* MakeCheckNull(CompilerState* S,
+ FlowGraph* flow_graph,
+ Definition* defn) {
+ return new CheckNullInstr(new Value(defn), String::ZoneHandle(),
+ S->GetNextDeoptId(), TokenPosition::kNoSource);
+}
+
+static Definition* MakeRedefinition(CompilerState* S,
+ FlowGraph* flow_graph,
+ Definition* defn) {
+ return new RedefinitionInstr(new Value(defn));
+}
+
+static Definition* MakeAssertAssignable(CompilerState* S,
+ FlowGraph* flow_graph,
+ Definition* defn) {
+ return new AssertAssignableInstr(TokenPosition::kNoSource, new Value(defn),
+ new Value(flow_graph->constant_null()),
+ new Value(flow_graph->constant_null()),
+ AbstractType::ZoneHandle(Type::ObjectType()),
+ Symbols::Empty(), S->GetNextDeoptId());
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_RedefinitionAliasing_CheckNull_NoEscape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/false, MakeCheckNull);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_RedefinitionAliasing_CheckNull_Escape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/true, MakeCheckNull);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_RedefinitionAliasing_Redefinition_NoEscape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/false,
+ MakeRedefinition);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_RedefinitionAliasing_Redefinition_Escape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/true,
+ MakeRedefinition);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_RedefinitionAliasing_AssertAssignable_NoEscape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/false,
+ MakeAssertAssignable);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_RedefinitionAliasing_AssertAssignable_Escape) {
+ TestAliasingViaRedefinition(thread, /*make_it_escape=*/true,
+ MakeAssertAssignable);
+}
+
+// This family of tests verifies behavior of load forwarding when alias for an
+// allocation A is created by storing it into another object B and then
+// either loaded from it ([make_it_escape] is true) or object B itself
+// escapes ([make_host_escape] is true).
+// We insert redefinition for object B to check that use list traversal
+// correctly discovers all loads and stores from B.
+static void TestAliasingViaStore(
+ Thread* thread,
+ bool make_it_escape,
+ bool make_host_escape,
+ std::function<Definition*(CompilerState* S, FlowGraph*, Definition*)>
+ make_redefinition) {
+ const char* script_chars = R"(
+ dynamic blackhole([a, b, c, d, e, f]) native 'BlackholeNative';
+ class K {
+ var field;
+ }
+ )";
+ const Library& lib =
+ Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
+
+ const Class& cls = Class::Handle(
+ lib.LookupLocalClass(String::Handle(Symbols::New(thread, "K"))));
+ const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
+ EXPECT(err.IsNull());
+
+ const Field& field = Field::Handle(
+ cls.LookupField(String::Handle(Symbols::New(thread, "field"))));
+ EXPECT(!field.IsNull());
+
+ const Function& blackhole =
+ Function::ZoneHandle(GetFunction(lib, "blackhole"));
+
+ using compiler::BlockBuilder;
+ CompilerState S(thread);
+ FlowGraphBuilderHelper H;
+
+ // We are going to build the following graph:
+ //
+ // B0[graph_entry]
+ // B1[function_entry]:
+ // v0 <- AllocateObject(class K)
+ // v5 <- AllocateObject(class K)
+ // #if !make_host_escape
+ // StoreField(v5 . K.field = v0)
+ // #endif
+ // v1 <- LoadField(v0, K.field)
+ // v2 <- REDEFINITION(v5)
+ // PushArgument(v1)
+ // #if make_it_escape
+ // v6 <- LoadField(v2, K.field)
+ // PushArgument(v6)
+ // #elif make_host_escape
+ // StoreField(v2 . K.field = v0)
+ // PushArgument(v5)
+ // #endif
+ // v3 <- StaticCall(blackhole, v1, v6)
+ // v4 <- LoadField(v0, K.field)
+ // Return v4
+
+ auto b1 = H.flow_graph()->graph_entry()->normal_entry();
+ AllocateObjectInstr* v0;
+ AllocateObjectInstr* v5;
+ LoadFieldInstr* v1;
+ PushArgumentInstr* push_v1;
+ LoadFieldInstr* v4;
+ ReturnInstr* ret;
+
+ {
+ BlockBuilder builder(H.flow_graph(), b1);
+ auto& slot = Slot::Get(field, &H.flow_graph()->parsed_function());
+ v0 = builder.AddDefinition(new AllocateObjectInstr(
+ TokenPosition::kNoSource, cls, new PushArgumentsArray(0)));
+ v5 = builder.AddDefinition(new AllocateObjectInstr(
+ TokenPosition::kNoSource, cls, new PushArgumentsArray(0)));
+ if (!make_host_escape) {
+ builder.AddInstruction(new StoreInstanceFieldInstr(
+ slot, new Value(v5), new Value(v0), kEmitStoreBarrier,
+ TokenPosition::kNoSource));
+ }
+ v1 = builder.AddDefinition(
+ new LoadFieldInstr(new Value(v0), slot, TokenPosition::kNoSource));
+ auto v2 = builder.AddDefinition(make_redefinition(&S, H.flow_graph(), v5));
+ push_v1 = builder.AddInstruction(new PushArgumentInstr(new Value(v1)));
+ auto args = new PushArgumentsArray(2);
+ args->Add(push_v1);
+ if (make_it_escape) {
+ auto v6 = builder.AddDefinition(
+ new LoadFieldInstr(new Value(v2), slot, TokenPosition::kNoSource));
+ auto push_v6 =
+ builder.AddInstruction(new PushArgumentInstr(new Value(v6)));
+ args->Add(push_v6);
+ } else if (make_host_escape) {
+ builder.AddInstruction(new StoreInstanceFieldInstr(
+ slot, new Value(v2), new Value(v0), kEmitStoreBarrier,
+ TokenPosition::kNoSource));
+ args->Add(builder.AddInstruction(new PushArgumentInstr(new Value(v5))));
+ }
+ builder.AddInstruction(new StaticCallInstr(
+ TokenPosition::kNoSource, blackhole, 0, Array::empty_array(), args,
+ S.GetNextDeoptId(), 0, ICData::RebindRule::kStatic));
+ v4 = builder.AddDefinition(
+ new LoadFieldInstr(new Value(v0), slot, TokenPosition::kNoSource));
+ ret = builder.AddInstruction(new ReturnInstr(
+ TokenPosition::kNoSource, new Value(v4), S.GetNextDeoptId()));
+ }
+ H.FinishGraph();
+ DominatorBasedCSE::Optimize(H.flow_graph());
+
+ if (make_it_escape || make_host_escape) {
+ // Allocation must be considered aliased.
+ EXPECT_PROPERTY(v0, !it.Identity().IsNotAliased());
+ } else {
+ // Allocation must not be considered aliased.
+ EXPECT_PROPERTY(v0, it.Identity().IsNotAliased());
+ }
+
+ if (make_host_escape) {
+ EXPECT_PROPERTY(v5, !it.Identity().IsNotAliased());
+ } else {
+ EXPECT_PROPERTY(v5, it.Identity().IsNotAliased());
+ }
+
+ // v1 should have been removed from the graph and replaced with constant_null.
+ EXPECT_PROPERTY(v1, it.next() == nullptr && it.previous() == nullptr);
+ EXPECT_PROPERTY(push_v1,
+ it.value()->definition() == H.flow_graph()->constant_null());
+
+ if (make_it_escape || make_host_escape) {
+ // v4 however should not be removed from the graph, because v0 escapes into
+ // blackhole.
+ EXPECT_PROPERTY(v4, it.next() != nullptr && it.previous() != nullptr);
+ EXPECT_PROPERTY(ret, it.value()->definition() == v4);
+ } else {
+ // If v0 it not aliased then v4 should also be removed from the graph.
+ EXPECT_PROPERTY(v4, it.next() == nullptr && it.previous() == nullptr);
+ EXPECT_PROPERTY(
+ ret, it.value()->definition() == H.flow_graph()->constant_null());
+ }
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_CheckNull_NoEscape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ false, MakeCheckNull);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_CheckNull_Escape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/true,
+ /* make_host_escape= */ false, MakeCheckNull);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_CheckNull_EscapeViaHost) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ true, MakeCheckNull);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_Redefinition_NoEscape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ false, MakeRedefinition);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_Redefinition_Escape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/true,
+ /* make_host_escape= */ false, MakeRedefinition);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_AliasingViaStore_Redefinition_EscapeViaHost) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ true, MakeRedefinition);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_AliasingViaStore_AssertAssignable_NoEscape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ false, MakeAssertAssignable);
+}
+
+ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaStore_AssertAssignable_Escape) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/true,
+ /* make_host_escape= */ false, MakeAssertAssignable);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+ LoadOptimizer_AliasingViaStore_AssertAssignable_EscapeViaHost) {
+ TestAliasingViaStore(thread, /*make_it_escape=*/false,
+ /* make_host_escape= */ true, MakeAssertAssignable);
+}
+
} // namespace dart
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index ab6501bc..89bc20c 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -6,6 +6,7 @@
#include "vm/compiler/backend/block_builder.h"
#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/backend/inliner.h"
#include "vm/compiler/backend/loops.h"
#include "vm/compiler/backend/redundancy_elimination.h"
@@ -22,129 +23,12 @@
namespace dart {
-#if !defined(PRODUCT)
-#define TOCSTRING(v) ((v)->ToCString())
-#else
-#define TOCSTRING(v) "<?>"
-#endif
-
-#define EXPECT_PROPERTY(entity, property) \
- do { \
- auto& it = *entity; \
- if (!(property)) { \
- dart::Expect(__FILE__, __LINE__) \
- .Fail("expected " #property " for " #entity " which is %s.\n", \
- TOCSTRING(entity)); \
- } \
- } while (0)
-
using compiler::BlockBuilder;
-FlowGraph* MakeDummyGraph(Thread* thread) {
- const Function& func = Function::ZoneHandle(Function::New(
- String::Handle(Symbols::New(thread, "dummy")),
- RawFunction::kRegularFunction,
- /*is_static=*/true,
- /*is_const=*/false,
- /*is_abstract=*/false,
- /*is_external=*/false,
- /*is_native=*/true,
- Class::Handle(thread->isolate()->object_store()->object_class()),
- TokenPosition::kNoSource));
-
- Zone* zone = thread->zone();
- ParsedFunction* parsed_function = new (zone) ParsedFunction(thread, func);
-
- parsed_function->SetNodeSequence(new SequenceNode(
- TokenPosition::kNoSource, new LocalScope(nullptr, 0, 0)));
-
- auto graph_entry =
- new GraphEntryInstr(*parsed_function, Compiler::kNoOSRDeoptId);
-
- intptr_t block_id = 1; // 0 is GraphEntry.
- graph_entry->set_normal_entry(
- new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex,
- CompilerState::Current().GetNextDeoptId()));
- return new FlowGraph(*parsed_function, graph_entry, block_id,
- PrologueInfo{-1, -1});
-}
-
-namespace {
-class FlowGraphBuilderHelper {
- public:
- explicit FlowGraphBuilderHelper(FlowGraph* flow_graph)
- : state_(CompilerState::Current()),
- flow_graph_(*flow_graph),
- constant_dead_(flow_graph->GetConstant(Symbols::OptimizedOut())) {}
-
- TargetEntryInstr* TargetEntry(intptr_t try_index = kInvalidTryIndex) const {
- return new TargetEntryInstr(flow_graph_.allocate_block_id(), try_index,
- state_.GetNextDeoptId());
- }
-
- JoinEntryInstr* JoinEntry(intptr_t try_index = kInvalidTryIndex) const {
- return new JoinEntryInstr(flow_graph_.allocate_block_id(), try_index,
- state_.GetNextDeoptId());
- }
-
- ConstantInstr* IntConstant(int64_t value) const {
- return flow_graph_.GetConstant(
- Integer::Handle(Integer::New(value, Heap::kOld)));
- }
-
- ConstantInstr* DoubleConstant(double value) {
- return flow_graph_.GetConstant(
- Double::Handle(Double::New(value, Heap::kOld)));
- }
-
- PhiInstr* Phi(JoinEntryInstr* join,
- std::initializer_list<std::pair<BlockEntryInstr*, Definition*>>
- incomming) {
- auto phi = new PhiInstr(join, incomming.size());
- for (size_t i = 0; i < incomming.size(); i++) {
- auto input = new Value(constant_dead_);
- phi->SetInputAt(i, input);
- input->definition()->AddInputUse(input);
- }
- for (auto pair : incomming) {
- pending_phis_.Add({phi, pair.first, pair.second});
- }
- return phi;
- }
-
- void FinishGraph() {
- flow_graph_.DiscoverBlocks();
- GrowableArray<BitVector*> dominance_frontier;
- flow_graph_.ComputeDominators(&dominance_frontier);
-
- for (auto& pending : pending_phis_) {
- auto join = pending.phi->block();
- EXPECT(pending.phi->InputCount() == join->PredecessorCount());
- auto pred_index = join->IndexOfPredecessor(pending.pred);
- EXPECT(pred_index != -1);
- pending.phi->InputAt(pred_index)->BindTo(pending.defn);
- }
- }
-
- private:
- CompilerState& state_;
- FlowGraph& flow_graph_;
- ConstantInstr* constant_dead_;
-
- struct PendingPhiInput {
- PhiInstr* phi;
- BlockEntryInstr* pred;
- Definition* defn;
- };
- GrowableArray<PendingPhiInput> pending_phis_;
-};
-} // namespace
-
ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) {
CompilerState S(thread);
- FlowGraph* flow_graph = MakeDummyGraph(thread);
- FlowGraphBuilderHelper H(flow_graph);
+ FlowGraphBuilderHelper H;
// Add a variable into the scope which would provide static type for the
// parameter.
@@ -153,9 +37,10 @@
String::Handle(Symbols::New(thread, "v0")),
AbstractType::ZoneHandle(Type::IntType()));
v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
- flow_graph->parsed_function().node_sequence()->scope()->AddVariable(v0_var);
+ H.flow_graph()->parsed_function().node_sequence()->scope()->AddVariable(
+ v0_var);
- auto normal_entry = flow_graph->graph_entry()->normal_entry();
+ auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
// We are going to build the following graph:
//
@@ -173,29 +58,29 @@
auto b3 = H.TargetEntry();
{
- BlockBuilder builder(flow_graph, normal_entry);
+ BlockBuilder builder(H.flow_graph(), normal_entry);
v0 = builder.AddParameter(0, /*with_frame=*/true);
builder.AddBranch(
new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(v0),
- new Value(flow_graph->GetConstant(Object::Handle())),
+ new Value(H.flow_graph()->GetConstant(Object::Handle())),
/*needs_number_check=*/false, S.GetNextDeoptId()),
b2, b3);
}
{
- BlockBuilder builder(flow_graph, b2);
+ BlockBuilder builder(H.flow_graph(), b2);
builder.AddReturn(new Value(v0));
}
{
- BlockBuilder builder(flow_graph, b3);
+ BlockBuilder builder(H.flow_graph(), b3);
builder.AddReturn(new Value(v0));
}
H.FinishGraph();
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
// We expect that v0 is inferred to be nullable int because that is what
// static type of an associated variable tells us.
@@ -219,8 +104,7 @@
TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) {
CompilerState S(thread);
- FlowGraph* flow_graph = MakeDummyGraph(thread);
- FlowGraphBuilderHelper H(flow_graph);
+ FlowGraphBuilderHelper H;
// We are going to build the following graph:
//
@@ -235,12 +119,12 @@
// Return(v0)
Definition* v0;
- auto b1 = flow_graph->graph_entry()->normal_entry();
+ auto b1 = H.flow_graph()->graph_entry()->normal_entry();
auto b2 = H.TargetEntry();
auto b3 = H.TargetEntry();
{
- BlockBuilder builder(flow_graph, b1);
+ BlockBuilder builder(H.flow_graph(), b1);
v0 = builder.AddParameter(0, /*with_frame=*/true);
auto load_cid = builder.AddDefinition(new LoadClassIdInstr(new Value(v0)));
builder.AddBranch(
@@ -252,18 +136,18 @@
}
{
- BlockBuilder builder(flow_graph, b2);
+ BlockBuilder builder(H.flow_graph(), b2);
builder.AddReturn(new Value(v0));
}
{
- BlockBuilder builder(flow_graph, b3);
+ BlockBuilder builder(H.flow_graph(), b3);
builder.AddReturn(new Value(v0));
}
H.FinishGraph();
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
// There should be no information available about the incoming type of
// the parameter either on entry or in B3.
@@ -304,8 +188,7 @@
/*is_reflectable=*/true, object_class, Object::dynamic_type(),
TokenPosition::kNoSource, TokenPosition::kNoSource));
- FlowGraph* flow_graph = MakeDummyGraph(thread);
- FlowGraphBuilderHelper H(flow_graph);
+ FlowGraphBuilderHelper H;
// We are going to build the following graph:
//
@@ -326,13 +209,13 @@
Definition* v0;
Definition* v2;
PhiInstr* v3;
- auto b1 = flow_graph->graph_entry()->normal_entry();
+ auto b1 = H.flow_graph()->graph_entry()->normal_entry();
auto b2 = H.TargetEntry();
auto b3 = H.TargetEntry();
auto b4 = H.JoinEntry();
{
- BlockBuilder builder(flow_graph, b1);
+ BlockBuilder builder(H.flow_graph(), b1);
v0 = builder.AddParameter(0, /*with_frame=*/true);
builder.AddBranch(new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT,
@@ -342,7 +225,7 @@
}
{
- BlockBuilder builder(flow_graph, b2);
+ BlockBuilder builder(H.flow_graph(), b2);
v2 = builder.AddDefinition(
new StaticCallInstr(TokenPosition::kNoSource, target_func,
/*type_args_len=*/0,
@@ -353,30 +236,30 @@
}
{
- BlockBuilder builder(flow_graph, b3);
+ BlockBuilder builder(H.flow_graph(), b3);
builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
}
{
- BlockBuilder builder(flow_graph, b4);
+ BlockBuilder builder(H.flow_graph(), b4);
v3 = H.Phi(b4, {{b2, v2}, {b3, H.IntConstant(0)}});
builder.AddPhi(v3);
builder.AddReturn(new Value(v3));
}
H.FinishGraph();
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
EXPECT_PROPERTY(v2->Type(), it.IsNullableInt());
EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());
- auto v4 = new LoadStaticFieldInstr(new Value(flow_graph->GetConstant(field)),
- TokenPosition::kNoSource);
- flow_graph->InsertBefore(v2, v4, nullptr, FlowGraph::kValue);
+ auto v4 = new LoadStaticFieldInstr(
+ new Value(H.flow_graph()->GetConstant(field)), TokenPosition::kNoSource);
+ H.flow_graph()->InsertBefore(v2, v4, nullptr, FlowGraph::kValue);
v2->ReplaceUsesWith(v4);
v2->RemoveFromGraph();
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());
}
@@ -385,9 +268,7 @@
// as reaching types after inference.
ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) {
CompilerState S(thread);
-
- FlowGraph* flow_graph = MakeDummyGraph(thread);
- FlowGraphBuilderHelper H(flow_graph);
+ FlowGraphBuilderHelper H;
// We are going to build the following graph:
//
@@ -416,7 +297,7 @@
Definition* v0;
PhiInstr* v3;
PhiInstr* v5;
- auto b1 = flow_graph->graph_entry()->normal_entry();
+ auto b1 = H.flow_graph()->graph_entry()->normal_entry();
auto b2 = H.TargetEntry();
auto b3 = H.TargetEntry();
auto b4 = H.TargetEntry();
@@ -425,7 +306,7 @@
auto b7 = H.JoinEntry();
{
- BlockBuilder builder(flow_graph, b1);
+ BlockBuilder builder(H.flow_graph(), b1);
v0 = builder.AddParameter(0, /*with_frame=*/true);
builder.AddBranch(new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT,
@@ -435,7 +316,7 @@
}
{
- BlockBuilder builder(flow_graph, b2);
+ BlockBuilder builder(H.flow_graph(), b2);
builder.AddBranch(new StrictCompareInstr(
TokenPosition::kNoSource, Token::kEQ_STRICT,
new Value(v0), new Value(H.IntConstant(2)),
@@ -444,29 +325,29 @@
}
{
- BlockBuilder builder(flow_graph, b3);
+ BlockBuilder builder(H.flow_graph(), b3);
builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
}
{
- BlockBuilder builder(flow_graph, b4);
+ BlockBuilder builder(H.flow_graph(), b4);
builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
}
{
- BlockBuilder builder(flow_graph, b5);
+ BlockBuilder builder(H.flow_graph(), b5);
v3 = H.Phi(b5, {{b3, H.IntConstant(42)}, {b4, H.IntConstant(24)}});
builder.AddPhi(v3);
builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
}
{
- BlockBuilder builder(flow_graph, b6);
+ BlockBuilder builder(H.flow_graph(), b6);
builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
}
{
- BlockBuilder builder(flow_graph, b7);
+ BlockBuilder builder(H.flow_graph(), b7);
v5 = H.Phi(b7, {{b5, v3}, {b6, H.DoubleConstant(1.0)}});
builder.AddPhi(v5);
builder.AddInstruction(new ReturnInstr(TokenPosition::kNoSource,
@@ -475,7 +356,7 @@
H.FinishGraph();
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
// We expect that v3 has an integer type, and v5 is either T{Object} or
// T{num}.
@@ -492,7 +373,7 @@
auto unbox =
new UnboxInt64Instr(input->CopyWithType(), S.GetNextDeoptId(),
Instruction::kNotSpeculative);
- flow_graph->InsertBefore(
+ H.flow_graph()->InsertBefore(
v3->block()->PredecessorAt(i)->last_instruction(), unbox, nullptr,
FlowGraph::kValue);
input->BindTo(unbox);
@@ -500,12 +381,12 @@
auto box = new BoxInt64Instr(new Value(v3));
v3->ReplaceUsesWith(box);
- flow_graph->InsertBefore(b4->last_instruction(), box, nullptr,
- FlowGraph::kValue);
+ H.flow_graph()->InsertBefore(b4->last_instruction(), box, nullptr,
+ FlowGraph::kValue);
}
// Run type propagation again.
- FlowGraphTypePropagator::Propagate(flow_graph);
+ FlowGraphTypePropagator::Propagate(H.flow_graph());
// If CompileType of v3 would be cached as a reaching type at its use in
// v5 then we will be incorrect type propagation results.
diff --git a/runtime/vm/compiler/ffi.cc b/runtime/vm/compiler/ffi.cc
index d63e1f7..8d8d136 100644
--- a/runtime/vm/compiler/ffi.cc
+++ b/runtime/vm/compiler/ffi.cc
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/compiler/ffi.h"
+#include <algorithm>
+#include "platform/globals.h"
#include "vm/compiler/runtime_api.h"
namespace dart {
@@ -11,8 +13,7 @@
namespace ffi {
-#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \
- defined(TARGET_ARCH_IA32)
+#if !defined(TARGET_ARCH_DBC)
static const size_t kSizeUnknown = 0;
@@ -106,7 +107,13 @@
for (intptr_t i = 0; i < num_arguments; i++) {
AbstractType& arg_type =
AbstractType::Handle(signature.ParameterTypeAt(i + 1));
- result->Add(TypeRepresentation(arg_type));
+ Representation rep = TypeRepresentation(arg_type);
+ if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
+ rep = kUnboxedInt32;
+ } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
+ rep = kUnboxedInt64;
+ }
+ result->Add(rep);
}
return result;
}
@@ -118,51 +125,100 @@
public:
Location AllocateArgument(Representation rep) {
switch (rep) {
+ case kUnboxedFloat:
+ case kUnboxedDouble: {
+ Location result = AllocateFpuRegister();
+ if (!result.IsUnallocated()) return result;
+ break;
+ }
case kUnboxedInt64:
case kUnboxedUint32:
- case kUnboxedInt32:
- if (rep == kUnboxedInt64) {
- ASSERT(compiler::target::kWordSize == 8);
- }
- if (cpu_regs_used < CallingConventions::kNumArgRegs) {
- Location result = Location::RegisterLocation(
- CallingConventions::ArgumentRegisters[cpu_regs_used]);
- cpu_regs_used++;
- if (CallingConventions::kArgumentIntRegXorFpuReg) {
- fpu_regs_used++;
- }
- return result;
- }
+ case kUnboxedInt32: {
+ Location result =
+ rep == kUnboxedInt64 && compiler::target::kWordSize == 4
+ ? AllocateAlignedRegisterPair()
+ : AllocateCpuRegister();
+ if (!result.IsUnallocated()) return result;
break;
- case kUnboxedFloat:
- case kUnboxedDouble:
- if (fpu_regs_used < CallingConventions::kNumFpuArgRegs) {
- Location result = Location::FpuRegisterLocation(
- CallingConventions::FpuArgumentRegisters[fpu_regs_used]);
- fpu_regs_used++;
- if (CallingConventions::kArgumentIntRegXorFpuReg) {
- cpu_regs_used++;
- }
- return result;
- }
- break;
+ }
default:
UNREACHABLE();
}
// Argument must be spilled.
- const intptr_t stack_slots_needed =
- rep == kUnboxedDouble || rep == kUnboxedInt64
- ? 8 / compiler::target::kWordSize
- : 1;
- Location result =
- stack_slots_needed == 1
- ? Location::StackSlot(stack_height_in_slots, SPREG)
- : Location::DoubleStackSlot(stack_height_in_slots, SPREG);
- stack_height_in_slots += stack_slots_needed;
+ if ((rep == kUnboxedInt64 || rep == kUnboxedDouble) &&
+ compiler::target::kWordSize == 4) {
+ return AllocateAlignedStackSlots(rep);
+ } else {
+ return AllocateStackSlot();
+ }
+ }
+
+ private:
+ Location AllocateStackSlot() {
+ return Location::StackSlot(stack_height_in_slots++, SPREG);
+ }
+
+ // Allocates a pair of stack slots where the first stack slot is aligned to an
+ // 8-byte boundary, if necessary.
+ Location AllocateAlignedStackSlots(Representation rep) {
+ if (CallingConventions::kAlignArguments &&
+ compiler::target::kWordSize == 4) {
+ stack_height_in_slots += stack_height_in_slots % 2;
+ }
+
+ Location result;
+ if (rep == kUnboxedDouble) {
+ result = Location::DoubleStackSlot(stack_height_in_slots, SPREG);
+ stack_height_in_slots += 2;
+ } else {
+ const Location low = AllocateStackSlot();
+ const Location high = AllocateStackSlot();
+ result = Location::Pair(low, high);
+ }
return result;
}
+ Location AllocateFpuRegister() {
+ if (fpu_regs_used == CallingConventions::kNumFpuArgRegs) {
+ return Location::RequiresFpuRegister();
+ }
+
+ const Location result = Location::FpuRegisterLocation(
+ CallingConventions::FpuArgumentRegisters[fpu_regs_used]);
+ fpu_regs_used++;
+ if (CallingConventions::kArgumentIntRegXorFpuReg) {
+ cpu_regs_used++;
+ }
+ return result;
+ }
+
+ Location AllocateCpuRegister() {
+ if (cpu_regs_used == CallingConventions::kNumArgRegs) {
+ return Location::RequiresRegister();
+ }
+
+ const Location result = Location::RegisterLocation(
+ CallingConventions::ArgumentRegisters[cpu_regs_used]);
+ cpu_regs_used++;
+ if (CallingConventions::kArgumentIntRegXorFpuReg) {
+ fpu_regs_used++;
+ }
+ return result;
+ }
+
+ // Allocates a pair of registers where the first register index is even, if
+ // necessary.
+ Location AllocateAlignedRegisterPair() {
+ if (CallingConventions::kAlignArguments) {
+ cpu_regs_used += cpu_regs_used % 2;
+ }
+ if (cpu_regs_used > CallingConventions::kNumArgRegs - 2) {
+ return Location::Any();
+ }
+ return Location::Pair(AllocateCpuRegister(), AllocateCpuRegister());
+ }
+
intptr_t cpu_regs_used = 0;
intptr_t fpu_regs_used = 0;
intptr_t stack_height_in_slots = 0;
@@ -179,25 +235,33 @@
ArgumentFrameState frame_state;
for (intptr_t i = 0; i < num_arguments; i++) {
Representation rep = arg_reps[i];
- if (rep == kUnboxedInt64 && compiler::target::kWordSize < 8) {
- Location low_bits_loc = frame_state.AllocateArgument(kUnboxedInt32);
- Location high_bits_loc = frame_state.AllocateArgument(kUnboxedInt32);
- ASSERT(low_bits_loc.IsStackSlot() == high_bits_loc.IsStackSlot());
- result->Add(Location::Pair(low_bits_loc, high_bits_loc));
- } else {
- result->Add(frame_state.AllocateArgument(rep));
- }
+ result->Add(frame_state.AllocateArgument(rep));
}
return result;
}
Representation ResultRepresentation(const Function& signature) {
AbstractType& arg_type = AbstractType::Handle(signature.result_type());
- return TypeRepresentation(arg_type);
+ Representation rep = TypeRepresentation(arg_type);
+ if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
+ rep = kUnboxedInt32;
+ } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
+ rep = kUnboxedInt64;
+ }
+ return rep;
}
Location ResultLocation(Representation result_rep) {
switch (result_rep) {
+ case kUnboxedFloat:
+ case kUnboxedDouble:
+#if defined(TARGET_ARCH_IA32)
+ // The result is returned in ST0, but we don't allocate ST registers, so
+ // the FFI trampoline will move it to XMM0.
+ return Location::FpuRegisterLocation(XMM0);
+#else
+ return Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg);
+#endif
case kUnboxedInt32:
case kUnboxedUint32:
return Location::RegisterLocation(CallingConventions::kReturnReg);
@@ -209,36 +273,30 @@
} else {
return Location::RegisterLocation(CallingConventions::kReturnReg);
}
- case kUnboxedFloat:
- case kUnboxedDouble:
-#if defined(TARGET_ARCH_IA32)
- // The result is returned in ST0, but we don't allocate ST registers, so
- // the FFI trampoline will move it to XMM0.
- return Location::FpuRegisterLocation(XMM0);
-#else
- return Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg);
-#endif
default:
UNREACHABLE();
}
}
+// Accounts for alignment, where some stack slots are used as padding.
intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
intptr_t num_arguments = locations.length();
- intptr_t num_stack_slots = 0;
+ intptr_t max_height_in_slots = 0;
for (intptr_t i = 0; i < num_arguments; i++) {
+ intptr_t height = 0;
if (locations.At(i).IsStackSlot()) {
- num_stack_slots++;
+ height = locations.At(i).stack_index() + 1;
} else if (locations.At(i).IsDoubleStackSlot()) {
- num_stack_slots += 8 / compiler::target::kWordSize;
+ height = locations.At(i).stack_index() + 8 / compiler::target::kWordSize;
} else if (locations.At(i).IsPairLocation()) {
- num_stack_slots +=
- locations.At(i).AsPairLocation()->At(0).IsStackSlot() ? 1 : 0;
- num_stack_slots +=
- locations.At(i).AsPairLocation()->At(1).IsStackSlot() ? 1 : 0;
+ const Location first = locations.At(i).AsPairLocation()->At(0);
+ const Location second = locations.At(i).AsPairLocation()->At(1);
+ height = std::max(first.IsStackSlot() ? first.stack_index() + 1 : 0,
+ second.IsStackSlot() ? second.stack_index() + 1 : 0);
}
+ max_height_in_slots = std::max(height, max_height_in_slots);
}
- return num_stack_slots;
+ return max_height_in_slots;
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -249,7 +307,7 @@
UNREACHABLE();
}
-#endif // defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
+#endif // !defined(TARGET_ARCH_DBC)
} // namespace ffi
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 0b6878c..07ac0b0 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -121,6 +121,17 @@
return instructions;
}
+Fragment BaseFlowGraphBuilder::StrictCompare(TokenPosition position,
+ Token::Kind kind,
+ bool number_check /* = false */) {
+ Value* right = Pop();
+ Value* left = Pop();
+ StrictCompareInstr* compare = new (Z) StrictCompareInstr(
+ position, kind, left, right, number_check, GetNextDeoptId());
+ Push(compare);
+ return Fragment(compare);
+}
+
Fragment BaseFlowGraphBuilder::StrictCompare(Token::Kind kind,
bool number_check /* = false */) {
Value* right = Pop();
@@ -190,9 +201,11 @@
}
Fragment BaseFlowGraphBuilder::CheckStackOverflow(TokenPosition position,
+ intptr_t stack_depth,
intptr_t loop_depth) {
- return Fragment(
- new (Z) CheckStackOverflowInstr(position, loop_depth, GetNextDeoptId()));
+ return Fragment(new (Z) CheckStackOverflowInstr(
+ position, stack_depth, loop_depth, GetNextDeoptId(),
+ CheckStackOverflowInstr::kOsrAndPreemption));
}
Fragment BaseFlowGraphBuilder::CheckStackOverflowInPrologue(
@@ -200,10 +213,10 @@
if (IsInlining()) {
// If we are inlining don't actually attach the stack check. We must still
// create the stack check in order to allocate a deopt id.
- CheckStackOverflow(position, 0);
+ CheckStackOverflow(position, 0, 0);
return Fragment();
}
- return CheckStackOverflow(position, 0);
+ return CheckStackOverflow(position, 0, 0);
}
Fragment BaseFlowGraphBuilder::Constant(const Object& value) {
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 5eb086b..a800743 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -205,6 +205,9 @@
JoinEntryInstr* BuildJoinEntry();
JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
+ Fragment StrictCompare(TokenPosition position,
+ Token::Kind kind,
+ bool number_check = false);
Fragment StrictCompare(Token::Kind kind, bool number_check = false);
Fragment Goto(JoinEntryInstr* destination);
Fragment IntConstant(int64_t value);
@@ -226,7 +229,9 @@
Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry,
TargetEntryInstr** otherwise_entry);
Fragment Return(TokenPosition position);
- Fragment CheckStackOverflow(TokenPosition position, intptr_t loop_depth);
+ Fragment CheckStackOverflow(TokenPosition position,
+ intptr_t stack_depth,
+ intptr_t loop_depth);
Fragment CheckStackOverflowInPrologue(TokenPosition position);
Fragment ThrowException(TokenPosition position);
Fragment TailCall(const Code& code);
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 03c8fc5..19b94e1 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -666,11 +666,8 @@
ASSERT(IsStackEmpty());
code_ += B->CheckStackOverflowInPrologue(position_);
} else {
- // Avoid OSR points inside block-expressions with pending stack slots.
- // TODO(ajcbik): make sure OSR works for such cases too.
- if (IsStackEmpty()) {
- code_ += B->CheckStackOverflow(position_, loop_depth);
- }
+ const intptr_t stack_depth = B->GetStackDepth();
+ code_ += B->CheckStackOverflow(position_, stack_depth, loop_depth);
}
}
@@ -783,7 +780,8 @@
B->Push(call);
}
-void BytecodeFlowGraphBuilder::BuildInterfaceCall() {
+void BytecodeFlowGraphBuilder::BuildInterfaceCallCommon(
+ bool is_unchecked_call) {
if (is_generating_interpreter()) {
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
}
@@ -821,10 +819,22 @@
// TODO(alexmarkov): add type info - call->SetResultType()
+ if (is_unchecked_call) {
+ call->set_entry_kind(Code::EntryKind::kUnchecked);
+ }
+
code_ <<= call;
B->Push(call);
}
+void BytecodeFlowGraphBuilder::BuildInterfaceCall() {
+ BuildInterfaceCallCommon(/*is_unchecked_call=*/false);
+}
+
+void BytecodeFlowGraphBuilder::BuildUncheckedInterfaceCall() {
+ BuildInterfaceCallCommon(/*is_unchecked_call=*/true);
+}
+
void BytecodeFlowGraphBuilder::BuildDynamicCall() {
if (is_generating_interpreter()) {
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
@@ -1551,9 +1561,11 @@
code_ += B->LoadLocal(scratch_var_);
}
-void BytecodeFlowGraphBuilder::BuildIntOp(const String& name,
- Token::Kind token_kind,
- int num_args) {
+void BytecodeFlowGraphBuilder::BuildPrimitiveOp(
+ const String& name,
+ Token::Kind token_kind,
+ const AbstractType& static_receiver_type,
+ int num_args) {
ASSERT((num_args == 1) || (num_args == 2));
ASSERT(MethodTokenRecognizer::RecognizeTokenKind(name) == token_kind);
@@ -1564,10 +1576,26 @@
position_, name, token_kind, arguments, 0, Array::null_array(), num_args,
*ic_data_array_, B->GetNextDeoptId());
+ call->set_receivers_static_type(&static_receiver_type);
+
code_ <<= call;
B->Push(call);
}
+void BytecodeFlowGraphBuilder::BuildIntOp(const String& name,
+ Token::Kind token_kind,
+ int num_args) {
+ BuildPrimitiveOp(name, token_kind,
+ AbstractType::ZoneHandle(Z, Type::IntType()), num_args);
+}
+
+void BytecodeFlowGraphBuilder::BuildDoubleOp(const String& name,
+ Token::Kind token_kind,
+ int num_args) {
+ BuildPrimitiveOp(name, token_kind,
+ AbstractType::ZoneHandle(Z, Type::Double()), num_args);
+}
+
void BytecodeFlowGraphBuilder::BuildNegateInt() {
BuildIntOp(Symbols::UnaryMinus(), Token::kNEGATE, 1);
}
@@ -1632,6 +1660,46 @@
BuildIntOp(Symbols::LessEqualOperator(), Token::kLTE, 2);
}
+void BytecodeFlowGraphBuilder::BuildNegateDouble() {
+ BuildDoubleOp(Symbols::UnaryMinus(), Token::kNEGATE, 1);
+}
+
+void BytecodeFlowGraphBuilder::BuildAddDouble() {
+ BuildDoubleOp(Symbols::Plus(), Token::kADD, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildSubDouble() {
+ BuildDoubleOp(Symbols::Minus(), Token::kSUB, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildMulDouble() {
+ BuildDoubleOp(Symbols::Star(), Token::kMUL, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildDivDouble() {
+ BuildDoubleOp(Symbols::Slash(), Token::kDIV, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildCompareDoubleEq() {
+ BuildDoubleOp(Symbols::EqualOperator(), Token::kEQ, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildCompareDoubleGt() {
+ BuildDoubleOp(Symbols::RAngleBracket(), Token::kGT, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildCompareDoubleLt() {
+ BuildDoubleOp(Symbols::LAngleBracket(), Token::kLT, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildCompareDoubleGe() {
+ BuildDoubleOp(Symbols::GreaterEqualOperator(), Token::kGTE, 2);
+}
+
+void BytecodeFlowGraphBuilder::BuildCompareDoubleLe() {
+ BuildDoubleOp(Symbols::LessEqualOperator(), Token::kLTE, 2);
+}
+
void BytecodeFlowGraphBuilder::BuildAllocateClosure() {
if (is_generating_interpreter()) {
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
@@ -1740,6 +1808,13 @@
if (KernelBytecode::IsJumpOpcode(instr)) {
const intptr_t target = pc + KernelBytecode::DecodeT(instr);
EnsureControlFlowJoin(descriptors, target);
+ } else if ((KernelBytecode::DecodeOpcode(instr) ==
+ KernelBytecode::kCheckStack) &&
+ (KernelBytecode::DecodeA(instr) != 0)) {
+ // (dartbug.com/36590) BlockEntryInstr::FindOsrEntryAndRelink assumes
+ // that CheckStackOverflow instruction is at the beginning of a join
+ // block.
+ EnsureControlFlowJoin(descriptors, pc);
}
if ((scratch_var_ == nullptr) && RequiresScratchVar(instr)) {
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 35f1cc5..c085374 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -132,7 +132,13 @@
void PropagateStackState(intptr_t target_pc);
void DropUnusedValuesFromStack();
void BuildJumpIfStrictCompare(Token::Kind cmp_kind);
+ void BuildPrimitiveOp(const String& name,
+ Token::Kind token_kind,
+ const AbstractType& static_receiver_type,
+ int num_args);
void BuildIntOp(const String& name, Token::Kind token_kind, int num_args);
+ void BuildDoubleOp(const String& name, Token::Kind token_kind, int num_args);
+ void BuildInterfaceCallCommon(bool is_unchecked_call);
void BuildInstruction(KernelBytecode::Opcode opcode);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 6e53e13..c2a6590 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -58,6 +58,9 @@
case RawFunction::kImplicitSetter:
function.AttachBytecode(Object::implicit_setter_bytecode());
return;
+ case RawFunction::kMethodExtractor:
+ function.AttachBytecode(Object::method_extractor_bytecode());
+ return;
default: {
}
}
@@ -95,11 +98,12 @@
ASSERT(function.is_declared_in_bytecode());
// No parsing is needed if function has bytecode attached.
- // With one exception: implicit getters and setters have artificial
- // bytecodes, but they are still handled by shared flow graph builder
- // which requires scopes/parsing.
- if (function.HasBytecode() && !function.IsImplicitGetterFunction() &&
- !function.IsImplicitSetterFunction()) {
+ // With one exception: implicit functions with artificial are still handled
+ // by shared flow graph builder which requires scopes/parsing.
+ if (function.HasBytecode() &&
+ (function.kind() != RawFunction::kImplicitGetter) &&
+ (function.kind() != RawFunction::kImplicitSetter) &&
+ (function.kind() != RawFunction::kMethodExtractor)) {
return;
}
@@ -338,7 +342,7 @@
Object& parent = Object::Handle(Z, ReadObject());
if (!parent.IsFunction()) {
ASSERT(parent.IsField());
- ASSERT(function.kind() == RawFunction::kImplicitStaticFinalGetter);
+ ASSERT(function.kind() == RawFunction::kStaticFieldInitializer);
// Closure in a static field initializer, so use current function as parent.
parent = function.raw();
}
@@ -1896,13 +1900,19 @@
break;
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
- case RawFunction::kImplicitStaticFinalGetter:
- if (IsBytecodeFieldInitializer(function, Z)) {
+ BytecodeScopeBuilder(parsed_function).BuildScopes();
+ break;
+ case RawFunction::kImplicitStaticFinalGetter: {
+ if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
ReadCode(function, function.bytecode_offset());
} else {
BytecodeScopeBuilder(parsed_function).BuildScopes();
}
break;
+ }
+ case RawFunction::kStaticFieldInitializer:
+ ReadCode(function, function.bytecode_offset());
+ break;
case RawFunction::kMethodExtractor:
BytecodeScopeBuilder(parsed_function).BuildScopes();
break;
@@ -2222,16 +2232,13 @@
annotation_field.bytecode_offset());
}
-bool IsBytecodeFieldInitializer(const Function& function, Zone* zone) {
- if (IsFieldInitializer(function, zone)) {
- return true;
- }
- if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
- const auto& field = Field::Handle(zone, function.accessor_field());
- return field.is_declared_in_bytecode() && field.is_const() &&
- field.has_initializer();
- }
- return false;
+bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
+ Zone* zone) {
+ ASSERT(function.kind() == RawFunction::kImplicitStaticFinalGetter);
+
+ const auto& field = Field::Handle(zone, function.accessor_field());
+ return field.is_declared_in_bytecode() && field.is_const() &&
+ field.has_initializer();
}
} // namespace kernel
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index c8859cd..bb858c3 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -303,10 +303,8 @@
intptr_t cur_token_pos_;
};
-// Returns [true] iff [function] body is a field initializer in bytecode.
-// This is [true] for ordinary static field initializers and getters of
-// const static fields.
-bool IsBytecodeFieldInitializer(const Function& function, Zone* zone);
+bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
+ Zone* zone);
} // namespace kernel
} // namespace dart
diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
index 5ff308b..5143ae9 100644
--- a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc
@@ -4,7 +4,7 @@
#include "vm/compiler/frontend/bytecode_scope_builder.h"
-#include "vm/compiler/frontend/bytecode_reader.h" // For IsBytecodeFieldInitializer.
+#include "vm/compiler/frontend/bytecode_reader.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -107,7 +107,7 @@
break;
}
case RawFunction::kImplicitStaticFinalGetter:
- ASSERT(!IsBytecodeFieldInitializer(function, Z));
+ ASSERT(!IsStaticFieldGetterGeneratedAsInitializer(function, Z));
break;
case RawFunction::kDynamicInvocationForwarder: {
// Create [this] variable.
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index 2aba84f..182e47d 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -101,7 +101,11 @@
// These only occur inside unevaluated constants, so if we decide to
// remove support for late evaluation of environment constants from
// dill files in the VM, an implementation here will not be necessary.
- UNIMPLEMENTED();
+ H.ReportError(
+ script_, TokenPosition::kNoSource,
+ "Unexpected unevaluated constant, All constant expressions"
+ " are expected to be evaluated at this point %s (%d)",
+ Reader::TagName(tag), tag);
break;
case kSymbolLiteral:
EvaluateSymbolLiteral();
@@ -118,7 +122,10 @@
case kConstSetLiteral:
// Set literals are currently desugared in the frontend and will not
// reach the VM. See http://dartbug.com/35124 for discussion.
- UNREACHABLE();
+ H.ReportError(script_, TokenPosition::kNoSource,
+ "Unexpected set literal constant, this constant"
+ " is expected to be evaluated at this point %s (%d)",
+ Reader::TagName(tag), tag);
break;
case kConstMapLiteral:
EvaluateMapLiteralInternal();
@@ -161,7 +168,10 @@
EvaluateNullLiteral();
break;
case kConstantExpression:
- EvaluateConstantExpression();
+ EvaluateConstantExpression(tag);
+ break;
+ case kDeprecated_ConstantExpression:
+ EvaluateConstantExpression(tag);
break;
default:
H.ReportError(
@@ -389,7 +399,6 @@
field.SetStaticValue(Object::null_instance());
H.ReportError(Error::Cast(value), script_, position,
"Not a constant expression.");
- UNREACHABLE();
}
Thread* thread = H.thread();
const Error& error =
@@ -397,7 +406,6 @@
if (!error.IsNull()) {
field.SetStaticValue(Object::null_instance());
H.ReportError(error, script_, position, "Not a constant expression.");
- UNREACHABLE();
}
ASSERT(value.IsNull() || value.IsInstance());
field.SetStaticValue(value.IsNull() ? Instance::null_instance()
@@ -860,12 +868,16 @@
result_ = Instance::null();
}
-void ConstantEvaluator::EvaluateConstantExpression() {
+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());
}
@@ -1038,7 +1050,8 @@
if (!IsBuildingFlowGraph()) return false;
const Function& function = flow_graph_builder_->parsed_function_->function();
- if (function.kind() == RawFunction::kImplicitStaticFinalGetter &&
+ if ((function.kind() == RawFunction::kImplicitStaticFinalGetter ||
+ function.kind() == RawFunction::kStaticFieldInitializer) &&
!I->CanOptimizeImmediately()) {
// Don't cache constants in initializer expressions. They get
// evaluated only once.
@@ -1070,7 +1083,8 @@
if (!IsBuildingFlowGraph()) return;
const Function& function = flow_graph_builder_->parsed_function_->function();
- if (function.kind() == RawFunction::kImplicitStaticFinalGetter &&
+ if ((function.kind() == RawFunction::kImplicitStaticFinalGetter ||
+ function.kind() == RawFunction::kStaticFieldInitializer) &&
!I->CanOptimizeImmediately()) {
// Don't cache constants in initializer expressions. They get
// evaluated only once.
@@ -1218,7 +1232,10 @@
case kSetConstant:
// Set literals are currently desugared in the frontend and will not
// reach the VM. See http://dartbug.com/35124 for discussion.
- UNREACHABLE();
+ 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();
@@ -1278,6 +1295,7 @@
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_].
@@ -1311,12 +1329,19 @@
}
case kMapConstant:
// Note: This is already lowered to InstanceConstant/ListConstant.
- UNREACHABLE();
+ 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.
- UNREACHABLE();
+ 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();
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.h b/runtime/vm/compiler/frontend/constant_evaluator.h
index f5fe543..0483baa 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.h
+++ b/runtime/vm/compiler/frontend/constant_evaluator.h
@@ -88,7 +88,7 @@
void EvaluateDoubleLiteral();
void EvaluateBoolLiteral(bool value);
void EvaluateNullLiteral();
- void EvaluateConstantExpression();
+ void EvaluateConstantExpression(Tag tag);
void EvaluateGetStringLength(intptr_t expression_offset,
TokenPosition position);
@@ -156,6 +156,8 @@
const Array& ReadConstantTable();
private:
+ const Script& script() const { return helper_.script_; }
+
void InstantiateTypeArguments(const Class& receiver_class,
TypeArguments* type_arguments);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 6f326e7..935ae39 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -9,7 +9,6 @@
#include "vm/compiler/frontend/flow_graph_builder.h" // For dart::FlowGraphBuilder::SimpleInstanceOfType.
#include "vm/compiler/frontend/prologue_builder.h"
#include "vm/compiler/jit/compiler.h"
-#include "vm/kernel.h" // For IsFieldInitializer.
#include "vm/object_store.h"
#include "vm/stack_frame.h"
@@ -936,11 +935,13 @@
return B->BuildGraphOfImplicitClosureFunction(function);
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
- case RawFunction::kImplicitStaticFinalGetter:
- if (!IsBytecodeFieldInitializer(function, Z)) {
- return B->BuildGraphOfFieldAccessor(function);
+ return B->BuildGraphOfFieldAccessor(function);
+ case RawFunction::kImplicitStaticFinalGetter: {
+ if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) {
+ break;
}
- break;
+ return B->BuildGraphOfFieldAccessor(function);
+ }
case RawFunction::kDynamicInvocationForwarder:
return B->BuildGraphOfDynamicInvocationForwarder(function);
case RawFunction::kMethodExtractor:
@@ -966,7 +967,8 @@
}
if (function.HasBytecode() &&
(function.kind() != RawFunction::kImplicitGetter) &&
- (function.kind() != RawFunction::kImplicitSetter)) {
+ (function.kind() != RawFunction::kImplicitSetter) &&
+ (function.kind() != RawFunction::kMethodExtractor)) {
BytecodeFlowGraphBuilder bytecode_compiler(
flow_graph_builder_, parsed_function(),
&(flow_graph_builder_->ic_data_array_));
@@ -991,15 +993,14 @@
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitStaticFinalGetter:
case RawFunction::kImplicitSetter: {
- if (IsFieldInitializer(function, Z)) {
- return BuildGraphOfFieldInitializer();
- }
const Field& field = Field::Handle(Z, function.accessor_field());
if (field.is_const() && field.IsUninitialized()) {
EvaluateConstFieldValue(field);
}
return B->BuildGraphOfFieldAccessor(function);
}
+ case RawFunction::kStaticFieldInitializer:
+ return BuildGraphOfFieldInitializer();
case RawFunction::kDynamicInvocationForwarder:
return B->BuildGraphOfDynamicInvocationForwarder(function);
case RawFunction::kMethodExtractor:
@@ -1054,6 +1055,7 @@
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitStaticFinalGetter:
case RawFunction::kImplicitSetter:
+ case RawFunction::kStaticFieldInitializer:
case RawFunction::kMethodExtractor:
case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kInvokeFieldDispatcher:
@@ -1217,7 +1219,9 @@
case kNullLiteral:
return BuildNullLiteral(position);
case kConstantExpression:
- return BuildConstantExpression(position);
+ return BuildConstantExpression(position, tag);
+ case kDeprecated_ConstantExpression:
+ return BuildConstantExpression(position, tag);
case kInstantiation:
return BuildPartialTearoffInstantiation(position);
case kLoadLibrary:
@@ -1614,9 +1618,10 @@
type_arguments);
}
-Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind,
+Fragment StreamingFlowGraphBuilder::StrictCompare(TokenPosition position,
+ Token::Kind kind,
bool number_check) {
- return flow_graph_builder_->StrictCompare(kind, number_check);
+ return flow_graph_builder_->StrictCompare(position, kind, number_check);
}
Fragment StreamingFlowGraphBuilder::AllocateObject(TokenPosition position,
@@ -1679,7 +1684,8 @@
Fragment StreamingFlowGraphBuilder::CheckStackOverflow(TokenPosition position) {
return flow_graph_builder_->CheckStackOverflow(
- position, flow_graph_builder_->loop_depth_);
+ position, flow_graph_builder_->GetStackDepth(),
+ flow_graph_builder_->loop_depth_);
}
Fragment StreamingFlowGraphBuilder::CloneContext(
@@ -2610,7 +2616,6 @@
bool is_unchecked_closure_call = false;
bool is_unchecked_call = result_type.IsSkipCheck();
-#ifndef TARGET_ARCH_DBC
if (call_site_attributes.receiver_type != nullptr) {
if (call_site_attributes.receiver_type->IsFunctionType()) {
AlternativeReadingScope alt(&reader_);
@@ -2623,7 +2628,6 @@
is_unchecked_call = true;
}
}
-#endif
Fragment instructions;
@@ -2677,7 +2681,7 @@
Token::Kind strict_cmp_kind =
token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
return instructions +
- StrictCompare(strict_cmp_kind, /*number_check = */ true);
+ StrictCompare(position, strict_cmp_kind, /*number_check = */ true);
}
LocalVariable* receiver_temp = NULL;
@@ -2851,7 +2855,7 @@
Token::Kind strict_cmp_kind =
token_kind == Token::kEQ ? Token::kEQ_STRICT : Token::kNE_STRICT;
return instructions +
- StrictCompare(strict_cmp_kind, /*number_check = */ true);
+ StrictCompare(position, strict_cmp_kind, /*number_check = */ true);
}
instructions += PushArgument(); // push receiver as argument.
@@ -3118,7 +3122,8 @@
// there.
if (special_case_identical) {
ASSERT(argument_count == 2);
- instructions += StrictCompare(Token::kEQ_STRICT, /*number_check=*/true);
+ instructions +=
+ StrictCompare(position, Token::kEQ_STRICT, /*number_check=*/true);
} else if (special_case_unchecked_cast) {
// Simply do nothing: the result value is already pushed on the stack.
} else {
@@ -3761,8 +3766,14 @@
}
Fragment StreamingFlowGraphBuilder::BuildConstantExpression(
- TokenPosition* position) {
- if (position != NULL) *position = TokenPosition::kNoSource;
+ TokenPosition* position,
+ Tag tag) {
+ TokenPosition p = TokenPosition::kNoSource;
+ if (tag == kConstantExpression) {
+ p = ReadPosition();
+ SkipDartType();
+ }
+ if (position != nullptr) *position = p;
const intptr_t constant_offset = ReadUInt();
KernelConstantsMap constant_map(H.constants().raw());
Fragment result =
@@ -4018,7 +4029,7 @@
Fragment StreamingFlowGraphBuilder::BuildWhileStatement() {
ASSERT(block_expression_depth() == 0); // no while in block-expr
loop_depth_inc();
- const TokenPosition position = ReadPosition(); // read position.
+ const TokenPosition position = ReadPosition(); // read position.
TestFragment condition = TranslateConditionForControl(); // read condition.
const Fragment body = BuildStatement(); // read body
@@ -4031,6 +4042,7 @@
body_entry += Goto(join);
Fragment loop(join);
+ ASSERT(B->GetStackDepth() == 0);
loop += CheckStackOverflow(position);
loop.current->LinkTo(condition.entry);
@@ -4059,6 +4071,7 @@
JoinEntryInstr* join = BuildJoinEntry();
Fragment loop(join);
+ ASSERT(B->GetStackDepth() == 0);
loop += CheckStackOverflow(position);
loop += body;
loop <<= condition.entry;
@@ -4127,11 +4140,7 @@
body += Goto(join);
Fragment loop(join);
-
- // Avoid OSR point inside block-expressions.
- // TODO(ajcbik): make sure OSR works inside BE too
- if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position);
-
+ loop += CheckStackOverflow(position); // may have non-empty stack
if (condition.entry != nullptr) {
loop <<= condition.entry;
} else {
@@ -4158,7 +4167,7 @@
intptr_t offset = ReaderOffset() - 1; // Include the tag.
const TokenPosition position = ReadPosition(); // read position.
- TokenPosition body_position = ReadPosition(); // read body position.
+ TokenPosition body_position = ReadPosition(); // read body position.
intptr_t variable_kernel_position = ReaderOffset() + data_program_offset_;
SkipVariableDeclaration(); // read variable.
@@ -4204,11 +4213,7 @@
body += Goto(join);
Fragment loop(join);
-
- // Avoid OSR point inside block-expressions.
- // TODO(ajcbik): make sure OSR works inside BE too
- if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position);
-
+ loop += CheckStackOverflow(position); // may have non-empty stack
loop += condition;
} else {
instructions += condition;
@@ -4451,7 +4456,7 @@
}
Fragment StreamingFlowGraphBuilder::BuildIfStatement() {
- ReadPosition(); // read position.
+ ReadPosition(); // read position.
TestFragment condition = TranslateConditionForControl();
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index ee76b40..edf29ea 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -202,7 +202,9 @@
Fragment BooleanNegate();
Fragment TranslateInstantiatedTypeArguments(
const TypeArguments& type_arguments);
- Fragment StrictCompare(Token::Kind kind, bool number_check = false);
+ Fragment StrictCompare(TokenPosition position,
+ Token::Kind kind,
+ bool number_check = false);
Fragment AllocateObject(TokenPosition position,
const Class& klass,
intptr_t argument_count);
@@ -321,7 +323,7 @@
Fragment BuildBoolLiteral(bool value, TokenPosition* position);
Fragment BuildNullLiteral(TokenPosition* position);
Fragment BuildFutureNullValue(TokenPosition* position);
- Fragment BuildConstantExpression(TokenPosition* position);
+ Fragment BuildConstantExpression(TokenPosition* position, Tag tag);
Fragment BuildPartialTearoffInstantiation(TokenPosition* position);
Fragment BuildExpressionStatement();
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index be15d45..848365d 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -549,6 +549,11 @@
case kNullLiteral:
return;
case kConstantExpression:
+ ReadPosition();
+ SkipDartType();
+ SkipConstantReference();
+ return;
+ case kDeprecated_ConstantExpression:
SkipConstantReference();
return;
case kLoadLibrary:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 713139f..ba7ab1b 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -738,7 +738,7 @@
const MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
bool omit_result_type_check = true;
switch (kind) {
- // On simdbc we fall back to natives.
+// On simdbc we fall back to natives.
#if !defined(TARGET_ARCH_DBC)
case MethodRecognizer::kTypedData_ByteDataView_factory:
body += BuildTypedDataViewFactoryConstructor(function, kByteDataViewCid);
@@ -1142,8 +1142,12 @@
}
Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) {
+#ifdef PRODUCT
+ return Fragment();
+#else
return Fragment(new (Z) DebugStepCheckInstr(
position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId()));
+#endif
}
Fragment FlowGraphBuilder::EvaluateAssertion() {
@@ -2011,7 +2015,12 @@
extra_entry += Drop();
extra_entry += Goto(join_entry);
- join_entry->LinkTo(prologue_start);
+ if (prologue_start != nullptr) {
+ join_entry->LinkTo(prologue_start);
+ } else {
+ // Prologue is empty.
+ shared_prologue_linked_in.current = join_entry;
+ }
TargetEntryInstr *do_checks, *skip_checks;
shared_prologue_linked_in +=
@@ -2486,12 +2495,15 @@
return rest;
}
+Fragment FlowGraphBuilder::BitCast(Representation from, Representation to) {
+ BitCastInstr* instr = new (Z) BitCastInstr(from, to, Pop());
+ Push(instr);
+ return Fragment(instr);
+}
+
FlowGraph* FlowGraphBuilder::BuildGraphOfFfiTrampoline(
const Function& function) {
-#if !defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64) && \
- !defined(TARGET_ARCH_IA32)
- UNREACHABLE();
-#else
+#if !defined(TARGET_ARCH_DBC)
graph_entry_ =
new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
@@ -2531,9 +2543,15 @@
body += LoadAddressFromFfiPointer();
body += UnboxTruncate(kUnboxedFfiIntPtr);
} else {
- Representation rep = arg_reps[pos - 1];
- body += UnboxTruncate(rep);
- body += FfiUnboxedExtend(rep, ffi_type);
+ Representation from_rep = compiler::ffi::TypeRepresentation(ffi_type);
+ body += UnboxTruncate(from_rep);
+
+ Representation to_rep = arg_reps[pos - 1];
+ if (from_rep != to_rep) {
+ body += BitCast(from_rep, to_rep);
+ } else {
+ body += FfiUnboxedExtend(from_rep, ffi_type);
+ }
}
}
@@ -2556,15 +2574,22 @@
body += Drop();
body += NullConstant();
} else {
- Representation rep = compiler::ffi::ResultRepresentation(signature);
- body += FfiUnboxedExtend(rep, ffi_type);
- body += Box(rep);
+ Representation from_rep = compiler::ffi::ResultRepresentation(signature);
+ Representation to_rep = compiler::ffi::TypeRepresentation(ffi_type);
+ if (from_rep != to_rep) {
+ body += BitCast(from_rep, to_rep);
+ } else {
+ body += FfiUnboxedExtend(from_rep, ffi_type);
+ }
+ body += Box(to_rep);
}
body += Return(TokenPosition::kNoSource);
return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
prologue_info);
+#else
+ UNREACHABLE();
#endif
}
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index c7fb8da..0b18641 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -233,6 +233,11 @@
// the pointer.
Fragment FfiPointerFromAddress(const Type& result_type);
+ // Bit-wise cast between representations.
+ // Pops the input and pushes the converted result.
+ // Currently only works with equal sizes and floating point <-> integer.
+ Fragment BitCast(Representation from, Representation to);
+
LocalVariable* LookupVariable(intptr_t kernel_offset);
// Build argument type checks for the current function.
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 971ac05..6f46ea7 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1313,74 +1313,7 @@
helper_->SkipLibraryDependency();
}
if (++next_read_ == field) return;
- FALL_THROUGH;
}
- case kAdditionalExports: {
- intptr_t name_count = helper_->ReadUInt();
- for (intptr_t i = 0; i < name_count; ++i) {
- helper_->SkipCanonicalNameReference();
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kParts: {
- intptr_t part_count = helper_->ReadUInt(); // read list length.
- for (intptr_t i = 0; i < part_count; ++i) {
- helper_->SkipLibraryPart();
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kTypedefs: {
- intptr_t typedef_count = helper_->ReadListLength(); // read list length.
- for (intptr_t i = 0; i < typedef_count; i++) {
- helper_->SkipLibraryTypedef();
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kClasses: {
- class_count_ = helper_->ReadListLength(); // read list length.
- for (intptr_t i = 0; i < class_count_; ++i) {
- ClassHelper class_helper(helper_);
- class_helper.ReadUntilExcluding(ClassHelper::kEnd);
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kToplevelField: {
- intptr_t field_count = helper_->ReadListLength(); // read list length.
- for (intptr_t i = 0; i < field_count; ++i) {
- FieldHelper field_helper(helper_);
- field_helper.ReadUntilExcluding(FieldHelper::kEnd);
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kToplevelProcedures: {
- procedure_count_ = helper_->ReadListLength(); // read list length.
- for (intptr_t i = 0; i < procedure_count_; ++i) {
- ProcedureHelper procedure_helper(helper_);
- procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd);
- }
- if (++next_read_ == field) return;
- FALL_THROUGH;
- }
- case kLibraryIndex:
- // Read library index.
- for (intptr_t i = 0; i < class_count_; ++i) {
- helper_->reader_.ReadUInt32();
- }
- helper_->reader_.ReadUInt32();
- helper_->reader_.ReadUInt32();
- for (intptr_t i = 0; i < procedure_count_; ++i) {
- helper_->reader_.ReadUInt32();
- }
- helper_->reader_.ReadUInt32();
- helper_->reader_.ReadUInt32();
- if (++next_read_ == field) return;
- FALL_THROUGH;
- case kEnd:
return;
}
}
@@ -2332,6 +2265,11 @@
case kNullLiteral:
return;
case kConstantExpression:
+ ReadPosition(); // read position.
+ SkipDartType(); // read type.
+ SkipConstantReference();
+ return;
+ case kDeprecated_ConstantExpression:
SkipConstantReference();
return;
case kLoadLibrary:
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 745daa7..9508b70 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -708,14 +708,17 @@
kProblemsAsJson,
kAnnotations,
kDependencies,
- kAdditionalExports,
- kParts,
- kTypedefs,
- kClasses,
- kToplevelField,
- kToplevelProcedures,
- kLibraryIndex,
- kEnd,
+ // There are other fields in a library:
+ // * kAdditionalExports
+ // * kParts
+ // * kTypedefs
+ // * kClasses
+ // * kToplevelField
+ // * kToplevelProcedures
+ // * kSourceReferences
+ // * kLibraryIndex
+ // but we never read them via this helper and it makes extending the format
+ // harder to keep the code around.
};
enum Flag {
@@ -742,8 +745,6 @@
NameIndex canonical_name_;
StringIndex name_index_;
intptr_t source_uri_index_;
- intptr_t class_count_;
- intptr_t procedure_count_;
private:
KernelReaderHelper* helper_;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index deb29dc..f0cb2cf 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -81,12 +81,13 @@
// Always do this to preserve deoptid numbering.
JoinEntryInstr* normal_code = BuildJoinEntry();
- prologue += Goto(normal_code);
+ Fragment jump_to_normal_code = Goto(normal_code);
if (is_empty_prologue) {
*prologue_info = PrologueInfo(-1, -1);
return entry;
} else {
+ prologue += jump_to_normal_code;
*prologue_info =
PrologueInfo(previous_block_id, normal_code->block_id() - 1);
return normal_code;
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index ea837d5..268e3d9 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -5,7 +5,6 @@
#include "vm/compiler/frontend/scope_builder.h"
#include "vm/compiler/backend/il.h" // For CompileType.
-#include "vm/kernel.h" // For IsFieldInitializer.
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -313,12 +312,17 @@
// In addition to static field initializers, scopes/local variables
// are needed for implicit getters of static const fields, in order to
// be able to evaluate their initializers in constant evaluator.
- if (IsFieldInitializer(function, Z) ||
- Field::Handle(Z, function.accessor_field()).is_const()) {
+ if (Field::Handle(Z, function.accessor_field()).is_const()) {
VisitNode();
}
break;
}
+ case RawFunction::kStaticFieldInitializer: {
+ ASSERT(helper_.PeekTag() == kField);
+ ASSERT(function.IsStaticFunction());
+ VisitNode();
+ break;
+ }
case RawFunction::kDynamicInvocationForwarder: {
if (helper_.PeekTag() == kField) {
#ifdef DEBUG
@@ -883,7 +887,12 @@
return;
case kNullLiteral:
return;
- case kConstantExpression: {
+ case kConstantExpression:
+ helper_.ReadPosition();
+ helper_.SkipDartType();
+ helper_.SkipConstantReference();
+ return;
+ case kDeprecated_ConstantExpression: {
helper_.SkipConstantReference();
return;
}
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index ae05577..8f927b8 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -214,6 +214,10 @@
Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
}
+word RuntimeEntry::OffsetFromThread() const {
+ return dart::Thread::OffsetFromThread(runtime_entry_);
+}
+
namespace target {
const word kPageSize = dart::kPageSize;
@@ -495,6 +499,7 @@
V(Thread, top_offset) \
V(Thread, top_resource_offset) \
V(Thread, vm_tag_offset) \
+ V(Thread, safepoint_state_offset) \
V(TimelineStream, enabled_offset) \
V(TwoByteString, data_offset) \
V(Type, arguments_offset) \
@@ -513,6 +518,14 @@
CLASS_NAME_LIST(DEFINE_FORWARDER)
#undef DEFINE_FORWARDER
+uword Thread::safepoint_state_unacquired() {
+ return dart::Thread::safepoint_state_unacquired();
+}
+
+uword Thread::safepoint_state_acquired() {
+ return dart::Thread::safepoint_state_acquired();
+}
+
const word HeapPage::kBytesPerCardLog2 = dart::HeapPage::kBytesPerCardLog2;
const word String::kHashBits = dart::String::kHashBits;
@@ -641,6 +654,30 @@
return dart::Thread::deoptimize_stub_offset();
}
+word Thread::enter_safepoint_stub_offset() {
+ return dart::Thread::enter_safepoint_stub_offset();
+}
+
+word Thread::exit_safepoint_stub_offset() {
+ return dart::Thread::exit_safepoint_stub_offset();
+}
+
+word Thread::execution_state_offset() {
+ return dart::Thread::execution_state_offset();
+}
+
+uword Thread::native_execution_state() {
+ return dart::Thread::ExecutionState::kThreadInNative;
+}
+
+uword Thread::generated_execution_state() {
+ return dart::Thread::ExecutionState::kThreadInGenerated;
+}
+
+uword Thread::vm_tag_compiled_id() {
+ return dart::VMTag::kDartCompiledTagId;
+}
+
#endif // !defined(TARGET_ARCH_DBC)
#define DECLARE_CONSTANT_OFFSET_GETTER(name) \
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 825bbb1..d910575 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -218,6 +218,8 @@
call_(runtime_entry_, assembler, argument_count);
}
+ word OffsetFromThread() const;
+
protected:
RuntimeEntry(const dart::RuntimeEntry* runtime_entry,
RuntimeEntryCallInternal call)
@@ -571,6 +573,15 @@
static word array_write_barrier_entry_point_offset();
static word write_barrier_entry_point_offset();
static word vm_tag_offset();
+ static uword vm_tag_compiled_id();
+
+ static word safepoint_state_offset();
+ static uword safepoint_state_unacquired();
+ static uword safepoint_state_acquired();
+
+ static word execution_state_offset();
+ static uword native_execution_state();
+ static uword generated_execution_state();
#if !defined(TARGET_ARCH_DBC)
static word write_barrier_code_offset();
@@ -593,6 +604,8 @@
static word lazy_deopt_from_return_stub_offset();
static word lazy_deopt_from_throw_stub_offset();
static word deoptimize_stub_offset();
+ static word enter_safepoint_stub_offset();
+ static word exit_safepoint_stub_offset();
#endif // !defined(TARGET_ARCH_DBC)
static word no_scope_native_wrapper_entry_point_offset();
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index ce9321b..7024fd8 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -4,6 +4,9 @@
#include "vm/globals.h"
+// For `AllocateObjectInstr::WillAllocateNewOrRemembered`
+#include "vm/compiler/backend/il.h"
+
#define SHOULD_NOT_INCLUDE_RUNTIME
#include "vm/compiler/stub_code_compiler.h"
@@ -32,6 +35,34 @@
namespace compiler {
+// Ensures that [R0] is a new object, if not it will be added to the remembered
+// set via a leaf runtime call.
+//
+// WARNING: This might clobber all registers except for [R0], [THR] and [FP].
+// The caller should simply call LeaveStubFrame() and return.
+static void EnsureIsNewOrRemembered(Assembler* assembler,
+ bool preserve_registers = true) {
+ // If the object is not remembered we call a leaf-runtime to add it to the
+ // remembered set.
+ Label done;
+ __ tst(R0, Operand(1 << target::ObjectAlignment::kNewObjectBitPosition));
+ __ BranchIf(NOT_ZERO, &done);
+
+ if (preserve_registers) {
+ __ EnterCallRuntimeFrame(0);
+ } else {
+ __ ReserveAlignedFrameSpace(0);
+ }
+ // [R0] already contains first argument.
+ __ mov(R1, Operand(THR));
+ __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ if (preserve_registers) {
+ __ LeaveCallRuntimeFrame();
+ }
+
+ __ Bind(&done);
+}
+
// Input parameters:
// LR : return address.
// SP : address of last argument in argument array.
@@ -239,6 +270,26 @@
__ Ret();
}
+void StubCodeCompiler::GenerateEnterSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers);
+ __ ldr(R0, Address(THR, kEnterSafepointRuntimeEntry.OffsetFromThread()));
+ __ blx(R0);
+ __ PopRegisters(all_registers);
+ __ Ret();
+}
+
+void StubCodeCompiler::GenerateExitSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers);
+ __ ldr(R0, Address(THR, kExitSafepointRuntimeEntry.OffsetFromThread()));
+ __ blx(R0);
+ __ PopRegisters(all_registers);
+ __ Ret();
+}
+
void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
Assembler* assembler) {
GenerateSharedStub(
@@ -955,6 +1006,12 @@
// Pop arguments; result is popped in IP.
__ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored.
__ mov(R0, Operand(IP));
+
+ // Write-barrier elimination might be enabled for this array (depending on the
+ // array length). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler);
+
__ LeaveStubFrame();
__ Ret();
}
@@ -1349,6 +1406,12 @@
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
__ Drop(1); // Pop number of context variables argument.
__ Pop(R0); // Pop the new context object.
+
+ // Write-barrier elimination might be enabled for this context (depending on
+ // the size). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
// R0: new object
// Restore the frame pointer.
__ LeaveStubFrame();
@@ -1677,6 +1740,14 @@
kInstanceReg,
Address(SP,
2 * target::kWordSize)); // Pop result (newly allocated object).
+
+ ASSERT(kInstanceReg == R0);
+ if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
+ // Write-barrier elimination is enabled for [cls] and we therefore need to
+ // ensure that the object is in new-space or has remembered bit set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+ }
+
__ LeaveDartFrameAndReturn(); // Restores correct SP.
}
@@ -2252,6 +2323,9 @@
// R9: Contains an ICData.
void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ LoadImmediate(R0, 0);
// Preserve arguments descriptor and make room for result.
@@ -2261,9 +2335,13 @@
__ LeaveStubFrame();
__ mov(CODE_REG, Operand(R0));
__ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+#endif // defined(PRODUCT)
}
void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ LoadImmediate(R0, 0);
// Make room for result.
@@ -2272,12 +2350,13 @@
__ PopList((1 << CODE_REG));
__ LeaveStubFrame();
__ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+#endif // defined(PRODUCT)
}
// Called only from unoptimized code. All relevant registers have been saved.
void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
#if defined(PRODUCT)
- __ Ret();
+ __ Stop("No debugging in PRODUCT mode");
#else
// Check single stepping.
Label stepping, done_stepping;
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 6b0d490..2205c2b 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -4,6 +4,9 @@
#include "vm/globals.h"
+// For `AllocateObjectInstr::WillAllocateNewOrRemembered`
+#include "vm/compiler/backend/il.h"
+
#define SHOULD_NOT_INCLUDE_RUNTIME
#include "vm/compiler/stub_code_compiler.h"
@@ -32,6 +35,33 @@
namespace compiler {
+// Ensures that [R0] is a new object, if not it will be added to the remembered
+// set via a leaf runtime call.
+//
+// WARNING: This might clobber all registers except for [R0], [THR] and [FP].
+// The caller should simply call LeaveStubFrame() and return.
+static void EnsureIsNewOrRemembered(Assembler* assembler,
+ bool preserve_registers = true) {
+ // If the object is not remembered we call a leaf-runtime to add it to the
+ // remembered set.
+ Label done;
+ __ tbnz(&done, R0, target::ObjectAlignment::kNewObjectBitPosition);
+
+ if (preserve_registers) {
+ __ EnterCallRuntimeFrame(0);
+ } else {
+ __ ReserveAlignedFrameSpace(0);
+ }
+ // [R0] already contains first argument.
+ __ mov(R1, THR);
+ __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ if (preserve_registers) {
+ __ LeaveCallRuntimeFrame();
+ }
+
+ __ Bind(&done);
+}
+
// Input parameters:
// LR : return address.
// SP : address of last argument in argument array.
@@ -175,6 +205,36 @@
__ ret(LR);
}
+void StubCodeCompiler::GenerateEnterSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers);
+ __ mov(CallingConventions::kFirstCalleeSavedCpuReg, SP);
+ __ ReserveAlignedFrameSpace(0);
+ __ mov(CSP, SP);
+ __ ldr(R0, Address(THR, kEnterSafepointRuntimeEntry.OffsetFromThread()));
+ __ blr(R0);
+ __ mov(SP, CallingConventions::kFirstCalleeSavedCpuReg);
+ __ PopRegisters(all_registers);
+ __ mov(CSP, SP);
+ __ Ret();
+}
+
+void StubCodeCompiler::GenerateExitSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers);
+ __ mov(CallingConventions::kFirstCalleeSavedCpuReg, SP);
+ __ ReserveAlignedFrameSpace(0);
+ __ mov(CSP, SP);
+ __ ldr(R0, Address(THR, kExitSafepointRuntimeEntry.OffsetFromThread()));
+ __ blr(R0);
+ __ mov(SP, CallingConventions::kFirstCalleeSavedCpuReg);
+ __ PopRegisters(all_registers);
+ __ mov(CSP, SP);
+ __ Ret();
+}
+
// R1: The extracted method.
// R4: The type_arguments_field_offset (or 0)
void StubCodeCompiler::GenerateBuildMethodExtractorStub(
@@ -1021,6 +1081,12 @@
__ Pop(R1);
__ Pop(R2);
__ Pop(R0);
+
+ // Write-barrier elimination might be enabled for this array (depending on the
+ // array length). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler);
+
__ LeaveStubFrame();
__ ret();
}
@@ -1432,6 +1498,12 @@
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
__ Drop(1); // Pop number of context variables argument.
__ Pop(R0); // Pop the new context object.
+
+ // Write-barrier elimination might be enabled for this context (depending on
+ // the size). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
// R0: new object
// Restore the frame pointer.
__ LeaveStubFrame();
@@ -1727,6 +1799,13 @@
kInstanceReg,
Address(SP,
2 * target::kWordSize)); // Pop result (newly allocated object).
+
+ ASSERT(kInstanceReg == R0);
+ if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
+ // Write-barrier elimination is enabled for [cls] and we therefore need to
+ // ensure that the object is in new-space or has remembered bit set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+ }
__ LeaveStubFrame(); // Restores correct SP.
__ ret();
}
@@ -2334,6 +2413,9 @@
// R5: Contains an ICData.
void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ Push(R5);
__ Push(ZR); // Space for result.
@@ -2343,9 +2425,13 @@
__ LeaveStubFrame();
__ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
__ br(R0);
+#endif // defined(PRODUCT)
}
void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ Push(ZR); // Space for result.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -2353,12 +2439,13 @@
__ LeaveStubFrame();
__ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
__ br(R0);
+#endif // defined(PRODUCT)
}
// Called only from unoptimized code. All relevant registers have been saved.
void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
#if defined(PRODUCT)
- __ ret();
+ __ Stop("No debugging in PRODUCT mode");
#else
// Check single stepping.
Label stepping, done_stepping;
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 86f75d6..12259cc 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -4,6 +4,9 @@
#include "vm/globals.h"
+// For `AllocateObjectInstr::WillAllocateNewOrRemembered`
+#include "vm/compiler/backend/il.h"
+
#define SHOULD_NOT_INCLUDE_RUNTIME
#include "vm/compiler/stub_code_compiler.h"
@@ -31,6 +34,34 @@
namespace compiler {
+// Ensures that [EAX] is a new object, if not it will be added to the remembered
+// set via a leaf runtime call.
+//
+// WARNING: This might clobber all registers except for [EAX], [THR] and [FP].
+// The caller should simply call LeaveFrame() and return.
+static void EnsureIsNewOrRemembered(Assembler* assembler,
+ bool preserve_registers = true) {
+ // If the object is not remembered we call a leaf-runtime to add it to the
+ // remembered set.
+ Label done;
+ __ testl(EAX, Immediate(1 << target::ObjectAlignment::kNewObjectBitPosition));
+ __ BranchIf(NOT_ZERO, &done);
+
+ if (preserve_registers) {
+ __ EnterCallRuntimeFrame(2 * target::kWordSize);
+ } else {
+ __ ReserveAlignedFrameSpace(2 * target::kWordSize);
+ }
+ __ movl(Address(ESP, 1 * target::kWordSize), THR);
+ __ movl(Address(ESP, 0 * target::kWordSize), EAX);
+ __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ if (preserve_registers) {
+ __ LeaveCallRuntimeFrame();
+ }
+
+ __ Bind(&done);
+}
+
// Input parameters:
// ESP : points to return address.
// ESP + 4 : address of last argument in argument array.
@@ -107,6 +138,22 @@
__ ret();
}
+void StubCodeCompiler::GenerateEnterSafepointStub(Assembler* assembler) {
+ __ pushal();
+ __ movl(EAX, Address(THR, kEnterSafepointRuntimeEntry.OffsetFromThread()));
+ __ call(EAX);
+ __ popal();
+ __ ret();
+}
+
+void StubCodeCompiler::GenerateExitSafepointStub(Assembler* assembler) {
+ __ pushal();
+ __ movl(EAX, Address(THR, kExitSafepointRuntimeEntry.OffsetFromThread()));
+ __ call(EAX);
+ __ popal();
+ __ ret();
+}
+
void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
Assembler* assembler) {
__ Breakpoint();
@@ -757,6 +804,12 @@
__ popl(EAX); // Pop element type argument.
__ popl(EDX); // Pop array length argument (preserved).
__ popl(EAX); // Pop return value from return slot.
+
+ // Write-barrier elimination might be enabled for this array (depending on the
+ // array length). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler);
+
__ LeaveFrame();
__ ret();
}
@@ -1115,6 +1168,12 @@
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
__ popl(EAX); // Pop number of context variables argument.
__ popl(EAX); // Pop the new context object.
+
+ // Write-barrier elimination might be enabled for this context (depending on
+ // the size). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
// EAX: new object
// Restore the frame pointer.
__ LeaveFrame();
@@ -1381,6 +1440,13 @@
__ popl(EAX); // Pop argument (type arguments of object).
__ popl(EAX); // Pop argument (class of object).
__ popl(EAX); // Pop result (newly allocated object).
+
+ if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
+ // Write-barrier elimination is enabled for [cls] and we therefore need to
+ // ensure that the object is in new-space or has remembered bit set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+ }
+
// EAX: new object
// Restore the frame pointer.
__ LeaveFrame();
@@ -1970,6 +2036,9 @@
// ECX: Contains an ICData.
void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
// Save IC data.
__ pushl(ECX);
@@ -1983,9 +2052,13 @@
// Jump to original stub.
__ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
__ jmp(EAX);
+#endif // defined(PRODUCT)
}
void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
// Room for result. Debugger stub returns address of the
// unpatched runtime stub.
@@ -1996,12 +2069,13 @@
// Jump to original stub.
__ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
__ jmp(EAX);
+#endif // defined(PRODUCT)
}
// Called only from unoptimized code.
void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
#if defined(PRODUCT)
- __ ret();
+ __ Stop("No debugging in PRODUCT mode");
#else
// Check single stepping.
Label stepping, done_stepping;
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 2c5dd0a..0df3f7a 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -2,10 +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.
+#include "vm/compiler/runtime_api.h"
#include "vm/globals.h"
+// For `AllocateObjectInstr::WillAllocateNewOrRemembered`
+#include "vm/compiler/backend/il.h"
+
#define SHOULD_NOT_INCLUDE_RUNTIME
+#include "vm/compiler/backend/locations.h"
#include "vm/compiler/stub_code_compiler.h"
#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
@@ -31,6 +36,34 @@
namespace compiler {
+// Ensures that [RAX] is a new object, if not it will be added to the remembered
+// set via a leaf runtime call.
+//
+// WARNING: This might clobber all registers except for [RAX], [THR] and [FP].
+// The caller should simply call LeaveStubFrame() and return.
+static void EnsureIsNewOrRemembered(Assembler* assembler,
+ bool preserve_registers = true) {
+ // If the object is not remembered we call a leaf-runtime to add it to the
+ // remembered set.
+ Label done;
+ __ testq(RAX, Immediate(1 << target::ObjectAlignment::kNewObjectBitPosition));
+ __ BranchIf(NOT_ZERO, &done);
+
+ if (preserve_registers) {
+ __ EnterCallRuntimeFrame(0);
+ } else {
+ __ ReserveAlignedFrameSpace(0);
+ }
+ __ movq(CallingConventions::kArg1Reg, RAX);
+ __ movq(CallingConventions::kArg2Reg, THR);
+ __ CallRuntime(kAddAllocatedObjectToRememberedSetRuntimeEntry, 2);
+ if (preserve_registers) {
+ __ LeaveCallRuntimeFrame();
+ }
+
+ __ Bind(&done);
+}
+
// Input parameters:
// RSP : points to return address.
// RSP + 8 : address of last argument in argument array.
@@ -166,6 +199,28 @@
__ ret();
}
+void StubCodeCompiler::GenerateEnterSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers.cpu_registers(),
+ all_registers.fpu_registers());
+ __ movq(RAX, Address(THR, kEnterSafepointRuntimeEntry.OffsetFromThread()));
+ __ CallCFunction(RAX);
+ __ PopRegisters(all_registers.cpu_registers(), all_registers.fpu_registers());
+ __ ret();
+}
+
+void StubCodeCompiler::GenerateExitSafepointStub(Assembler* assembler) {
+ RegisterSet all_registers;
+ all_registers.AddAllGeneralRegisters();
+ __ PushRegisters(all_registers.cpu_registers(),
+ all_registers.fpu_registers());
+ __ movq(RAX, Address(THR, kExitSafepointRuntimeEntry.OffsetFromThread()));
+ __ CallCFunction(RAX);
+ __ PopRegisters(all_registers.cpu_registers(), all_registers.fpu_registers());
+ __ ret();
+}
+
// RBX: The extracted method.
// RDX: The type_arguments_field_offset (or 0)
void StubCodeCompiler::GenerateBuildMethodExtractorStub(
@@ -967,6 +1022,12 @@
__ popq(RAX); // Pop element type argument.
__ popq(R10); // Pop array length argument.
__ popq(RAX); // Pop return value from return slot.
+
+ // Write-barrier elimination might be enabled for this array (depending on the
+ // array length). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler);
+
__ LeaveStubFrame();
__ ret();
}
@@ -1391,6 +1452,12 @@
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
__ popq(RAX); // Pop number of context variables argument.
__ popq(RAX); // Pop the new context object.
+
+ // Write-barrier elimination might be enabled for this context (depending on
+ // the size). To be sure we will check if the allocated object is in old
+ // space and if so call a leaf runtime to add it to the remembered set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+
// RAX: new object
// Restore the frame pointer.
__ LeaveStubFrame();
@@ -1694,6 +1761,7 @@
// RDX: new object type arguments.
// Create a stub frame.
__ EnterStubFrame(); // Uses PP to access class object.
+
__ pushq(R9); // Setup space on stack for return value.
__ PushObject(
CastHandle<Object>(cls)); // Push class of object to be allocated.
@@ -1706,6 +1774,13 @@
__ popq(RAX); // Pop argument (type arguments of object).
__ popq(RAX); // Pop argument (class of object).
__ popq(RAX); // Pop result (newly allocated object).
+
+ if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
+ // Write-barrier elimination is enabled for [cls] and we therefore need to
+ // ensure that the object is in new-space or has remembered bit set.
+ EnsureIsNewOrRemembered(assembler, /*preserve_registers=*/false);
+ }
+
// RAX: new object
// Restore the frame pointer.
__ LeaveStubFrame();
@@ -2354,6 +2429,9 @@
// RBX: Contains an ICData.
// TOS(0): return address (Dart code).
void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ pushq(RBX); // Preserve IC data.
__ pushq(Immediate(0)); // Result slot.
@@ -2364,10 +2442,14 @@
__ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
__ jmp(RAX); // Jump to original stub.
+#endif // defined(PRODUCT)
}
// TOS(0): return address (Dart code).
void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+#if defined(PRODUCT)
+ __ Stop("No debugging in PRODUCT mode");
+#else
__ EnterStubFrame();
__ pushq(Immediate(0)); // Result slot.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -2376,12 +2458,13 @@
__ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
__ jmp(RAX); // Jump to original stub.
+#endif // defined(PRODUCT)
}
// Called only from unoptimized code.
void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
#if defined(PRODUCT)
- __ Ret();
+ __ Stop("No debugging in PRODUCT mode");
#else
// Check single stepping.
Label stepping, done_stepping;
diff --git a/runtime/vm/constants.h b/runtime/vm/constants.h
index 90137d3..7fe6c15 100644
--- a/runtime/vm/constants.h
+++ b/runtime/vm/constants.h
@@ -63,6 +63,28 @@
} // namespace host
+class RegisterNames {
+ public:
+ static const char* RegisterName(Register reg) {
+ ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
+ return cpu_reg_names[reg];
+ }
+ static const char* FpuRegisterName(FpuRegister reg) {
+ ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
+ return fpu_reg_names[reg];
+ }
+#if !defined(HOST_ARCH_EQUALS_TARGET_ARCH)
+ static const char* RegisterName(host::Register reg) {
+ ASSERT((0 <= reg) && (reg < host::kNumberOfCpuRegisters));
+ return host::cpu_reg_names[reg];
+ }
+ static const char* FpuRegisterName(host::FpuRegister reg) {
+ ASSERT((0 <= reg) && (reg < host::kNumberOfFpuRegisters));
+ return host::fpu_reg_names[reg];
+ }
+#endif // !defined(HOST_ARCH_EQUALS_TARGET_ARCH)
+};
+
} // namespace dart
#endif // RUNTIME_VM_CONSTANTS_H_
diff --git a/runtime/vm/constants_arm.cc b/runtime/vm/constants_arm.cc
new file mode 100644
index 0000000..0934c48
--- /dev/null
+++ b/runtime/vm/constants_arm.cc
@@ -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.
+
+#define RUNTIME_VM_CONSTANTS_H_ // To work around include guard.
+#include "vm/constants_arm.h"
+
+namespace arch_arm {
+
+const Register CallingConventions::ArgumentRegisters[] = {R0, R1, R2, R3};
+
+// Although 'kFpuArgumentRegisters' is 0, we have to give this array at least
+// one element to appease MSVC.
+const FpuRegister CallingConventions::FpuArgumentRegisters[] = {Q0};
+
+} // namespace arch_arm
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index fe2ffcc..afbcb92 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -265,6 +265,18 @@
const int kNumberOfFpuRegisters = kNumberOfQRegisters;
const FpuRegister kNoFpuRegister = kNoQRegister;
+static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc",
+};
+
+static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
+ "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
+#if defined(VFPv3_D32)
+ "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
+#endif
+};
+
// Register aliases.
const Register TMP = IP; // Used as scratch register by assembler.
const Register TMP2 = kNoRegister; // There is no second assembler temporary.
@@ -332,6 +344,46 @@
const QRegister kDartLastVolatileFpuReg = Q3;
const int kDartVolatileFpuRegCount = 4;
+#define R(REG) (1 << REG)
+
+class CallingConventions {
+ public:
+ static const intptr_t kArgumentRegisters = kAbiArgumentCpuRegs;
+ static const Register ArgumentRegisters[];
+ static const intptr_t kNumArgRegs = 4;
+
+ static const FpuRegister FpuArgumentRegisters[];
+ static const intptr_t kFpuArgumentRegisters = 0;
+ static const intptr_t kNumFpuArgRegs = 0;
+
+ static constexpr bool kArgumentIntRegXorFpuReg = false;
+
+ // Whether floating-point values should be passed as integers ("softfp" vs
+ // "hardfp"). Android and iOS always use the "softfp" calling convention, even
+ // when hardfp support is present.
+#if defined(TARGET_OS_MACOS_IOS) || defined(TARGET_OS_ANDROID)
+ static constexpr bool kAbiSoftFP = true;
+#else
+ static constexpr bool kAbiSoftFP = false;
+#endif
+
+ // Whether 64-bit arguments must be aligned to an even register or 8-byte
+ // stack address. True for ARM 32-bit, see "Procedure Call Standard for the
+ // ARM Architecture".
+ static constexpr bool kAlignArguments = true;
+
+ static constexpr Register kReturnReg = R0;
+ static constexpr Register kSecondReturnReg = R1;
+ static constexpr FpuRegister kReturnFpuReg = kNoFpuRegister;
+
+ // We choose these to avoid overlap between themselves and reserved registers.
+ static constexpr Register kFirstNonArgumentRegister = R8;
+ static constexpr Register kSecondNonArgumentRegister = R9;
+ static constexpr Register kFirstCalleeSavedCpuReg = NOTFP;
+};
+
+#undef R
+
// Values for the condition field as defined in section A3.2.
enum Condition {
kNoCondition = -1,
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 8dfabc8..9f3355a 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -108,6 +108,18 @@
const int kNumberOfFpuRegisters = kNumberOfVRegisters;
const FpuRegister kNoFpuRegister = kNoVRegister;
+static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
+ "r22", "r23", "r24", "ip0", "ip1", "pp", "ctx", "fp", "lr", "r31",
+};
+
+static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10",
+ "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
+ "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
+};
+
// Register aliases.
const Register TMP = R16; // Used as scratch register by assembler.
const Register TMP2 = R17;
@@ -195,6 +207,14 @@
static const bool kArgumentIntRegXorFpuReg = false;
+ // Whether floating-point values should be passed as integers ("softfp" vs
+ // "hardfp").
+ static constexpr bool kAbiSoftFP = false;
+
+ // Whether 64-bit arguments must be aligned to an even register or 8-byte
+ // stack address. Not relevant on X64 since the word size is 64-bits already.
+ static constexpr bool kAlignArguments = false;
+
static constexpr Register kReturnReg = R0;
static constexpr Register kSecondReturnReg = kNoRegister;
static constexpr FpuRegister kReturnFpuReg = V0;
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index d0b7703..2eb202d 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -337,6 +337,7 @@
// Jump T ;; jump if not equal
//
// - If<Cond>Null rA
+// If<Cond>NullTOS
//
// Cond is Eq or Ne. Skips the next instruction unless the given condition
// holds.
@@ -723,6 +724,10 @@
// InstanceCall ... <- lazy deopt inside first call
// InstanceCall ... <- patches second call with Deopt
//
+// - NullError
+//
+// Throws a NullError.
+//
// BYTECODE LIST FORMAT
//
// Bytecode list below is specified using the following format:
@@ -862,6 +867,8 @@
V(IfEqStrictNum, A_D, reg, reg, ___) \
V(IfEqNull, A, reg, ___, ___) \
V(IfNeNull, A, reg, ___, ___) \
+ V(IfEqNullTOS, 0, ___, ___, ___) \
+ V(IfNeNullTOS, 0, ___, ___, ___) \
V(CreateArrayTOS, 0, ___, ___, ___) \
V(CreateArrayOpt, A_B_C, reg, reg, reg) \
V(Allocate, D, lit, ___, ___) \
@@ -949,7 +956,8 @@
V(DebugStep, 0, ___, ___, ___) \
V(DebugBreak, A, num, ___, ___) \
V(Deopt, A_D, num, num, ___) \
- V(DeoptRewind, 0, ___, ___, ___)
+ V(DeoptRewind, 0, ___, ___, ___) \
+ V(NullError, 0, ___, ___, ___)
// clang-format on
@@ -1103,6 +1111,21 @@
const FpuRegister FpuTMP = kFakeFpuRegister;
const intptr_t kNumberOfFpuRegisters = 1;
+static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10",
+ "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20", "R21",
+ "R22", "R23", "R24", "R25", "R26", "R27", "R28", "R29", "R30", "R31",
+#if defined(ARCH_IS_64_BIT)
+ "R32", "R33", "R34", "R35", "R36", "R37", "R38", "R39", "R40", "R41", "R42",
+ "R43", "R44", "R45", "R46", "R47", "R48", "R49", "R50", "R51", "R52", "R53",
+ "R54", "R55", "R56", "R57", "R58", "R59", "R60", "R61", "R62", "R63",
+#endif
+};
+
+static const char* fpu_reg_names[kNumberOfFpuRegisters] = {
+ "F0",
+};
+
// After a comparison, the condition NEXT_IS_TRUE means the following
// instruction is executed if the comparison is true and skipped over overwise.
// Condition NEXT_IS_FALSE means the following instruction is executed if the
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 16eeb4e..ce697b9 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -57,6 +57,12 @@
const int kNumberOfFpuRegisters = kNumberOfXmmRegisters;
const FpuRegister kNoFpuRegister = kNoXmmRegister;
+static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
+
+static const char* fpu_reg_names[kNumberOfXmmRegisters] = {
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
+
// Register aliases.
const Register TMP = kNoRegister; // No scratch register used by assembler.
const Register TMP2 = kNoRegister; // No second assembler scratch register.
@@ -135,6 +141,10 @@
static const bool kArgumentIntRegXorFpuReg = false;
+ // Whether floating-point values should be passed as integers ("softfp" vs
+ // "hardfp").
+ static constexpr bool kAbiSoftFP = false;
+
static constexpr Register kReturnReg = EAX;
static constexpr Register kSecondReturnReg = EDX;
@@ -144,6 +154,11 @@
static constexpr Register kFirstCalleeSavedCpuReg = EBX;
static constexpr Register kFirstNonArgumentRegister = EAX;
static constexpr Register kSecondNonArgumentRegister = ECX;
+
+ // Whether 64-bit arguments must be aligned to an even register or 8-byte
+ // stack address. On IA32, 64-bit integers and floating-point values do *not*
+ // need to be 8-byte aligned.
+ static constexpr bool kAlignArguments = false;
};
} // namespace arch_ia32
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index d3b0f35..dc8e954 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -285,6 +285,11 @@
// interface method declaration.
// The ICData indicates whether the first argument is a type argument vector.
//
+// - UncheckedInterfaceCall ArgC, D
+//
+// Same as InterfaceCall, but can omit type checks of generic-covariant
+// parameters.
+//
// - DynamicCall ArgC, D
//
// Lookup and invoke method using ICData in PP[D]
@@ -389,6 +394,25 @@
// Receiver and argument should have static type int.
// Check SP[-1] and SP[0] for null; push SP[-1] <op> SP[0] ? true : false.
//
+// - NegateDouble
+//
+// Equivalent to invocation of unary double operator-.
+// Receiver should have static type double.
+// Check SP[0] for null; SP[0] = -SP[0].
+//
+// - AddDouble; SubDouble; MulDouble; DivDouble
+//
+// Equivalent to invocation of binary int operator +, -, *, /.
+// Receiver and argument should have static type double.
+// Check SP[-1] and SP[0] for null; push SP[-1] <op> SP[0].
+//
+// - CompareDoubleEq; CompareDoubleGt; CompareDoubleLt; CompareDoubleGe;
+// CompareDoubleLe
+//
+// Equivalent to invocation of binary double operator ==, >, <, >= or <=.
+// Receiver and argument should have static type double.
+// Check SP[-1] and SP[0] for null; push SP[-1] <op> SP[0] ? true : false.
+//
// - AllocateClosure D
//
// Allocate closure object for closure function ConstantPool[D].
@@ -490,12 +514,24 @@
V(CompareIntLe, 0, ___, ___, ___) \
V(DirectCall, A_D, num, num, ___) \
V(AllocateClosure, D, lit, ___, ___) \
+ V(UncheckedInterfaceCall, A_D, num, num, ___) \
+ V(NegateDouble, 0, ___, ___, ___) \
+ V(AddDouble, 0, ___, ___, ___) \
+ V(SubDouble, 0, ___, ___, ___) \
+ V(MulDouble, 0, ___, ___, ___) \
+ V(DivDouble, 0, ___, ___, ___) \
+ V(CompareDoubleEq, 0, ___, ___, ___) \
+ V(CompareDoubleGt, 0, ___, ___, ___) \
+ V(CompareDoubleLt, 0, ___, ___, ___) \
+ V(CompareDoubleGe, 0, ___, ___, ___) \
+ V(CompareDoubleLe, 0, ___, ___, ___) \
// These bytecodes are only generated within the VM. Reassinging their
// opcodes is not a breaking change.
#define INTERNAL_KERNEL_BYTECODES_LIST(V) \
V(VMInternal_ImplicitGetter, 0, ___, ___, ___) \
V(VMInternal_ImplicitSetter, 0, ___, ___, ___) \
+ V(VMInternal_MethodExtractor, 0, ___, ___, ___) \
#define KERNEL_BYTECODES_LIST(V) \
PUBLIC_KERNEL_BYTECODES_LIST(V) \
@@ -514,7 +550,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 = 4;
+ static const intptr_t kMaxSupportedBytecodeFormatVersion = 6;
enum Opcode {
#define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
@@ -630,6 +666,7 @@
switch (DecodeOpcode(instr)) {
case KernelBytecode::kIndirectStaticCall:
case KernelBytecode::kInterfaceCall:
+ case KernelBytecode::kUncheckedInterfaceCall:
case KernelBytecode::kDynamicCall:
case KernelBytecode::kDirectCall:
return true;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 3d37645..c9eea38 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -94,6 +94,14 @@
const int kNumberOfFpuRegisters = kNumberOfXmmRegisters;
const FpuRegister kNoFpuRegister = kNoXmmRegister;
+static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "thr", "pp"};
+
+static const char* fpu_reg_names[kNumberOfXmmRegisters] = {
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"};
+
enum RexBits {
REX_NONE = 0,
REX_B = 1 << 0,
@@ -194,6 +202,14 @@
static constexpr Register kReturnReg = RAX;
static constexpr Register kSecondReturnReg = kNoRegister;
static constexpr FpuRegister kReturnFpuReg = XMM0;
+
+ // Whether floating-point values should be passed as integers ("softfp" vs
+ // "hardfp").
+ static constexpr bool kAbiSoftFP = false;
+
+ // Whether 64-bit arguments must be aligned to an even register or 8-byte
+ // stack address. Not relevant on X64 since the word size is 64-bits already.
+ static constexpr bool kAlignArguments = false;
#else
static const Register kArg1Reg = RDI;
static const Register kArg2Reg = RSI;
@@ -208,7 +224,7 @@
static const intptr_t kNumArgRegs = 6;
static const XmmRegister FpuArgumentRegisters[];
- static const intptr_t kXmmArgumentRegisters = R(XMM0) | R(XMM1) | R(XMM2) |
+ static const intptr_t kFpuArgumentRegisters = R(XMM0) | R(XMM1) | R(XMM2) |
R(XMM3) | R(XMM4) | R(XMM5) |
R(XMM6) | R(XMM7);
static const intptr_t kNumFpuArgRegs = 8;
@@ -238,6 +254,14 @@
static constexpr Register kReturnReg = RAX;
static constexpr Register kSecondReturnReg = kNoRegister;
static constexpr FpuRegister kReturnFpuReg = XMM0;
+
+ // Whether floating-point values should be passed as integers ("softfp" vs
+ // "hardfp").
+ static constexpr bool kAbiSoftFP = false;
+
+ // Whether 64-bit arguments must be aligned to an even register or 8-byte
+ // stack address. Not relevant on X64 since the word size is 64-bits already.
+ static constexpr bool kAlignArguments = false;
#endif
COMPILE_ASSERT((kArgumentRegisters & kReservedCpuRegisters) == 0);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b1f2ce4..0f50b62 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -820,8 +820,7 @@
if (thread->top_exit_frame_info() == 0) {
// There are no dart frames on the stack so it would be illegal to
// propagate an error here.
- FATAL1("No Dart frames on stack, cannot propagate error: %s",
- Error::Cast(obj).ToErrorCString());
+ FATAL("No Dart frames on stack, cannot propagate error.");
}
// Unwind all the API scopes till the exit frame before propagating.
const Error* error;
@@ -6342,4 +6341,8 @@
#endif
}
+DART_EXPORT void Dart_PrepareToAbort() {
+ OS::PrepareToAbort();
+}
+
} // namespace dart
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 202143e..f2cd2e8 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -297,16 +297,15 @@
static bool IsFfiEnabled() {
// dart:ffi is not implemented for the following configurations
-#if !defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64) && \
- !defined(TARGET_ARCH_IA32)
- // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
- // https://github.com/dart-lang/sdk/issues/35772 Arm64
+#if defined(TARGET_ARCH_DBC)
+ // https://github.com/dart-lang/sdk/issues/35773 DBC
+ return false;
+#elif defined(TARGET_ARCH_ARM) && \
+ !(defined(TARGET_OS_ANDROID) || defined(TARGET_OS_MACOS_IOS))
+ // TODO(36309): Support hardfp calling convention.
return false;
#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) && \
!defined(TARGET_OS_ANDROID) && !defined(TARGET_OS_WINDOWS)
- // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
- // https://github.com/dart-lang/sdk/issues/35772 Arm64
- // https://github.com/dart-lang/sdk/issues/35773 DBC
return false;
#else
// dart:ffi is also not implemented for precompiled in which case
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3759e0f..e117e1d 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -446,6 +446,7 @@
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticFieldInitializer:
case RawFunction::kMethodExtractor:
case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kInvokeFieldDispatcher:
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 9270768..3e5d46c 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -19,7 +19,6 @@
namespace dart {
-class Location;
class Value;
class MaterializeObjectInstr;
class StackFrame;
@@ -462,10 +461,12 @@
RegisterType reg() const { return static_cast<RegisterType>(raw_index()); }
- static const char* Name(Register reg) { return Assembler::RegisterName(reg); }
+ static const char* Name(Register reg) {
+ return RegisterNames::RegisterName(reg);
+ }
static const char* Name(FpuRegister fpu_reg) {
- return Assembler::FpuRegisterName(fpu_reg);
+ return RegisterNames::FpuRegisterName(fpu_reg);
}
const intptr_t source_index_;
@@ -601,7 +602,6 @@
static const intptr_t kEntrySize = 3;
};
-
// Holds deopt information at one deoptimization point. The information consists
// of two parts:
// - first a prefix consisting of kMaterializeObject instructions describing
@@ -638,7 +638,6 @@
const Array& deopt_table,
const TypedData& packed);
-
private:
static void UnpackInto(const Array& table,
const TypedData& packed,
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index c36b640..c72f6b0 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -117,6 +117,19 @@
: static_cast<intptr_t>(kSmiCid);
}
+ DART_FORCE_INLINE static RawTypeArguments* GetTypeArguments(
+ Thread* thread,
+ RawInstance* instance) {
+ RawClass* instance_class =
+ thread->isolate()->class_table()->At(GetClassId(instance));
+ return instance_class->ptr()->num_type_arguments_ > 0
+ ? reinterpret_cast<RawTypeArguments**>(
+ instance
+ ->ptr())[instance_class->ptr()
+ ->type_arguments_field_offset_in_words_]
+ : TypeArguments::null();
+ }
+
// The usage counter is actually a 'hotness' counter.
// For an instance call, both the usage counters of the caller and of the
// calle will get incremented, as well as the ICdata counter at the call site.
@@ -641,21 +654,6 @@
*invoked = true;
return true;
}
- case RawFunction::kMethodExtractor: {
- ASSERT(InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) == 0);
- call_top[1] = 0; // Result of runtime call.
- call_top[2] = *call_base; // Receiver.
- call_top[3] = function->ptr()->data_; // Method.
- Exit(thread, *FP, call_top + 4, *pc);
- NativeArguments native_args(thread, 2, call_top + 2, call_top + 1);
- if (!InvokeRuntime(thread, this, DRT_ExtractMethod, native_args)) {
- return false;
- }
- *SP = call_base;
- **SP = call_top[1];
- *invoked = true;
- return true;
- }
case RawFunction::kInvokeFieldDispatcher: {
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
@@ -1119,62 +1117,11 @@
USE(rD)
#define DECODE_A_X rD = (static_cast<int32_t>(op) >> KernelBytecode::kDShift);
-
-// Exception handling helper. Gets handler FP and PC from the Interpreter where
-// they were stored by Interpreter::Longjmp and proceeds to execute the handler.
-// Corner case: handler PC can be a fake marker that marks entry frame, which
-// means exception was not handled in the Dart code. In this case we return
-// caught exception from Interpreter::Call.
-#if defined(DEBUG)
-
#define HANDLE_EXCEPTION \
do { \
- FP = fp_; \
- pc = pc_; \
- if (IsEntryFrameMarker(pc)) { \
- pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
- argdesc_ = \
- reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]); \
- uword exit_fp = \
- reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]); \
- thread->set_top_exit_frame_info(exit_fp); \
- thread->set_top_resource(top_resource); \
- thread->set_vm_tag(vm_tag); \
- if (IsTracingExecution()) { \
- THR_Print("%" Pu64 " ", icount_); \
- THR_Print("Returning exception from interpreter 0x%" Px \
- " at fp_ 0x%" Px " exit 0x%" Px "\n", \
- reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_), \
- exit_fp); \
- } \
- ASSERT(HasFrame(reinterpret_cast<uword>(fp_))); \
- return special_[KernelBytecode::kExceptionSpecialIndex]; \
- } \
- goto DispatchAfterException; \
+ goto HandleException; \
} while (0)
-#else // !defined(DEBUG)
-
-#define HANDLE_EXCEPTION \
- do { \
- FP = fp_; \
- pc = pc_; \
- if (IsEntryFrameMarker(pc)) { \
- pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
- argdesc_ = \
- reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]); \
- uword exit_fp = \
- reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]); \
- thread->set_top_exit_frame_info(exit_fp); \
- thread->set_top_resource(top_resource); \
- thread->set_vm_tag(vm_tag); \
- return special_[KernelBytecode::kExceptionSpecialIndex]; \
- } \
- goto DispatchAfterException; \
- } while (0)
-
-#endif // !defined(DEBUG)
-
#define HANDLE_RETURN \
do { \
pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; \
@@ -1220,6 +1167,22 @@
} \
ASSERT(Integer::GetInt64Value(RAW_CAST(Integer, SP[0])) == result);
+#define UNBOX_DOUBLE(value, obj, selector) \
+ double value; \
+ { \
+ if (UNLIKELY(obj == null_value)) { \
+ SP[0] = selector.raw(); \
+ goto ThrowNullError; \
+ } \
+ value = Double::RawCast(obj)->ptr()->value_; \
+ }
+
+#define BOX_DOUBLE_RESULT(result) \
+ if (!AllocateDouble(thread, result, pc, FP, SP)) { \
+ HANDLE_EXCEPTION; \
+ } \
+ ASSERT(Utils::DoublesBitEqual(Double::RawCast(SP[0])->ptr()->value_, result));
+
bool Interpreter::AssertAssignable(Thread* thread,
uint32_t* pc,
RawObject** FP,
@@ -1468,6 +1431,67 @@
return InvokeRuntime(thread, this, DRT_AllocateArray, args);
}
+// Allocate a _Context with the given length and put it into SP[0].
+// Returns false on exception.
+bool Interpreter::AllocateContext(Thread* thread,
+ intptr_t num_context_variables,
+ uint32_t* 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));
+ 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;
+ }
+ SP[0] = result;
+ return true;
+ } else {
+ SP[0] = 0; // Space for the result.
+ SP[1] = Smi::New(num_context_variables);
+ Exit(thread, FP, SP + 2, pc);
+ NativeArguments args(thread, 1, SP + 1, SP);
+ return InvokeRuntime(thread, this, DRT_AllocateContext, args);
+ }
+}
+
+// Allocate a _Closure and put it into SP[0].
+// Returns false on exception.
+bool Interpreter::AllocateClosure(Thread* thread,
+ uint32_t* pc,
+ 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));
+ RawObject* null_value = Object::null();
+ for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+ offset += kWordSize) {
+ *reinterpret_cast<RawObject**>(start + offset) = null_value;
+ }
+ SP[0] = result;
+ return true;
+ } else {
+ SP[0] = 0; // Space for the result.
+ SP[1] = thread->isolate()->object_store()->closure_class();
+ SP[2] = Object::null(); // Type arguments.
+ Exit(thread, FP, SP + 3, pc);
+ NativeArguments args(thread, 2, SP + 1, SP);
+ return InvokeRuntime(thread, this, DRT_AllocateObject, args);
+ }
+}
+
RawObject* Interpreter::Call(RawFunction* function,
RawArray* argdesc,
intptr_t argc,
@@ -1540,7 +1564,7 @@
FP[kKBCFunctionSlotFromFp] = function;
FP[kKBCPcMarkerSlotFromFp] = bytecode;
FP[kKBCSavedCallerPcSlotFromFp] =
- reinterpret_cast<RawObject*>((arg_count << 2) | 2);
+ reinterpret_cast<RawObject*>(kEntryFramePcMarker);
FP[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(fp_);
// Load argument descriptor.
@@ -2056,6 +2080,38 @@
}
{
+ BYTECODE(UncheckedInterfaceCall, A_D);
+
+#ifndef PRODUCT
+ // Check if single stepping.
+ if (thread->isolate()->single_step()) {
+ Exit(thread, FP, SP + 1, pc);
+ NativeArguments args(thread, 0, NULL, NULL);
+ INVOKE_RUNTIME(DRT_SingleStepHandler, args);
+ }
+#endif // !PRODUCT
+
+ {
+ const uint16_t argc = rA;
+ const uint16_t kidx = rD;
+
+ RawObject** call_base = SP - argc + 1;
+ RawObject** call_top = SP + 1;
+
+ InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
+ RawString* target_name =
+ static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
+ argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ if (!InterfaceCall(thread, target_name, call_base, call_top, &pc, &FP,
+ &SP)) {
+ HANDLE_EXCEPTION;
+ }
+ }
+
+ DISPATCH();
+ }
+
+ {
BYTECODE(DynamicCall, A_D);
#ifndef PRODUCT
@@ -2306,8 +2362,6 @@
exit_fp);
}
ASSERT(HasFrame(reinterpret_cast<uword>(fp_)));
- const intptr_t argc = reinterpret_cast<uword>(pc) >> 2;
- ASSERT(fp_ == FrameArguments(FP, argc + kKBCEntrySavedSlots));
// Exception propagation should have been done.
ASSERT(!result->IsHeapObject() ||
result->GetClassId() != kUnhandledExceptionCid);
@@ -2498,30 +2552,10 @@
{
BYTECODE(AllocateContext, A_D);
+ ++SP;
const uint16_t num_context_variables = rD;
- {
- 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));
- result->ptr()->num_variables_ = num_context_variables;
- 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;
- }
- *++SP = result;
- } else {
- *++SP = 0;
- SP[1] = Smi::New(num_context_variables);
- Exit(thread, FP, SP + 2, pc);
- NativeArguments args(thread, 1, SP + 1, SP);
- INVOKE_RUNTIME(DRT_AllocateContext, args);
- }
+ if (!AllocateContext(thread, num_context_variables, pc, FP, SP)) {
+ HANDLE_EXCEPTION;
}
DISPATCH();
}
@@ -2971,27 +3005,107 @@
}
{
- BYTECODE(AllocateClosure, A_D);
- 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));
- for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
- offset += kWordSize) {
- *reinterpret_cast<RawObject**>(start + offset) = null_value;
- }
- SP[1] = result;
- ++SP;
+ BYTECODE(NegateDouble, 0);
+ UNBOX_DOUBLE(value, SP[0], Symbols::UnaryMinus());
+ double result = -value;
+ BOX_DOUBLE_RESULT(result);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(AddDouble, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::Plus());
+ UNBOX_DOUBLE(b, SP[1], Symbols::Plus());
+ double result = a + b;
+ BOX_DOUBLE_RESULT(result);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(SubDouble, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::Minus());
+ UNBOX_DOUBLE(b, SP[1], Symbols::Minus());
+ double result = a - b;
+ BOX_DOUBLE_RESULT(result);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(MulDouble, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::Star());
+ UNBOX_DOUBLE(b, SP[1], Symbols::Star());
+ double result = a * b;
+ BOX_DOUBLE_RESULT(result);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(DivDouble, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::Slash());
+ UNBOX_DOUBLE(b, SP[1], Symbols::Slash());
+ double result = a / b;
+ BOX_DOUBLE_RESULT(result);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(CompareDoubleEq, 0);
+ SP -= 1;
+ if ((SP[0] == null_value) || (SP[1] == null_value)) {
+ SP[0] = (SP[0] == SP[1]) ? true_value : false_value;
} else {
- SP[1] = 0; // Space for the result.
- SP[2] = thread->isolate()->object_store()->closure_class();
- SP[3] = null_value; // Type arguments.
- Exit(thread, FP, SP + 4, pc);
- NativeArguments args(thread, 2, SP + 2, SP + 1);
- INVOKE_RUNTIME(DRT_AllocateObject, args);
- ++SP;
+ double a = Double::RawCast(SP[0])->ptr()->value_;
+ double b = Double::RawCast(SP[1])->ptr()->value_;
+ SP[0] = (a == b) ? true_value : false_value;
+ }
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(CompareDoubleGt, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::RAngleBracket());
+ UNBOX_DOUBLE(b, SP[1], Symbols::RAngleBracket());
+ SP[0] = (a > b) ? true_value : false_value;
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(CompareDoubleLt, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::LAngleBracket());
+ UNBOX_DOUBLE(b, SP[1], Symbols::LAngleBracket());
+ SP[0] = (a < b) ? true_value : false_value;
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(CompareDoubleGe, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::GreaterEqualOperator());
+ UNBOX_DOUBLE(b, SP[1], Symbols::GreaterEqualOperator());
+ SP[0] = (a >= b) ? true_value : false_value;
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(CompareDoubleLe, 0);
+ SP -= 1;
+ UNBOX_DOUBLE(a, SP[0], Symbols::LessEqualOperator());
+ UNBOX_DOUBLE(b, SP[1], Symbols::LessEqualOperator());
+ SP[0] = (a <= b) ? true_value : false_value;
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(AllocateClosure, A_D);
+ ++SP;
+ if (!AllocateClosure(thread, pc, FP, SP)) {
+ HANDLE_EXCEPTION;
}
DISPATCH();
}
@@ -3122,15 +3236,7 @@
SP[1] = value;
SP[2] = field_type;
// Provide type arguments of instance as instantiator.
- RawClass* instance_class = thread->isolate()->class_table()->At(
- InterpreterHelpers::GetClassId(instance));
- SP[3] =
- instance_class->ptr()->num_type_arguments_ > 0
- ? reinterpret_cast<RawObject**>(
- instance
- ->ptr())[instance_class->ptr()
- ->type_arguments_field_offset_in_words_]
- : null_value;
+ SP[3] = InterpreterHelpers::GetTypeArguments(thread, instance);
SP[4] = null_value; // Implicit setters cannot be generic.
SP[5] = field->ptr()->name_;
if (!AssertAssignable(thread, pc, FP, /* argv */ SP + 5,
@@ -3195,6 +3301,54 @@
DISPATCH();
}
+ {
+ BYTECODE(VMInternal_MethodExtractor, 0);
+
+ RawFunction* function = FrameFunction(FP);
+ int32_t counter = ++(function->ptr()->usage_counter_);
+ if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
+ counter >= FLAG_compilation_counter_threshold &&
+ !Function::HasCode(function))) {
+ SP[1] = 0; // Unused code result.
+ SP[2] = function;
+ Exit(thread, FP, SP + 3, pc);
+ NativeArguments native_args(thread, 1, SP + 2, SP + 1);
+ INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args);
+ function = FrameFunction(FP);
+ }
+
+ ASSERT(InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) == 0);
+
+ ++SP;
+ if (!AllocateClosure(thread, pc, FP, SP)) {
+ HANDLE_EXCEPTION;
+ }
+
+ ++SP;
+ if (!AllocateContext(thread, 1, pc, FP, SP)) {
+ HANDLE_EXCEPTION;
+ }
+
+ RawContext* context = Context::RawCast(*SP--);
+ RawInstance* instance = Instance::RawCast(FrameArguments(FP, 1)[0]);
+ context->StorePointer(
+ reinterpret_cast<RawInstance**>(&context->ptr()->data()[0]), instance);
+
+ RawClosure* closure = Closure::RawCast(*SP);
+ closure->StorePointer(
+ &closure->ptr()->instantiator_type_arguments_,
+ InterpreterHelpers::GetTypeArguments(thread, instance));
+ // function_type_arguments_ is already null
+ closure->ptr()->delayed_type_arguments_ =
+ Object::empty_type_arguments().raw();
+ closure->StorePointer(&closure->ptr()->function_,
+ Function::RawCast(FrameFunction(FP)->ptr()->data_));
+ closure->StorePointer(&closure->ptr()->context_, context);
+ // hash_ is already null
+
+ DISPATCH();
+ }
+
// Helper used to handle noSuchMethod on closures.
{
ClosureNoSuchMethod:
@@ -3207,11 +3361,11 @@
pc = SavedCallerPC(FP);
const bool has_dart_caller = !IsEntryFrameMarker(pc);
- const intptr_t argc = has_dart_caller ? KernelBytecode::DecodeArgc(pc[-1])
- : (reinterpret_cast<uword>(pc) >> 2);
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
+ const intptr_t argc =
+ InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
SP = FrameArguments(FP, 0);
RawObject** args = SP - argc;
@@ -3287,9 +3441,36 @@
UNREACHABLE();
}
- // Single dispatch point used by exception handling macros.
+ // Exception handling helper. Gets handler FP and PC from the Interpreter
+ // where they were stored by Interpreter::Longjmp and proceeds to execute the
+ // handler. Corner case: handler PC can be a fake marker that marks entry
+ // frame, which means exception was not handled in the interpreter. In this
+ // case we return the caught exception from Interpreter::Call.
{
- DispatchAfterException:
+ HandleException:
+ FP = fp_;
+ pc = pc_;
+ if (IsEntryFrameMarker(pc)) {
+ pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]);
+ argdesc_ =
+ reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
+ uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
+ thread->set_top_exit_frame_info(exit_fp);
+ thread->set_top_resource(top_resource);
+ thread->set_vm_tag(vm_tag);
+#if defined(DEBUG)
+ if (IsTracingExecution()) {
+ THR_Print("%" Pu64 " ", icount_);
+ THR_Print("Returning exception from interpreter 0x%" Px " at fp_ 0x%" Px
+ " exit 0x%" Px "\n",
+ reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_),
+ exit_fp);
+ }
+#endif
+ ASSERT(HasFrame(reinterpret_cast<uword>(fp_)));
+ return special_[KernelBytecode::kExceptionSpecialIndex];
+ }
+
pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
DISPATCH();
}
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 165a6d7..e8fe9db 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -71,6 +71,8 @@
class Interpreter {
public:
static const uword kInterpreterStackUnderflowSize = 0x80;
+ // The entry frame pc marker must be non-zero (a valid exception handler pc).
+ static const word kEntryFramePcMarker = -1;
Interpreter();
~Interpreter();
@@ -95,7 +97,7 @@
// Identify an entry frame by looking at its pc marker value.
static bool IsEntryFrameMarker(uint32_t* pc) {
- return (reinterpret_cast<uword>(pc) & 2) != 0;
+ return reinterpret_cast<word>(pc) == kEntryFramePcMarker;
}
RawObject* Call(const Function& function,
@@ -236,6 +238,15 @@
uint32_t* pc,
RawObject** FP,
RawObject** SP);
+ bool AllocateContext(Thread* thread,
+ intptr_t num_variables,
+ uint32_t* pc,
+ RawObject** FP,
+ RawObject** SP);
+ bool AllocateClosure(Thread* thread,
+ uint32_t* pc,
+ RawObject** FP,
+ RawObject** SP);
#if defined(DEBUG)
// Returns true if tracing of executed instructions is enabled.
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 13227c5..a4a6eea 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -314,7 +314,9 @@
temp_array = klass.fields();
for (intptr_t i = 0; i < temp_array.Length(); ++i) {
temp_field ^= temp_array.At(i);
- if (temp_field.kernel_offset() <= 0) {
+ // TODO(alexmarkov): collect token positions from bytecode
+ if (temp_field.is_declared_in_bytecode() ||
+ temp_field.kernel_offset() <= 0) {
// Skip artificially injected fields.
continue;
}
@@ -333,6 +335,10 @@
for (intptr_t i = 0; i < temp_array.Length(); ++i) {
temp_function ^= temp_array.At(i);
entry_script = temp_function.script();
+ // TODO(alexmarkov): collect token positions from bytecode
+ if (temp_function.is_declared_in_bytecode()) {
+ continue;
+ }
if (entry_script.raw() != interesting_script.raw()) {
continue;
}
@@ -363,6 +369,10 @@
}
} else if (entry.IsFunction()) {
temp_function ^= entry.raw();
+ // TODO(alexmarkov): collect token positions from bytecode
+ if (temp_function.is_declared_in_bytecode()) {
+ continue;
+ }
entry_script = temp_function.script();
if (entry_script.raw() != interesting_script.raw()) {
continue;
@@ -375,7 +385,8 @@
&yield_positions);
} else if (entry.IsField()) {
const Field& field = Field::Cast(entry);
- if (field.kernel_offset() <= 0) {
+ // TODO(alexmarkov): collect token positions from bytecode
+ if (field.is_declared_in_bytecode() || field.kernel_offset() <= 0) {
// Skip artificially injected fields.
continue;
}
@@ -696,11 +707,6 @@
return false;
}
-bool IsFieldInitializer(const Function& function, Zone* zone) {
- return (function.kind() == RawFunction::kImplicitStaticFinalGetter) &&
- Field::IsInitName(String::Handle(zone, function.name()));
-}
-
static ProcedureAttributesMetadata ProcedureAttributesOf(
Zone* zone,
const Script& script,
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 99b3454..0de9d5d 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -212,8 +212,6 @@
// as such function already checks all of its parameters.
bool NeedsDynamicInvocationForwarder(const Function& function);
-bool IsFieldInitializer(const Function& function, Zone* zone);
-
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
Zone* zone);
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 96c4986..760c6ac 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 23;
+static const uint32_t kMaxSupportedKernelFormatVersion = 25;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
@@ -126,7 +126,8 @@
V(NullReference, 99) \
V(ClassReference, 100) \
V(MemberReference, 101) \
- V(ConstantExpression, 107) \
+ V(ConstantExpression, 106) \
+ V(Deprecated_ConstantExpression, 107) \
V(SpecializedVariableGet, 128) \
V(SpecializedVariableSet, 136) \
V(SpecializedIntLiteral, 144)
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 79fb581..4862219 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -44,8 +44,6 @@
"URI scheme that replaces filepaths prefixes specified"
" by kernel_multiroot_filepaths option");
-const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
-
// Tags used to indicate different requests to the dart frontend.
//
// Current tags include the following:
@@ -61,10 +59,11 @@
const int KernelIsolate::kListDependenciesTag = 5;
const int KernelIsolate::kNotifyIsolateShutdown = 6;
+const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
Monitor* KernelIsolate::monitor_ = new Monitor();
+KernelIsolate::State KernelIsolate::state_ = KernelIsolate::kStopped;
Isolate* KernelIsolate::isolate_ = NULL;
-bool KernelIsolate::initializing_ = true;
Dart_Port KernelIsolate::kernel_port_ = ILLEGAL_PORT;
class RunKernelTask : public ThreadPool::Task {
@@ -79,11 +78,7 @@
Dart_IsolateCreateCallback create_callback =
KernelIsolate::create_callback();
-
- if (create_callback == NULL) {
- KernelIsolate::FinishedInitializing();
- return;
- }
+ ASSERT(create_callback != NULL);
// Note: these flags must match those passed to the VM during
// the app-jit training run (see //utils/kernel-service/BUILD.gn).
@@ -109,7 +104,7 @@
free(error);
error = NULL;
KernelIsolate::SetKernelIsolate(NULL);
- KernelIsolate::FinishedInitializing();
+ KernelIsolate::InitializingFailed();
return;
}
@@ -171,6 +166,7 @@
if (FLAG_trace_kernel) {
OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
}
+ KernelIsolate::FinishedExiting();
}
bool RunMain(Isolate* I) {
@@ -223,18 +219,36 @@
};
void KernelIsolate::Run() {
- MonitorLocker ml(monitor_);
- initializing_ = true;
+ {
+ MonitorLocker ml(monitor_);
+ ASSERT(state_ == kStopped);
+ state_ = kStarting;
+ ml.NotifyAll();
+ }
// Grab the isolate create callback here to avoid race conditions with tests
// that change this after Dart_Initialize returns.
create_callback_ = Isolate::CreateCallback();
- Dart::thread_pool()->Run(new RunKernelTask());
+ if (create_callback_ == NULL) {
+ KernelIsolate::InitializingFailed();
+ return;
+ }
+ bool task_started = Dart::thread_pool()->Run(new RunKernelTask());
+ ASSERT(task_started);
}
void KernelIsolate::Shutdown() {
MonitorLocker ml(monitor_);
- while (isolate_ != NULL) {
- Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg);
+ while (state_ == kStarting) {
+ ml.Wait();
+ }
+ if (state_ == kStopped) {
+ return;
+ }
+ ASSERT(state_ == kStarted);
+ state_ = kStopping;
+ ml.NotifyAll();
+ Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg);
+ while (state_ != kStopped) {
ml.Wait();
}
}
@@ -290,16 +304,31 @@
ml.NotifyAll();
}
+void KernelIsolate::FinishedExiting() {
+ MonitorLocker ml(monitor_);
+ ASSERT(state_ == kStarted || state_ == kStopping);
+ state_ = kStopped;
+ ml.NotifyAll();
+}
+
void KernelIsolate::FinishedInitializing() {
MonitorLocker ml(monitor_);
- initializing_ = false;
+ ASSERT(state_ == kStarting);
+ state_ = kStarted;
+ ml.NotifyAll();
+}
+
+void KernelIsolate::InitializingFailed() {
+ MonitorLocker ml(monitor_);
+ ASSERT(state_ == kStarting);
+ state_ = kStopped;
ml.NotifyAll();
}
Dart_Port KernelIsolate::WaitForKernelPort() {
VMTagScope tagScope(Thread::Current(), VMTag::kLoadWaitTagId);
MonitorLocker ml(monitor_);
- while (initializing_ && (kernel_port_ == ILLEGAL_PORT)) {
+ while (state_ == kStarting && (kernel_port_ == ILLEGAL_PORT)) {
ml.Wait();
}
return kernel_port_;
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index 284177b..cdfe9da 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -70,22 +70,28 @@
static void AddExperimentalFlag(const char* value);
protected:
- static Monitor* monitor_;
- static Dart_IsolateCreateCallback create_callback_;
-
static void InitCallback(Isolate* I);
static void SetKernelIsolate(Isolate* isolate);
static void SetLoadPort(Dart_Port port);
+ static void FinishedExiting();
static void FinishedInitializing();
-
- static Dart_Port kernel_port_;
- static Isolate* isolate_;
- static bool initializing_;
-
+ static void InitializingFailed();
static Dart_IsolateCreateCallback create_callback() {
return create_callback_;
}
+ static Dart_IsolateCreateCallback create_callback_;
+ static Monitor* monitor_;
+ enum State {
+ kStopped,
+ kStarting,
+ kStarted,
+ kStopping,
+ };
+ static State state_;
+ static Isolate* isolate_;
+ static Dart_Port kernel_port_;
+
static MallocGrowableArray<char*>* experimental_flags_;
friend class Dart;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 183ae42..b90a609 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -143,8 +143,9 @@
return loader_->LookupClass(library_lookup_handle_, klass);
}
-LibraryIndex::LibraryIndex(const ExternalTypedData& kernel_data)
- : reader_(kernel_data) {
+LibraryIndex::LibraryIndex(const ExternalTypedData& kernel_data,
+ int32_t binary_version)
+ : reader_(kernel_data), binary_version_(binary_version) {
intptr_t data_size = reader_.size();
procedure_count_ = reader_.ReadUInt32At(data_size - 4);
@@ -152,6 +153,11 @@
class_count_ = reader_.ReadUInt32At(procedure_index_offset_ - 4);
class_index_offset_ = procedure_index_offset_ - 4 - (class_count_ + 1) * 4;
+
+ source_references_offset_ = -1;
+ if (binary_version >= 25) {
+ source_references_offset_ = reader_.ReadUInt32At(class_index_offset_ - 4);
+ }
}
ClassIndex::ClassIndex(const uint8_t* buffer,
@@ -539,11 +545,16 @@
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) {
+ if (tag == kConstantExpression ||
+ tag == kDeprecated_ConstantExpression) {
helper_.ReadByte(); // Skip the tag.
// 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()) {
@@ -654,9 +665,13 @@
uri_path = String::null();
const intptr_t tag = helper_.PeekTag();
- if (tag == kConstantExpression) {
+ 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_index = helper_.ReadUInt();
constant ^= constant_table.GetOrDie(constant_table_index);
if (constant.clazz() == external_name_class_.raw()) {
@@ -910,7 +925,8 @@
library_kernel_data_ =
helper_.reader_.ExternalDataFromTo(kernel_offset, library_end);
- LibraryIndex library_index(library_kernel_data_);
+ LibraryIndex library_index(library_kernel_data_,
+ program_->binary_version());
num_classes += library_index.class_count();
num_procedures += library_index.procedure_count();
}
@@ -1001,7 +1017,7 @@
library.set_kernel_data(library_kernel_data_);
library.set_kernel_offset(library_kernel_offset_);
- LibraryIndex library_index(library_kernel_data_);
+ LibraryIndex library_index(library_kernel_data_, program_->binary_version());
intptr_t class_count = library_index.class_count();
library_helper.ReadUntilIncluding(LibraryHelper::kName);
@@ -1084,6 +1100,19 @@
if (register_class) {
classes.Add(toplevel_class, Heap::kOld);
+
+ if (library_index.HasSourceReferences()) {
+ helper_.SetOffset(library_index.SourceReferencesOffset());
+ intptr_t count = helper_.ReadUInt();
+ const GrowableObjectArray& owned_scripts =
+ GrowableObjectArray::Handle(library.owned_scripts());
+ Script& script = Script::Handle(Z);
+ for (intptr_t i = 0; i < count; i++) {
+ intptr_t uri_index = helper_.ReadUInt();
+ script = ScriptAt(uri_index);
+ owned_scripts.Add(script);
+ }
+ }
}
if (!library.Loaded()) library.SetLoaded();
@@ -1668,7 +1697,7 @@
KernelLoader kernel_loader(script, library_kernel_data,
library_kernel_offset);
- LibraryIndex library_index(library_kernel_data);
+ LibraryIndex library_index(library_kernel_data, /*binary_version=*/-1);
if (klass.IsTopLevel()) {
ASSERT(klass.raw() == toplevel_class.raw());
@@ -1725,7 +1754,8 @@
if (DetectPragmaCtor()) {
*has_pragma_annotation = true;
}
- } else if (tag == kConstantExpression) {
+ } else if (tag == kConstantExpression ||
+ tag == kDeprecated_ConstantExpression) {
const Array& constant_table_array =
Array::Handle(kernel_program_info_.constants());
if (constant_table_array.IsNull()) {
@@ -1747,6 +1777,10 @@
helper_.ReadByte(); // Skip the tag.
+ if (tag == kConstantExpression) {
+ helper_.ReadPosition(); // Skip fileOffset.
+ helper_.SkipDartType(); // Skip type.
+ }
const intptr_t offset_in_constant_table = helper_.ReadUInt();
AlternativeReadingScope scope(
@@ -1776,6 +1810,10 @@
// Obtain `dart:_internal::pragma`.
EnsurePragmaClassIsLookedUp();
+ if (tag == kConstantExpression) {
+ 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));
@@ -2233,10 +2271,7 @@
// Create a static initializer.
const Function& initializer_fun = Function::Handle(
- zone, Function::New(init_name,
- // TODO(alexmarkov): Consider creating a separate
- // function kind for field initializers.
- RawFunction::kImplicitStaticFinalGetter,
+ zone, Function::New(init_name, RawFunction::kStaticFieldInitializer,
true, // is_static
false, // is_const
false, // is_abstract
@@ -2248,6 +2283,7 @@
initializer_fun.set_is_inlinable(false);
initializer_fun.set_token_pos(field.token_pos());
initializer_fun.set_end_token_pos(field.end_token_pos());
+ initializer_fun.set_accessor_field(field);
initializer_fun.InheritBinaryDeclarationFrom(field);
field.SetInitializerFunction(initializer_fun);
return initializer_fun.raw();
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index ea39aac..79c58b6 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -82,7 +82,10 @@
class LibraryIndex {
public:
// |kernel_data| is the kernel data for one library alone.
- explicit LibraryIndex(const ExternalTypedData& kernel_data);
+ // binary_version can be -1 in which case some parts of the index might not
+ // be read.
+ explicit LibraryIndex(const ExternalTypedData& kernel_data,
+ int32_t binary_version);
intptr_t class_count() const { return class_count_; }
intptr_t procedure_count() const { return procedure_count_; }
@@ -106,8 +109,17 @@
return -1;
}
+ bool HasSourceReferences() {
+ if (binary_version_ < 25) return false;
+ return true;
+ }
+
+ intptr_t SourceReferencesOffset() { return source_references_offset_; }
+
private:
Reader reader_;
+ int32_t binary_version_;
+ intptr_t source_references_offset_;
intptr_t class_index_offset_;
intptr_t class_count_;
intptr_t procedure_index_offset_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 0397d9c..7a8b971 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -36,6 +36,7 @@
#include "vm/heap/weak_code.h"
#include "vm/isolate_reload.h"
#include "vm/kernel.h"
+#include "vm/kernel_binary.h"
#include "vm/kernel_isolate.h"
#include "vm/kernel_loader.h"
#include "vm/native_symbol.h"
@@ -901,6 +902,17 @@
implicit_setter_bytecode_->set_exception_handlers(
Object::empty_exception_handlers());
+ static const KBCInstr method_extractor_instr[2] = {
+ KernelBytecode::Encode(KernelBytecode::kVMInternal_MethodExtractor),
+ KernelBytecode::Encode(KernelBytecode::kReturnTOS),
+ };
+ *method_extractor_bytecode_ = Bytecode::New(
+ reinterpret_cast<uword>(method_extractor_instr),
+ sizeof(method_extractor_instr), -1, Object::empty_object_pool());
+ method_extractor_bytecode_->set_pc_descriptors(Object::empty_descriptors());
+ method_extractor_bytecode_->set_exception_handlers(
+ Object::empty_exception_handlers());
+
// Some thread fields need to be reinitialized as null constants have not been
// initialized until now.
Thread* thr = Thread::Current();
@@ -962,6 +974,8 @@
ASSERT(implicit_getter_bytecode_->IsBytecode());
ASSERT(!implicit_setter_bytecode_->IsSmi());
ASSERT(implicit_setter_bytecode_->IsBytecode());
+ ASSERT(!method_extractor_bytecode_->IsSmi());
+ ASSERT(method_extractor_bytecode_->IsBytecode());
}
void Object::FinishInit(Isolate* isolate) {
@@ -5678,7 +5692,6 @@
}
}
switch (kind()) {
- case RawFunction::kMethodExtractor:
case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kInvokeFieldDispatcher:
case RawFunction::kDynamicInvocationForwarder:
@@ -5687,7 +5700,7 @@
case RawFunction::kFfiTrampoline:
return false;
case RawFunction::kImplicitStaticFinalGetter:
- return kernel::IsFieldInitializer(*this, zone) || is_const();
+ return is_const();
default:
return true;
}
@@ -5913,6 +5926,7 @@
ASSERT(kind() == RawFunction::kImplicitGetter ||
kind() == RawFunction::kImplicitSetter ||
kind() == RawFunction::kImplicitStaticFinalGetter ||
+ kind() == RawFunction::kStaticFieldInitializer ||
kind() == RawFunction::kDynamicInvocationForwarder);
return Field::RawCast(raw_ptr()->data_);
}
@@ -5920,7 +5934,8 @@
void Function::set_accessor_field(const Field& value) const {
ASSERT(kind() == RawFunction::kImplicitGetter ||
kind() == RawFunction::kImplicitSetter ||
- kind() == RawFunction::kImplicitStaticFinalGetter);
+ kind() == RawFunction::kImplicitStaticFinalGetter ||
+ kind() == RawFunction::kStaticFieldInitializer);
// Top level classes may be finalized multiple times.
ASSERT(raw_ptr()->data_ == Object::null() || raw_ptr()->data_ == value.raw());
set_data(value);
@@ -6148,6 +6163,9 @@
case RawFunction::kImplicitStaticFinalGetter:
return "ImplicitStaticFinalGetter";
break;
+ case RawFunction::kStaticFieldInitializer:
+ return "StaticFieldInitializer";
+ break;
case RawFunction::kMethodExtractor:
return "MethodExtractor";
break;
@@ -6222,6 +6240,7 @@
// implicit getter: Field
// implicit setter: Field
// impl. static final gttr: Field
+// field initializer: Field
// noSuchMethod dispatcher: Array arguments descriptor
// invoke-field dispatcher: Array arguments descriptor
// redirecting constructor: RedirectionData
@@ -8051,6 +8070,9 @@
case RawFunction::kImplicitStaticFinalGetter:
kind_str = " static-final-getter";
break;
+ case RawFunction::kStaticFieldInitializer:
+ kind_str = " static-field-initializer";
+ break;
case RawFunction::kMethodExtractor:
kind_str = " method-extractor";
break;
@@ -10378,6 +10400,15 @@
// We compute the list of loaded scripts lazily. The result is
// cached in loaded_scripts_.
if (loaded_scripts() == Array::null()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // TODO(jensj): Once minimum kernel support is >= 25 this can be cleaned up.
+ // It really should just return the content of `owned_scripts`, and there
+ // should be no need to do the O(n) call to `AddScriptIfUnique` per script.
+ static_assert(
+ kernel::kMinSupportedKernelFormatVersion < 25,
+ "Once minimum kernel support is >= 25 this can be cleaned up.");
+#endif
+
// Iterate over the library dictionary and collect all scripts.
const GrowableObjectArray& scripts =
GrowableObjectArray::Handle(GrowableObjectArray::New(8));
@@ -10400,7 +10431,7 @@
}
// Add all scripts from patch classes.
- GrowableObjectArray& patches = GrowableObjectArray::Handle(patch_classes());
+ GrowableObjectArray& patches = GrowableObjectArray::Handle(owned_scripts());
for (intptr_t i = 0; i < patches.Length(); i++) {
entry = patches.At(i);
if (entry.IsClass()) {
@@ -10856,7 +10887,7 @@
GrowableObjectArray::New(4, Heap::kOld));
result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
result.StorePointer(
- &result.raw_ptr()->patch_classes_,
+ &result.raw_ptr()->owned_scripts_,
GrowableObjectArray::New(Object::empty_array(), Heap::kOld));
result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw());
@@ -15120,6 +15151,8 @@
return "[Bytecode Stub] VMInternal_ImplicitGetter";
} else if (raw() == Object::implicit_setter_bytecode().raw()) {
return "[Bytecode Stub] VMInternal_ImplicitSetter";
+ } else if (raw() == Object::method_extractor_bytecode().raw()) {
+ return "[Bytecode Stub] VMInternal_MethodExtractor";
}
Zone* zone = Thread::Current()->zone();
@@ -15132,9 +15165,11 @@
const char* Bytecode::QualifiedName() const {
if (raw() == Object::implicit_getter_bytecode().raw()) {
- return "[Bytecode Stub] VMInternal__ImplicitGetter";
+ return "[Bytecode Stub] VMInternal_ImplicitGetter";
} else if (raw() == Object::implicit_setter_bytecode().raw()) {
- return "[Bytecode Stub] VMInternal__ImplicitSetter";
+ return "[Bytecode Stub] VMInternal_ImplicitSetter";
+ } else if (raw() == Object::method_extractor_bytecode().raw()) {
+ return "[Bytecode Stub] VMInternal_MethodExtractor";
}
Zone* zone = Thread::Current()->zone();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a3a1aca..b1a0d3b 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -398,6 +398,7 @@
V(Array, extractor_parameter_names) \
V(Bytecode, implicit_getter_bytecode) \
V(Bytecode, implicit_setter_bytecode) \
+ V(Bytecode, method_extractor_bytecode) \
V(Instance, sentinel) \
V(Instance, transition_sentinel) \
V(Instance, unknown_constant) \
@@ -2296,6 +2297,7 @@
case RawFunction::kSignatureFunction:
case RawFunction::kConstructor:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticFieldInitializer:
case RawFunction::kIrregexpFunction:
return false;
default:
@@ -2314,6 +2316,7 @@
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticFieldInitializer:
case RawFunction::kIrregexpFunction:
return true;
case RawFunction::kClosureFunction:
@@ -2592,6 +2595,7 @@
switch (kind()) {
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
+ case RawFunction::kImplicitStaticFinalGetter:
case RawFunction::kNoSuchMethodDispatcher:
case RawFunction::kInvokeFieldDispatcher:
case RawFunction::kDynamicInvocationForwarder:
@@ -2624,7 +2628,7 @@
// Returns true if this function represents an implicit static field
// initializer function.
bool IsImplicitStaticFieldInitializer() const {
- return kind() == RawFunction::kImplicitStaticFinalGetter;
+ return kind() == RawFunction::kStaticFieldInitializer;
}
// Returns true if this function represents a (possibly implicit) closure
@@ -2875,9 +2879,6 @@
// dispatchers is not visible. Synthetic code that can trigger
// exceptions such as the outer async functions that create Futures
// is visible.
- // optimizable: Candidate for going through the optimizing compiler. False for
- // some functions known to be execute infrequently and functions
- // which have been de-optimized too many times.
// instrinsic: Has a hand-written assembly prologue.
// inlinable: Candidate for inlining. False for functions with features we
// don't support during inlining (e.g., optional parameters),
@@ -2899,7 +2900,6 @@
V(Reflectable, is_reflectable) \
V(Visible, is_visible) \
V(Debuggable, is_debuggable) \
- V(Optimizable, is_optimizable) \
V(Inlinable, is_inlinable) \
V(Intrinsic, is_intrinsic) \
V(Native, is_native) \
@@ -2919,6 +2919,17 @@
FOR_EACH_FUNCTION_KIND_BIT(DEFINE_ACCESSORS)
#undef DEFINE_ACCESSORS
+ // optimizable: Candidate for going through the optimizing compiler. False for
+ // some functions known to be execute infrequently and functions
+ // which have been de-optimized too many times.
+ bool is_optimizable() const {
+ return RawFunction::OptimizableBit::decode(raw_ptr()->packed_fields_);
+ }
+ void set_is_optimizable(bool value) const {
+ set_packed_fields(
+ RawFunction::OptimizableBit::update(value, raw_ptr()->packed_fields_));
+ }
+
// Indicates whether this function can be optimized on the background compiler
// thread.
bool is_background_optimizable() const {
@@ -2937,7 +2948,7 @@
enum KindTagBits {
kKindTagPos = 0,
- kKindTagSize = 4,
+ kKindTagSize = 5,
kRecognizedTagPos = kKindTagPos + kKindTagSize,
kRecognizedTagSize = 9,
kModifierPos = kRecognizedTagPos + kRecognizedTagSize,
@@ -3886,8 +3897,8 @@
RawClass* toplevel_class() const { return raw_ptr()->toplevel_class_; }
void set_toplevel_class(const Class& value) const;
- RawGrowableObjectArray* patch_classes() const {
- return raw_ptr()->patch_classes_;
+ RawGrowableObjectArray* owned_scripts() const {
+ return raw_ptr()->owned_scripts_;
}
// Library imports.
@@ -5498,6 +5509,9 @@
static intptr_t num_variables_offset() {
return OFFSET_OF(RawContext, num_variables_);
}
+ static intptr_t NumVariables(const RawContext* context) {
+ return context->ptr()->num_variables_;
+ }
RawObject* At(intptr_t context_index) const {
return *ObjectAddr(context_index);
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 99576c6..e0d65f9 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -332,7 +332,8 @@
static_cast<intptr_t>(deoptimization_counter()));
if ((kind() == RawFunction::kImplicitGetter) ||
(kind() == RawFunction::kImplicitSetter) ||
- (kind() == RawFunction::kImplicitStaticFinalGetter)) {
+ (kind() == RawFunction::kImplicitStaticFinalGetter) ||
+ (kind() == RawFunction::kStaticFieldInitializer)) {
const Field& field = Field::Handle(accessor_field());
if (!field.IsNull()) {
jsobj.AddProperty("_field", field);
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index e987b5c..af98eb1 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -122,6 +122,9 @@
// Cleanup the OS class.
static void Cleanup();
+ // Only implemented on Windows, prevents cleanup code from running.
+ static void PrepareToAbort();
+
DART_NORETURN static void Abort();
DART_NORETURN static void Exit(int code);
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 997578c..196620f 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -337,6 +337,8 @@
void OS::Cleanup() {}
+void OS::PrepareToAbort() {}
+
void OS::Abort() {
abort();
}
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 600141e..df94ba9 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -258,6 +258,8 @@
void OS::Cleanup() {}
+void OS::PrepareToAbort() {}
+
void OS::Abort() {
abort();
}
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 20db94d..bc254e4 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -659,6 +659,8 @@
void OS::Cleanup() {}
+void OS::PrepareToAbort() {}
+
void OS::Abort() {
abort();
}
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 16ce7e8..be6455d 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -323,6 +323,8 @@
void OS::Cleanup() {}
+void OS::PrepareToAbort() {}
+
void OS::Abort() {
abort();
}
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 885009c..1ff4eb9 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -336,9 +336,13 @@
// ThreadLocalData::Cleanup();
}
-void OS::Abort() {
+void OS::PrepareToAbort() {
// TODO(zra): Remove once VM shuts down cleanly.
private_flag_windows_run_tls_destructors = false;
+}
+
+void OS::Abort() {
+ PrepareToAbort();
abort();
}
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index dfc48dd..bae18f7 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -34,7 +34,7 @@
}
visitor->Visit(cls);
}
- patches = lib.patch_classes();
+ patches = lib.owned_scripts();
for (intptr_t j = 0; j < patches.Length(); j++) {
entry = patches.At(j);
if (entry.IsClass()) {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 5f77d72..ffff441 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -851,6 +851,7 @@
kImplicitSetter, // represents an implicit setter for fields.
kImplicitStaticFinalGetter, // represents an implicit getter for static
// final fields (incl. static const fields).
+ kStaticFieldInitializer,
kMethodExtractor, // converts method into implicit closure on the receiver.
kNoSuchMethodDispatcher, // invokes noSuchMethod.
kInvokeFieldDispatcher, // invokes a field as a closure.
@@ -935,6 +936,8 @@
bool,
PackedHasNamedOptionalParameters::kNextBit,
1>
+ OptimizableBit;
+ typedef BitField<uint32_t, bool, OptimizableBit::kNextBit, 1>
BackgroundOptimizableBit;
typedef BitField<uint32_t,
uint16_t,
@@ -1153,7 +1156,7 @@
RawArray* dictionary_; // Top-level names in this library.
RawGrowableObjectArray* metadata_; // Metadata on classes, methods etc.
RawClass* toplevel_class_; // Class containing top-level elements.
- RawGrowableObjectArray* patch_classes_;
+ RawGrowableObjectArray* owned_scripts_;
RawArray* imports_; // List of Namespaces imported without prefix.
RawArray* exports_; // List of re-exported Namespaces.
RawInstance* load_error_; // Error iff load_state_ == kLoadError.
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 6bb1ac1..5728dad 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -71,7 +71,7 @@
F(Library, dictionary_) \
F(Library, metadata_) \
F(Library, toplevel_class_) \
- F(Library, patch_classes_) \
+ F(Library, owned_scripts_) \
F(Library, imports_) \
F(Library, exports_) \
F(Library, load_error_) \
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 69b8a7a..f54d840 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -1718,6 +1718,7 @@
// not act as an OSR entry outside loops.
AppendInstruction(new (Z) CheckStackOverflowInstr(
TokenPosition::kNoSource,
+ /*stack_depth=*/0,
/*loop_depth=*/1, GetNextDeoptId(),
is_backtrack ? CheckStackOverflowInstr::kOsrAndPreemption
: CheckStackOverflowInstr::kOsrOnly));
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index bcc8277..da70f90 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -219,30 +219,6 @@
Exceptions::ThrowByType(Exceptions::kIntegerDivisionByZeroException, args);
}
-static void EnsureNewOrRemembered(Thread* thread, const Object& result) {
- // For generational write barrier elimination, we need to ensure that the
- // allocation ends up in the new space if Heap::IsGuaranteedNewSpaceAllocation
- // is true for this size or else the object needs to go into the store buffer.
- NoSafepointScope no_safepoint_scope;
-
- RawObject* object = result.raw();
- if (!object->IsNewObject()) {
- object->AddToRememberedSet(thread);
- }
-}
-
-static void EnsureNewOrDeferredMarking(Thread* thread, const Object& result) {
- // For incremental write barrier elimination, we need to ensure that the
- // allocation ends up in the new space or else the object needs to added
- // to deferred marking stack so it will be [re]scanned.
- NoSafepointScope no_safepoint_scope;
-
- RawObject* object = result.raw();
- if (object->IsOldObject() && thread->is_marking()) {
- thread->DeferredMarkingStackAddObject(object);
- }
-}
-
// Allocation of a fixed length array of given element type.
// This runtime entry is never called for allocating a List of a generic type,
// because a prior run time call instantiates the element type if necessary.
@@ -272,14 +248,6 @@
ASSERT(element_type.IsNull() ||
(element_type.Length() >= 1 && element_type.IsInstantiated()));
array.SetTypeArguments(element_type); // May be null.
-
- ASSERT(Array::UseCardMarkingForAllocation(len) ==
- array.raw()->IsCardRemembered());
- if (!array.raw()->IsCardRemembered()) {
- EnsureNewOrRemembered(thread, array);
- }
- EnsureNewOrDeferredMarking(thread, array);
-
return;
}
}
@@ -325,13 +293,57 @@
(type_arguments.Length() >= cls.NumTypeArguments())));
instance.SetTypeArguments(type_arguments);
}
-
- if (AllocateObjectInstr::WillAllocateNewOrRemembered(cls)) {
- EnsureNewOrRemembered(thread, instance);
- EnsureNewOrDeferredMarking(thread, instance);
- }
}
+DEFINE_LEAF_RUNTIME_ENTRY(RawObject*,
+ AddAllocatedObjectToRememberedSet,
+ 2,
+ RawObject* object,
+ Thread* thread) {
+ // The allocation stubs in will call this leaf method for newly allocated
+ // old space objects.
+ RELEASE_ASSERT(object->IsOldObject() && !object->IsRemembered());
+
+ // If we eliminate a generational write barriers on allocations of an object
+ // we need to ensure it's either a new-space object or it has been added to
+ // the remebered set.
+ //
+ // NOTE: We use reinterpret_cast<>() instead of ::RawCast() to avoid handle
+ // allocations in debug mode. Handle allocations in leaf runtimes can cause
+ // memory leaks because they will allocate into a handle scope from the next
+ // outermost runtime code (to which the genenerated Dart code might not return
+ // in a long time).
+ bool add_to_remembered_set = true;
+ if (object->IsArray()) {
+ const intptr_t length =
+ Array::LengthOf(reinterpret_cast<RawArray*>(object));
+ add_to_remembered_set =
+ CreateArrayInstr::WillAllocateNewOrRemembered(length);
+ } else if (object->IsContext()) {
+ const intptr_t num_context_variables =
+ Context::NumVariables(reinterpret_cast<RawContext*>(object));
+ add_to_remembered_set =
+ AllocateContextInstr::WillAllocateNewOrRemembered(
+ num_context_variables) ||
+ AllocateUninitializedContextInstr::WillAllocateNewOrRemembered(
+ num_context_variables);
+ }
+
+ if (add_to_remembered_set) {
+ object->AddToRememberedSet(thread);
+ }
+
+ // For incremental write barrier elimination, we need to ensure that the
+ // allocation ends up in the new space or else the object needs to added
+ // to deferred marking stack so it will be [re]scanned.
+ if (thread->is_marking()) {
+ thread->DeferredMarkingStackAddObject(object);
+ }
+
+ return object;
+}
+END_LEAF_RUNTIME_ENTRY
+
// Instantiate type.
// Arg0: uninstantiated type.
// Arg1: instantiator type arguments.
@@ -433,15 +445,6 @@
const Context& context =
Context::Handle(zone, Context::New(num_variables.Value()));
arguments.SetReturn(context);
-
- const intptr_t num_context_variables = num_variables.Value();
- if (AllocateContextInstr::WillAllocateNewOrRemembered(
- num_context_variables) ||
- AllocateUninitializedContextInstr::WillAllocateNewOrRemembered(
- num_context_variables)) {
- EnsureNewOrRemembered(thread, context);
- EnsureNewOrDeferredMarking(thread, context);
- }
}
// Make a copy of the given context, including the values of the captured
@@ -461,28 +464,6 @@
arguments.SetReturn(cloned_ctx);
}
-// Extract a method by allocating and initializing a new Closure.
-// Arg0: receiver.
-// Arg1: method.
-// Return value: newly allocated Closure.
-DEFINE_RUNTIME_ENTRY(ExtractMethod, 2) {
- ASSERT(FLAG_enable_interpreter);
- const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
- const Function& method = Function::CheckedHandle(zone, arguments.ArgAt(1));
- const TypeArguments& instantiator_type_arguments =
- method.HasInstantiatedSignature(kCurrentClass)
- ? Object::null_type_arguments()
- : TypeArguments::Handle(zone, receiver.GetTypeArguments());
- ASSERT(method.HasInstantiatedSignature(kFunctions));
- const Context& context = Context::Handle(zone, Context::New(1));
- context.SetAt(0, receiver);
- const Closure& closure = Closure::Handle(
- zone,
- Closure::New(instantiator_type_arguments, Object::null_type_arguments(),
- Object::empty_type_arguments(), method, context));
- arguments.SetReturn(closure);
-}
-
// Result of an invoke may be an unhandled exception, in which case we
// rethrow it.
static void ThrowIfError(const Object& result) {
@@ -2761,4 +2742,20 @@
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
+extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) {
+ Thread* thread = Thread::Current();
+ ASSERT(thread->top_exit_frame_info() != 0);
+ ASSERT(thread->execution_state() == Thread::kThreadInNative);
+ thread->EnterSafepoint();
+}
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(EnterSafepoint, 0, false, &DFLRT_EnterSafepoint);
+
+extern "C" void DFLRT_ExitSafepoint(NativeArguments __unusable_) {
+ Thread* thread = Thread::Current();
+ ASSERT(thread->top_exit_frame_info() != 0);
+ ASSERT(thread->execution_state() == Thread::kThreadInNative);
+ thread->ExitSafepoint();
+}
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(ExitSafepoint, 0, false, &DFLRT_ExitSafepoint);
+
} // namespace dart
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 13fb2b8ec..bb2eca9 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -15,7 +15,6 @@
V(BreakpointRuntimeHandler) \
V(SingleStepHandler) \
V(CloneContext) \
- V(ExtractMethod) \
V(GetFieldForDispatch) \
V(ResolveCallFunction) \
V(FixCallersTarget) \
@@ -65,6 +64,8 @@
V(void, StoreBufferBlockProcess, Thread*) \
V(void, MarkingStackBlockProcess, Thread*) \
V(void, RememberCard, RawObject*, RawObject**) \
+ V(RawObject*, AddAllocatedObjectToRememberedSet, RawObject* object, \
+ Thread* thread) \
V(double, LibcPow, double, double) \
V(double, DartModulo, double, double) \
V(double, LibcFloor, double) \
@@ -78,7 +79,10 @@
V(double, LibcAsin, double) \
V(double, LibcAtan, double) \
V(double, LibcAtan2, double, double) \
- V(RawBool*, CaseInsensitiveCompareUC16, RawString*, RawSmi*, RawSmi*, RawSmi*)
+ V(RawBool*, CaseInsensitiveCompareUC16, RawString*, RawSmi*, RawSmi*, \
+ RawSmi*) \
+ V(void, EnterSafepoint) \
+ V(void, ExitSafepoint)
} // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 2aeb4a3..e96f9a5 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -513,7 +513,7 @@
return true;
}
- static intptr_t Parse(const char* value) {
+ static uintptr_t Parse(const char* value) {
if (value == NULL) {
return -1;
}
@@ -3849,9 +3849,9 @@
Profile::TagOrder tag_order =
EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
int64_t time_origin_micros =
- UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
+ Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
int64_t time_extent_micros =
- UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
+ Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
bool code_trie = BoolParameter::Parse(js->LookupParam("code"), false);
ProfilerService::PrintTimelineJSON(js, tag_order, time_origin_micros,
time_extent_micros, code_trie);
@@ -3862,9 +3862,9 @@
Profile::TagOrder tag_order =
EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
int64_t time_origin_micros =
- UIntParameter::Parse(js->LookupParam("timeOriginMicros"));
+ Int64Parameter::Parse(js->LookupParam("timeOriginMicros"));
int64_t time_extent_micros =
- UIntParameter::Parse(js->LookupParam("timeExtentMicros"));
+ Int64Parameter::Parse(js->LookupParam("timeExtentMicros"));
bool code_trie = BoolParameter::Parse(js->LookupParam("code"), true);
ProfilerService::AddToTimeline(tag_order, time_origin_micros,
time_extent_micros, code_trie);
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 46f8f02..085b11a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -72,15 +72,14 @@
return list.raw();
}
-const char* ServiceIsolate::kName = "vm-service";
+const char* ServiceIsolate::kName = DART_VM_SERVICE_ISOLATE_NAME;
+Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL;
+Monitor* ServiceIsolate::monitor_ = new Monitor();
+ServiceIsolate::State ServiceIsolate::state_ = ServiceIsolate::kStopped;
Isolate* ServiceIsolate::isolate_ = NULL;
Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT;
Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT;
Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT;
-Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL;
-Monitor* ServiceIsolate::monitor_ = new Monitor();
-bool ServiceIsolate::initializing_ = true;
-bool ServiceIsolate::shutting_down_ = false;
char* ServiceIsolate::server_address_ = NULL;
void ServiceIsolate::RequestServerInfo(const SendPort& sp) {
@@ -145,7 +144,7 @@
Dart_Port ServiceIsolate::WaitForLoadPort() {
VMTagScope tagScope(Thread::Current(), VMTag::kLoadWaitTagId);
MonitorLocker ml(monitor_);
- while (initializing_ && (load_port_ == ILLEGAL_PORT)) {
+ while (state_ == kStarting && (load_port_ == ILLEGAL_PORT)) {
ml.Wait();
}
return load_port_;
@@ -207,7 +206,8 @@
ASSERT(!list.IsNull());
MessageWriter writer(false);
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
+ " registered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
@@ -232,7 +232,8 @@
ASSERT(!list.IsNull());
MessageWriter writer(false);
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Isolate %s %" Pd64 " deregistered.\n",
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
+ " deregistered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
@@ -244,7 +245,8 @@
return;
}
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: sending service exit message.\n");
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
+ ": sending service exit message.\n");
}
Dart_CObject code;
@@ -299,13 +301,22 @@
void ServiceIsolate::FinishedExiting() {
MonitorLocker ml(monitor_);
- shutting_down_ = false;
+ ASSERT(state_ == kStarted || state_ == kStopping);
+ state_ = kStopped;
ml.NotifyAll();
}
void ServiceIsolate::FinishedInitializing() {
MonitorLocker ml(monitor_);
- initializing_ = false;
+ ASSERT(state_ == kStarting);
+ state_ = kStarted;
+ ml.NotifyAll();
+}
+
+void ServiceIsolate::InitializingFailed() {
+ MonitorLocker ml(monitor_);
+ ASSERT(state_ == kStarting);
+ state_ = kStopped;
ml.NotifyAll();
}
@@ -331,11 +342,12 @@
NULL, &api_flags, NULL, &error));
if (isolate == NULL) {
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
+ ": Isolate creation error: %s\n",
+ error);
}
ServiceIsolate::SetServiceIsolate(NULL);
- ServiceIsolate::FinishedInitializing();
- ServiceIsolate::FinishedExiting();
+ ServiceIsolate::InitializingFailed();
return;
}
@@ -380,11 +392,13 @@
Error& error = Error::Handle(Z);
error = T->sticky_error();
if (!error.IsNull() && !error.IsUnwindError()) {
- OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Error: %s\n",
+ error.ToErrorCString());
}
error = I->sticky_error();
if (!error.IsNull() && !error.IsUnwindError()) {
- OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Error: %s\n",
+ error.ToErrorCString());
}
Dart::RunShutdownCallback();
}
@@ -395,7 +409,7 @@
// Shut the isolate down.
Dart::ShutdownIsolate(I);
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Shutdown.\n");
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Shutdown.\n");
}
ServiceIsolate::FinishedExiting();
}
@@ -410,7 +424,8 @@
Library::Handle(Z, I->object_store()->root_library());
if (root_library.IsNull()) {
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Embedder did not install a script.");
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
+ ": Embedder did not install a script.");
}
// Service isolate is not supported by embedder.
return false;
@@ -423,7 +438,8 @@
if (entry.IsNull()) {
// Service isolate is not supported by embedder.
if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Embedder did not provide a main function.");
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
+ ": Embedder did not provide a main function.");
}
return false;
}
@@ -435,7 +451,8 @@
// Service isolate did not initialize properly.
if (FLAG_trace_service) {
const Error& error = Error::Cast(result);
- OS::PrintErr("vm-service: Calling main resulted in an error: %s",
+ OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
+ ": Calling main resulted in an error: %s",
error.ToErrorCString());
}
if (result.IsUnwindError()) {
@@ -451,42 +468,65 @@
};
void ServiceIsolate::Run() {
+ {
+ MonitorLocker ml(monitor_);
+ ASSERT(state_ == kStopped);
+ state_ = kStarting;
+ ml.NotifyAll();
+ }
// Grab the isolate create callback here to avoid race conditions with tests
// that change this after Dart_Initialize returns.
create_callback_ = Isolate::CreateCallback();
if (create_callback_ == NULL) {
- ServiceIsolate::FinishedInitializing();
+ ServiceIsolate::InitializingFailed();
return;
}
- Dart::thread_pool()->Run(new RunServiceTask());
+ bool task_started = Dart::thread_pool()->Run(new RunServiceTask());
+ ASSERT(task_started);
}
void ServiceIsolate::KillServiceIsolate() {
{
MonitorLocker ml(monitor_);
- shutting_down_ = true;
+ if (state_ == kStopped) {
+ return;
+ }
+ ASSERT(state_ == kStarted);
+ state_ = kStopping;
+ ml.NotifyAll();
}
Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg);
{
MonitorLocker ml(monitor_);
- while (shutting_down_) {
+ while (state_ == kStopping) {
ml.Wait();
}
+ ASSERT(state_ == kStopped);
}
}
void ServiceIsolate::Shutdown() {
+ {
+ MonitorLocker ml(monitor_);
+ while (state_ == kStarting) {
+ ml.Wait();
+ }
+ }
+
if (IsRunning()) {
{
MonitorLocker ml(monitor_);
- shutting_down_ = true;
+ ASSERT(state_ == kStarted);
+ state_ = kStopping;
+ ml.NotifyAll();
}
SendServiceExitMessage();
{
MonitorLocker ml(monitor_);
- while (shutting_down_ && (port_ != ILLEGAL_PORT)) {
+ while (state_ == kStopping) {
ml.Wait();
}
+ ASSERT(state_ == kStopped);
}
} else {
if (isolate_ != NULL) {
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index e6ecc405f..ab08649 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -63,6 +63,7 @@
static void SetLoadPort(Dart_Port port);
static void FinishedExiting();
static void FinishedInitializing();
+ static void InitializingFailed();
static void MaybeMakeServiceIsolate(Isolate* isolate);
static Dart_IsolateCreateCallback create_callback() {
return create_callback_;
@@ -70,8 +71,13 @@
static Dart_IsolateCreateCallback create_callback_;
static Monitor* monitor_;
- static bool initializing_;
- static bool shutting_down_;
+ enum State {
+ kStopped,
+ kStarting,
+ kStarted,
+ kStopping,
+ };
+ static State state_;
static Isolate* isolate_;
static Dart_Port port_;
static Dart_Port load_port_;
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 2af28ff..18839b45 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1220,9 +1220,9 @@
const Array& arguments,
Thread* thread) {
// Interpreter state (see constants_dbc.h for high-level overview).
- uint32_t* pc; // Program Counter: points to the next op to execute.
- RawObject** FP; // Frame Pointer.
- RawObject** SP; // Stack Pointer.
+ uint32_t* pc; // Program Counter: points to the next op to execute.
+ RawObject** FP; // Frame Pointer.
+ RawObject** SP; // Stack Pointer.
uint32_t op; // Currently executing op.
uint16_t rA; // A component of the currently executing op.
@@ -1471,7 +1471,9 @@
{
BYTECODE(DebugStep, A);
-#ifndef PRODUCT
+#ifdef PRODUCT
+ FATAL("No debugging in PRODUCT mode");
+#else
if (thread->isolate()->single_step()) {
Exit(thread, FP, SP + 1, pc);
NativeArguments args(thread, 0, NULL, NULL);
@@ -1483,7 +1485,9 @@
{
BYTECODE(DebugBreak, A);
-#if !defined(PRODUCT)
+#ifdef PRODUCT
+ FATAL("No debugging in PRODUCT mode");
+#else
{
const uint32_t original_bc =
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(
@@ -1496,9 +1500,6 @@
INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args)
DISPATCH_OP(original_bc);
}
-#else
- // There should be no debug breaks in product mode.
- UNREACHABLE();
#endif
DISPATCH();
}
@@ -3025,6 +3026,14 @@
}
{
+ BYTECODE(NullError, 0);
+ Exit(thread, FP, SP, pc);
+ NativeArguments native_args(thread, 0, SP, SP);
+ INVOKE_RUNTIME(DRT_NullError, native_args);
+ UNREACHABLE();
+ }
+
+ {
BYTECODE(BadTypeError, 0);
// Stack: instance, instantiator type args, function type args, type, name
RawObject** args = SP - 4;
@@ -3655,6 +3664,22 @@
}
{
+ BYTECODE(IfEqNullTOS, 0);
+ if (SP[0] != null_value) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(IfNeNullTOS, 0);
+ if (SP[0] == null_value) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(Jump, 0);
const int32_t target = static_cast<int32_t>(op) >> 8;
pc += (target - 1);
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 9061c99..6cf4754 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -93,6 +93,7 @@
case RawFunction::kClosureFunction:
case RawFunction::kImplicitClosureFunction:
case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kStaticFieldInitializer:
case RawFunction::kGetterFunction:
case RawFunction::kSetterFunction:
case RawFunction::kConstructor:
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index ae8edb8..b1d4b79 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -387,8 +387,17 @@
#if !defined(TARGET_ARCH_DBC)
// For normal unoptimized Dart frames and Stub frames each slot
// between the first and last included are tagged objects.
- RawObject** first = reinterpret_cast<RawObject**>(
- is_interpreted() ? fp() + (kKBCFirstObjectSlotFromFp * kWordSize) : sp());
+ if (is_interpreted()) {
+ // Do not visit caller's pc or caller's fp.
+ RawObject** first =
+ reinterpret_cast<RawObject**>(fp()) + kKBCFirstObjectSlotFromFp;
+ RawObject** last =
+ reinterpret_cast<RawObject**>(fp()) + kKBCLastFixedObjectSlotFromFp;
+
+ visitor->VisitPointers(first, last);
+ }
+ RawObject** first =
+ reinterpret_cast<RawObject**>(is_interpreted() ? fp() : sp());
RawObject** last = reinterpret_cast<RawObject**>(
is_interpreted()
? sp()
diff --git a/runtime/vm/stack_frame_kbc.h b/runtime/vm/stack_frame_kbc.h
index 8bfe809..3418eaa 100644
--- a/runtime/vm/stack_frame_kbc.h
+++ b/runtime/vm/stack_frame_kbc.h
@@ -22,8 +22,8 @@
Current frame | ... T| <- SP of current frame
| ... T|
| first local T| <- FP of current frame
- | caller's FP *|
- | caller's PC *|
+ | caller's FP |
+ | caller's PC |
| code object T| (current frame's code object)
| function object T| (current frame's function object)
+--------------------+
@@ -31,8 +31,6 @@
| ... |
T against a slot indicates it needs to be traversed during GC.
- * against a slot indicates that it can be traversed during GC
- because it will look like a smi to the visitor.
*/
static const int kKBCDartFrameFixedSize = 4; // Function, Code, PC, FP
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index ce9d729..602ec4d 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -75,7 +75,9 @@
V(StackOverflowSharedWithFPURegs) \
V(StackOverflowSharedWithoutFPURegs) \
V(OneArgCheckInlineCacheWithExactnessCheck) \
- V(OneArgOptimizedCheckInlineCacheWithExactnessCheck)
+ V(OneArgOptimizedCheckInlineCacheWithExactnessCheck) \
+ V(EnterSafepoint) \
+ V(ExitSafepoint)
#else
#define VM_STUB_CODE_LIST(V) \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 8ea5953..e4b6658 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -76,6 +76,8 @@
active_stacktrace_(Object::null()),
global_object_pool_(ObjectPool::null()),
resume_pc_(0),
+ execution_state_(kThreadInNative),
+ safepoint_state_(0),
task_kind_(kUnknownTask),
dart_stream_(NULL),
thread_lock_(new Monitor()),
@@ -97,10 +99,9 @@
pending_functions_(GrowableObjectArray::null()),
sticky_error_(Error::null()),
REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
- REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) safepoint_state_(0),
- execution_state_(kThreadInNative),
+ REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
#if defined(USING_SAFE_STACK)
- saved_safestack_limit_(0),
+ saved_safestack_limit_(0),
#endif
#if !defined(DART_PRECOMPILED_RUNTIME)
interpreter_(nullptr),
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 5e771b0..f5b7c97 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -121,7 +121,9 @@
StubCode::DeoptimizeLazyFromThrow().raw(), NULL) \
V(RawCode*, slow_type_test_stub_, StubCode::SlowTypeTest().raw(), NULL) \
V(RawCode*, lazy_specialize_type_test_stub_, \
- StubCode::LazySpecializeTypeTest().raw(), NULL)
+ StubCode::LazySpecializeTypeTest().raw(), NULL) \
+ V(RawCode*, enter_safepoint_stub_, StubCode::EnterSafepoint().raw(), NULL) \
+ V(RawCode*, exit_safepoint_stub_, StubCode::ExitSafepoint().raw(), NULL)
#endif
@@ -307,6 +309,10 @@
}
#endif
+ static intptr_t safepoint_state_offset() {
+ return OFFSET_OF(Thread, safepoint_state_);
+ }
+
TaskKind task_kind() const { return task_kind_; }
// Retrieves and clears the stack overflow flags. These are set by
@@ -673,8 +679,8 @@
do {
old_state = safepoint_state_;
new_state = SafepointRequestedField::update(value, old_state);
- } while (AtomicOperations::CompareAndSwapUint32(
- &safepoint_state_, old_state, new_state) != old_state);
+ } while (AtomicOperations::CompareAndSwapWord(&safepoint_state_, old_state,
+ new_state) != old_state);
return old_state;
}
static bool IsBlockedForSafepoint(uint32_t state) {
@@ -706,7 +712,10 @@
return static_cast<ExecutionState>(execution_state_);
}
void set_execution_state(ExecutionState state) {
- execution_state_ = static_cast<uint32_t>(state);
+ execution_state_ = static_cast<uword>(state);
+ }
+ static intptr_t execution_state_offset() {
+ return OFFSET_OF(Thread, execution_state_);
}
virtual bool MayAllocateHandles() {
@@ -714,10 +723,13 @@
(execution_state() == kThreadInGenerated);
}
+ static uword safepoint_state_unacquired() { return SetAtSafepoint(false, 0); }
+ static uword safepoint_state_acquired() { return SetAtSafepoint(true, 0); }
+
bool TryEnterSafepoint() {
uint32_t new_state = SetAtSafepoint(true, 0);
- if (AtomicOperations::CompareAndSwapUint32(&safepoint_state_, 0,
- new_state) != 0) {
+ if (AtomicOperations::CompareAndSwapWord(&safepoint_state_, 0, new_state) !=
+ 0) {
return false;
}
return true;
@@ -735,8 +747,8 @@
bool TryExitSafepoint() {
uint32_t old_state = SetAtSafepoint(true, 0);
- if (AtomicOperations::CompareAndSwapUint32(&safepoint_state_, old_state,
- 0) != old_state) {
+ if (AtomicOperations::CompareAndSwapWord(&safepoint_state_, old_state, 0) !=
+ old_state) {
return false;
}
return true;
@@ -838,6 +850,8 @@
RawObject* active_stacktrace_;
RawObjectPool* global_object_pool_;
uword resume_pc_;
+ uword execution_state_;
+ uword safepoint_state_;
// ---- End accessed from generated code. ----
@@ -889,8 +903,6 @@
class SafepointRequestedField : public BitField<uint32_t, bool, 1, 1> {};
class BlockedForSafepointField : public BitField<uint32_t, bool, 2, 1> {};
class BypassSafepointsField : public BitField<uint32_t, bool, 3, 1> {};
- uint32_t safepoint_state_;
- uint32_t execution_state_;
#if defined(USING_SAFE_STACK)
uword saved_safestack_limit_;
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index ebb07bd..a7becbe 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -116,6 +116,10 @@
// Delay between interrupts.
void ThreadInterrupter::SetInterruptPeriod(intptr_t period) {
+ if (!initialized_) {
+ // Profiler may not be enabled.
+ return;
+ }
MonitorLocker ml(monitor_);
if (shutdown_) {
return;
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index b627ddf..3f934fd 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -77,16 +77,20 @@
uword alignment,
uword vmar_base,
uword padded_size) {
+ // Allocate a larger mapping than needed in order to find a suitable aligned
+ // mapping within it.
uword base;
zx_status_t status =
zx_vmar_map(vmar, options, 0, vmo, 0u, padded_size, &base);
LOG_INFO("zx_vmar_map(%u, 0x%lx, 0x%lx)\n", options, base, padded_size);
-
if (status != ZX_OK) {
LOG_ERR("zx_vmar_map(%u, 0x%lx, 0x%lx) failed: %s\n", options, base,
padded_size, zx_status_get_string(status));
return NULL;
}
+
+ // Allocate a smaller aligned mapping inside the larger mapping.
+ const uword orig_base = base;
const uword aligned_base = Utils::RoundUp(base, alignment);
const zx_vm_option_t overwrite_options = options | ZX_VM_SPECIFIC_OVERWRITE;
status = zx_vmar_map(vmar, overwrite_options, aligned_base - vmar_base, vmo,
@@ -100,6 +104,11 @@
return NULL;
}
ASSERT(base == aligned_base);
+
+ // Unmap the unused prefix and suffix.
+ Unmap(vmar, orig_base, base);
+ Unmap(vmar, base + size, orig_base + padded_size);
+
return reinterpret_cast<void*>(base);
}
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index f4aa3ef..586cc38 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -42,6 +42,7 @@
"code_patcher_x64.cc",
"compilation_trace.cc",
"compilation_trace.h",
+ "constants_arm.cc",
"constants_arm.h",
"constants_arm64.cc",
"constants_arm64.h",
diff --git a/samples/sample_extension/sample_extension.cc b/samples/sample_extension/sample_extension.cc
index 5af3f74..f183d36 100644
--- a/samples/sample_extension/sample_extension.cc
+++ b/samples/sample_extension/sample_extension.cc
@@ -102,7 +102,11 @@
result.value.as_typed_data.type = Dart_TypedData_kUint8;
result.value.as_typed_data.values = values;
result.value.as_typed_data.length = length;
- Dart_PostCObject(reply_port_id, &result);
+ if (Dart_PostCObject(reply_port_id, &result)) {
+ Dart_CObject error;
+ error.type = Dart_CObject_kNull;
+ Dart_PostCObject(reply_port_id, &error);
+ }
free(values);
// It is OK that result is destroyed when function exits.
// Dart_PostCObject has copied its data.
@@ -110,9 +114,8 @@
}
}
}
- Dart_CObject result;
- result.type = Dart_CObject_kNull;
- Dart_PostCObject(reply_port_id, &result);
+ fprintf(stderr, "Invalid message received, cannot proceed. Aborting the process.\n");
+ abort();
}
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 44a9352..e637ca2 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -170,6 +170,14 @@
Language/Expressions/Shift/equivalent_super_t02: Skip # triple-shift flag
Language/Expressions/Shift/equivalent_t02: Skip # triple-shift flag
Language/Expressions/Shift/integer_t03: Skip # triple-shift flag
+Language/Expressions/Shift/integer_t04/01: Crash
+Language/Expressions/Shift/integer_t04/02: Crash
+Language/Expressions/Shift/integer_t04/03: Crash
+Language/Expressions/Shift/integer_t04/04: Crash
+Language/Expressions/Shift/integer_t04/05: Crash
+Language/Expressions/Shift/integer_t04/06: Crash
+Language/Expressions/Shift/integer_t04/07: Crash
+Language/Expressions/Shift/integer_t04/none: Crash
Language/Expressions/Shift/syntax_t01: Skip # triple-shift experiment flag
Language/Expressions/Shift/syntax_t15: Skip # triple-shift experiment flag
Language/Expressions/Shift/syntax_t17: Skip # triple-shift experiment flag
@@ -283,11 +291,19 @@
LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash
LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash
LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash
-LanguageFeatures/Constant-update-2018/TypeTestOperator_A01_t01: CompileTimeError
-LanguageFeatures/Control-flow-collections/type_inference_A09_t01: Crash
-LanguageFeatures/Control-flow-collections/type_inference_A11_t01: CompileTimeError
-LanguageFeatures/Control-flow-collections/type_inference_A13_t01: CompileTimeError
-LanguageFeatures/Control-flow-collections/type_inference_A13_t02: CompileTimeError
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/none: Crash
LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t02: CompileTimeError
LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
@@ -563,6 +579,8 @@
LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t04/01: MissingCompileTimeError
LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t04/02: MissingCompileTimeError
LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t10: CompileTimeError
+LanguageFeatures/Spread-collections/ConstSpreads_A09_t09/04: MissingCompileTimeError
+LanguageFeatures/Spread-collections/ConstSpreads_A10_t09/04: MissingCompileTimeError
LanguageFeatures/Spread-collections/TypeInference_A01_t03/06: MissingCompileTimeError
LanguageFeatures/Spread-collections/TypeInference_A01_t03/07: MissingCompileTimeError
LanguageFeatures/Spread-collections/TypeInference_A01_t03/08: MissingCompileTimeError
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
new file mode 100644
index 0000000..75fa653
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class I1 {}
+
+class I2 {}
+
+class A implements I1, I2 {}
+
+class B implements I1, I2 {}
+
+/*element: foo:params=1*/
+@pragma('dart2js:noInline')
+void foo(I1 x) {}
+
+/*element: 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*/
+main() {
+ dynamic f = bar;
+
+ foo(new A());
+ foo(new B());
+ f(new A());
+ f(new B());
+}
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
index 8a1f1ec..52f93c0 100644
--- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -99,11 +99,11 @@
const ConstantData(
'const {0: 1, 2: 3}',
'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})'),
+ 'IntConstant(2): IntConstant(3)})'),
const ConstantData(
'const <int, int>{0: 1, 2: 3}',
'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})'),
+ 'IntConstant(2): IntConstant(3)})'),
const ConstantData('const <int, int>{0: 1, 0: 2}', 'NonConstant',
expectedErrors: 'ConstEvalDuplicateKey'),
const ConstantData(
@@ -155,36 +155,36 @@
const ConstantData(
'const C()',
'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(false)))'),
+ 'field2=BoolConstant(false)))'),
const ConstantData(
'const C(field1: 87)',
'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=BoolConstant(false)))'),
+ 'field2=BoolConstant(false)))'),
const ConstantData(
'const C(field2: true)',
'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(true)))'),
+ 'field2=BoolConstant(true)))'),
const ConstantData(
'const C.named()',
'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=BoolConstant(false)))'),
+ 'field2=BoolConstant(false)))'),
const ConstantData(
'const C.named(87)',
'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=IntConstant(87)))'),
+ 'field2=IntConstant(87)))'),
const ConstantData(
'const C(field1: a, field2: b)', const <Map<String, String>, String>{
const {}: 'ConstructedConstant(C(field1=BoolConstant(true),'
'field2=IntConstant(42)))',
const {'foo': 'false', 'bar': '87'}:
'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=IntConstant(87)))',
+ 'field2=IntConstant(87)))',
}),
const ConstantData(
'const D(42, 87)',
'ConstructedConstant(D(field1=IntConstant(87),'
- 'field2=IntConstant(42),'
- 'field3=IntConstant(99)))'),
+ 'field2=IntConstant(42),'
+ 'field3=IntConstant(99)))'),
]),
const TestData('redirect', '''
class A<T> implements B<Null> {
@@ -252,19 +252,19 @@
const ConstantData(
'const A.named(99, 100)',
'ConstructedConstant(A('
- 't=IntConstant(100),'
- 'u=IntConstant(42),'
- 'x=IntConstant(3),'
- 'y=IntConstant(499),'
- 'z=IntConstant(99)))'),
+ 't=IntConstant(100),'
+ 'u=IntConstant(42),'
+ 'x=IntConstant(3),'
+ 'y=IntConstant(499),'
+ 'z=IntConstant(99)))'),
const ConstantData(
'const A(99, 100)',
'ConstructedConstant(A('
- 't=IntConstant(100),'
- 'u=IntConstant(42),'
- 'x=IntConstant(3),'
- 'y=IntConstant(499),'
- 'z=IntConstant(99)))'),
+ 't=IntConstant(100),'
+ 'u=IntConstant(42),'
+ 'x=IntConstant(3),'
+ 'y=IntConstant(499),'
+ 'z=IntConstant(99)))'),
]),
const TestData('errors', r'''
const dynamic null_ = const bool.fromEnvironment('x') ? null : null;
@@ -441,13 +441,13 @@
const ConstantData(
'const C<int>(0, identity)',
'ConstructedConstant(C<int>(defaultValue=IntConstant(0),'
- 'identityFunction=InstantiationConstant([int],'
- 'FunctionConstant(identity))))'),
+ 'identityFunction=InstantiationConstant([int],'
+ 'FunctionConstant(identity))))'),
const ConstantData(
'const C<double>(0.5, identity)',
'ConstructedConstant(C<double>(defaultValue=DoubleConstant(0.5),'
- 'identityFunction=InstantiationConstant([double],'
- 'FunctionConstant(identity))))'),
+ 'identityFunction=InstantiationConstant([double],'
+ 'FunctionConstant(identity))))'),
]),
const TestData('generic class', '''
class C<T> {
@@ -508,7 +508,6 @@
CompilationResult result = await runCompiler(memorySourceFiles: {
'main.dart': source
}, options: [
- '${Flags.enableLanguageExperiments}=constant-update-2018',
Flags.enableAsserts,
]);
Compiler compiler = result.compiler;
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
deleted file mode 100644
index fafdcbb..0000000
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ /dev/null
@@ -1,685 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.constants.expressions.evaluate_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/common.dart';
-import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/constants/constructors.dart';
-import 'package:compiler/src/constants/evaluation.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/diagnostics/messages.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/kernel/element_map_impl.dart';
-import '../helpers/memory_compiler.dart';
-
-class TestData {
- final String name;
-
- /// Declarations needed for the [constants].
- final String declarations;
-
- /// Tested constants.
- final List<ConstantData> constants;
-
- const TestData(this.name, this.declarations, this.constants);
-}
-
-class ConstantData {
- /// Source code for the constant expression.
- final String code;
-
- /// Constant value as structured text for the empty environment or a map from
- /// environment to either the expected constant value as structured text or
- /// a [ConstantResult].
- final expectedResults;
-
- /// A [MessageKind] or a list of [MessageKind]s containing the error messages
- /// expected as the result of evaluating the constant under the empty
- /// environment.
- final expectedErrors;
-
- const ConstantData(this.code, this.expectedResults, {this.expectedErrors});
-}
-
-class EvaluationError {
- final MessageKind kind;
- final Map arguments;
-
- EvaluationError(this.kind, this.arguments);
-}
-
-class MemoryEnvironment implements EvaluationEnvironment {
- final EvaluationEnvironment _environment;
- final Map<String, String> env;
- final List<EvaluationError> errors = <EvaluationError>[];
-
- MemoryEnvironment(this._environment, [this.env = const <String, String>{}]);
-
- @override
- bool get checkCasts => true;
-
- @override
- String readFromEnvironment(String name) => env[name];
-
- @override
- InterfaceType substByContext(InterfaceType base, InterfaceType target) {
- return _environment.substByContext(base, target);
- }
-
- @override
- DartType getTypeInContext(DartType type) =>
- _environment.getTypeInContext(type);
-
- @override
- ConstantConstructor getConstructorConstant(ConstructorEntity constructor) {
- return _environment.getConstructorConstant(constructor);
- }
-
- @override
- ConstantExpression getFieldConstant(FieldEntity field) {
- return _environment.getFieldConstant(field);
- }
-
- @override
- ConstantExpression getLocalConstant(Local local) {
- return _environment.getLocalConstant(local);
- }
-
- @override
- CommonElements get commonElements => _environment.commonElements;
-
- @override
- DartTypes get types => _environment.types;
-
- @override
- InterfaceType get enclosingConstructedType =>
- _environment.enclosingConstructedType;
-
- @override
- void reportWarning(
- ConstantExpression expression, MessageKind kind, Map arguments) {
- errors.add(new EvaluationError(kind, arguments));
- _environment.reportWarning(expression, kind, arguments);
- }
-
- @override
- void reportError(
- ConstantExpression expression, MessageKind kind, Map arguments) {
- errors.add(new EvaluationError(kind, arguments));
- _environment.reportError(expression, kind, arguments);
- }
-
- @override
- ConstantValue evaluateConstructor(ConstructorEntity constructor,
- InterfaceType type, ConstantValue evaluate()) {
- return _environment.evaluateConstructor(constructor, type, evaluate);
- }
-
- @override
- ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate()) {
- return _environment.evaluateField(field, evaluate);
- }
-
- @override
- ConstantValue evaluateMapBody(ConstantValue evaluate()) {
- return _environment.evaluateMapBody(evaluate);
- }
-
- @override
- bool get enableAssertions => true;
-}
-
-const List<TestData> DATA = const [
- const TestData('simple', '', const [
- const ConstantData('null', 'NullConstant'),
- const ConstantData('false', 'BoolConstant(false)'),
- const ConstantData('true', 'BoolConstant(true)'),
- const ConstantData('0', 'IntConstant(0)'),
- const ConstantData('0.0', 'IntConstant(0)'),
- const ConstantData('"foo"', 'StringConstant("foo")'),
- const ConstantData('1 + 2', 'IntConstant(3)'),
- const ConstantData('-(1)', 'IntConstant(-1)'),
- const ConstantData('1 == 2', 'BoolConstant(false)'),
- const ConstantData('1 != 2', 'BoolConstant(true)'),
- const ConstantData('1 / 0', 'DoubleConstant(Infinity)'),
- const ConstantData('0 / 0', 'DoubleConstant(NaN)'),
- const ConstantData('1 << 0', 'IntConstant(1)'),
- const ConstantData('1 >> 0', 'IntConstant(1)'),
- const ConstantData('"foo".length', 'IntConstant(3)'),
- const ConstantData('identical(0, 1)', 'BoolConstant(false)'),
- const ConstantData('"a" "b"', 'StringConstant("ab")'),
- const ConstantData(r'"${null}"', 'StringConstant("null")'),
- const ConstantData('identical', 'FunctionConstant(identical)'),
- const ConstantData('true ? 0 : 1', 'IntConstant(0)'),
- const ConstantData('proxy', 'ConstructedConstant(_Proxy())'),
- const ConstantData('const [] == null', 'BoolConstant(false)'),
- const ConstantData('proxy == null', 'BoolConstant(false)'),
- const ConstantData('Object', 'TypeConstant(Object)'),
- const ConstantData('null ?? 0', 'IntConstant(0)'),
- const ConstantData(
- 'const [0, 1]', 'ListConstant(<int>[IntConstant(0), IntConstant(1)])'),
- const ConstantData('const <int>[0, 1]',
- 'ListConstant(<int>[IntConstant(0), IntConstant(1)])'),
- const ConstantData(
- 'const {0: 1, 2: 3}',
- 'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})'),
- const ConstantData(
- 'const <int, int>{0: 1, 2: 3}',
- 'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})'),
- const ConstantData('const <int, int>{0: 1, 0: 2}',
- 'MapConstant(<int, int>{IntConstant(0): IntConstant(2)})',
- expectedErrors: MessageKind.EQUAL_MAP_ENTRY_KEY),
- const ConstantData(
- 'const bool.fromEnvironment("foo", defaultValue: false)',
- const <Map<String, String>, String>{
- const {}: 'BoolConstant(false)',
- const {'foo': 'true'}: 'BoolConstant(true)'
- }),
- const ConstantData(
- 'const int.fromEnvironment("foo", defaultValue: 42)',
- const <Map<String, String>, String>{
- const {}: 'IntConstant(42)',
- const {'foo': '87'}: 'IntConstant(87)'
- }),
- const ConstantData(
- 'const String.fromEnvironment("foo", defaultValue: "bar")',
- const <Map<String, String>, String>{
- const {}: 'StringConstant("bar")',
- const {'foo': 'foo'}: 'StringConstant("foo")'
- }),
- ]),
- const TestData('env', '''
-const a = const bool.fromEnvironment("foo", defaultValue: true);
-const b = const int.fromEnvironment("bar", defaultValue: 42);
-
-class A {
- const A();
-}
-class B {
- final field1;
- const B(this.field1);
-}
-class C extends B {
- final field2;
- const C({field1: 42, this.field2: false}) : super(field1);
- const C.named([field = false]) : this(field1: field, field2: field);
-}
-class D extends C {
- final field3 = 99;
- const D(a, b) : super(field2: a, field1: b);
-}
-''', const [
- const ConstantData('const Object()', 'ConstructedConstant(Object())'),
- const ConstantData('const A()', 'ConstructedConstant(A())'),
- const ConstantData(
- 'const B(0)', 'ConstructedConstant(B(field1=IntConstant(0)))'),
- const ConstantData('const B(const A())',
- 'ConstructedConstant(B(field1=ConstructedConstant(A())))'),
- const ConstantData(
- 'const C()',
- 'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(false)))'),
- const ConstantData(
- 'const C(field1: 87)',
- 'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=BoolConstant(false)))'),
- const ConstantData(
- 'const C(field2: true)',
- 'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(true)))'),
- const ConstantData(
- 'const C.named()',
- 'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=BoolConstant(false)))'),
- const ConstantData(
- 'const C.named(87)',
- 'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=IntConstant(87)))'),
- const ConstantData(
- 'const C(field1: a, field2: b)', const <Map<String, String>, String>{
- const {}: 'ConstructedConstant(C(field1=BoolConstant(true),'
- 'field2=IntConstant(42)))',
- const {'foo': 'false', 'bar': '87'}:
- 'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=IntConstant(87)))',
- }),
- const ConstantData(
- 'const D(42, 87)',
- 'ConstructedConstant(D(field1=IntConstant(87),'
- 'field2=IntConstant(42),'
- 'field3=IntConstant(99)))'),
- ]),
- const TestData('redirect', '''
-class A<T> implements B<Null> {
- final field1;
- const A({this.field1:42});
-}
-class B<S> implements C<Null> {
- const factory B({field1}) = A<B<S>>;
- const factory B.named() = A<S>;
-}
-class C<U> {
- const factory C({field1}) = A<B<double>>;
-}
-''', const [
- const ConstantData(
- 'const A()', 'ConstructedConstant(A<dynamic>(field1=IntConstant(42)))'),
- const ConstantData('const A<int>(field1: 87)',
- 'ConstructedConstant(A<int>(field1=IntConstant(87)))'),
- const ConstantData('const B()',
- 'ConstructedConstant(A<B<dynamic>>(field1=IntConstant(42)))'),
- const ConstantData('const B<int>()',
- 'ConstructedConstant(A<B<int>>(field1=IntConstant(42)))'),
- const ConstantData('const B<int>(field1: 87)',
- 'ConstructedConstant(A<B<int>>(field1=IntConstant(87)))'),
- const ConstantData('const C<int>(field1: 87)',
- 'ConstructedConstant(A<B<double>>(field1=IntConstant(87)))'),
- const ConstantData('const B<int>.named()',
- 'ConstructedConstant(A<int>(field1=IntConstant(42)))'),
- ]),
- const TestData('env2', '''
-const c = const int.fromEnvironment("foo", defaultValue: 5);
-const d = const int.fromEnvironment("bar", defaultValue: 10);
-
-class A {
- final field;
- const A(a, b) : field = a + b;
-}
-
-class B extends A {
- const B(a) : super(a, a * 2);
-}
-''', const [
- const ConstantData('const A(c, d)', const <Map<String, String>, String>{
- const {}: 'ConstructedConstant(A(field=IntConstant(15)))',
- const {'foo': '7', 'bar': '11'}:
- 'ConstructedConstant(A(field=IntConstant(18)))',
- }),
- const ConstantData('const B(d)', const <Map<String, String>, String>{
- const {}: 'ConstructedConstant(B(field=IntConstant(30)))',
- const {'bar': '42'}: 'ConstructedConstant(B(field=IntConstant(126)))',
- }),
- ]),
- const TestData('construct', '''
- class A {
- final x;
- final y;
- final z;
- final t;
- final u = 42;
- const A(this.z, tt) : y = 499, t = tt, x = 3;
- const A.named(z, this.t) : y = 400 + z, this.z = z, x = 3;
- const A.named2(t, z, y, x) : x = t, y = z, z = y, t = x;
- }
- ''', const [
- const ConstantData(
- 'const A.named(99, 100)',
- 'ConstructedConstant(A('
- 't=IntConstant(100),'
- 'u=IntConstant(42),'
- 'x=IntConstant(3),'
- 'y=IntConstant(499),'
- 'z=IntConstant(99)))'),
- const ConstantData(
- 'const A(99, 100)',
- 'ConstructedConstant(A('
- 't=IntConstant(100),'
- 'u=IntConstant(42),'
- 'x=IntConstant(3),'
- 'y=IntConstant(499),'
- 'z=IntConstant(99)))'),
- ]),
- const TestData('errors', r'''
- const integer = const int.fromEnvironment("foo", defaultValue: 5);
- const string = const String.fromEnvironment("bar", defaultValue: "baz");
- const boolean = const bool.fromEnvironment("baz", defaultValue: false);
- const not_string =
- const bool.fromEnvironment("not_string", defaultValue: false) ? '' : 0;
- get getter => 0;
- class Class1 {
- final field;
- const Class1() : field = not_string.length;
- }
- class Class2 implements Class3 {
- const Class2() : assert(false);
- const Class2.redirect() : this();
- }
- class Class3 {
- const Class3() : assert(false, "Message");
- const factory Class3.fact() = Class2;
- }
- class Class4 extends Class2 {
- const Class4();
- }
- class Class5 {
- const Class5(a) : assert(a > 0, "$a <= 0");
- }
- class Class6 extends Class5 {
- const Class6(a) : super(a - 1);
- }
- class Class7 {
- const Class7();
- }
- ''', const [
- const ConstantData(
- r'"$integer $string $boolean"', 'StringConstant("5 baz false")'),
- const ConstantData('0 ? true : false', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_CONDITIONAL_TYPE),
- const ConstantData('integer ? true : false', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_CONDITIONAL_TYPE),
- const ConstantData(r'"${const []}"', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE),
- const ConstantData(r'"${proxy}"', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE),
- const ConstantData(r'"${proxy}${const []}"', 'NonConstant',
- expectedErrors: const [
- MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE,
- MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE
- ]),
- const ConstantData(r'"${"${proxy}"}${const []}"', 'NonConstant',
- expectedErrors: const [
- MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE,
- MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE
- ]),
- const ConstantData('0 + ""', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NUM_ADD_TYPE),
- const ConstantData('0 + string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NUM_ADD_TYPE),
- const ConstantData('"" + 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_ADD_TYPE),
- const ConstantData('string + 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_ADD_TYPE),
- const ConstantData('true + ""', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_ADD_TYPE),
- const ConstantData('boolean + string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_ADD_TYPE),
- const ConstantData('true + false', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_ADD_TYPES),
- const ConstantData('boolean + false', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_ADD_TYPES),
- const ConstantData('0 * ""', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_NUM_TYPE),
- const ConstantData('0 * string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_NUM_TYPE),
- const ConstantData('0 % ""', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_NUM_TYPE),
- const ConstantData('0 % string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_NUM_TYPE),
- const ConstantData('0 << ""', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_INT_TYPE),
- const ConstantData('0 << string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_INT_TYPE),
- const ConstantData('1 ~/ 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_DIV),
- const ConstantData('1 ~/ 0.0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_DIV),
- const ConstantData('1 % 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_DIV),
- const ConstantData('1 % 0.0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_DIV),
- const ConstantData('1 << -1', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_SHIFT),
- const ConstantData('1 >> -1', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_SHIFT),
- const ConstantData('null[0]', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_INDEX),
- const ConstantData('const bool.fromEnvironment(0)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData('const bool.fromEnvironment(integer)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData(
- 'const bool.fromEnvironment("baz", defaultValue: 0)', 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_BOOL_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData(
- 'const bool.fromEnvironment("baz", defaultValue: integer)',
- 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_BOOL_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData('const int.fromEnvironment(0)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData('const int.fromEnvironment(integer)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData(
- 'const int.fromEnvironment("baz", defaultValue: "")', 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_INT_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData(
- 'const int.fromEnvironment("baz", defaultValue: string)', 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_INT_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData('const String.fromEnvironment(0)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData('const String.fromEnvironment(integer)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_FROM_ENVIRONMENT_NAME_TYPE),
- const ConstantData(
- 'const String.fromEnvironment("baz", defaultValue: 0)', 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_STRING_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData(
- 'const String.fromEnvironment("baz", defaultValue: integer)',
- 'NonConstant',
- expectedErrors:
- MessageKind.INVALID_STRING_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE),
- const ConstantData('true || 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_OR_OPERAND_TYPE),
- const ConstantData('0 || true', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_OR_OPERAND_TYPE),
- const ConstantData('true || integer', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_OR_OPERAND_TYPE),
- const ConstantData('integer || true', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_OR_OPERAND_TYPE),
- const ConstantData('true && 0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_AND_OPERAND_TYPE),
- const ConstantData('0 && true', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_AND_OPERAND_TYPE),
- const ConstantData('integer && true', 'NonConstant',
- expectedErrors: MessageKind.INVALID_LOGICAL_AND_OPERAND_TYPE),
- const ConstantData('!0', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NOT_TYPE),
- const ConstantData('!string', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NOT_TYPE),
- const ConstantData('-("")', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NEGATE_TYPE),
- const ConstantData('-(string)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_NEGATE_TYPE),
- const ConstantData('not_string.length', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_LENGTH_TYPE),
- const ConstantData('const Class1()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_CONSTANT_STRING_LENGTH_TYPE),
- const ConstantData('getter', 'NonConstant'),
- const ConstantData('const Class2()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE),
- const ConstantData('const Class2.redirect()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE),
- const ConstantData('const Class3()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE_MESSAGE),
- const ConstantData('const Class3.fact()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE),
- const ConstantData('const Class4()', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE),
- const ConstantData('const Class5(0)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE_MESSAGE),
- const ConstantData('const Class5(1)', 'ConstructedConstant(Class5())'),
- const ConstantData('const Class6(1)', 'NonConstant',
- expectedErrors: MessageKind.INVALID_ASSERT_VALUE_MESSAGE),
- const ConstantData('const Class6(2)', 'ConstructedConstant(Class6())'),
- const ConstantData('const Class7()', 'ConstructedConstant(Class7())'),
- const ConstantData('const Class7() == const Class7()', 'NonConstant',
- expectedErrors: const [
- MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE,
- MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE
- ]),
- ]),
- const TestData('assert', '''
- class A {
- const A() : assert(true);
- }
- class B {
- const B() : assert(true, "Message");
- }
- class C {
- final a;
- const C(this.a);
- }
- class D extends C {
- final b;
- const D(c) : b = c + 2, super(c + 1);
- }
- ''', const [
- const ConstantData(r'const A()', 'ConstructedConstant(A())'),
- const ConstantData(r'const B()', 'ConstructedConstant(B())'),
- const ConstantData(r'const D(0)',
- 'ConstructedConstant(D(a=IntConstant(1),b=IntConstant(2)))'),
- ]),
- const TestData('instantiations', '''
-T identity<T>(T t) => t;
-class C<T> {
- final T defaultValue;
- final T Function(T t) identityFunction;
-
- const C(this.defaultValue, this.identityFunction);
-}
- ''', const <ConstantData>[
- const ConstantData('identity', 'FunctionConstant(identity)'),
- const ConstantData(
- 'const C<int>(0, identity)',
- 'ConstructedConstant(C<int>(defaultValue=IntConstant(0),'
- 'identityFunction=InstantiationConstant([int],'
- 'FunctionConstant(identity))))'),
- const ConstantData(
- 'const C<double>(0.5, identity)',
- 'ConstructedConstant(C<double>(defaultValue=DoubleConstant(0.5),'
- 'identityFunction=InstantiationConstant([double],'
- 'FunctionConstant(identity))))'),
- ]),
- const TestData('generic class', '''
-class C<T> {
- const C.generative();
- const C.redirect() : this.generative();
-}
- ''', const <ConstantData>[
- const ConstantData(
- 'const C<int>.generative()', 'ConstructedConstant(C<int>())'),
- const ConstantData(
- 'const C<int>.redirect()', 'ConstructedConstant(C<int>())'),
- ])
-];
-
-main(List<String> args) {
- asyncTest(() async {
- for (TestData data in DATA) {
- if (args.isNotEmpty && !args.contains(data.name)) continue;
- await testData(data);
- }
- });
-}
-
-Future testData(TestData data) async {
- StringBuffer sb = new StringBuffer();
- sb.writeln('${data.declarations}');
- Map<String, ConstantData> constants = {};
- List<String> names = <String>[];
- data.constants.forEach((ConstantData constantData) {
- String name = 'c${constants.length}';
- names.add(name);
- sb.writeln('const $name = ${constantData.code};');
- constants[name] = constantData;
- });
- sb.writeln('main() {');
- for (String name in names) {
- sb.writeln(' print($name);');
- }
- sb.writeln('}');
- String source = sb.toString();
- print("--source '${data.name}'---------------------------------------------");
- print(source);
-
- Future runTest(
- EvaluationEnvironment getEnvironment(
- Compiler compiler, FieldEntity field)) async {
- CompilationResult result =
- await runCompiler(memorySourceFiles: {'main.dart': source});
- Compiler compiler = result.compiler;
- KElementEnvironment elementEnvironment =
- compiler.frontendStrategy.elementEnvironment;
- LibraryEntity library = elementEnvironment.mainLibrary;
- constants.forEach((String name, ConstantData data) {
- FieldEntity field = elementEnvironment.lookupLibraryMember(library, name);
- compiler.reporter.withCurrentElement(field, () {
- ConstantExpression constant =
- elementEnvironment.getFieldConstantForTesting(field);
-
- var expectedResults = data.expectedResults;
- if (expectedResults is String) {
- expectedResults = <Map<String, String>, String>{
- const <String, String>{}: expectedResults
- };
- }
- expectedResults.forEach((Map<String, String> env, String expectedText) {
- MemoryEnvironment environment =
- new MemoryEnvironment(getEnvironment(compiler, field), env);
- ConstantValue value = constant.evaluate(environment);
-
- Expect.isNotNull(
- value,
- "Expected non-null value from evaluation of "
- "`${constant.toStructuredText()}`.");
-
- String valueText = value.toStructuredText();
- Expect.equals(
- expectedText,
- valueText,
- "Unexpected value '${valueText}' for field $field = "
- "`${constant.toDartText()}`, expected '${expectedText}'.");
-
- List<MessageKind> errors =
- environment.errors.map((m) => m.kind).toList();
- var expectedErrors = data.expectedErrors;
- if (expectedErrors != null) {
- if (expectedErrors is! List) {
- expectedErrors = [expectedErrors];
- }
- Expect.listEquals(
- expectedErrors,
- errors,
- "Error mismatch for `$field = ${constant.toDartText()}`:\n"
- "Expected: ${data.expectedErrors},\n"
- "Found: ${errors}.");
- } else {
- Expect.isTrue(
- errors.isEmpty,
- "Unexpected errors for `$field = ${constant.toDartText()}`:\n"
- "Found: ${errors}.");
- }
- });
- });
- });
- }
-
- const skipStrongList = const [
- // TODO(johnniwinther): Investigate why different errors are reported in
- // strong mode.
- 'errors',
- ];
-
- if (!skipStrongList.contains(data.name)) {
- await runTest((Compiler compiler, FieldEntity field) {
- KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
- KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
- return new KernelEvaluationEnvironment(elementMap, null, field,
- constantRequired: field.isConst);
- });
- }
-}
diff --git a/tests/compiler/dart2js/model/constant_expression_test.dart b/tests/compiler/dart2js/model/constant_expression_test.dart
deleted file mode 100644
index dee8ee5..0000000
--- a/tests/compiler/dart2js/model/constant_expression_test.dart
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library constant_expression_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/common_elements.dart' show KElementEnvironment;
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/kernel/element_map_impl.dart';
-import 'package:compiler/src/elements/entities.dart';
-import '../helpers/memory_compiler.dart';
-import 'constant_expression_evaluate_test.dart' show MemoryEnvironment;
-
-class TestData {
- /// Declarations needed for the [constants].
- final String declarations;
-
- /// Tested constants.
- final List<ConstantData> constants;
-
- const TestData(this.declarations, this.constants);
-}
-
-class ConstantData {
- /// Source code for the constant expression.
- final String code;
-
- /// The expected constant expression kind.
- final ConstantExpressionKind kind;
-
- /// ConstantExpression.getText() result if different from [code].
- final String text;
-
- /// The expected instance type for ConstructedConstantExpression.
- final String type;
-
- /// The expected instance fields for ConstructedConstantExpression.
- final Map<String, String> fields;
-
- const ConstantData(String code, this.kind,
- {String text, this.type, this.fields})
- : this.code = code,
- this.text = text ?? code;
-}
-
-const List<TestData> DATA = const [
- const TestData('''
-class Class<T, S> {
- final a;
- final b;
- final c;
- const Class(this.a, {this.b, this.c: true});
- const Class.named([this.a, this.b = 0, this.c = 2]);
-
- static const staticConstant = 0;
- static staticFunction() {}
-}
-const t = true;
-const f = false;
-const toplevelConstant = 0;
-toplevelFunction() {}
-''', const [
- const ConstantData('null', ConstantExpressionKind.NULL),
- const ConstantData('false', ConstantExpressionKind.BOOL),
- const ConstantData('true', ConstantExpressionKind.BOOL),
- const ConstantData('0', ConstantExpressionKind.INT),
- const ConstantData('0.0', ConstantExpressionKind.DOUBLE),
- const ConstantData('"foo"', ConstantExpressionKind.STRING),
- const ConstantData('1 + 2', ConstantExpressionKind.BINARY),
- const ConstantData('1 == 2', ConstantExpressionKind.BINARY),
- const ConstantData('1 != 2', ConstantExpressionKind.UNARY,
- // a != b is encoded as !(a == b) by CFE.
- text: '!(1 == 2)'),
- const ConstantData('1 ?? 2', ConstantExpressionKind.BINARY),
- const ConstantData('-(1)', ConstantExpressionKind.UNARY, text: '-1'),
- const ConstantData('"foo".length', ConstantExpressionKind.STRING_LENGTH),
- const ConstantData('identical(0, 1)', ConstantExpressionKind.IDENTICAL),
- const ConstantData('"a" "b"', ConstantExpressionKind.CONCATENATE,
- text: '"ab"'),
- const ConstantData('identical', ConstantExpressionKind.FUNCTION),
- const ConstantData('true ? 0 : 1', ConstantExpressionKind.CONDITIONAL),
- const ConstantData('proxy', ConstantExpressionKind.FIELD),
- const ConstantData('Object', ConstantExpressionKind.TYPE),
- const ConstantData('#name', ConstantExpressionKind.SYMBOL),
- const ConstantData('const []', ConstantExpressionKind.LIST),
- const ConstantData('const [0, 1]', ConstantExpressionKind.LIST,
- text: 'const <int>[0, 1]'),
- const ConstantData('const <int>[0, 1]', ConstantExpressionKind.LIST),
- const ConstantData('const <dynamic>[0, 1]', ConstantExpressionKind.LIST,
- text: 'const [0, 1]'),
- const ConstantData('const {}', ConstantExpressionKind.MAP),
- const ConstantData('const {0: 1, 2: 3}', ConstantExpressionKind.MAP,
- text: 'const <int, int>{0: 1, 2: 3}'),
- const ConstantData(
- 'const <int, int>{0: 1, 2: 3}', ConstantExpressionKind.MAP),
- const ConstantData(
- 'const <String, int>{"0": 1, "2": 3}', ConstantExpressionKind.MAP),
- const ConstantData(
- 'const <String, dynamic>{"0": 1, "2": 3}', ConstantExpressionKind.MAP),
- const ConstantData(
- 'const <dynamic, dynamic>{"0": 1, "2": 3}', ConstantExpressionKind.MAP,
- text: 'const {"0": 1, "2": 3}'),
- const ConstantData('const bool.fromEnvironment("foo", defaultValue: false)',
- ConstantExpressionKind.BOOL_FROM_ENVIRONMENT),
- const ConstantData('const int.fromEnvironment("foo", defaultValue: 42)',
- ConstantExpressionKind.INT_FROM_ENVIRONMENT),
- const ConstantData(
- 'const String.fromEnvironment("foo", defaultValue: "bar")',
- ConstantExpressionKind.STRING_FROM_ENVIRONMENT),
- const ConstantData('const Class(0)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class(0, b: 1)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class(0, c: 2)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class(0, b: 3, c: 4)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class.named()', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class.named(0)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class.named(0, 1)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class.named(0, 1, 2)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class<String, int>(0)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class<String, dynamic>(0)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class<dynamic, String>(0)', ConstantExpressionKind.CONSTRUCTED),
- const ConstantData(
- 'const Class<dynamic, dynamic>(0)', ConstantExpressionKind.CONSTRUCTED,
- text: 'const Class(0)'),
- const ConstantData('toplevelConstant', ConstantExpressionKind.FIELD),
- const ConstantData('toplevelFunction', ConstantExpressionKind.FUNCTION),
- const ConstantData('Class.staticConstant', ConstantExpressionKind.FIELD),
- const ConstantData('Class.staticFunction', ConstantExpressionKind.FUNCTION),
- const ConstantData('1 + 2', ConstantExpressionKind.BINARY),
- const ConstantData('1 + 2 + 3', ConstantExpressionKind.BINARY),
- const ConstantData('1 + -2', ConstantExpressionKind.BINARY),
- const ConstantData('-1 + 2', ConstantExpressionKind.BINARY),
- const ConstantData('(1 + 2) + 3', ConstantExpressionKind.BINARY,
- text: '1 + 2 + 3'),
- const ConstantData('1 + (2 + 3)', ConstantExpressionKind.BINARY,
- text: '1 + 2 + 3'),
- const ConstantData('1 * 2', ConstantExpressionKind.BINARY),
- const ConstantData('1 * 2 + 3', ConstantExpressionKind.BINARY),
- const ConstantData('1 * (2 + 3)', ConstantExpressionKind.BINARY),
- const ConstantData('1 + 2 * 3', ConstantExpressionKind.BINARY),
- const ConstantData('(1 + 2) * 3', ConstantExpressionKind.BINARY),
- const ConstantData(
- 'false || identical(0, 1)', ConstantExpressionKind.BINARY),
- const ConstantData('!identical(0, 1)', ConstantExpressionKind.UNARY),
- const ConstantData(
- '!identical(0, 1) || false', ConstantExpressionKind.BINARY),
- const ConstantData(
- '!(identical(0, 1) || false)', ConstantExpressionKind.UNARY),
- const ConstantData('identical(0, 1) ? 3 * 4 + 5 : 6 + 7 * 8',
- ConstantExpressionKind.CONDITIONAL),
- const ConstantData('t ? f ? 0 : 1 : 2', ConstantExpressionKind.CONDITIONAL),
- const ConstantData(
- '(t ? t : f) ? f ? 0 : 1 : 2', ConstantExpressionKind.CONDITIONAL),
- const ConstantData(
- 't ? t : f ? f ? 0 : 1 : 2', ConstantExpressionKind.CONDITIONAL),
- const ConstantData(
- 't ? t ? t : t : t ? t : t', ConstantExpressionKind.CONDITIONAL),
- const ConstantData(
- 't ? (t ? t : t) : (t ? t : t)', ConstantExpressionKind.CONDITIONAL,
- text: 't ? t ? t : t : t ? t : t'),
- const ConstantData(
- 'const [const <dynamic, dynamic>{0: true, "1": "c" "d"}, '
- 'const Class(const Class<dynamic, dynamic>(toplevelConstant))]',
- ConstantExpressionKind.LIST,
- text: 'const <Object>[const {0: true, "1": "cd"}, '
- 'const Class(const Class(toplevelConstant))]'),
- ]),
- const TestData('''
-class A {
- const A();
-}
-class B {
- final field1;
- const B(this.field1);
-}
-class C extends B {
- final field2;
- const C({field1: 42, this.field2: false}) : super(field1);
- const C.named([field = false]) : this(field1: field, field2: field);
-}
-''', const [
- const ConstantData('const Object()', ConstantExpressionKind.CONSTRUCTED,
- type: 'Object', fields: const {}),
- const ConstantData('const A()', ConstantExpressionKind.CONSTRUCTED,
- type: 'A', fields: const {}),
- const ConstantData('const B(0)', ConstantExpressionKind.CONSTRUCTED,
- type: 'B', fields: const {'field(B#field1)': '0'}),
- const ConstantData('const B(const A())', ConstantExpressionKind.CONSTRUCTED,
- type: 'B', fields: const {'field(B#field1)': 'const A()'}),
- const ConstantData('const C()', ConstantExpressionKind.CONSTRUCTED,
- type: 'C',
- fields: const {
- 'field(B#field1)': '42',
- 'field(C#field2)': 'false',
- }),
- const ConstantData(
- 'const C(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- type: 'C',
- fields: const {
- 'field(B#field1)': '87',
- 'field(C#field2)': 'false',
- }),
- const ConstantData(
- 'const C(field2: true)', ConstantExpressionKind.CONSTRUCTED,
- type: 'C',
- fields: const {
- 'field(B#field1)': '42',
- 'field(C#field2)': 'true',
- }),
- const ConstantData('const C.named()', ConstantExpressionKind.CONSTRUCTED,
- type: 'C',
- fields: const {
- 'field(B#field1)': 'false',
- 'field(C#field2)': 'false',
- }),
- const ConstantData('const C.named(87)', ConstantExpressionKind.CONSTRUCTED,
- type: 'C',
- fields: const {
- 'field(B#field1)': '87',
- 'field(C#field2)': '87',
- }),
- ]),
- const TestData('''
-class A<T> implements B<Null> {
- final field1;
- const A({this.field1:42});
-}
-class B<S> implements C<Null> {
- const factory B({field1}) = A<B<S>>;
- const factory B.named() = A<S>;
-}
-class C<U> {
- const factory C({field1}) = A<B<double>>;
-}
-''', const [
- const ConstantData('const A()', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<dynamic>', fields: const {'field(A#field1)': '42'}),
- const ConstantData(
- 'const A<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<int>', fields: const {'field(A#field1)': '87'}),
- const ConstantData('const B()', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<B<dynamic>>',
- fields: const {
- 'field(A#field1)': '42',
- },
- // Redirecting factories are replaced by their effective targets by CFE.
- text: 'const A<B<dynamic>>()'),
- const ConstantData('const B<int>()', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<B<int>>',
- fields: const {
- 'field(A#field1)': '42',
- },
- // Redirecting factories are replaced by their effective targets by CFE.
- text: 'const A<B<int>>()'),
- const ConstantData(
- 'const B<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<B<int>>',
- fields: const {
- 'field(A#field1)': '87',
- },
- // Redirecting factories are replaced by their effective targets by CFE.
- text: 'const A<B<int>>(field1: 87)'),
- const ConstantData(
- 'const C<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<B<double>>',
- fields: const {
- 'field(A#field1)': '87',
- },
- // Redirecting factories are replaced by their effective targets by CFE.
- text: 'const A<B<double>>(field1: 87)'),
- const ConstantData(
- 'const B<int>.named()', ConstantExpressionKind.CONSTRUCTED,
- type: 'A<int>',
- fields: const {
- 'field(A#field1)': '42',
- },
- // Redirecting factories are replaced by their effective targets by CFE.
- text: 'const A<int>()'),
- ]),
- const TestData('''
-T identity<T>(T t) => t;
-class C<T> {
- final T defaultValue;
- final T Function(T t) identityFunction;
-
- const C(this.defaultValue, this.identityFunction);
-}
- ''', const <ConstantData>[
- const ConstantData('identity', ConstantExpressionKind.FUNCTION),
- const ConstantData(
- 'const C<int>(0, identity)', ConstantExpressionKind.CONSTRUCTED,
- type: 'C<int>', text: 'const C<int>(0, <int>(identity))'),
- const ConstantData(
- 'const C<double>(0.5, identity)', ConstantExpressionKind.CONSTRUCTED,
- type: 'C<double>', text: 'const C<double>(0.5, <double>(identity))'),
- ])
-];
-
-main() {
- asyncTest(() async {
- await runTest();
- });
-}
-
-Future runTest() async {
- for (TestData data in DATA) {
- await testData(data);
- }
-}
-
-Future testData(TestData data) async {
- StringBuffer sb = new StringBuffer();
- sb.writeln('${data.declarations}');
- Map<String, ConstantData> constants = {};
- List<String> names = <String>[];
- data.constants.forEach((ConstantData constantData) {
- String name = 'c${constants.length}';
- names.add(name);
- sb.writeln('const $name = ${constantData.code};');
- constants[name] = constantData;
- });
- sb.writeln('main() {');
- for (String name in names) {
- sb.writeln(' print($name);');
- }
- sb.writeln('}');
- String source = sb.toString();
- CompilationResult result =
- await runCompiler(memorySourceFiles: {'main.dart': source});
- Compiler compiler = result.compiler;
- KElementEnvironment elementEnvironment =
- compiler.frontendStrategy.elementEnvironment;
-
- MemoryEnvironment environment = new MemoryEnvironment(
- new KernelEvaluationEnvironment(
- (compiler.frontendStrategy as dynamic).elementMap,
- compiler.environment,
- null));
- dynamic library = elementEnvironment.mainLibrary;
- constants.forEach((String name, ConstantData data) {
- FieldEntity field = elementEnvironment.lookupLibraryMember(library, name);
- dynamic constant = elementEnvironment.getFieldConstantForTesting(field);
- Expect.equals(
- data.kind,
- constant.kind,
- "Unexpected kind '${constant.kind}' for constant "
- "`${constant.toDartText()}`, expected '${data.kind}'.");
- String text = data.text;
- Expect.equals(
- text,
- constant.toDartText(),
- "Unexpected text '${constant.toDartText()}' for constant, "
- "expected '${text}'.");
- if (data.type != null) {
- String instanceType =
- constant.computeInstanceType(environment).toString();
- Expect.equals(
- data.type,
- instanceType,
- "Unexpected type '$instanceType' for constant "
- "`${constant.toDartText()}`, expected '${data.type}'.");
- }
- if (data.fields != null) {
- Map instanceFields = constant.computeInstanceData(environment).fieldMap;
- Expect.equals(
- data.fields.length,
- instanceFields.length,
- "Unexpected field count ${instanceFields.length} for constant "
- "`${constant.toDartText()}`, expected '${data.fields.length}'.");
- instanceFields.forEach((field, expression) {
- String name = '$field';
- Expect.isTrue(name.startsWith('k:'));
- name = name.substring(2).replaceAll('.', "#");
- String expression = instanceFields[field].toDartText();
- String expected = data.fields[name];
- Expect.equals(
- expected,
- expression,
- "Unexpected field expression ${expression} for field '$name' in "
- "constant `${constant.toDartText()}`, expected '${expected}'.");
- });
- }
- });
-}
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
index a4a6fa0..b3ca79e 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
@@ -63,6 +63,13 @@
writeJs: writeJs,
verbose: verbose,
inlineData: inlineData);
+ print('---from kernel with CFE constants-----------------------------------');
+ await runTest(test, kernelMarker,
+ printJs: printJs,
+ writeJs: writeJs,
+ verbose: verbose,
+ inlineData: inlineData,
+ options: ['${Flags.enableLanguageExperiments}=constant-update-2018']);
}
Future runTest(Test test, String config,
diff --git a/tests/corelib_2/map_test.dart b/tests/corelib_2/map_test.dart
index 5c9e9a4..88d6e92 100644
--- a/tests/corelib_2/map_test.dart
+++ b/tests/corelib_2/map_test.dart
@@ -1043,4 +1043,5 @@
checkUnmodifiable(const {1: 1});
checkUnmodifiable(Map.unmodifiable({1: 1}));
checkUnmodifiable(UnmodifiableMapView({1: 1}));
+ checkUnmodifiable(const MapView({1: 1}));
}
diff --git a/tests/ffi/enable_ffi_test.dart b/tests/ffi/enable_ffi_test.dart
index ebe1b9b..1ccb5ec 100644
--- a/tests/ffi/enable_ffi_test.dart
+++ b/tests/ffi/enable_ffi_test.dart
@@ -13,8 +13,8 @@
import "package:expect/expect.dart";
void main() {
- ffi.Pointer<ffi.Int64> p = ffi.allocate(); //# 01: compile-time error
- p.store(42); //# 01: compile-time error
- Expect.equals(42, p.load<int>()); //# 01: compile-time error
- p.free(); //# 01: compile-time error
+ ffi.Pointer<ffi.Int64> p = ffi.allocate(); //# 01: compile-time error, runtime error
+ p.store(42); //# 01: compile-time error, runtime error
+ Expect.equals(42, p.load<int>()); //# 01: compile-time error, runtime error
+ p.free(); //# 01: compile-time error, runtime error
}
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index f56725a..5b0ab46 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -28,8 +28,11 @@
[ $runtime == dart_precompiled ]
*: Skip # AOT is not yet supported: dartbug.com/35765
-[ $arch != arm64 && $arch != ia32 && $arch != x64 ]
-*: Skip # FFI not yet supported on other architectures.
+[ $arch == simdbc64 || $arch == simarm || $arch == simarm64 ]
+*: Skip # FFI not yet supported on DBC or other simulated architectures.
[ $system != android && $system != linux && $system != macos && $system != windows ]
*: Skip # FFI not yet supported on other OSes.
+
+[ $system != android && $arch == arm ]
+*: Skip # "hardfp" calling convention is not yet supported (iOS is also supported but not tested): dartbug.com/36309
diff --git a/tests/ffi/function_stress_test.dart b/tests/ffi/function_stress_test.dart
index 1c0d9f4..92e807c 100644
--- a/tests/ffi/function_stress_test.dart
+++ b/tests/ffi/function_stress_test.dart
@@ -18,15 +18,21 @@
import "package:expect/expect.dart";
import 'gc_helper.dart';
-test(GCWatcher watcher, void Function() testee,
- {bool mustTriggerGC: true}) async {
+test(GCWatcher watcher, Function testee,
+ {bool mustTriggerGC: true, bool batched: false}) async {
// Warmup.
for (int i = 0; i < 1000; ++i) {
- testee();
+ batched ? testee(1) : testee();
}
int size = await watcher.size();
- for (int i = 0; i < 1000000; ++i) {
- testee();
+ for (int i = 0; i < 1000000;) {
+ if (batched) {
+ testee(1000);
+ i += 1000;
+ } else {
+ testee();
+ i++;
+ }
}
int new_size = await watcher.size();
if (mustTriggerGC) {
@@ -44,6 +50,8 @@
await test(watcher, testBoxInt32, mustTriggerGC: false);
await test(watcher, testBoxDouble);
await test(watcher, testBoxPointer);
+ await test(watcher, testAllocateMints, batched: true);
+ await test(watcher, testAllocationsInDart, batched: true);
} finally {
watcher.dispose();
}
@@ -56,9 +64,11 @@
typedef NativeNullaryOp32 = ffi.Int32 Function();
typedef NativeNullaryOpDouble = ffi.Double Function();
typedef NativeNullaryOpPtr = ffi.Pointer<ffi.Void> Function();
+typedef NativeUnaryOp = ffi.Void Function(ffi.Uint64);
typedef NullaryOp = int Function();
typedef NullaryOpDbl = double Function();
typedef NullaryOpPtr = ffi.Pointer<ffi.Void> Function();
+typedef UnaryOp = void Function(int);
//// These functions return values that require boxing into different types.
@@ -100,3 +110,34 @@
}
}
}
+
+final allocateMint =
+ ffiTestFunctions.lookupFunction<NativeUnaryOp, UnaryOp>("AllocateMints");
+
+// Test GC in the FFI call path by calling a C function which allocates through
+// the Dart API.
+void testAllocateMints(int batchSize) {
+ allocateMint(batchSize);
+}
+
+class C {
+ final int i;
+ C(this.i);
+}
+
+C c = null;
+@pragma("vm:entry-point", "call")
+void testAllocationsInDartHelper(int count) {
+ for (int i = 0; i < count; ++i) {
+ c = C(i);
+ }
+}
+
+final allocateThroughDart = ffiTestFunctions
+ .lookupFunction<NativeUnaryOp, UnaryOp>("AllocateThroughDart");
+
+// Test GC in the FFI call path by calling a C function which allocates by
+// calling back into Dart ('testAllocationsInDartHelper').
+void testAllocationsInDart(int batchSize) {
+ allocateThroughDart(batchSize * 10);
+}
diff --git a/tests/language_2/control_flow_collections/await_for_inference_test.dart b/tests/language_2/control_flow_collections/await_for_inference_test.dart
index d4d4bb8..6987f58 100644
--- a/tests/language_2/control_flow_collections/await_for_inference_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_inference_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test how await for interacts with inference.
import "package:async_helper/async_helper.dart";
diff --git a/tests/language_2/control_flow_collections/await_for_null_test.dart b/tests/language_2/control_flow_collections/await_for_null_test.dart
index d040e92..7e2fc5e 100644
--- a/tests/language_2/control_flow_collections/await_for_null_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_null_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test that a null stream expression procudes a runtime error.
import 'package:async_helper/async_helper.dart';
diff --git a/tests/language_2/control_flow_collections/await_for_syntax_error_test.dart b/tests/language_2/control_flow_collections/await_for_syntax_error_test.dart
index 0b7c20a..f5e30ce 100644
--- a/tests/language_2/control_flow_collections/await_for_syntax_error_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_syntax_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
void main() {
// Use await for in non-async function.
diff --git a/tests/language_2/control_flow_collections/await_for_test.dart b/tests/language_2/control_flow_collections/await_for_test.dart
index 032084e..c838c49 100644
--- a/tests/language_2/control_flow_collections/await_for_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/await_for_type_error_test.dart b/tests/language_2/control_flow_collections/await_for_type_error_test.dart
index 7090cee..8cc87da 100644
--- a/tests/language_2/control_flow_collections/await_for_type_error_test.dart
+++ b/tests/language_2/control_flow_collections/await_for_type_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
void main() {
() async {
diff --git a/tests/language_2/control_flow_collections/experimental_flag_test.dart b/tests/language_2/control_flow_collections/experimental_flag_test.dart
deleted file mode 100644
index a044a01..0000000
--- a/tests/language_2/control_flow_collections/experimental_flag_test.dart
+++ /dev/null
@@ -1,31 +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.
-
-// Check that control flow is not enabled without the experimental flag.
-
-// TODO(rnystrom): Remove this test when the feature is enabled without a flag.
-
-void main() {
- var _ = <int>[if (true) 1]; //# 01: compile-time error
- var _ = <int, int>{if (true) 1: 1}; //# 02: compile-time error
- var _ = <int>{if (true) 1}; //# 03: compile-time error
-
- var _ = <int>[if (true) 1 else 2]; //# 04: compile-time error
- var _ = <int, int>{if (true) 1: 1 else 2: 2}; //# 05: compile-time error
- var _ = <int>{if (true) 1 else 2}; //# 06: compile-time error
-
- var _ = <int>[for (var i in []) 1]; //# 07: compile-time error
- var _ = <int, int>{for (var i in []) 1: 1}; //# 08: compile-time error
- var _ = <int>{for (var i in []) 1}; //# 09: compile-time error
-
- var _ = <int>[for (; false;) 1]; //# 10: compile-time error
- var _ = <int, int>{for (; false;) 1: 1}; //# 11: compile-time error
- var _ = <int>{for (; false;) 1}; //# 12: compile-time error
-
- () async {
- var _ = <int>[await for (var i in []) 1]; //# 13: compile-time error
- var _ = <int, int>{await for (var i in []) 1: 1}; //# 14: compile-time error
- var _ = <int>{await for (var i in []) 1}; //# 15: compile-time error
- }();
-}
diff --git a/tests/language_2/control_flow_collections/for_await_test.dart b/tests/language_2/control_flow_collections/for_await_test.dart
index 81b0a3f..55d24ae 100644
--- a/tests/language_2/control_flow_collections/for_await_test.dart
+++ b/tests/language_2/control_flow_collections/for_await_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
import "package:async_helper/async_helper.dart";
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_const_test.dart b/tests/language_2/control_flow_collections/for_const_error_test.dart
similarity index 82%
rename from tests/language_2/control_flow_collections/for_const_test.dart
rename to tests/language_2/control_flow_collections/for_const_error_test.dart
index 32f7e51..626c7a8 100644
--- a/tests/language_2/control_flow_collections/for_const_test.dart
+++ b/tests/language_2/control_flow_collections/for_const_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
void main() {
// For cannot be used in a const collection.
@@ -16,7 +16,7 @@
() async {
const _ = <int>[await for (var i in []) 1]; //# 06: compile-time error
- const _ = <int, int>{await for (var i in []) 1: 1}; //# 07: compile-time error
+ const _ = <int, int>{await for (var i in []) 1: 1}; //# 07: compile-time error
const _ = <int>{await for (var i in []) 1}; //# 08: compile-time error
}();
}
diff --git a/tests/language_2/control_flow_collections/for_inference_test.dart b/tests/language_2/control_flow_collections/for_inference_test.dart
index 7835d7a..9479dd6 100644
--- a/tests/language_2/control_flow_collections/for_inference_test.dart
+++ b/tests/language_2/control_flow_collections/for_inference_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test how control flow interacts with inference.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart b/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart
index fbc3834..74b00df 100644
--- a/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart
+++ b/tests/language_2/control_flow_collections/for_non_bool_condition_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_null_condition_test.dart b/tests/language_2/control_flow_collections/for_null_condition_test.dart
index 6b890fd..2f9a6c0 100644
--- a/tests/language_2/control_flow_collections/for_null_condition_test.dart
+++ b/tests/language_2/control_flow_collections/for_null_condition_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_runtime_error_test.dart b/tests/language_2/control_flow_collections/for_runtime_error_test.dart
index f036a94..b8fa267 100644
--- a/tests/language_2/control_flow_collections/for_runtime_error_test.dart
+++ b/tests/language_2/control_flow_collections/for_runtime_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_test.dart b/tests/language_2/control_flow_collections/for_test.dart
index 8df9d75..a264cb6 100644
--- a/tests/language_2/control_flow_collections/for_test.dart
+++ b/tests/language_2/control_flow_collections/for_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/for_variable_test.dart b/tests/language_2/control_flow_collections/for_variable_test.dart
index 69d0b3f..f866daf 100644
--- a/tests/language_2/control_flow_collections/for_variable_test.dart
+++ b/tests/language_2/control_flow_collections/for_variable_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
/// Tests for how variables and scoping work with for elements.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/if_await_test.dart b/tests/language_2/control_flow_collections/if_await_test.dart
index a0e8bad..2db3f62 100644
--- a/tests/language_2/control_flow_collections/if_await_test.dart
+++ b/tests/language_2/control_flow_collections/if_await_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
import "package:async_helper/async_helper.dart";
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/if_const_error_test.dart b/tests/language_2/control_flow_collections/if_const_error_test.dart
index c644acf..f3645f2 100644
--- a/tests/language_2/control_flow_collections/if_const_error_test.dart
+++ b/tests/language_2/control_flow_collections/if_const_error_test.dart
@@ -2,138 +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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
-
-import 'dart:collection';
-
-import 'package:expect/expect.dart';
-
-import 'utils.dart';
-
-final nonConstBool = true;
-final nonConstInt = 3;
-
-const dynamic nonBool = 3;
-const dynamic nonInt = "s";
+// SharedOptions=--enable-experiment=control-flow-collections
void main() {
- testList();
- testMap();
- testSet();
- testShortCircuit();
-}
-
-void testList() {
- // Condition must be constant.
- const _ = <int>[if (nonConstBool) 1]; //# 01: compile-time error
-
- // Condition must be Boolean.
- const _ = <int>[if (nonBool) 1]; //# 02: compile-time error
-
- // Then element must be constant, whether or not branch is taken.
- const _ = <int>[if (true) nonConstInt]; //# 03: compile-time error
- const _ = <int>[if (false) nonConstInt]; //# 04: compile-time error
-
- // Else element must be constant, whether or not branch is taken.
- const _ = <int>[if (true) 1 else nonConstInt]; //# 05: compile-time error
- const _ = <int>[if (false) 1 else nonConstInt]; //# 06: compile-time error
-
- // Then element must have right type if branch is chosen.
- const _ = <int>[if (true) nonInt]; //# 07: compile-time error
-
- // Else element must have right type if branch is chosen.
- const _ = <int>[if (false) 9 else nonInt]; //# 08: compile-time error
-}
-
-void testMap() {
- // Condition must be constant.
- const _ = <int, int>{if (nonConstBool) 1: 1}; //# 09: compile-time error
-
- // Condition must be Boolean.
- const _ = <int, int>{if (nonBool) 1: 1}; //# 10: compile-time error
-
- // Then key element must be constant, whether or not branch is taken.
- const _ = <int, int>{if (true) nonConstInt: 1}; //# 11: compile-time error
- const _ = <int, int>{if (false) nonConstInt: 1}; //# 12: compile-time error
-
- // Then value element must be constant, whether or not branch is taken.
- const _ = <int, int>{if (true) 1: nonConstInt}; //# 13: compile-time error
- const _ = <int, int>{if (false) 1: nonConstInt}; //# 14: compile-time error
-
- // Else key element must be constant, whether or not branch is taken.
- const _ = <int, int>{if (true) 1 else nonConstInt: 1}; //# 15: compile-time error
- const _ = <int, int>{if (false) 1 else nonConstInt: 1}; //# 16: compile-time error
-
- // Else value element must be constant, whether or not branch is taken.
- const _ = <int, int>{if (true) 1 else 1: nonConstInt}; //# 17: compile-time error
- const _ = <int, int>{if (false) 1 else 1: nonConstInt}; //# 18: compile-time error
-
- // Then key element must have right type if branch is chosen.
- const _ = <int, int>{if (true) nonInt: 1}; //# 19: compile-time error
-
- // Then value element must have right type if branch is chosen.
- const _ = <int, int>{if (true) 1: nonInt}; //# 20: compile-time error
-
- // Else key element must have right type if branch is chosen.
- const _ = <int, int>{if (false) 9 else nonInt: 1}; //# 21: compile-time error
-
- // Else value element must have right type if branch is chosen.
- const _ = <int, int>{if (false) 9 else 1: nonInt}; //# 22: compile-time error
-
- // Key cannot override operator.==().
- const obj = 0.1;
- const _ = {if (true) 0.1: 1}; //# 23: compile-time error
- const _ = {if (true) Duration(seconds: 0): 1}; //# 24: compile-time error
- const _ = {if (true) obj: 1}; //# 25: compile-time error
-
- // Cannot have key collision when branch is chosen.
- const _ = <int, int>{1: 1, if (true) 1: 1}; //# 25: compile-time error
- const _ = <int, int>{if (true) 1: 1, if (true) 1: 1}; //# 26: compile-time error
-}
-
-void testSet() {
- // Condition must be constant.
- const _ = <int>{if (nonConstBool) 1}; //# 27: compile-time error
-
- // Condition must be Boolean.
- const _ = <int>{if (nonBool) 1}; //# 28: compile-time error
-
- // Then element must be constant, whether or not branch is taken.
- const _ = <int>{if (true) nonConstInt}; //# 29: compile-time error
- const _ = <int>{if (false) nonConstInt}; //# 30: compile-time error
-
- // Else element must be constant, whether or not branch is taken.
- const _ = <int>{if (true) 1 else nonConstInt}; //# 31: compile-time error
- const _ = <int>{if (false) 1 else nonConstInt}; //# 32: compile-time error
-
- // Then element must have right type if branch is chosen.
- const _ = <int>{if (true) nonInt}; //# 33: compile-time error
-
- // Else element must have right type if branch is chosen.
- const _ = <int>{if (false) 9 else nonInt}; //# 34: compile-time error
-
- // Cannot override operator.==().
- const obj = 0.1;
- const _ = {if (true) 0.1}; //# 35: compile-time error
- const _ = {if (true) Duration(seconds: 0)}; //# 36: compile-time error
- const _ = {if (true) obj}; //# 37: compile-time error
-
- // Cannot have collision when branch is chosen.
- const _ = <int>{1, if (true) 1}; //# 38: compile-time error
- const _ = <int>{if (true) 1, if (true) 1}; //# 39: compile-time error
-}
-
-void testShortCircuit() {
- // A const expression that throws causes a compile error if it occurs inside
- // the chosen branch of an if.
-
- // Store null in a dynamically-typed constant to avoid the type error on "+".
- const dynamic nil = null;
-
- // With no else.
- const _ = [if (true) nil + 1]; //# 40: compile-time error
-
- // With else.
- const _ = [if (true) nil + 1 else 1]; //# 41: compile-time error
- const _ = [if (false) 1 else nil + 1]; //# 42: compile-time error
+ // If cannot be used in a const collection.
+ const _ = [if (true) 1]; //# 00: compile-time error
+ const _ = [if (false) 1 else 2]; //# 01: compile-time error
+ const _ = {if (true) 1}; //# 02: compile-time error
+ const _ = {if (false) 1 else 2}; //# 03: compile-time error
+ const _ = {if (true) 1: 1}; //# 04: compile-time error
+ const _ = {if (false) 1: 1 else 2: 2}; //# 05: compile-time error
}
diff --git a/tests/language_2/control_flow_collections/if_const_test.dart b/tests/language_2/control_flow_collections/if_const_test.dart
deleted file mode 100644
index db38174..0000000
--- a/tests/language_2/control_flow_collections/if_const_test.dart
+++ /dev/null
@@ -1,244 +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=control-flow-collections,spread-collections,constant-update-2018
-
-import 'package:expect/expect.dart';
-
-import 'utils.dart';
-
-// Typed as dynamic to also test spreading a value of type dynamic.
-const dynamic list = [1, 2, 3];
-const dynamic map = {1: 1, 2: 2, 3: 3};
-const dynamic set = {1, 2, 3};
-
-const dynamic dynamicTrue = true;
-const Object objectTrue = true;
-
-void main() {
- testList();
- testMap();
- testSet();
- testShortCircuit();
- testDuplicateKeys();
- testKeyOrder();
-}
-
-void testList() {
- // Then if true.
- Expect.identical(list, const <int>[1, if (true) 2, 3]);
-
- // Nothing if false and no else.
- Expect.identical(list, const <int>[1, if (false) 9, 2, 3]);
-
- // Else if false.
- Expect.identical(list, const <int>[1, if (false) 9 else 2, 3]);
-
- // Only if.
- Expect.identical(const [1], const <int>[if (true) 1]);
-
- // If at beginning.
- Expect.identical(list, const <int>[if (true) 1, 2, 3]);
-
- // If in middle.
- Expect.identical(list, const <int>[1, if (true) 2, 3]);
-
- // If at end.
- Expect.identical(list, const <int>[1, 2, if (true) 3]);
-
- // Multiple ifs.
- Expect.identical(list,
- const <int>[if (true) 1, if (false) 9, 2, if (true) 3]);
-
- // Cast condition.
- Expect.identical(const [1], const <int>[if (dynamicTrue) 1]);
- Expect.identical(const [1], const <int>[if (objectTrue) 1]);
-
- // Does not flatten nested collection literal.
- Expect.identical(const [1], const [if (true) [1]].first);
- Expect.identical(const {1: 1}, const [if (true) {1: 1}].first);
- Expect.identical(const {1}, const [if (true) {1}].first);
-
- // Nested spread.
- Expect.identical(list,
- const <int>[if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]]);
-
- // Nested if in then.
- Expect.identical(const [1],
- const <int>[if (true) if (true) 1, if (true) if (false) 9]);
-
- // Nested if in else.
- Expect.identical(const [1], const <int>[if (false) 9 else if (true) 1]);
-}
-
-void testMap() {
- // Then if true.
- Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});
-
- // Nothing if false and no else.
- Expect.identical(map, const <int, int>{1: 1, if (false) 9: 9, 2: 2, 3: 3});
-
- // Else if false.
- Expect.identical(map,
- const <int, int>{1: 1, if (false) 9: 9 else 2: 2, 3: 3});
-
- // Only if.
- Expect.identical(const {1: 1}, const <int, int>{if (true) 1: 1});
-
- // If at beginning.
- Expect.identical(map, const <int, int>{if (true) 1: 1, 2: 2, 3: 3});
-
- // If in middle.
- Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});
-
- // If at end.
- Expect.identical(map, const <int, int>{1: 1, 2: 2, if (true) 3: 3});
-
- // Multiple ifs.
- Expect.identical(map,
- const <int, int>{if (true) 1: 1, if (false) 9: 9, 2: 2, if (true) 3: 3});
-
- // Cast condition.
- Expect.identical(const {1: 1}, const <int, int>{if (dynamicTrue) 1: 1});
- Expect.identical(const {1: 1}, const <int, int>{if (objectTrue) 1: 1});
-
- // Nested spread.
- Expect.identical(map, const <int, int>{
- if (true) ...<int, int>{1: 1, 2: 2},
- if (false) 9: 9 else ...<int, int>{3: 3}
- });
-
- // Nested if in then.
- Expect.identical(const {1: 1},
- const <int, int>{if (true) if (true) 1: 1, if (true) if (false) 9: 9});
-
- // Nested if in else.
- Expect.identical(const {1: 1},
- const <int, int>{if (false) 9: 9 else if (true) 1: 1});
-}
-
-void testSet() {
- // Then if true.
- Expect.identical(set, const <int>{1, if (true) 2, 3});
-
- // Nothing if false and no else.
- Expect.identical(set, const <int>{1, if (false) 9, 2, 3});
-
- // Else if false.
- Expect.identical(set, const <int>{1, if (false) 9 else 2, 3});
-
- // Only if.
- Expect.identical(const <int>{1}, const <int>{if (true) 1});
-
- // If at beginning.
- Expect.identical(set, const <int>{if (true) 1, 2, 3});
-
- // If in middle.
- Expect.identical(set, const <int>{1, if (true) 2, 3});
-
- // If at end.
- Expect.identical(set, const <int>{1, 2, if (true) 3});
-
- // Multiple ifs.
- Expect.identical(set,
- const <int>{if (true) 1, if (false) 9, 2, if (true) 3});
-
- // Cast condition.
- Expect.identical(const <int>{1}, const <int>{if (dynamicTrue) 1});
- Expect.identical(const <int>{1}, const <int>{if (objectTrue) 1});
-
- // Does not flatten nested collection literal.
- Expect.identical(const <int>[1], const <List<int>>{if (true) [1]}.first);
- Expect.identical(
- const <int, int>{1: 1}, const <Map<int, int>>{if (true) {1: 1}}.first);
- Expect.identical(const <int>{1}, const <Set<int>>{if (true) {1}}.first);
-
- // Nested spread.
- Expect.identical(set,
- const <int>{if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]});
-
- // Nested if in then.
- Expect.identical(const <int>{1},
- const <int>{if (true) if (true) 1, if (true) if (false) 9});
-
- // Nested if in else.
- Expect.identical(const <int>{1}, const <int>{if (false) 9 else if (true) 1});
-}
-
-void testShortCircuit() {
- // A const expression that throws does not cause a compile error if it occurs
- // inside an unchosen branch of an if.
-
- // Store null in a dynamically-typed constant to avoid the type error on "+".
- const dynamic nil = null;
-
- Expect.identical(const <int>[1],
- const <int>[if (true) 1, if (false) nil + 1]);
- Expect.identical(const <int>[1, 2],
- const <int>[if (true) 1 else nil + 1, if (false) nil + 1 else 2]);
-
- Expect.identical(const <int, int>{1: 1}, const <int, int>{
- if (true) 1: 1,
- if (false) nil + 1: 9,
- if (false) 9: nil + 1
- });
- Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
- if (true) 1: 1 else nil + 1: 9,
- if (false) 9: nil + 1 else 2: 2
- });
-
- Expect.identical(const <int>{1},
- const <int>{if (true) 1, if (false) nil + 1});
- Expect.identical(const <int>{1, 2},
- const <int>{if (true) 1 else nil + 1, if (false) nil + 1 else 2});
-
- // A const expression whose value isn't the right type does not cause a
- // compile error if it occurs inside an unchosen branch.
- const dynamic nonInt = "s";
-
- Expect.identical(const <int>[1], const <int>[if (true) 1, if (false) nonInt]);
- Expect.identical(const <int>[1, 2],
- const <int>[if (true) 1 else nonInt, if (false) nonInt else 2]);
-
- Expect.identical(const <int, int>{1: 1}, const <int, int>{
- if (true) 1: 1,
- if (false) nonInt: 9,
- if (false) 9: nonInt
- });
- Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
- if (true) 1: 1 else nonInt: 9,
- if (false) 9: nonInt else 2: 2
- });
-
- Expect.identical(const <int>{1}, const <int>{if (true) 1, if (false) nonInt});
- Expect.identical(const <int>{1, 2},
- const <int>{if (true) 1 else nonInt, if (false) nonInt else 2});
-}
-
-void testDuplicateKeys() {
- // Duplicate keys from unchosen branches are not an error.
- Expect.mapEquals(map, <int, int>{
- 1: 1,
- if (false) 1: 1,
- if (true) 2: 2 else 3: 3,
- 3: 3
- });
-
- Expect.setEquals(set, const <int>{1, if (false) 1, if (true) 2 else 3, 3});
-}
-
-void testKeyOrder() {
- // Canonicalization isn't affected by which elements are conditional.
- Expect.identical(map,
- const <int, int>{1: 1, if (true) 2: 2, if (false) 9: 9, 3: 3});
- Expect.identical(map,
- const <int, int>{if (false) 9: 9 else 1: 1, 2: 2, if (true) 3: 3});
-
- Expect.identical(set, const <int>{1, if (true) 2, if (false) 9, 3});
- Expect.identical(set, const <int>{if (false) 9 else 1, 2, if (true) 3});
-
- // Ordering does affect canonicalization.
- Expect.notIdentical(map, const <int, int>{1: 1, if (true) 3: 3, 2: 2});
- Expect.notIdentical(set, const <int>{1, if (true) 3, 2});
-}
diff --git a/tests/language_2/control_flow_collections/if_inference_test.dart b/tests/language_2/control_flow_collections/if_inference_test.dart
index 454c903..0c73618 100644
--- a/tests/language_2/control_flow_collections/if_inference_test.dart
+++ b/tests/language_2/control_flow_collections/if_inference_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test how control flow interacts with inference.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/if_null_condition_test.dart b/tests/language_2/control_flow_collections/if_null_condition_test.dart
index 10cbb6b..c5a1e96 100644
--- a/tests/language_2/control_flow_collections/if_null_condition_test.dart
+++ b/tests/language_2/control_flow_collections/if_null_condition_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/if_promotion_test.dart b/tests/language_2/control_flow_collections/if_promotion_test.dart
index 152d225..5622a47 100644
--- a/tests/language_2/control_flow_collections/if_promotion_test.dart
+++ b/tests/language_2/control_flow_collections/if_promotion_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
class A {
var a = "a";
diff --git a/tests/language_2/control_flow_collections/if_runtime_error_test.dart b/tests/language_2/control_flow_collections/if_runtime_error_test.dart
index 8bf5469..8e48bea 100644
--- a/tests/language_2/control_flow_collections/if_runtime_error_test.dart
+++ b/tests/language_2/control_flow_collections/if_runtime_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/if_test.dart b/tests/language_2/control_flow_collections/if_test.dart
index 4a922f8..c835dd6 100644
--- a/tests/language_2/control_flow_collections/if_test.dart
+++ b/tests/language_2/control_flow_collections/if_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/map_set_ambiguity_error_test.dart b/tests/language_2/control_flow_collections/map_set_ambiguity_error_test.dart
index 0c4073e..452ac9b 100644
--- a/tests/language_2/control_flow_collections/map_set_ambiguity_error_test.dart
+++ b/tests/language_2/control_flow_collections/map_set_ambiguity_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test cases where the syntax is ambiguous between maps and sets when control
// flow elements contain spreads.
diff --git a/tests/language_2/control_flow_collections/map_set_ambiguity_test.dart b/tests/language_2/control_flow_collections/map_set_ambiguity_test.dart
index 3331770..6ce77de 100644
--- a/tests/language_2/control_flow_collections/map_set_ambiguity_test.dart
+++ b/tests/language_2/control_flow_collections/map_set_ambiguity_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
// Test cases where the syntax is ambiguous between maps and sets because of
// spreads inside control flow.
diff --git a/tests/language_2/control_flow_collections/syntax_error_test.dart b/tests/language_2/control_flow_collections/syntax_error_test.dart
index 25bff6b..e0f0ba8 100644
--- a/tests/language_2/control_flow_collections/syntax_error_test.dart
+++ b/tests/language_2/control_flow_collections/syntax_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
void main() {
// No then element.
diff --git a/tests/language_2/control_flow_collections/syntax_test.dart b/tests/language_2/control_flow_collections/syntax_test.dart
index 71c3f62..0810aec 100644
--- a/tests/language_2/control_flow_collections/syntax_test.dart
+++ b/tests/language_2/control_flow_collections/syntax_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
// Tests syntax edge cases.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/control_flow_collections/type_error_test.dart b/tests/language_2/control_flow_collections/type_error_test.dart
index 533dc18..91e0ebb 100644
--- a/tests/language_2/control_flow_collections/type_error_test.dart
+++ b/tests/language_2/control_flow_collections/type_error_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.
-// SharedOptions=--enable-experiment=control-flow-collections,constant-update-2018
+// SharedOptions=--enable-experiment=control-flow-collections
void main() {
// Non-Boolean if condition.
@@ -11,42 +11,42 @@
var _ = <int>{if (1) 2}; //# 02: compile-time error
// Wrong then element type.
- var _ = <int>[if (true) "s"]; //# 06: compile-time error
- var _ = <int, int>{if (true) "s": 1}; //# 07: compile-time error
- var _ = <int, int>{if (true) 1: "s"}; //# 08: compile-time error
- var _ = <int>{if (true) "s"}; //# 09: compile-time error
+ var _ = <int>[if (true) "s"]; //# 04: compile-time error
+ var _ = <int, int>{if (true) "s": 1}; //# 05: compile-time error
+ var _ = <int, int>{if (true) 1: "s"}; //# 06: compile-time error
+ var _ = <int>{if (true) "s"}; //# 07: compile-time error
// Wrong else element type.
- var _ = <int>[if (false) 1 else "s"]; //# 10: compile-time error
- var _ = <int, int>{if (false) 1: 1 else "s": 2}; //# 11: compile-time error
- var _ = <int, int>{if (false) 1: 1 else 2: "s"}; //# 12: compile-time error
- var _ = <int>{if (false) 1 else "s"}; //# 13: compile-time error
+ var _ = <int>[if (false) 1 else "s"]; //# 08: compile-time error
+ var _ = <int, int>{if (false) 1: 1 else "s": 2}; //# 09: compile-time error
+ var _ = <int, int>{if (false) 1: 1 else 2: "s"}; //# 10: compile-time error
+ var _ = <int>{if (false) 1 else "s"}; //# 11: compile-time error
// Non-Boolean for condition.
- var _ = <int>[for (; 1;) 2]; //# 14: compile-time error
- var _ = <int, int>{for (; 1;) 2: 2}; //# 15: compile-time error
- var _ = <int>{for (; 1;) 2}; //# 16: compile-time error
+ var _ = <int>[for (; 1;) 2]; //# 12: compile-time error
+ var _ = <int, int>{for (; 1;) 2: 2}; //# 13: compile-time error
+ var _ = <int>{for (; 1;) 2}; //# 14: compile-time error
// Wrong for-in element type.
List<String> s = ["s"];
- var _ = <int>[for (int i in s) 1]; //# 20: compile-time error
- var _ = <int, int>{for (int i in s) 1: 1}; //# 21: compile-time error
- var _ = <int>{for (int i in s) 1}; //# 22: compile-time error
+ var _ = <int>[for (int i in s) 1]; //# 15: compile-time error
+ var _ = <int, int>{for (int i in s) 1: 1}; //# 16: compile-time error
+ var _ = <int>{for (int i in s) 1}; //# 17: compile-time error
// Wrong for declaration element type.
- var _ = <int>[for (int i = "s"; false;) 1]; //# 23: compile-time error
- var _ = <int, int>{for (int i = "s"; false;) 1: 1}; //# 24: compile-time error
- var _ = <int>{for (int i = "s"; false;) 1}; //# 25: compile-time error
+ var _ = <int>[for (int i = "s"; false;) 1]; //# 18: compile-time error
+ var _ = <int, int>{for (int i = "s"; false;) 1: 1}; //# 19: compile-time error
+ var _ = <int>{for (int i = "s"; false;) 1}; //# 20: compile-time error
// Wrong for body element type.
- var _ = <int>[for (; false;) "s"]; //# 26: compile-time error
- var _ = <int, int>{for (; false;) "s": 1}; //# 27: compile-time error
- var _ = <int, int>{for (; false;) 1: "s"}; //# 28: compile-time error
- var _ = <int>{for (; false;) "s"}; //# 29: compile-time error
+ var _ = <int>[for (; false;) "s"]; //# 21: compile-time error
+ var _ = <int, int>{for (; false;) "s": 1}; //# 22: compile-time error
+ var _ = <int, int>{for (; false;) 1: "s"}; //# 23: compile-time error
+ var _ = <int>{for (; false;) "s"}; //# 24: compile-time error
// Non-iterable sequence type.
int nonIterable = 3;
- var _ = <int>[for (int i in nonIterable) 1]; //# 30: compile-time error
- var _ = <int, int>{for (int i in nonIterable) 1: 1}; //# 31: compile-time error
- var _ = <int>{for (int i in nonIterable) 1}; //# 32: compile-time error
+ var _ = <int>[for (int i in nonIterable) 1]; //# 25: compile-time error
+ var _ = <int, int>{for (int i in nonIterable) 1: 1}; //# 26: compile-time error
+ var _ = <int>{for (int i in nonIterable) 1}; //# 27: compile-time error
}
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 3047a9d..63b4104 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -106,6 +106,7 @@
mixin_super_use_test: CompileTimeError # Issue 34806
mock_writable_final_private_field_test: CompileTimeError # Issue 30848
nested_generic_closure_test: CompileTimeError
+nnbd/*: Skip
override_inheritance_field_test/42: CompileTimeError
part_of_multiple_libs_test/01: MissingCompileTimeError
part_refers_to_core_library_test/01: Crash
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 96c638e..f5b2b09 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -216,6 +216,7 @@
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
diff --git a/tests/language_2/nnbd/static_errors/nullable_supertype_test.dart b/tests/language_2/nnbd/static_errors/nullable_supertype_test.dart
new file mode 100644
index 0000000..711fefd
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/nullable_supertype_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
+
+// Test that it is an error to use a nullable type as a supertype.
+import 'package:expect/expect.dart';
+import 'dart:core';
+import 'dart:core' as core;
+
+main() {}
+
+class A {}
+class B extends A? {} //# 01: compile-time error
+class B implements A? {} //# 02: compile-time error
+class B with A? {} //# 03: compile-time error
+mixin B on A? {} //# 04: compile-time error
+mixin B implements A? {} //# 05: compile-time error
diff --git a/tests/language_2/nnbd/syntax/null_assertion_ambiguous_test.dart b/tests/language_2/nnbd/syntax/null_assertion_ambiguous_test.dart
new file mode 100644
index 0000000..b2955e9
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/null_assertion_ambiguous_test.dart
@@ -0,0 +1,86 @@
+// 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
+import 'package:expect/expect.dart';
+
+class C {
+ C operator*(int? other) => this;
+ Object? operator-() => null;
+}
+
+// Test ambiguous cases of trailing "!" syntax. Where possible, we verify that
+// both the compiler and the runtime resolve the ambiguity correctly.
+main() async {
+ Object? a = null;
+
+ // `throw a!` means `throw (a!)`, not `(throw a)!`. Since it's a compile-time
+ // error for a thrown expression to be potentially nullable, this is
+ // sufficient to verify that the compiler has resolved the ambiguity
+ // correctly. Unforunately there's no good way to test the runtime behavior
+ // because `throw a` wouldn't complete anyway.
+ Expect.throws(() {
+ throw a!;
+ });
+
+ // `() => a!` means `() => (a!)`, not `(() => a)!`. We check the compile-time
+ // behavior by trying to assign to a function returning non-null. We check
+ // the runtime behavior by ensuring that a call to the closure causes an
+ // exception in the correct circumstances.
+ var x1 = () => a!;
+ Object Function() x2 = x1;
+ Expect.throws(() {
+ x1();
+ });
+
+ // `x = a!` means `x = (a!)`, not `(x = a)!`. We check the compile-time
+ // behavior by trying to assign to a non-nullable variable. We check the
+ // runtime behavior by verifying that the exception is thrown before an
+ // assignment occurs.
+ Object x3;
+ Expect.throws(() {
+ x3 = a!;
+ });
+ Object? x4 = 0;
+ Expect.throws(() {
+ x4 = a!;
+ });
+ Expect.equals(x4, 0);
+
+ // `true ? null : a!` means `true ? null : (a!)`, not `(true ? null : a)!`.
+ // We check the compile-time behavior by checking that the inferred type of
+ // the expression is nullable. We check the runtime behavior by verifying
+ // that a null value can propagate from the true branch of the conditional.
+ var x5 = true ? null : a!;
+ x5 = null;
+
+ // `x * i!` means `x * (i!)`, not `(x * i)!`. We check the compile-time
+ // behavior by checking that the multiplication is accepted even though i is
+ // nullable. We check the runtime behavior by using an object whose operator*
+ // ignores its argument, and verify that the appropriate exception is still
+ // thrown.
+ var x6 = 2;
+ int? i = 2;
+ x6 * i!;
+ var x7 = new C();
+ Expect.throws(() {
+ x7 * i!;
+ });
+
+ // `-x!` means `-(x!)`, not `(-x)!`. We check the compile-time behavior by
+ // checking that the negation is accepted even though x is nullable. We check
+ // the runtime behavior by using an object whose operator- returns null.
+ int? x8 = 2;
+ -x8!;
+ var x9 = new C();
+ -x9!;
+
+ // `await x!` means `await (x!)`, not `(await x)!`. We check the compile-time
+ // behavior by checking that the inferred type of the expression is nullable.
+ // We check the runtime behavior by ensuring that the future completes to a
+ // null value, and this does not produce an exception.
+ var x10 = new Future<Object?>.value(null);
+ var x11 = await x10!;
+ x11 = null;
+}
diff --git a/tests/language_2/nnbd/syntax/null_assertion_test.dart b/tests/language_2/nnbd/syntax/null_assertion_test.dart
new file mode 100644
index 0000000..4b27e00
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/null_assertion_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that the trailing "!" is accepted after a sampling of expression
+// syntaxes. Verify that the compiler understands the resulting type to be
+// non-nullable by constructing a list containing the expression, and assigning
+// it to List<Object>. Where possible, verify that the runtime implements the
+// proper null-check semantics by verifying that the presence of `null` causes
+// an exception to be thrown.
+import 'package:expect/expect.dart';
+
+class C {
+ const C();
+
+ Object? get x => null;
+
+ void f() {}
+}
+
+Object? f() => null;
+
+main() {
+ List<Object> listOfObject;
+
+ var x1 = [0!];
+ listOfObject = x1;
+
+ var x2 = [true!];
+ listOfObject = x2;
+
+ var x3 = ["foo"!];
+ listOfObject = x3;
+
+ var x4 = [#foo!];
+ listOfObject = x4;
+
+ var x5 = [[1]!];
+ listOfObject = x5;
+
+ var x6 = [{1:2}!];
+ listOfObject = x6;
+
+ var x7 = [{1}!];
+ listOfObject = x7;
+
+ var x8 = [new C()!];
+ listOfObject = x8;
+
+ var x9 = [const C()!];
+ listOfObject = x9;
+
+ Expect.throws(() {
+ var x10 = [f()!];
+ listOfObject = x10;
+ });
+
+ C c = new C();
+ Expect.throws(() {
+ var x11 = [c.x!];
+ listOfObject = x11;
+ });
+
+ var g = f;
+ Expect.throws(() {
+ var x12 = [g()!];
+ listOfObject = x12;
+ });
+
+ int i = 0;
+ var x13 = [i++!];
+ listOfObject = x13;
+}
diff --git a/tests/language_2/nnbd/syntax/nullable_type_ambiguous_test.dart b/tests/language_2/nnbd/syntax/nullable_type_ambiguous_test.dart
new file mode 100644
index 0000000..e6f6ad6
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/nullable_type_ambiguous_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+import 'package:expect/expect.dart';
+
+class C {
+ bool operator *(Type t) => true;
+}
+
+main() {
+ // { a as bool ? - 3 : 3 } is parsed as a set literal { (a as bool) ? - 3 : 3 }.
+ dynamic a = true;
+ var x1 = {a as bool ? -3 : 3};
+ Expect.isTrue(x1 is Set<dynamic>);
+ Set<dynamic> y1 = x1;
+
+ // { a is int ? -3 : 3 } is parsed as a set literal { (a is int) ? -3 : 3 }.
+ a = 0;
+ var x2 = {a is int ? -3 : 3};
+ Expect.isTrue(x2 is Set<dynamic>);
+ Set<dynamic> y2 = x2;
+
+ // { a * int ? -3 : 3 } is parsed as a set literal { (a * int) ? -3 : 3 }.
+ a = C();
+ var x3 = {a * int ? -3 : 3};
+ Expect.isTrue(x3 is Set<dynamic>);
+ Set<dynamic> y3 = x3;
+}
diff --git a/tests/language_2/nnbd/syntax/nullable_type_error_test.dart b/tests/language_2/nnbd/syntax/nullable_type_error_test.dart
new file mode 100644
index 0000000..3cd9b8f
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/nullable_type_error_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
+import 'dart:core';
+import 'dart:core' as core;
+
+void f() {}
+
+main() {
+ // The grammar for types does not allow multiple successive ? operators on a
+ // type. Note: we test both with and without a space between `?`s because the
+ // scanner treats `??` as a single token.
+ int?? x1 = 0; //# 01: compile-time error
+ core.int?? x2 = 0; //# 02: compile-time error
+ List<int>?? x3 = <int>[]; //# 03: compile-time error
+ void Function()?? x4 = f; //# 04: compile-time error
+ int? ? x5 = 0; //# 05: compile-time error
+ core.int? ? x6 = 0; //# 06: compile-time error
+ List<int>? ? x7 = <int>[]; //# 07: compile-time error
+ void Function()? ? x4 = f; //# 08: compile-time error
+}
diff --git a/tests/language_2/nnbd/syntax/nullable_type_test.dart b/tests/language_2/nnbd/syntax/nullable_type_test.dart
new file mode 100644
index 0000000..8ed8fc3
--- /dev/null
+++ b/tests/language_2/nnbd/syntax/nullable_type_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that the trailing "?" is accepted after all type syntaxes. Verify that
+// the compiler understands the resulting type to be nullable by trying to
+// construct a list containing `null`. Verify that the runtime understands the
+// resulting type to be nullable by checking the reified list type.
+import 'package:expect/expect.dart';
+import 'dart:core';
+import 'dart:core' as core;
+
+main() {
+ var x1 = <int?>[null];
+ Expect.type<List<int?>>(x1);
+ Expect.notType<List<int>>(x1);
+
+ var x2 = <core.int?>[null];
+ Expect.type<List<int?>>(x2);
+ Expect.notType<List<int>>(x2);
+
+ var x3 = <List<int>?>[null];
+ Expect.type<List<List<int>?>>(x3);
+ Expect.notType<List<List<int>>>(x3);
+
+ var x4 = <void Function()?>[null];
+ Expect.type<List<void Function()?>>(x4);
+ Expect.notType<List<void Function()>>(x4);
+}
diff --git a/tests/language_2/spread_collections/await_test.dart b/tests/language_2/spread_collections/await_test.dart
index 839cfc9..886a94a 100644
--- a/tests/language_2/spread_collections/await_test.dart
+++ b/tests/language_2/spread_collections/await_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
import "package:async_helper/async_helper.dart";
import 'package:expect/expect.dart';
diff --git a/tests/language_2/spread_collections/const_error_test.dart b/tests/language_2/spread_collections/const_error_test.dart
index 7b4bb94..c186f13 100644
--- a/tests/language_2/spread_collections/const_error_test.dart
+++ b/tests/language_2/spread_collections/const_error_test.dart
@@ -2,67 +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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
-
-import 'dart:collection';
+// SharedOptions=--enable-experiment=spread-collections
import 'package:expect/expect.dart';
-import 'helper_classes.dart';
-var nonConstList = <int>[];
-var nonConstMap = <int, String>{};
-const dynamic nonIterable = 3;
-const dynamic nonMap = 3;
+const constList = [1, 2, 3, 4];
+const constSet = {1, 2, 3, 4};
+const constMap = {1: 1, 2: 2, 3: 3, 4: 4};
void main() {
- testList();
- testMap();
- testSet();
-}
+ var list = [1, 2, 3];
+ var set = {1, 2, 3};
+ var map = {1:1, 2:2, 3:3};
-void testList() {
- // Must be constant.
- const _ = <int>[...nonConstList]; //# 01: compile-time error
-
- // Must be iterable.
- const _ = <int>[...nonIterable]; //# 02: compile-time error
-
- // Cannot be custom iterable type.
- const _ = <int>[...ConstIterable()]; //# 03: compile-time error
-}
-
-void testMap() {
- // Must be constant.
- const _ = <int, String>{...nonConstMap}; //# 04: compile-time error
-
- // Must be map.
- const _ = <int, String>{...nonMap}; //# 05: compile-time error
-
- // Cannot be custom map type.
- const _ = <int, String>{...ConstMap()}; //# 06: compile-time error
-
- // Cannot have key collision.
- const _ = <int, String>{1: "s", ...{1: "t"}}; //# 07: compile-time error
- const _ = <int, String>{...{1: "s"}, ...{1: "t"}}; //# 08: compile-time error
-}
-
-void testSet() {
- // Must be constant.
- const _ = <int>{...nonConstList}; //# 09: compile-time error
-
- // Must be iterable.
- const _ = <int>{...nonIterable}; //# 10: compile-time error
-
- // Cannot be custom iterable type.
- const _ = <int>{...ConstIterable()}; //# 11: compile-time error
-
- // Cannot override operator.==().
- const obj = 0.1;
- const _ = {...[0.1]}; //# 12: compile-time error
- const _ = {...[Duration(seconds: 0)]}; //# 13: compile-time error
- const _ = {...[obj]}; //# 14: compile-time error
-
- // Cannot have collision.
- const _ = {1, ...[1]}; //# 15: compile-time error
- const _ = {...[1], ...[1]}; //# 16: compile-time error
+ // Spread cannot be used in a const collection.
+ const _ = [...list]; //# 00: compile-time error
+ const _ = [...constList]; //# 01: compile-time error
+ const _ = {...set}; //# 02: compile-time error
+ const _ = {...constSet}; //# 03: compile-time error
+ const _ = {...map}; //# 04: compile-time error
+ const _ = {...constMap}; //# 05: compile-time error
}
diff --git a/tests/language_2/spread_collections/const_test.dart b/tests/language_2/spread_collections/const_test.dart
deleted file mode 100644
index dccfab2..0000000
--- a/tests/language_2/spread_collections/const_test.dart
+++ /dev/null
@@ -1,182 +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=spread-collections,constant-update-2018
-
-import 'package:expect/expect.dart';
-
-// Typed as dynamic to also test spreading a value of type dynamic.
-const dynamic list = [1, 2, 3, 4];
-const dynamic map = {1: 1, 2: 2, 3: 3, 4: 4};
-const dynamic set = {1, 2, 3, 4};
-
-void main() {
- testList();
- testMap();
- testSet();
- testKeyOrder();
-}
-
-void testList() {
- // Only spread.
- Expect.identical(list, const <int>[...list]);
- Expect.identical(list, const <int>[...set]);
-
- // Spread at beginning.
- Expect.identical(list, const <int>[...<int>[1, 2], 3, 4]);
-
- // Spread in middle.
- Expect.identical(list, const <int>[1, ...<int>[2, 3], 4]);
-
- // Spread at end.
- Expect.identical(list, const <int>[1, 2, ...<int>[3, 4]]);
-
- // Empty spreads.
- Expect.identical(list,
- const <int>[...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]]);
-
- // Multiple spreads.
- Expect.identical(list,
- const <int>[...<int>[1], 2, ...<int>[3, 4]]);
-
- // Nested spreads.
- Expect.identical(list,
- const <int>[...<int>[...<int>[1, 2], ...<int>[3, 4]]]);
-
- // Null-aware.
- Expect.identical(list,
- const <int>[1, ...?<int>[2, 3], ...?(null), ...?<int>[4]]);
-
- // Does not deep flatten.
- Expect.identical(
- const <Object>[1, 2, <int>[3], 4],
- const <Object>[1, ...<Object>[2, <int>[3], 4]]);
-
- // Establishes const context.
- Expect.identical(const <Symbol>[Symbol("sym")],
- const <Symbol>[...<Symbol>[Symbol("sym")]]);
-}
-
-void testMap() {
- // Only spread.
- Expect.identical(map, const <int, int>{...map});
-
- // Spread at beginning.
- Expect.identical(map,
- const <int, int>{...<int, int>{1: 1, 2: 2}, 3: 3, 4: 4});
-
- // Spread in middle.
- Expect.identical(map,
- const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
-
- // Spread at end.
- Expect.identical(map,
- const <int, int>{1: 1, 2: 2, ...<int, int>{3: 3, 4: 4}});
-
- // Empty spreads.
- Expect.identical(map, const <int, int>{
- ...<int, int>{},
- 1: 1,
- 2: 2,
- ...<int, int>{},
- 3: 3,
- 4: 4,
- ...<int, int>{}
- });
-
- // Multiple spreads.
- Expect.identical(map,
- const <int, int>{...<int, int>{1: 1}, 2: 2, ...<int, int>{3: 3, 4: 4}});
-
- // Nested spreads.
- Expect.identical(map, const <int, int>{
- ...<int, int>{
- ...<int, int>{1: 1, 2: 2},
- ...<int, int>{3: 3, 4: 4}
- }
- });
-
- // Null-aware.
- Expect.identical(map, const <int, int>{
- 1: 1,
- ...?<int, int>{2: 2, 3: 3},
- ...?(null),
- ...?<int, int>{4: 4}
- });
-
- // Does not deep flatten.
- Expect.identical(const <int, Object>{
- 1: 1,
- 2: 2,
- 3: <int, int>{3: 3},
- 4: 4
- }, const <int, Object>{
- 1: 1,
- ...<int, Object>{
- 2: 2,
- 3: <int, int>{3: 3},
- 4: 4
- }
- });
-
- // Establishes const context.
- Expect.identical(const <Symbol, Symbol>{
- Symbol("sym"): Symbol("bol")
- }, const <Symbol, Symbol>{
- ...<Symbol, Symbol>{Symbol("sym"): Symbol("bol")}
- });
-}
-
-void testSet() {
- // Only spread.
- Expect.identical(set, const <int>{...set});
- Expect.identical(set, const <int>{...list});
-
- // Spread at beginning.
- Expect.identical(set, const <int>{...<int>[1, 2], 3, 4});
-
- // Spread in middle.
- Expect.identical(set, const <int>{1, ...<int>[2, 3], 4});
-
- // Spread at end.
- Expect.identical(set, const <int>{1, 2, ...<int>[3, 4]});
-
- // Empty spreads.
- Expect.identical(set,
- const <int>{...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]});
-
- // Multiple spreads.
- Expect.identical(set, const <int>{...<int>[1], 2, ...<int>[3, 4]});
-
- // Nested spreads.
- Expect.identical(set, const <int>{...<int>{...<int>[1, 2], ...<int>[3, 4]}});
-
- // Null-aware.
- Expect.identical(set,
- const <int>{1, ...?<int>[2, 3], ...?(null), ...?<int>[4]});
-
- // Does not deep flatten.
- Expect.identical(const <Object>{1, 2, <int>{3}, 4},
- const <Object>{1, ...<Object>{2, <int>{3}, 4}});
-
- // Establishes const context.
- Expect.identical(const <Symbol>{Symbol("sym")},
- const <Symbol>{...<Symbol>{Symbol("sym")}});
-}
-
-void testKeyOrder() {
- // Canonicalization isn't affected by which elements are spread.
- Expect.identical(map,
- const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
- Expect.identical(map,
- const <int, int>{1: 1, ...<int, int>{2: 2}, 3: 3, ...<int, int>{4: 4}});
-
- Expect.identical(set, const <int>{1, ...<int>{2, 3}, 4});
- Expect.identical(set, const <int>{1, ...<int>{2}, 3, ...<int>{4}});
-
- // Ordering does affect canonicalization.
- Expect.notIdentical(const <int, int>{1: 1, 2: 2, 3: 3},
- const <int, int>{1: 1, ...<int, int>{3: 3, 2: 2}});
- Expect.notIdentical(const <int>{1, 2, 3}, const <int>{1, ...<int>{3, 2}});
-}
diff --git a/tests/language_2/spread_collections/experimental_flag_test.dart b/tests/language_2/spread_collections/experimental_flag_test.dart
deleted file mode 100644
index 84135f1..0000000
--- a/tests/language_2/spread_collections/experimental_flag_test.dart
+++ /dev/null
@@ -1,16 +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.
-
-// Check that spread collections are not enabled without the experimental flag.
-
-// TODO(rnystrom): Remove this test when the feature is enabled without a flag.
-
-void main() {
- var _ = <int>[...<int>[1]]; //# 01: compile-time error
- var _ = <int, int>{...<int, int>{1: 1}}; //# 02: compile-time error
- var _ = <int>{...<int>{1}}; //# 03: compile-time error
- var _ = <int>[...?null]; //# 04: compile-time error
- var _ = <int, int>{...?null}; //# 05: compile-time error
- var _ = <int>{...?null}; //# 06: compile-time error
-}
diff --git a/tests/language_2/spread_collections/inference_test.dart b/tests/language_2/spread_collections/inference_test.dart
index 7d0ffef..e3c429f 100644
--- a/tests/language_2/spread_collections/inference_test.dart
+++ b/tests/language_2/spread_collections/inference_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
// Test how spread interacts with inference.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart b/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart
index 458f264..5f6576d 100644
--- a/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart
+++ b/tests/language_2/spread_collections/map_set_ambiguity_error_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
// Test cases where the syntax is ambiguous between maps and sets.
import 'dart:collection';
diff --git a/tests/language_2/spread_collections/map_set_ambiguity_test.dart b/tests/language_2/spread_collections/map_set_ambiguity_test.dart
index 4b11ccf..9b3d537 100644
--- a/tests/language_2/spread_collections/map_set_ambiguity_test.dart
+++ b/tests/language_2/spread_collections/map_set_ambiguity_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
// Test cases where the syntax is ambiguous between maps and sets.
import 'dart:collection';
diff --git a/tests/language_2/spread_collections/runtime_error_test.dart b/tests/language_2/spread_collections/runtime_error_test.dart
index 095e77b..ad74289 100644
--- a/tests/language_2/spread_collections/runtime_error_test.dart
+++ b/tests/language_2/spread_collections/runtime_error_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/spread_collections/spread_test.dart b/tests/language_2/spread_collections/spread_test.dart
index bb2e166..7bc721d 100644
--- a/tests/language_2/spread_collections/spread_test.dart
+++ b/tests/language_2/spread_collections/spread_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
import 'package:expect/expect.dart';
diff --git a/tests/language_2/spread_collections/syntax_error_test.dart b/tests/language_2/spread_collections/syntax_error_test.dart
index 96802da..05261cd 100644
--- a/tests/language_2/spread_collections/syntax_error_test.dart
+++ b/tests/language_2/spread_collections/syntax_error_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
void main() {
// Spread nothing.
diff --git a/tests/language_2/spread_collections/syntax_test.dart b/tests/language_2/spread_collections/syntax_test.dart
index 716ec22..7100394 100644
--- a/tests/language_2/spread_collections/syntax_test.dart
+++ b/tests/language_2/spread_collections/syntax_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
// Tests syntax edge cases.
import 'package:expect/expect.dart';
diff --git a/tests/language_2/spread_collections/type_error_test.dart b/tests/language_2/spread_collections/type_error_test.dart
index 4c7a338..68cf98c 100644
--- a/tests/language_2/spread_collections/type_error_test.dart
+++ b/tests/language_2/spread_collections/type_error_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.
-// SharedOptions=--enable-experiment=spread-collections,constant-update-2018
+// SharedOptions=--enable-experiment=spread-collections
void main() {
// Spread non-iterable or non-map.
diff --git a/tests/language_2/vm/osr_nonempty_stack_test.dart b/tests/language_2/vm/osr_nonempty_stack_test.dart
new file mode 100644
index 0000000..20af5d6
--- /dev/null
+++ b/tests/language_2/vm/osr_nonempty_stack_test.dart
@@ -0,0 +1,141 @@
+// 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=spread-collections,control-flow-collections,constant-update-2018
+
+// Test with OSR on non-empty stack (block expression).
+
+import 'dart:core';
+import "package:expect/expect.dart";
+
+const String NeverInline = 'NeverInline';
+
+class Z {
+ @NeverInline
+ check(int a, int b, String c, List<int> d) {
+ Expect.equals(a, 42);
+ Expect.equals(b, global_bazz);
+ Expect.equals(c, 'abc');
+ return d;
+ }
+}
+
+Z z = new Z();
+int global_bazz = 123;
+int global_more_bazz = 456;
+
+@NeverInline
+int bazz() {
+ return ++global_bazz;
+}
+
+@NeverInline
+int more_bazz() {
+ return ++global_more_bazz;
+}
+
+@NeverInline
+int bar(int i) {
+ return i - 1;
+}
+
+@NeverInline
+List<int> spread(int v, List<int> x) {
+ return [v, ...x];
+}
+
+// Long running control-flow collection (block expression),
+// leaves the stack non-empty during a potential OSR.
+@NeverInline
+List<int> test1(int n) {
+ return spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
+}
+
+// Long running control-flow collection (block expression) inside outer
+// loop, leaves the stack non-empty during a potential OSR.
+List<int> test2(int n) {
+ List<int> x = [];
+ for (int k = 0; k < 10; k++) {
+ x += spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
+ }
+ return x;
+}
+
+// Long running control-flow collection (block expression) inside two
+// outer loops, leaves the stack non-empty during a potential OSR.
+List<int> test3(int n) {
+ List<int> x = [];
+ for (int k = 0; k < 4; k++) {
+ for (int j = 0; j < 4; j++) {
+ x += spread(more_bazz(), [for (int i = 0; i < n; i++) i]);
+ }
+ }
+ return x;
+}
+
+// Long running control-flow collection (block expression),
+// leaves the stack non-empty during a potential OSR.
+@NeverInline
+List<int> test4(int n) {
+ var x = [10] +
+ z.check(42, bazz(), 'abc',
+ [more_bazz(), for (int i = 0; i < n; i++) bar(2 * i)]);
+ return x;
+}
+
+// Long running control-flow collection (block expression) inside outer
+// loop, also leaves the stack non-empty during a potential OSR.
+@NeverInline
+List<int> test5(int m, int n) {
+ List<int> x = [];
+ for (int k = 0; k < m; k++) {
+ x += [10] +
+ z.check(42, bazz(), 'abc',
+ [more_bazz(), for (int i = 0; i < n; i++) bar(2 * i)]);
+ }
+ return x;
+}
+
+main() {
+ int n = 100000;
+ int g = 457;
+
+ var a = test1(n);
+ Expect.equals(a.length, n + 1);
+ for (int k = 0; k < n + 1; k++) {
+ int expect = (k == 0) ? g++ : k - 1;
+ Expect.equals(a[k], expect);
+ }
+
+ var b = test2(n);
+ Expect.equals(b.length, 10 * (n + 1));
+ for (int i = 0, k = 0; i < 10 * (n + 1); i++) {
+ int expect = (k == 0) ? g++ : k - 1;
+ Expect.equals(b[i], expect);
+ if (++k == (n + 1)) k = 0;
+ }
+
+ var c = test3(n);
+ Expect.equals(c.length, 16 * (n + 1));
+ for (int i = 0, k = 0; i < 16 * (n + 1); i++) {
+ int expect = (k == 0) ? g++ : k - 1;
+ Expect.equals(c[i], expect);
+ if (++k == (n + 1)) k = 0;
+ }
+
+ var d = test4(n);
+ Expect.equals(d.length, n + 2);
+ for (int k = 0; k < n + 2; k++) {
+ int expect = k <= 1 ? ((k == 0) ? 10 : g++) : -5 + 2 * k;
+ Expect.equals(d[k], expect);
+ }
+
+ var e = test5(10, n);
+ Expect.equals(e.length, 10 * (n + 2));
+ for (int i = 0, k = 0; i < 10 * (n + 2); i++) {
+ int expect = k <= 1 ? ((k == 0) ? 10 : g++) : -5 + 2 * k;
+ Expect.equals(e[i], expect);
+ if (++k == (n + 2)) k = 0;
+ }
+}
diff --git a/tests/language_2/vm/regression_36587_test.dart b/tests/language_2/vm/regression_36587_test.dart
new file mode 100644
index 0000000..a014641
--- /dev/null
+++ b/tests/language_2/vm/regression_36587_test.dart
@@ -0,0 +1,105 @@
+// 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 extracted from a large DartFuzz-generated test.
+// https://github.com/dart-lang/sdk/issues/36587
+
+import "package:expect/expect.dart";
+
+import 'dart:async';
+import 'dart:cli';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:core';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:typed_data';
+
+Set<int> var0 = {-62, -13, 2147483648, -10, -9223372028264841217, -54, 47};
+Set<int> var1 = {-59};
+bool var2 = false;
+bool var3 = true;
+int var4 = 58;
+double var5 = 0.004032426761438224;
+String var6 = 'u6X2';
+List<int> var7 = [56, -95, 6442450944, -31, 82];
+Set<int> var8 = {9223372036854775807, 4294967297};
+Map<int, String> var9 = {
+ 6: 'Ei(ZR',
+ 75: 'O0A-',
+ 99: 't',
+ 49: 'Qu',
+ 20: 'FujA\u2665',
+ 47: ''
+};
+
+String foo2() {
+ var8 ??= Set.identity();
+ switch ((--var4)) {
+ case 3826530052:
+ {
+ {
+ int loc0 = 0;
+ do {
+ try {
+ throw {64: var6};
+ } catch (e) {
+ if ((!(var3))) {
+ break;
+ } else {
+ try {
+ var8 = ((false ? FileSystemEntity.isWatchSupported : var3)
+ ? {Int32x4.wxxx, var4, -43, Float32x4.wzxz}
+ : {
+ (var4++),
+ (var7[(false ? -87 : (++loc0))] %
+ (var7[((++loc0) * var4)] ~/ 73))
+ });
+ var0 = ((((-((((true ? var2 : false) ? (!(var3)) : true)
+ ? var5
+ : (0.38834735336907733 ??
+ 0.8105736840461367)))) +
+ (0.3752597438445757).abs()))
+ .isFinite
+ ? {
+ (true ? 65 : (var3 ? (loc0--) : var4)),
+ var7[Float32x4.xxxx]
+ }
+ : Set.identity());
+ var1 = ((true
+ ? ({var7[var7[-9223372032559808513]]}).toSet()
+ : (Set.identity()).difference(var8)) ??
+ var8);
+ var9[Float32x4.zxyz] = '';
+ } catch (e) {
+ loc0 ~/= ((var3 != var3)
+ ? (~((false ? (-(loc0)) : Int32x4.wzwx)))
+ : var4);
+ } finally {
+ var1 = var8;
+ var5 ??= 0.6273822429057158;
+ throw [
+ (loc0++),
+ 2147483647,
+ (var4--),
+ (-(ZLibOption.defaultWindowBits)),
+ (~((loc0--))),
+ (var4++)
+ ];
+ }
+ }
+ break;
+ }
+ } while (++loc0 < 74);
+ }
+ }
+ }
+}
+
+main() {
+ Expect.equals(58, var4);
+ foo2();
+ Expect.equals(57, var4);
+}
diff --git a/third_party/d8/README.google b/third_party/d8/README.google
index 9b592e1..303e812 100644
--- a/third_party/d8/README.google
+++ b/third_party/d8/README.google
@@ -1,9 +1,9 @@
Name: V8 command line javascript shell.
Short Name: d8
-URL: https://chromium.googlesource.com/v8/v8/+/refs/tags/6.9.427.23
-Version: 6.9.427.23
-Revision: 40b7c570a56b1134ff5083d8311e69ad8bf8fbd7
-Date: September 14 2018
+URL: https://chromium.googlesource.com/v8/v8/+/refs/tags/7.5.149
+Version: 7.5.149
+Revision: 804cfc5fb2ab8c49facc7a5f486c1555c2cbad63
+Date: March 31 2019
License: BSD
Description:
diff --git a/third_party/d8/update.sh b/third_party/d8/update.sh
index 3236046..bb5e2d3 100755
--- a/third_party/d8/update.sh
+++ b/third_party/d8/update.sh
@@ -26,7 +26,7 @@
for i in "${!arch[@]}"
do
filename="v8-${arch[$i]}-rel-$version.zip"
- gsutil cp "gs://chromium-v8/official/$major.$minor/$filename" .
+ gsutil cp "gs://chromium-v8/official/canary/$filename" .
mkdir -p d8/${path[$i]}
unzip -q $filename -d d8/${path[$i]}
rm $filename
diff --git a/tools/VERSION b/tools/VERSION
index e0edd34..cf8239f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -31,9 +31,9 @@
#
CHANNEL dev
MAJOR 2
-MINOR 2
-PATCH 1
-PRERELEASE 4
-PRERELEASE_PATCH 2
-ABI_VERSION 2
+MINOR 3
+PATCH 0
+PRERELEASE 0
+PRERELEASE_PATCH 0
+ABI_VERSION 4
OLDEST_SUPPORTED_ABI_VERSION 1
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
new file mode 100755
index 0000000..1c81fba
--- /dev/null
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Compile flutter tests with a locally built SDK.
+
+set -e
+
+checkout=$(pwd)
+dart=$checkout/out/ReleaseX64/dart-sdk/bin/dart
+sdk=$checkout/out/ReleaseX64/dart-sdk
+tmpdir=$(mktemp -d)
+cleanup() {
+ rm -rf "$tmpdir"
+}
+trap cleanup EXIT HUP INT QUIT TERM PIPE
+pushd "$tmpdir"
+
+git clone -vv https://chromium.googlesource.com/external/github.com/flutter/flutter
+
+pushd flutter
+bin/flutter config --no-analytics
+pinned_dart_sdk=$(cat bin/cache/dart-sdk/revision)
+patch=$checkout/tools/patches/flutter-engine/${pinned_dart_sdk}.flutter.patch
+if [ -e "$patch" ]; then
+ git apply $patch
+fi
+bin/flutter update-packages
+popd
+
+# Directly in temp directory again.
+mkdir engine
+pushd engine
+git clone -vv --depth 1 https://chromium.googlesource.com/external/github.com/flutter/engine flutter
+mkdir third_party
+pushd third_party
+ln -s $checkout dart
+popd
+popd
+
+mkdir flutter_patched_sdk
+
+$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=$checkout/ org-dartlang-sdk:///sdk/lib/libraries.json vm_outline_strong.dill vm_platform_strong.dill vm_outline_strong.dill
+$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart --target=flutter dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=engine org-dartlang-sdk:///flutter/lib/snapshot/libraries.json vm_outline_strong.dill flutter_patched_sdk/platform_strong.dill flutter_patched_sdk/outline_strong.dill
+
+popd
+
+$dart --enable-asserts pkg/vm/test/frontend_server_flutter.dart --flutterDir=$tmpdir/flutter --flutterPlatformDir=$tmpdir/flutter_patched_sdk
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 78e10bc..3cd4ed0 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -885,6 +885,14 @@
"pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart",
"-rnone"
]
+ },
+ {
+ "name": "ddc worker tests",
+ "script": "out/ReleaseX64/dart",
+ "arguments": [
+ "pkg/dev_compiler/test/worker/worker_test.dart",
+ "-rnone"
+ ]
}
]
},
@@ -950,6 +958,14 @@
"pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart",
"-rnone"
]
+ },
+ {
+ "name": "ddc worker tests",
+ "script": "xcodebuild/ReleaseX64/dart",
+ "arguments": [
+ "pkg/dev_compiler/test/worker/worker_test.dart",
+ "-rnone"
+ ]
}
]
},
@@ -1839,6 +1855,30 @@
]
},
{
+ "builders": [
+ "flutter-frontend"
+ ],
+ "meta": {
+ "description": "This configuration is used for running frontend tests on flutter code."
+ },
+ "steps": [
+ {
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": [
+ "--mode=release",
+ "--arch=x64",
+ "create_sdk"
+ ]
+ },
+ {
+
+ "name": "compile flutter tests",
+ "script": "tools/bots/flutter/compile_flutter.sh"
+ }
+ ]
+ },
+ {
"builders": ["fuzz-linux"],
"meta": {
"description": "This configuration is used for fuzz testing."
diff --git a/tools/download_abi_dills.py b/tools/download_abi_dills.py
index 6eaa9e6..51dd8c1 100644
--- a/tools/download_abi_dills.py
+++ b/tools/download_abi_dills.py
@@ -23,11 +23,14 @@
return procWait(p) == 0
-def downloadAbiDills(oldest_abi_version, abi_version):
+def main():
+ abi_version = int(utils.GetAbiVersion())
+ oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
cmd = ['cipd', 'ensure', '-root', 'tools/abiversions', '-ensure-file', '-']
ensure_file = ''
for i in xrange(oldest_abi_version, abi_version + 1):
- ensure_file += '@Subdir %d\ndart/abiversions/%d latest\n\n' % (i, i)
+ if findAbiVersion(i):
+ ensure_file += '@Subdir %d\ndart/abiversions/%d latest\n\n' % (i, i)
if not ensure_file:
return 0
p = subprocess.Popen(cmd,
@@ -41,16 +44,5 @@
return procWait(p)
-def main():
- abi_version = int(utils.GetAbiVersion())
- oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
-
- # The latest abi version may not have an entry in CIPD yet, so check first.
- if not findAbiVersion(abi_version):
- abi_version -= 1
-
- return downloadAbiDills(oldest_abi_version, abi_version)
-
-
if __name__ == '__main__':
sys.exit(main())
diff --git a/tools/testing/dart/command.dart b/tools/testing/dart/command.dart
index 9b41d64..d89b964 100644
--- a/tools/testing/dart/command.dart
+++ b/tools/testing/dart/command.dart
@@ -41,9 +41,10 @@
List<Uri> bootstrapDependencies,
String executable,
List<String> arguments,
- Map<String, String> environment) {
+ Map<String, String> environment,
+ List<String> batchArgs) {
return new VMKernelCompilationCommand._(outputFile, neverSkipCompilation,
- bootstrapDependencies, executable, arguments, environment);
+ bootstrapDependencies, executable, arguments, environment, batchArgs);
}
static Command analysis(String executable, List<String> arguments,
@@ -419,6 +420,8 @@
}
class VMKernelCompilationCommand extends CompilationCommand {
+ final List<String> batchArgs;
+
VMKernelCompilationCommand._(
String outputFile,
bool alwaysCompile,
@@ -426,17 +429,29 @@
String executable,
List<String> arguments,
Map<String, String> environmentOverrides,
+ this.batchArgs,
{int index = 0})
- : super._('vm_compile_to_kernel', outputFile, alwaysCompile,
+ : super._('vm_compile_to_kernel $batchArgs', outputFile, alwaysCompile,
bootstrapDependencies, executable, arguments, environmentOverrides,
index: index);
VMKernelCompilationCommand indexedCopy(int index) =>
- VMKernelCompilationCommand._(_outputFile, _alwaysCompile,
- _bootstrapDependencies, executable, arguments, environmentOverrides,
+ VMKernelCompilationCommand._(
+ _outputFile,
+ _alwaysCompile,
+ _bootstrapDependencies,
+ executable,
+ arguments,
+ environmentOverrides,
+ batchArgs,
index: index);
int get maxNumRetries => 1;
+
+ @override
+ List<String> get batchArguments {
+ return batchArgs;
+ }
}
/// This is just a Pair(String, Map) class with hashCode and operator ==
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 6f6c394..9edb9fb 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -539,10 +539,23 @@
Command createCommand(String inputFile, String outputFile,
List<String> sharedOptions, Map<String, String> environment) {
- // TODO(jmesserly): restore testing on this once we have everyone migrated
- // to DDC's Kernel backend. At that point we'd like to migrate from Analyzer
- // summaries to Kernel IL.
- final useDillFormat = false;
+ /// This can be disabled to test DDC's hybrid mode (automatically converting
+ /// Analyzer summaries to Kernel files).
+ ///
+ /// The current DDC configurations are:
+ ///
+ /// - using Analyzer ASTs and Analyzer summaries: the current default
+ /// configuration; used in internal builds.
+ /// - using Kernel trees and Kernel IL files: the new default for external
+ /// users (e.g. Flutter Web), and in the future, the only DDC mode.
+ /// - using Kernel trees, but Analyzer summaries (converted automatically):
+ /// this was intended to help migrate internal users, but is currently
+ /// unused.
+ ///
+ /// The first two are tested on the bots and are called "dartdevc" and
+ /// "dartdevk" respectively. This flag switches "dartdevk" to use either
+ /// Kernel IL files, or the Analyzer summaries.
+ final useDillFormat = useKernel;
var args = <String>[];
if (useKernel) {
@@ -1095,11 +1108,18 @@
final pkgVmDir = Platform.script.resolve('../../../pkg/vm').toFilePath();
final genKernel = '${pkgVmDir}/tool/gen_kernel${executableScriptSuffix}';
- final kernelBinariesFolder = _useSdk
- ? '${_configuration.buildDirectory}/dart-sdk/lib/_internal'
- : '${_configuration.buildDirectory}';
+ final String useAbiVersion = arguments.firstWhere(
+ (arg) => arg.startsWith('--use-abi-version='),
+ orElse: () => null);
- // Always use strong platform as preview_dart_2 implies strong.
+ var kernelBinariesFolder = '${_configuration.buildDirectory}';
+ if (useAbiVersion != null) {
+ var version = useAbiVersion.split('=')[1];
+ kernelBinariesFolder += '/dart-sdk/lib/_internal/abiversions/$version';
+ } else if (_useSdk) {
+ kernelBinariesFolder += '/dart-sdk/lib/_internal';
+ }
+
final vmPlatform = '$kernelBinariesFolder/vm_platform_strong.dill';
final dillFile = tempKernelFile(tempDir);
@@ -1111,6 +1131,11 @@
dillFile,
];
+ 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') ||
@@ -1132,7 +1157,7 @@
}
return Command.vmKernelCompilation(dillFile, true, bootstrapDependencies(),
- genKernel, args, environmentOverrides);
+ genKernel, args, environmentOverrides, batchArgs);
}
}
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index c0c6d7d..902dd9e 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -306,6 +306,7 @@
// over.
DebugLogger.error("${filePath.toNativePath()}: "
"Relative import in multitest containing '..' is not allowed.");
+ DebugLogger.close();
exit(1);
}
diff --git a/tools/utils.py b/tools/utils.py
index d6878bc..32d843e 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -472,7 +472,7 @@
def GetShortGitHash():
- p = subprocess.Popen(['git', '--short', 'rev-parse', 'HEAD'],
+ p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, shell=IsWindows(),
cwd = DART_DIR)
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index c97152e..3723077 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -258,14 +258,17 @@
state.options.onDiagnostic = onDiagnostic;
Component incrementalComponent = await state.incrementalCompiler
.computeDelta(entryPoints: sources, fullComponent: true);
- if (summaryOnly) {
- incrementalComponent.uriToSource.clear();
- incrementalComponent.problemsAsJson = null;
- incrementalComponent.mainMethod = null;
- target.performOutlineTransformations(incrementalComponent);
- }
- kernel = fe.serializeComponent(incrementalComponent);
+ kernel = await state.incrementalCompiler.context.runInContext((_) {
+ if (summaryOnly) {
+ incrementalComponent.uriToSource.clear();
+ incrementalComponent.problemsAsJson = null;
+ incrementalComponent.mainMethod = null;
+ target.performOutlineTransformations(incrementalComponent);
+ }
+
+ return Future.value(fe.serializeComponent(incrementalComponent));
+ });
} else {
kernel = await fe.compile(state, sources, onDiagnostic,
summaryOnly: summaryOnly);