Version 1.18.0-dev.3.0
Merge '3d9f53a4e663f537c061205fdf65afbd6d3e3acd' into dev
diff --git a/.gitignore b/.gitignore
index e66367d..f839f5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,10 @@
-# These ignores are auto-generated from the canonical svn ignore metadata
-# using:
-#
-# $ git svn create-ignore
-#
-# Whenever possible, prefer creating ignores in svn and then generating them
-# to keep git in sync.
+# Build artifacts and dependencies.
/.children
/.project
/Makefile
+/base
/benchmarks
-/build
+/buildtools
/ipch
/out
/xcodebuild
@@ -27,9 +22,6 @@
*.vcxproj.filters
/*.vcxproj.user
-# End generated ignores. The following are hand-added because the svn:ignore
-# stuff doesn't handle them well.
-
# Gyp generated files
*.xcodeproj
*.intermediate
diff --git a/DEPS b/DEPS
index 626a258..62967ba 100644
--- a/DEPS
+++ b/DEPS
@@ -21,12 +21,18 @@
"github_mirror":
"https://chromium.googlesource.com/external/github.com/dart-lang/%s.git",
+ # Chromium git
+ "chromium_git": "https://chromium.googlesource.com",
+
# Only use this temporarily while waiting for a mirror for a new package.
"github_dartlang": "https://github.com/dart-lang/%s.git",
"gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
"co19_rev": "@3f0a4bc9a080a792cdf5f093147a900f99ea301f",
- "chromium_git": "https://chromium.googlesource.com",
+
+ # Revisions of GN/Mojo/Flutter related dependencies.
+ "base_revision": "@672b04e54b937ec899429a6bd5409c5a6300d151",
+ "buildtools_revision": "@565d04e8741429fb1b4f26d102f2c6c3b849edeb",
# Revisions of /third_party/* dependencies.
"args_tag": "@0.13.4",
@@ -49,7 +55,7 @@
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.4",
- "dartdoc_tag" : "@v0.9.6",
+ "dartdoc_tag" : "@v0.9.6+1",
"dev_compiler_rev": "@7e9708eb5e9f3fcdc68b9af039d78cf39ce502b7",
"fixnum_tag": "@0.10.5",
"func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
@@ -64,7 +70,7 @@
"intl_tag": "@0.13.0",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.0",
- "linter_rev": "@1a08f395b1f4e24b3901018938320f053bad6aa8",
+ "linter_rev": "@7ca3aab6ca45b988440e425c187993a533fbe27e",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
"matcher_tag": "@0.12.0",
@@ -119,6 +125,14 @@
Var("dart_root") + "/third_party/gyp":
Var('chromium_git') + '/external/gyp.git' + Var("gyp_rev"),
+ # Stuff needed for GN/Mojo/Flutter.
+ Var("dart_root") + "/base":
+ Var('chromium_git') + '/external/github.com/domokit/base' + Var('base_revision'),
+
+ Var("dart_root") + "/buildtools":
+ Var('chromium_git') + '/chromium/buildtools.git' +
+ Var('buildtools_revision'),
+
Var("dart_root") + "/tests/co19/src":
(Var("github_mirror") % "co19") + Var("co19_rev"),
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_local.dart b/pkg/analysis_server/benchmark/perf/benchmark_local.dart
index 7b17591..a6fd493 100644
--- a/pkg/analysis_server/benchmark/perf/benchmark_local.dart
+++ b/pkg/analysis_server/benchmark/perf/benchmark_local.dart
@@ -4,192 +4,236 @@
library server.performance.local;
+import 'dart:async';
+
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'benchmark_scenario.dart';
main(List<String> args) async {
- String pathRepository = args[0];
- String pathServer = '$pathRepository/pkg/analysis_server';
- String pathAnalyzer = '$pathRepository/pkg/analyzer';
- {
- String now = new DateTime.now().toUtc().toIso8601String();
- print('Benchmark started: $now');
- print('');
- print('');
+ int length = args.length;
+ if (length < 1) {
+ print(
+ 'Usage: dart benchmark_local.dart path_to_sdk_checkout [path_to_flutter_checkout]');
+ return;
+ } else if (length == 1) {
+ paths = new PathHolder(sdkPath: args[0]);
+ } else {
+ paths = new PathHolder(sdkPath: args[0], flutterPath: args[1]);
}
+ String now = new DateTime.now().toUtc().toIso8601String();
+ print('Benchmark started: $now');
+ print('');
+ print('');
+ await run_local_initialAnalysis_1();
+ await run_local_initialAnalysis_2();
+ await run_local_initialAnalysis_3();
+ await run_local_change_1();
+ await run_local_change_2();
+ await run_local_completion_1();
+ await run_local_completion_2();
+ await run_local_completion_3();
+ await run_local_completion_4();
+ await run_local_refactoring_1();
+}
- {
- String id = 'local-initialAnalysis-1';
- String description = r'''
+PathHolder paths;
+
+Future run_local_change_1() async {
+ String id = 'local-change-1';
+ String description = r'''
+1. Open 'analyzer'.
+2. Change a method body in src/task/dart.dart.
+3. Measure the time to finish analysis.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
+ roots: [paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'if (hasDirectiveChange) {', insertStr: 'print(12345);'),
+ numOfRepeats: 10);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_change_2() async {
+ String id = 'local-change-2';
+ String description = r'''
+1. Open 'analyzer'.
+2. Change the name of a public method in src/task/dart.dart.
+3. Measure the time to finish analysis.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
+ roots: [paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'resolveDirective(An',
+ afterStrBack: 3,
+ insertStr: 'NewName'),
+ numOfRepeats: 5);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_completion_1() async {
+ String id = 'local-completion-1';
+ String description = r'''
+1. Open 'analyzer'.
+2. Change a method body in src/task/dart.dart.
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario()
+ .waitAnalyze_change_getCompletion(
+ roots: [paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'if (hasDirectiveChange) {',
+ insertStr: 'print(12345);'),
+ completeAfterStr: 'print(12345);',
+ numOfRepeats: 10);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_completion_2() async {
+ String id = 'local-completion-2';
+ String description = r'''
+1. Open 'analyzer'.
+2. Change the name of a public method in src/task/dart.dart.
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario()
+ .waitAnalyze_change_getCompletion(
+ roots: [paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'DeltaResult validate(In',
+ afterStrBack: 3,
+ insertStr: 'NewName'),
+ completeAfterStr: 'if (hasDirectiveChange) {',
+ numOfRepeats: 5);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_completion_3() async {
+ String id = 'local-completion-3';
+ String description = r'''
+1. Open 'analysis_server' and 'analyzer'.
+2. Change a method body in src/task/dart.dart.
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario()
+ .waitAnalyze_change_getCompletion(
+ roots: [paths.analysisServer, paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'if (hasDirectiveChange) {',
+ insertStr: 'print(12345);'),
+ completeAfterStr: 'print(12345);',
+ numOfRepeats: 10);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_completion_4() async {
+ String id = 'local-completion-4';
+ String description = r'''
+1. Open 'analysis_server' and 'analyzer'.
+2. Change the name of a public method in src/task/dart.dart.
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+ List<int> times = await new BenchmarkScenario()
+ .waitAnalyze_change_getCompletion(
+ roots: [paths.analysisServer, paths.analyzer],
+ file: '${paths.analyzer}/lib/src/task/dart.dart',
+ fileChange: new FileChange(
+ afterStr: 'DeltaResult validate(In',
+ afterStrBack: 3,
+ insertStr: 'NewName'),
+ completeAfterStr: 'if (hasDirectiveChange) {',
+ numOfRepeats: 5);
+ printBenchmarkResults(id, description, times);
+}
+
+Future run_local_initialAnalysis_1() async {
+ String id = 'local-initialAnalysis-1';
+ String description = r'''
1. Start server, set 'analyzer' analysis root.
2. Measure the time to finish initial analysis.
3. Shutdown the server.
4. Go to (1).
''';
- List<int> times = await BenchmarkScenario
- .start_waitInitialAnalysis_shutdown(
- roots: [pathAnalyzer], numOfRepeats: 3);
- printBenchmarkResults(id, description, times);
- }
+ List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
+ roots: [paths.analyzer], numOfRepeats: 3);
+ printBenchmarkResults(id, description, times);
+}
- {
- String id = 'local-initialAnalysis-2';
- String description = r'''
+Future run_local_initialAnalysis_2() async {
+ String id = 'local-initialAnalysis-2';
+ String description = r'''
1. Start server, set 'analyzer' and 'analysis_server' analysis roots.
2. Measure the time to finish initial analysis.
3. Shutdown the server.
4. Go to (1).
''';
- List<int> times = await BenchmarkScenario
- .start_waitInitialAnalysis_shutdown(
- roots: [pathAnalyzer, pathServer], numOfRepeats: 3);
- printBenchmarkResults(id, description, times);
- }
+ List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
+ roots: [paths.analyzer, paths.analysisServer], numOfRepeats: 3);
+ printBenchmarkResults(id, description, times);
+}
- {
- String id = 'local-change-1';
- String description = r'''
-1. Open 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
+Future run_local_initialAnalysis_3() async {
+ String id = 'local-initialAnalysis-3';
+ String description = r'''
+1. Start server, set 'hello_world' and 'stocks' analysis roots.
+2. Measure the time to finish initial analysis.
+3. Shutdown the server.
+4. Go to (1).
''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'if (hasDirectiveChange) {', insertStr: 'print(12345);'),
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
- }
+ List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
+ roots: [paths.flutterHelloWorld, paths.flutterStocks], numOfRepeats: 3);
+ printBenchmarkResults(id, description, times);
+}
- {
- String id = 'local-change-2';
- String description = r'''
-1. Open 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'resolveDirective(An',
- afterStrBack: 3,
- insertStr: 'NewName'),
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
- }
-
- {
- String id = 'local-completion-1';
- String description = r'''
-1. Open 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'if (hasDirectiveChange) {',
- insertStr: 'print(12345);'),
- completeAfterStr: 'print(12345);',
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
- }
-
- {
- String id = 'local-completion-2';
- String description = r'''
-1. Open 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'DeltaResult validate(In',
- afterStrBack: 3,
- insertStr: 'NewName'),
- completeAfterStr: 'if (hasDirectiveChange) {',
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
- }
-
- {
- String id = 'local-completion-3';
- String description = r'''
-1. Open 'analysis_server' and 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [pathServer, pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'if (hasDirectiveChange) {',
- insertStr: 'print(12345);'),
- completeAfterStr: 'print(12345);',
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
- }
-
- {
- String id = 'local-completion-4';
- String description = r'''
-1. Open 'analysis_server' and 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [pathServer, pathAnalyzer],
- file: '$pathAnalyzer/lib/src/task/dart.dart',
- fileChange: new FileChange(
- afterStr: 'DeltaResult validate(In',
- afterStrBack: 3,
- insertStr: 'NewName'),
- completeAfterStr: 'if (hasDirectiveChange) {',
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
- }
-
- {
- String id = 'local-refactoring-1';
- String description = r'''
+Future run_local_refactoring_1() async {
+ String id = 'local-refactoring-1';
+ String description = r'''
1. Open 'analyzer'.
2. Change the name of a public method in src/context/cache.dart.
3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results.
4. Rollback changes to the file and wait for analysis.
5. Go to (2).
''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getRefactoring(
- roots: [pathAnalyzer],
- file: '$pathAnalyzer/lib/src/context/cache.dart',
- fileChange: new FileChange(
- afterStr: 'getState(An', afterStrBack: 3, insertStr: 'NewName'),
- refactoringAtStr: 'getSourcesWithFullName(String path)',
- refactoringKind: RefactoringKind.RENAME,
- refactoringOptions: new RenameOptions('getSourcesWithFullName2'),
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
+ List<int> times = await new BenchmarkScenario()
+ .waitAnalyze_change_getRefactoring(
+ roots: [paths.analyzer],
+ file: '${paths.analyzer}/lib/src/context/cache.dart',
+ fileChange: new FileChange(
+ afterStr: 'getState(An', afterStrBack: 3, insertStr: 'NewName'),
+ refactoringAtStr: 'getSourcesWithFullName(String path)',
+ refactoringKind: RefactoringKind.RENAME,
+ refactoringOptions: new RenameOptions('getSourcesWithFullName2'),
+ numOfRepeats: 5);
+ printBenchmarkResults(id, description, times);
+}
+
+class PathHolder {
+ String analysisServer;
+ String analyzer;
+ String flutterHelloWorld;
+ String flutterStocks;
+
+ PathHolder({String sdkPath, String flutterPath}) {
+ analysisServer = '$sdkPath/pkg/analysis_server';
+ analyzer = '$sdkPath/pkg/analyzer';
+ flutterHelloWorld = '$flutterPath/examples/hello_world';
+ flutterStocks = '$flutterPath/examples/stocks';
}
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index bda82af..7e695a2 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -43,6 +43,7 @@
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer/task/dart.dart';
import 'package:plugin/plugin.dart';
+import 'package:yaml/yaml.dart';
typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -151,11 +152,6 @@
List<RequestHandler> handlers;
/**
- * The function used to create a new SDK using the default SDK.
- */
- final SdkCreator defaultSdkCreator;
-
- /**
* The object used to manage the SDK's known to this server.
*/
DartSdkManager sdkManager;
@@ -317,7 +313,7 @@
Index _index,
this.serverPlugin,
this.options,
- this.defaultSdkCreator,
+ this.sdkManager,
this.instrumentationService,
{ResolverProvider fileResolverProvider: null,
ResolverProvider packageResolverProvider: null,
@@ -331,9 +327,10 @@
options.enableIncrementalResolutionApi;
defaultContextOptions.incrementalValidation =
options.enableIncrementalResolutionValidation;
+ defaultContextOptions.finerGrainedInvalidation =
+ options.finerGrainedInvalidation;
defaultContextOptions.generateImplicitErrors = false;
operationQueue = new ServerOperationQueue();
- sdkManager = new DartSdkManager(defaultSdkCreator);
if (useSingleContextManager) {
contextManager = new SingleContextManager(resourceProvider, sdkManager,
packageResolverProvider, analyzedFilesGlobs, defaultContextOptions);
@@ -1512,6 +1509,7 @@
class AnalysisServerOptions {
bool enableIncrementalResolutionApi = false;
bool enableIncrementalResolutionValidation = false;
+ bool finerGrainedInvalidation = false;
bool noErrorNotification = false;
bool noIndex = false;
bool useAnalysisHighlight2 = false;
@@ -1636,15 +1634,30 @@
// If no embedded URI resolver was provided, defer to a locator-backed one.
EmbedderYamlLocator locator =
disposition.getEmbedderLocator(resourceProvider);
- EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
- if (sdk.libraryMap.size() == 0) {
- // The embedder file has no mappings, so use the default Dart SDK.
+ Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
+ EmbedderSdk embedderSdk = new EmbedderSdk(embedderYamls);
+ if (embedderSdk.libraryMap.size() == 0) {
+ // There was no embedder file, or the file was empty, so used the default
+ // SDK.
resolvers.add(new DartUriResolver(
analysisServer.sdkManager.getSdkForOptions(options)));
} else {
- // The embedder uri resolver has mappings, use it instead of the default
- // Dart SDK uri resolver.
- resolvers.add(new DartUriResolver(sdk));
+ // The embedder file defines an alternate SDK, so use it.
+ List<String> paths = <String>[];
+ for (Folder folder in embedderYamls.keys) {
+ paths.add(folder
+ .getChildAssumingFile(EmbedderYamlLocator.EMBEDDER_FILE_NAME)
+ .path);
+ }
+ DartSdk dartSdk = analysisServer.sdkManager
+ .getSdk(new SdkDescription(paths, options), () {
+ embedderSdk.analysisOptions = options;
+ // TODO(brianwilkerson) Enable summary use after we have decided where
+ // summary files for embedder files will live.
+ embedderSdk.useSummary = false;
+ return embedderSdk;
+ });
+ resolvers.add(new DartUriResolver(dartSdk));
}
resolvers.addAll(packageUriResolvers);
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 785ccfe..585da46 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -1157,15 +1157,29 @@
EmbedderYamlLocator locator =
disposition.getEmbedderLocator(resourceProvider);
- EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
- if (sdk.libraryMap.size() == 0) {
- // The embedder uri resolver has no mappings. Use the default Dart SDK
- // uri resolver.
+ Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
+ EmbedderSdk embedderSdk = new EmbedderSdk(embedderYamls);
+ if (embedderSdk.libraryMap.size() == 0) {
+ // There was no embedder file, or the file was empty, so used the default
+ // SDK.
resolvers.add(new DartUriResolver(sdkManager.getSdkForOptions(options)));
} else {
- // The embedder uri resolver has mappings, use it instead of the default
- // Dart SDK uri resolver.
- resolvers.add(new DartUriResolver(sdk));
+ // The embedder file defines an alternate SDK, so use it.
+ List<String> paths = <String>[];
+ for (Folder folder in embedderYamls.keys) {
+ paths.add(folder
+ .getChildAssumingFile(EmbedderYamlLocator.EMBEDDER_FILE_NAME)
+ .path);
+ }
+ DartSdk dartSdk =
+ sdkManager.getSdk(new SdkDescription(paths, options), () {
+ embedderSdk.analysisOptions = options;
+ // TODO(brianwilkerson) Enable summary use after we have decided where
+ // summary files for embedder files will live.
+ embedderSdk.useSummary = false;
+ return embedderSdk;
+ });
+ resolvers.add(new DartUriResolver(dartSdk));
}
resolvers.addAll(packageUriResolvers);
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 5c86115..138c20f 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -43,14 +43,7 @@
.add(newAnalysisError_fromEngine(lineInfo, error, severity));
}
} else {
- AnalysisError error2 = newAnalysisError_fromEngine(lineInfo, error);
- bool isStrongMode = context.analysisOptions.strongMode;
- if (isStrongMode &&
- error is engine.StaticWarningCode &&
- (error as engine.StaticWarningCode).isStrongModeError) {
- error2.severity = AnalysisErrorSeverity.ERROR;
- }
- serverErrors.add(error2);
+ serverErrors.add(newAnalysisError_fromEngine(lineInfo, error));
}
}
return serverErrors;
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index a70ecb7..b6c878f 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -244,6 +244,11 @@
"incremental-resolution-validation";
/**
+ * The name of the option used to enable fined grained invalidation.
+ */
+ static const String FINER_GRAINED_INVALIDATION = 'finer-grained-invalidation';
+
+ /**
* The name of the option used to cause instrumentation to also be written to
* a local file.
*/
@@ -374,6 +379,8 @@
results[ENABLE_INCREMENTAL_RESOLUTION_API];
analysisServerOptions.enableIncrementalResolutionValidation =
results[INCREMENTAL_RESOLUTION_VALIDATION];
+ analysisServerOptions.finerGrainedInvalidation =
+ results[FINER_GRAINED_INVALIDATION];
analysisServerOptions.noErrorNotification = results[NO_ERROR_NOTIFICATION];
analysisServerOptions.noIndex = results[NO_INDEX];
analysisServerOptions.useAnalysisHighlight2 =
@@ -441,7 +448,8 @@
//
socketServer = new SocketServer(
analysisServerOptions,
- defaultSdkCreator,
+ new DartSdkManager(defaultSdkDirectory.getAbsolutePath(), useSummaries,
+ defaultSdkCreator),
defaultSdk,
service,
serverPlugin,
@@ -524,6 +532,10 @@
help: "enable validation of incremental resolution results (slow)",
defaultsTo: false,
negatable: false);
+ parser.addFlag(FINER_GRAINED_INVALIDATION,
+ help: "enable finer grained invalidation",
+ defaultsTo: false,
+ negatable: false);
parser.addOption(INSTRUMENTATION_LOG_FILE,
help:
"the path of the file to which instrumentation data will be written");
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 380f3a8..bce9dc8 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -29,7 +29,7 @@
/**
* The function used to create a new SDK using the default SDK.
*/
- final SdkCreator defaultSdkCreator;
+ final DartSdkManager sdkManager;
final DirectoryBasedDartSdk defaultSdk;
final InstrumentationService instrumentationService;
@@ -51,7 +51,7 @@
SocketServer(
this.analysisServerOptions,
- this.defaultSdkCreator,
+ this.sdkManager,
this.defaultSdk,
this.instrumentationService,
this.serverPlugin,
@@ -97,7 +97,7 @@
index,
serverPlugin,
analysisServerOptions,
- defaultSdkCreator,
+ sdkManager,
instrumentationService,
fileResolverProvider: fileResolverProvider,
packageResolverProvider: packageResolverProvider,
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 2983b7d..a493100 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -1717,7 +1717,27 @@
buffer.write(' <small>[no .packages file]</small>');
}
});
- // TODO(brianwilkerson) Add items for the SDK contexts (currently only one).
+ buffer.write('</p>');
+ buffer.write('<p><b>SDK Contexts</b></p>');
+ buffer.write('<p>');
+ first = true;
+ List<String> descriptors = analysisServer.sdkManager.sdkDescriptors
+ .map((SdkDescription descriptor) => descriptor.toString())
+ .toList();
+ if (descriptors.isEmpty) {
+ buffer.write('none');
+ } else {
+ descriptors.sort();
+ for (String descriptor in descriptors) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write('<br>');
+ }
+ // TODO(brianwilkerson) Add a link to information about the contexts.
+ buffer.write(descriptor);
+ }
+ }
buffer.write('</p>');
int freq = AnalysisServer.performOperationDelayFrequency;
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index cf8aed1..063329d 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -18,6 +18,7 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:linter/src/plugin/linter_plugin.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
@@ -129,7 +130,7 @@
index,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index b05cf9c..eaea9a6 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -19,6 +19,7 @@
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
@@ -144,7 +145,7 @@
null,
plugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE,
rethrowExceptions: true);
processRequiredPlugins();
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index b6643de..2f481cc 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1820,9 +1820,8 @@
processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
- DartSdkManager sdkManager = new DartSdkManager((_) {
- return new MockSdk();
- });
+ DartSdkManager sdkManager =
+ new DartSdkManager('', false, (_) => new MockSdk());
manager = new ContextManagerImpl(
resourceProvider,
sdkManager,
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index ad5319e..45ca634 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -13,6 +13,7 @@
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:path/path.dart';
import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -47,7 +48,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
});
@@ -474,7 +475,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
// listen for notifications
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index d2288ae..3a6f3cb 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:unittest/unittest.dart';
@@ -53,7 +54,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
handler = new DiagnosticDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 7824a1b..e3de661 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -16,6 +16,7 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:plugin/manager.dart';
@@ -48,7 +49,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
handler = new ExecutionDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 5c3d75e..5ffd328 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -11,6 +11,7 @@
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
import 'package:unittest/unittest.dart';
@@ -37,7 +38,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- (_) => new MockSdk(),
+ new DartSdkManager('', false, (_) => new MockSdk()),
InstrumentationService.NULL_SERVICE);
handler = new ServerDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 3505da6..b678bd1 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -13,7 +13,6 @@
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -53,8 +52,7 @@
addTestSource('part of libB; main() {^}');
// Associate part with library
- context.computeResult(
- new LibrarySpecificUnit(libSource, testSource), LIBRARY_CYCLE_UNITS);
+ context.computeResult(libSource, LIBRARY_CYCLE_UNITS);
// Build the request
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
diff --git a/pkg/analysis_server/test/single_context_manager_test.dart b/pkg/analysis_server/test/single_context_manager_test.dart
index 25ab3bd..d85214a 100644
--- a/pkg/analysis_server/test/single_context_manager_test.dart
+++ b/pkg/analysis_server/test/single_context_manager_test.dart
@@ -65,9 +65,8 @@
packageResolver = new TestUriResolver();
_processRequiredPlugins();
- DartSdkManager sdkManager = new DartSdkManager((_) {
- return new MockSdk();
- });
+ DartSdkManager sdkManager =
+ new DartSdkManager('', false, (_) => new MockSdk());
manager = new SingleContextManager(resourceProvider, sdkManager,
(_) => packageResolver, analysisFilesGlobs, new AnalysisOptionsImpl());
callbacks = new TestContextManagerCallbacks(resourceProvider);
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index 4ff5ea7..a3279d2 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -116,7 +116,7 @@
new DirectoryBasedDartSdk(DirectoryBasedDartSdk.defaultSdkDirectory);
return new SocketServer(
new AnalysisServerOptions(),
- sdkCreator,
+ new DartSdkManager('', false, sdkCreator),
sdkCreator(null),
InstrumentationService.NULL_SERVICE,
serverPlugin,
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index 10147f7..eb19b8b 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -30,6 +30,7 @@
BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
BuildLibraryElementTask -> IS_LAUNCHABLE
BuildLibraryElementTask -> LIBRARY_ELEMENT1
+ BuildLibraryElementTask -> REFERENCED_NAMES
BuildPublicNamespaceTask -> LIBRARY_ELEMENT3
BuildSourceExportClosureTask -> EXPORT_SOURCE_CLOSURE
BuildTypeProviderTask -> TYPE_PROVIDER
@@ -305,7 +306,6 @@
ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
- ResolveLibraryReferencesTask -> REFERENCED_NAMES
ResolveLibraryTask -> LIBRARY_ELEMENT
ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
ResolveTopLevelLibraryTypeBoundsTask -> LIBRARY_ELEMENT5
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 13fbe48..b829bee 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -624,6 +624,11 @@
bool get isDeprecated;
/**
+ * Return `true` if this element has an annotation of the form '@factory'.
+ */
+ bool get isFactory;
+
+ /**
* Return `true` if this element has an annotation of the form '@JS(..)'.
*/
bool get isJS;
@@ -819,6 +824,11 @@
bool get isDeprecated;
/**
+ * Return `true` if this annotation marks the associated member as a factory.
+ */
+ bool get isFactory;
+
+ /**
* Return `true` if this annotation marks the associated element with the `JS`
* annotation.
*/
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
index 1fd9577..81778bc 100644
--- a/pkg/analyzer/lib/source/error_processor.dart
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -121,6 +121,14 @@
ErrorSeverity get severity => ErrorSeverity.ERROR;
/// Check if this processor applies to the given [error].
- bool appliesTo(AnalysisError error) =>
- error.errorCode.type == ErrorType.STATIC_TYPE_WARNING;
+ bool appliesTo(AnalysisError error) {
+ ErrorCode errorCode = error.errorCode;
+ if (errorCode is StaticTypeWarningCode) {
+ return true;
+ }
+ if (errorCode is StaticWarningCode) {
+ return errorCode.isStrongModeError;
+ }
+ return false;
+ }
}
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index fa7fbad..1f0f42c 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -625,6 +625,11 @@
return;
}
}
+// if (deltaResult != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
+// String indent = ' ' * level;
+// String deltaResultName = deltaResult.toString().split('.').last;
+// print('[$id]$indent$deltaResultName $descriptor for $target');
+// }
if (deltaResult == DeltaResult.INVALIDATE_NO_DELTA) {
delta = null;
}
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index dd0e0ee..a5f8c37 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -281,6 +281,9 @@
((options is AnalysisOptionsImpl)
? this._options.implicitCasts != options.implicitCasts
: false) ||
+ ((options is AnalysisOptionsImpl)
+ ? this._options.implicitDynamic != options.implicitDynamic
+ : false) ||
this._options.enableStrictCallChecks !=
options.enableStrictCallChecks ||
this._options.enableGenericMethods != options.enableGenericMethods ||
@@ -309,9 +312,11 @@
this._options.preserveComments = options.preserveComments;
this._options.strongMode = options.strongMode;
this._options.trackCacheDependencies = options.trackCacheDependencies;
+ this._options.finerGrainedInvalidation = options.finerGrainedInvalidation;
if (options is AnalysisOptionsImpl) {
this._options.strongModeHints = options.strongModeHints;
this._options.implicitCasts = options.implicitCasts;
+ this._options.implicitDynamic = options.implicitDynamic;
}
if (needsRecompute) {
for (WorkManager workManager in workManagers) {
@@ -1068,6 +1073,16 @@
if (entry == null) {
return false;
}
+ // If there were no "originalContents" in the content cache,
+ // use the contents of the file instead.
+ if (originalContents == null) {
+ try {
+ TimestampedData<String> fileContents = source.contents;
+ if (fileContents.modificationTime == entry.modificationTime) {
+ originalContents = fileContents.data;
+ }
+ } catch (e) {}
+ }
bool changed = newContents != originalContents;
if (newContents != null) {
if (changed) {
@@ -1871,8 +1886,7 @@
}
// We need to invalidate the cache.
{
- Object delta = null;
- if (AnalysisEngine.instance.limitInvalidationInTaskModel &&
+ if (analysisOptions.finerGrainedInvalidation &&
AnalysisEngine.isDartFileName(source.fullName)) {
// TODO(scheglov) Incorrect implementation in general.
entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
@@ -1880,8 +1894,13 @@
List<Source> librarySources = getLibrariesContaining(source);
if (librarySources.length == 1) {
Source librarySource = librarySources[0];
- CompilationUnit oldUnit =
- getResolvedCompilationUnit2(source, librarySource);
+ // Try to find an old unit which has element model.
+ CacheEntry unitEntry =
+ getCacheEntry(new LibrarySpecificUnit(librarySource, source));
+ CompilationUnit oldUnit = RESOLVED_UNIT_RESULTS
+ .map(unitEntry.getValue)
+ .firstWhere((unit) => unit != null, orElse: () => null);
+ // If we have the old unit, we can try to update it.
if (oldUnit != null) {
CompilationUnit newUnit = parseCompilationUnit(source);
IncrementalCompilationUnitElementBuilder builder =
@@ -1891,15 +1910,17 @@
if (!unitDelta.hasDirectiveChange) {
DartDelta dartDelta = new DartDelta(source);
dartDelta.hasDirectiveChange = unitDelta.hasDirectiveChange;
- unitDelta.addedDeclarations.forEach(dartDelta.elementAdded);
- unitDelta.removedDeclarations.forEach(dartDelta.elementRemoved);
- for (ClassElementDelta classDelta in unitDelta.classDeltas) {
- dartDelta.elementChanged(classDelta.element);
+ unitDelta.addedDeclarations.forEach(dartDelta.elementChanged);
+ unitDelta.removedDeclarations.forEach(dartDelta.elementChanged);
+ unitDelta.classDeltas.values.forEach(dartDelta.classChanged);
+ // Add other names in the library that are changed transitively.
+ {
+ ReferencedNames referencedNames = new ReferencedNames(source);
+ new ReferencedNamesBuilder(referencedNames).build(oldUnit);
+ dartDelta.addChangedElements(referencedNames);
}
-// print(
-// 'dartDelta: add=${dartDelta.addedNames} remove=${dartDelta.removedNames}');
- delta = dartDelta;
- entry.setState(CONTENT, CacheState.INVALID, delta: delta);
+ // Invalidate using the prepared DartDelta.
+ entry.setState(CONTENT, CacheState.INVALID, delta: dartDelta);
return;
}
}
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index e531a68..3b09bef 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -350,6 +350,13 @@
_currentHolder = initialHolder;
}
+ /**
+ * Prepares for incremental resolution of a function body.
+ */
+ void initForFunctionBodyIncrementalResolution() {
+ _inFunction = true;
+ }
+
@override
Object visitAnnotation(Annotation node) {
// Although it isn't valid to do so because closures are not constant
@@ -445,19 +452,6 @@
return null;
}
- /**
- * Implementation of this method should be synchronized with
- * [visitClassDeclaration].
- */
- void visitClassDeclarationIncrementally(ClassDeclaration node) {
- //
- // Process field declarations before constructors and methods so that field
- // formal parameters can be correctly resolved to their fields.
- //
- ClassElement classElement = node.element;
- _buildFieldMap(classElement.fields);
- }
-
@override
Object visitClassTypeAlias(ClassTypeAlias node) {
ElementHolder holder = new ElementHolder();
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 790fab6..4619738 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2462,6 +2462,12 @@
static String _DEPRECATED_VARIABLE_NAME = "deprecated";
/**
+ * The name of the top-level variable used to mark a method as being a
+ * factory.
+ */
+ static String _FACTORY_VARIABLE_NAME = "factory";
+
+ /**
* The name of the class used to JS annotate an element.
*/
static String _JS_CLASS_NAME = "JS";
@@ -2560,6 +2566,12 @@
}
@override
+ bool get isFactory =>
+ element is PropertyAccessorElement &&
+ element.name == _FACTORY_VARIABLE_NAME &&
+ element.library?.name == _META_LIB_NAME;
+
+ @override
bool get isJS =>
element is ConstructorElement &&
element.enclosingElement.name == _JS_CLASS_NAME &&
@@ -2803,6 +2815,16 @@
}
@override
+ bool get isFactory {
+ for (ElementAnnotation annotation in metadata) {
+ if (annotation.isFactory) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
bool get isJS {
for (ElementAnnotation annotation in metadata) {
if (annotation.isJS) {
@@ -2867,6 +2889,9 @@
getAncestor((element) => element is LibraryElement);
@override
+ Source get librarySource => library?.source;
+
+ @override
ElementLocation get location {
if (_cachedLocation == null) {
if (library == null) {
@@ -6482,6 +6507,9 @@
bool get isDeprecated => false;
@override
+ bool get isFactory => false;
+
+ @override
bool get isJS => false;
@override
@@ -6515,6 +6543,9 @@
LibraryElement get library => null;
@override
+ Source get librarySource => null;
+
+ @override
ElementLocation get location => null;
@override
@@ -6579,7 +6610,12 @@
if (i > 0) {
buffer.write(", ");
}
- (conflictingElements[i] as ElementImpl).appendTo(buffer);
+ Element element = conflictingElements[i];
+ if (element is ElementImpl) {
+ element.appendTo(buffer);
+ } else {
+ buffer.write(element);
+ }
}
buffer.write("]");
return buffer.toString();
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 266853a..6823b99 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -357,6 +357,9 @@
bool get isDeprecated => actualElement.isDeprecated;
@override
+ bool get isFactory => actualElement.isFactory;
+
+ @override
bool get isJS => actualElement.isJS;
@override
@@ -382,6 +385,9 @@
getAncestor((element) => element is LibraryElement);
@override
+ Source get librarySource => actualElement.librarySource;
+
+ @override
ElementLocation get location => _location;
@override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 025c7c5..76ec36c 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -461,6 +461,9 @@
bool get isDeprecated => _baseElement.isDeprecated;
@override
+ bool get isFactory => _baseElement.isFactory;
+
+ @override
bool get isJS => _baseElement.isJS;
@override
@@ -488,6 +491,9 @@
LibraryElement get library => _baseElement.library;
@override
+ Source get librarySource => _baseElement.librarySource;
+
+ @override
ElementLocation get location => _baseElement.location;
@override
@@ -515,7 +521,8 @@
AstNode computeNode() => _baseElement.computeNode();
@override
- Element/*=E*/ getAncestor/*<E extends Element >*/(Predicate<Element> predicate) =>
+ Element/*=E*/ getAncestor/*<E extends Element >*/(
+ Predicate<Element> predicate) =>
baseElement.getAncestor(predicate);
@override
@@ -700,7 +707,8 @@
FormalParameter computeNode() => baseElement.computeNode();
@override
- Element/*=E*/ getAncestor/*<E extends Element>*/(Predicate<Element> predicate) {
+ Element/*=E*/ getAncestor/*<E extends Element>*/(
+ Predicate<Element> predicate) {
Element element = baseElement.getAncestor(predicate);
ParameterizedType definingType = this.definingType;
if (definingType is InterfaceType) {
@@ -709,7 +717,8 @@
} else if (element is MethodElement) {
return MethodMember.from(element, definingType) as Element/*=E*/;
} else if (element is PropertyAccessorElement) {
- return PropertyAccessorMember.from(element, definingType) as Element/*=E*/;
+ return PropertyAccessorMember.from(element, definingType)
+ as Element/*=E*/;
}
}
return element as Element/*=E*/;
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 8d6aec0..22a247a 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -927,6 +927,39 @@
}
/**
+ * Given a generic function type [g] and an instantiated function type [f],
+ * find a list of type arguments TArgs such that `g<TArgs> == f`,
+ * and return TArgs.
+ *
+ * This function must be called with type [f] that was instantiated from [g].
+ */
+ static Iterable<DartType> recoverTypeArguments(
+ FunctionType g, FunctionType f) {
+ // TODO(jmesserly): perhaps a better design here would be: instead of
+ // recording staticInvokeType on InvocationExpression, we could record the
+ // instantiated type arguments, that way we wouldn't need to recover them.
+ //
+ // For now though, this is a pretty quick operation.
+ assert(identical(g.element, f.element));
+ assert(g.typeFormals.isNotEmpty && f.typeFormals.isEmpty);
+ assert(g.typeFormals.length + g.typeArguments.length ==
+ f.typeArguments.length);
+
+ // Instantiation in Analyzer works like this:
+ // Given:
+ // {U/T} <S> T -> S
+ // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
+ // and <S> represents the typeFormals.
+ //
+ // Now instantiate([V]), and the result should be:
+ // {U/T, V/S} T -> S.
+ //
+ // Therefore, we can recover the typeArguments from our instantiated
+ // function.
+ return f.typeArguments.skip(g.typeArguments.length);
+ }
+
+ /**
* Compares two function types [t] and [s] to see if their corresponding
* parameter types match [parameterRelation] and their return types match
* [returnRelation].
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 4e67792..abded10 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -86,6 +86,12 @@
static const List<AnalysisContext> EMPTY_LIST = const <AnalysisContext>[];
/**
+ * The file resolver provider used to override the way file URI's are
+ * resolved in some contexts.
+ */
+ ResolverProvider fileResolverProvider;
+
+ /**
* Return the set of analysis options controlling the behavior of this
* context. Clients should not modify the returned set of options. The options
* should only be set by invoking the method [setAnalysisOptions].
@@ -333,12 +339,6 @@
bool exists(Source source);
/**
- * The file resolver provider used to override the way file URI's are
- * resolved in some contexts.
- */
- ResolverProvider fileResolverProvider;
-
- /**
* Return the element model corresponding to the compilation unit defined by
* the given [unitSource] in the library defined by the given [librarySource],
* or `null` if the element model does not currently exist or if the library
@@ -787,12 +787,6 @@
final PartitionManager partitionManager = new PartitionManager();
/**
- * A flag indicating whether the task model should attempt to limit
- * invalidation after a change.
- */
- bool limitInvalidationInTaskModel = false;
-
- /**
* The task manager used to manage the tasks used to analyze code.
*/
TaskManager _taskManager;
@@ -1101,6 +1095,14 @@
bool get enableTiming;
/**
+ * A flag indicating whether finer grained dependencies should be used
+ * instead of just source level dependencies.
+ *
+ * This option is experimental and subject to change.
+ */
+ bool get finerGrainedInvalidation;
+
+ /**
* Return `true` if errors, warnings and hints should be generated for sources
* that are implicitly being analyzed. The default value is `true`.
*/
@@ -1309,6 +1311,21 @@
*/
bool implicitCasts = true;
+ @override
+ bool finerGrainedInvalidation = false;
+
+ /**
+ * A flag indicating whether implicit dynamic type is allowed, on by default.
+ *
+ * This flag can be used without necessarily enabling [strongMode], but it is
+ * designed with strong mode's type inference in mind. Without type inference,
+ * it will raise many errors. Also it does not provide type safety without
+ * strong mode.
+ *
+ * This option is experimental and subject to change.
+ */
+ bool implicitDynamic = true;
+
/**
* Initialize a newly created set of analysis options to have their default
* values.
@@ -1341,8 +1358,10 @@
if (options is AnalysisOptionsImpl) {
strongModeHints = options.strongModeHints;
implicitCasts = options.implicitCasts;
+ implicitDynamic = options.implicitDynamic;
}
trackCacheDependencies = options.trackCacheDependencies;
+ finerGrainedInvalidation = options.finerGrainedInvalidation;
}
bool get analyzeFunctionBodies {
@@ -1407,6 +1426,48 @@
}
/**
+ * Produce a human readable list of option names corresponding to the options
+ * encoded in the given [encoding], presumably from invoking the method
+ * [encodeCrossContextOptions].
+ */
+ static String decodeCrossContextOptions(int encoding) {
+ if (encoding == 0) {
+ return 'none';
+ }
+ StringBuffer buffer = new StringBuffer();
+ bool needsSeparator = false;
+ void add(String optionName) {
+ if (needsSeparator) {
+ buffer.write(', ');
+ }
+ buffer.write(optionName);
+ needsSeparator = true;
+ }
+ if (encoding & ENABLE_ASSERT_FLAG > 0) {
+ add('assert');
+ }
+ if (encoding & ENABLE_ASYNC_FLAG > 0) {
+ add('async');
+ }
+ if (encoding & ENABLE_GENERIC_METHODS_FLAG > 0) {
+ add('genericMethods');
+ }
+ if (encoding & ENABLE_STRICT_CALL_CHECKS_FLAG > 0) {
+ add('strictCallChecks');
+ }
+ if (encoding & ENABLE_STRONG_MODE_FLAG > 0) {
+ add('strongMode');
+ }
+ if (encoding & ENABLE_STRONG_MODE_HINTS_FLAG > 0) {
+ add('strongModeHints');
+ }
+ if (encoding & ENABLE_SUPER_MIXINS_FLAG > 0) {
+ add('superMixins');
+ }
+ return buffer.toString();
+ }
+
+ /**
* Predicate used for [analyzeFunctionBodiesPredicate] when
* [analyzeFunctionBodies] is set to `true`.
*/
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 074a6aa..f8b369c 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2682,6 +2682,9 @@
HintCode.DEPRECATED_MEMBER_USE,
HintCode.DUPLICATE_IMPORT,
HintCode.DIVISION_OPTIMIZATION,
+ HintCode.INVALID_FACTORY_ANNOTATION,
+ HintCode.INVALID_FACTORY_METHOD_DECL,
+ HintCode.INVALID_FACTORY_METHOD_IMPL,
HintCode.IS_DOUBLE,
HintCode.IS_INT,
HintCode.IS_NOT_DOUBLE,
@@ -2856,6 +2859,16 @@
StrongModeCode.DOWN_CAST_IMPLICIT,
StrongModeCode.DYNAMIC_CAST,
StrongModeCode.DYNAMIC_INVOKE,
+ StrongModeCode.IMPLICIT_DYNAMIC_FIELD,
+ StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
+ StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
+ StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL,
+ StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL,
+ StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
+ StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER,
+ StrongModeCode.IMPLICIT_DYNAMIC_RETURN,
+ StrongModeCode.IMPLICIT_DYNAMIC_TYPE,
+ StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE,
StrongModeCode.INFERRED_TYPE,
StrongModeCode.INFERRED_TYPE_ALLOCATION,
StrongModeCode.INFERRED_TYPE_CLOSURE,
@@ -3609,6 +3622,34 @@
"A value of type '{0}' cannot be assigned to a variable of type '{1}'");
/**
+ * This hint is generated anywhere a @factory annotation is associated with
+ * anything other than a method.
+ */
+ static const HintCode INVALID_FACTORY_ANNOTATION = const HintCode(
+ 'INVALID_FACTORY_ANNOTATION',
+ "Only methods can be annotated as factories.");
+
+ /**
+ * This hint is generated anywhere a @factory annotation is associated with
+ * a method that does not declare a return type.
+ */
+ static const HintCode INVALID_FACTORY_METHOD_DECL = const HintCode(
+ 'INVALID_FACTORY_METHOD_DECL',
+ "Factory method '{0}' must have a return type.");
+
+ /**
+ * This hint is generated anywhere a @factory annotation is associated with
+ * a non-abstract method that can return anything other than a newly allocated
+ * object.
+ *
+ * Parameters:
+ * 0: the name of the method
+ */
+ static const HintCode INVALID_FACTORY_METHOD_IMPL = const HintCode(
+ 'INVALID_FACTORY_METHOD_IMPL',
+ "Factory method '{0}' does not return a newly allocated object.");
+
+ /**
* This hint is generated anywhere where a member annotated with `@protected`
* is used outside an instance member of a subclass.
*
@@ -4885,7 +4926,7 @@
*/
static const StaticWarningCode FINAL_NOT_INITIALIZED =
const StaticWarningCode('FINAL_NOT_INITIALIZED',
- "The final variable '{0}' must be initialized");
+ "The final variable '{0}' must be initialized", null, false);
/**
* 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -4901,7 +4942,7 @@
*/
static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
- "The final variable '{0}' must be initialized");
+ "The final variable '{0}' must be initialized", null, false);
/**
* 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -4917,8 +4958,11 @@
* 1: the name of the uninitialized final variable
*/
static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
- const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
- "The final variables '{0}' and '{1}' must be initialized");
+ const StaticWarningCode(
+ 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+ "The final variables '{0}' and '{1}' must be initialized",
+ null,
+ false);
/**
* 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -4935,8 +4979,11 @@
* 2: the number of additional not initialized variables that aren't listed
*/
static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
- const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
- "The final variables '{0}', '{1}' and '{2}' more must be initialized");
+ const StaticWarningCode(
+ 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+ "The final variables '{0}', '{1}' and '{2}' more must be initialized",
+ null,
+ false);
/**
* 15.5 Function Types: It is a static warning if a concrete class implements
@@ -5257,8 +5304,11 @@
* <i>S</i>, and <i>T</i> may not be assigned to <i>S</i>.
*/
static const StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES =
- const StaticWarningCode('MISMATCHED_GETTER_AND_SETTER_TYPES',
- "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}')");
+ const StaticWarningCode(
+ 'MISMATCHED_GETTER_AND_SETTER_TYPES',
+ "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}')",
+ null,
+ false);
/**
* 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i>
@@ -5269,7 +5319,9 @@
MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE =
const StaticWarningCode(
'MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE',
- "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}'), from superclass '{3}'");
+ "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}'), from superclass '{3}'",
+ null,
+ false);
/**
* 13.12 Return: It is a static warning if a function contains both one or
@@ -5278,7 +5330,9 @@
*/
static const StaticWarningCode MIXED_RETURN_TYPES = const StaticWarningCode(
'MIXED_RETURN_TYPES',
- "Methods and functions cannot use return both with and without values");
+ "Methods and functions cannot use return both with and without values",
+ null,
+ false);
/**
* 12.11.1 New: It is a static warning if <i>q</i> is a constructor of an
@@ -5490,7 +5544,7 @@
*/
static const StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR =
const StaticWarningCode('NON_VOID_RETURN_FOR_OPERATOR',
- "The return type of the operator []= must be 'void'");
+ "The return type of the operator []= must be 'void'", null, false);
/**
* 7.3 Setters: It is a static warning if a setter declares a return type
@@ -5498,7 +5552,7 @@
*/
static const StaticWarningCode NON_VOID_RETURN_FOR_SETTER =
const StaticWarningCode('NON_VOID_RETURN_FOR_SETTER',
- "The return type of the setter must be 'void'");
+ "The return type of the setter must be 'void'", null, false);
/**
* 15.1 Static Types: A type <i>T</i> is malformed iff:
@@ -5597,7 +5651,10 @@
* * The return type of <i>f</i> may not be assigned to void.
*/
static const StaticWarningCode RETURN_WITHOUT_VALUE = const StaticWarningCode(
- 'RETURN_WITHOUT_VALUE', "Missing return value after 'return'");
+ 'RETURN_WITHOUT_VALUE',
+ "Missing return value after 'return'",
+ null,
+ false);
/**
* 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
@@ -5780,7 +5837,7 @@
*/
static const StaticWarningCode VOID_RETURN_FOR_GETTER =
const StaticWarningCode('VOID_RETURN_FOR_GETTER',
- "The return type of the getter must not be 'void'");
+ "The return type of the getter must not be 'void'", null, false);
/**
* 17.9 Switch: It is a static warning if all of the following conditions
@@ -5799,7 +5856,8 @@
const StaticWarningCode(
'MISSING_ENUM_CONSTANT_IN_SWITCH',
"Missing case clause for '{0}'",
- "Add a case clause for the missing constant or add a default clause.");
+ "Add a case clause for the missing constant or add a default clause.",
+ false);
/**
* A flag indicating whether this warning is an error when running with strong
@@ -5814,7 +5872,7 @@
* given [correction] template.
*/
const StaticWarningCode(String name, String message,
- [String correction, this.isStrongModeError = false])
+ [String correction, this.isStrongModeError = true])
: super(name, message, correction);
@override
@@ -5843,6 +5901,17 @@
'The type of {0}.{1} ({2}) is not a '
'subtype of {3}.{1} ({4}).';
+ /**
+ * This is appended to the end of an error message about implicit dynamic.
+ *
+ * The idea is to make sure the user is aware that this error message is the
+ * result of turning on a particular option, and they are free to turn it
+ * back off.
+ */
+ static const String _implicitDynamicTip =
+ ". Either add an explicit type like 'dynamic'"
+ ", or enable implicit-dynamic in your Analyzer options.";
+
static const String _inferredTypeMessage = '{0} has inferred type {1}';
static const StrongModeCode DOWN_CAST_COMPOSITE = const StrongModeCode(
@@ -5916,6 +5985,62 @@
'Field declaration {3}.{1} cannot be '
'overridden in {0}.');
+ static const StrongModeCode IMPLICIT_DYNAMIC_PARAMETER = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_PARAMETER',
+ "Missing parameter type for '{0}'$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_RETURN = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_RETURN',
+ "Missing return type for '{0}'$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_VARIABLE = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_VARIABLE',
+ "Missing variable type for '{0}'$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_FIELD = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_FIELD',
+ "Missing field type for '{0}'$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_TYPE = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_TYPE',
+ "Missing type arguments for generic type '{0}'"
+ "$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_LIST_LITERAL =
+ const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_LIST_LITERAL',
+ "Missing type argument for list literal$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_MAP_LITERAL =
+ const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_MAP_LITERAL',
+ 'Missing type arguments for map literal$_implicitDynamicTip');
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_FUNCTION = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_FUNCTION',
+ "Missing type arguments for generic function '{0}<{1}>'"
+ "$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_METHOD = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_METHOD',
+ "Missing type arguments for generic method '{0}<{1}>'"
+ "$_implicitDynamicTip");
+
+ static const StrongModeCode IMPLICIT_DYNAMIC_INVOKE = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'IMPLICIT_DYNAMIC_INVOKE',
+ "Missing type arguments for calling generic function type '{0}'"
+ "$_implicitDynamicTip");
+
@override
final ErrorType type;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index eca427d..6d4177b 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -79,7 +79,7 @@
/**
* The options for verification.
*/
- AnalysisOptions _options;
+ AnalysisOptionsImpl _options;
/**
* The object providing access to the types defined by the language.
@@ -676,6 +676,12 @@
}
@override
+ Object visitExtendsClause(ExtendsClause node) {
+ _checkForImplicitDynamicType(node.superclass);
+ return super.visitExtendsClause(node);
+ }
+
+ @override
Object visitFieldDeclaration(FieldDeclaration node) {
_isInStaticVariableDeclaration = node.isStatic;
_isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
@@ -747,6 +753,7 @@
}
_checkForTypeAnnotationDeferredClass(returnType);
_checkForIllegalReturnType(returnType);
+ _checkForImplicitDynamicReturn(node, node.element);
return super.visitFunctionDeclaration(node);
} finally {
_enclosingFunction = outerFunction;
@@ -781,6 +788,7 @@
} else if (expressionType is FunctionType) {
_checkTypeArguments(expressionType.element, node.typeArguments);
}
+ _checkForImplicitDynamicInvoke(node);
return super.visitFunctionExpressionInvocation(node);
}
@@ -799,6 +807,18 @@
_isInFunctionTypedFormalParameter = true;
try {
_checkForTypeAnnotationDeferredClass(node.returnType);
+
+ // TODO(jmesserly): ideally we'd use _checkForImplicitDynamicReturn, and
+ // we can get the function element via `node?.element?.type?.element` but
+ // it doesn't have hasImplicitReturnType set correctly.
+ if (!_options.implicitDynamic && node.returnType == null) {
+ DartType parameterType = node.element.type;
+ if (parameterType is FunctionType &&
+ parameterType.returnType.isDynamic) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [node.identifier]);
+ }
+ }
return super.visitFunctionTypedFormalParameter(node);
} finally {
_isInFunctionTypedFormalParameter = old;
@@ -812,6 +832,12 @@
}
@override
+ Object visitImplementsClause(ImplementsClause node) {
+ node.interfaces.forEach(_checkForImplicitDynamicType);
+ return super.visitImplementsClause(node);
+ }
+
+ @override
Object visitImportDirective(ImportDirective node) {
ImportElement importElement = node.element;
if (importElement != null) {
@@ -848,6 +874,7 @@
_checkForNewWithUndefinedConstructor(node, constructorName, typeName);
}
}
+ _checkForImplicitDynamicType(typeName);
return super.visitInstanceCreationExpression(node);
} finally {
_isInConstInstanceCreation = wasInConstInstanceCreation;
@@ -873,7 +900,7 @@
}
_checkForExpectedOneListTypeArgument(node, typeArguments);
}
-
+ _checkForImplicitDynamicTypedLiteral(node);
_checkForListElementTypeNotAssignable(node);
return super.visitListLiteral(node);
}
@@ -891,7 +918,7 @@
}
_checkExpectedTwoMapTypeArguments(typeArguments);
}
-
+ _checkForImplicitDynamicTypedLiteral(node);
_checkForMapTypeNotAssignable(node);
_checkForNonConstMapAsExpressionStatement(node);
return super.visitMapLiteral(node);
@@ -930,6 +957,7 @@
_checkForAllInvalidOverrideErrorCodesForMethod(node);
_checkForTypeAnnotationDeferredClass(returnTypeName);
_checkForIllegalReturnType(returnTypeName);
+ _checkForImplicitDynamicReturn(node, node.element);
_checkForMustCallSuper(node);
return super.visitMethodDeclaration(node);
} finally {
@@ -951,6 +979,7 @@
}
_checkTypeArguments(
node.methodName.staticElement, node.typeArguments, target?.staticType);
+ _checkForImplicitDynamicInvoke(node);
return super.visitMethodInvocation(node);
}
@@ -1046,6 +1075,15 @@
_checkForConstFormalParameter(node);
_checkForPrivateOptionalParameter(node);
_checkForTypeAnnotationDeferredClass(node.type);
+
+ // Checks for an implicit dynamic parameter type.
+ //
+ // We can skip other parameter kinds besides simple formal, because:
+ // - DefaultFormalParameter contains a simple one, so it gets here,
+ // - FieldFormalParameter error should be reported on the field,
+ // - FunctionTypedFormalParameter is a function type, not dynamic.
+ _checkForImplicitDynamicIdentifier(node, node.identifier);
+
return super.visitSimpleFormalParameter(node);
}
@@ -1116,6 +1154,7 @@
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
_checkForTypeParameterSupertypeOfItsBound(node);
_checkForTypeAnnotationDeferredClass(node.bound);
+ _checkForImplicitDynamicType(node.bound);
return super.visitTypeParameter(node);
}
@@ -1125,6 +1164,7 @@
Expression initializerNode = node.initializer;
// do checks
_checkForInvalidAssignment(nameNode, initializerNode);
+ _checkForImplicitDynamicIdentifier(node, nameNode);
// visit name
nameNode.accept(this);
// visit initializer
@@ -1163,6 +1203,12 @@
}
@override
+ Object visitWithClause(WithClause node) {
+ node.mixinTypes.forEach(_checkForImplicitDynamicType);
+ return super.visitWithClause(node);
+ }
+
+ @override
Object visitYieldStatement(YieldStatement node) {
if (_inGenerator) {
_checkForYieldOfInvalidType(node.expression, node.star != null);
@@ -3538,6 +3584,113 @@
return foundError;
}
+ void _checkForImplicitDynamicIdentifier(AstNode node, Identifier id) {
+ if (_options.implicitDynamic) {
+ return;
+ }
+ VariableElement variable = getVariableElement(id);
+ if (variable != null &&
+ variable.hasImplicitType &&
+ variable.type.isDynamic) {
+ ErrorCode errorCode;
+ if (variable is FieldElement) {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_FIELD;
+ } else if (variable is ParameterElement) {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_PARAMETER;
+ } else {
+ errorCode = StrongModeCode.IMPLICIT_DYNAMIC_VARIABLE;
+ }
+ _errorReporter.reportErrorForNode(errorCode, node, [id]);
+ }
+ }
+
+ void _checkForImplicitDynamicInvoke(InvocationExpression node) {
+ if (_options.implicitDynamic ||
+ node == null ||
+ node.typeArguments != null) {
+ return;
+ }
+ DartType invokeType = node.staticInvokeType;
+ DartType declaredType = node.function.staticType;
+ if (invokeType is FunctionType && declaredType is FunctionType) {
+ Iterable<DartType> typeArgs =
+ FunctionTypeImpl.recoverTypeArguments(declaredType, invokeType);
+ if (typeArgs.any((t) => t.isDynamic)) {
+ // Issue an error depending on what we're trying to call.
+ Expression function = node.function;
+ if (function is Identifier) {
+ Element element = function.staticElement;
+ if (element is MethodElement) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_METHOD,
+ node.function,
+ [element.displayName, element.typeParameters.join(', ')]);
+ return;
+ }
+
+ if (element is FunctionElement) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_FUNCTION,
+ node.function,
+ [element.displayName, element.typeParameters.join(', ')]);
+ return;
+ }
+ }
+
+ // The catch all case if neither of those matched.
+ // For example, invoking a function expression.
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_INVOKE,
+ node.function,
+ [declaredType]);
+ }
+ }
+ }
+
+ void _checkForImplicitDynamicReturn(AstNode node, ExecutableElement element) {
+ if (_options.implicitDynamic) {
+ return;
+ }
+ if (element is PropertyAccessorElement && element.isSetter) {
+ return;
+ }
+ if (element != null &&
+ element.hasImplicitReturnType &&
+ element.returnType.isDynamic) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_RETURN, node, [element.displayName]);
+ }
+ }
+
+ void _checkForImplicitDynamicType(TypeName node) {
+ if (_options.implicitDynamic ||
+ node == null ||
+ node.typeArguments != null) {
+ return;
+ }
+ DartType type = node.type;
+ if (type is ParameterizedType &&
+ type.typeArguments.isNotEmpty &&
+ type.typeArguments.any((t) => t.isDynamic)) {
+ _errorReporter.reportErrorForNode(
+ StrongModeCode.IMPLICIT_DYNAMIC_TYPE, node, [type]);
+ }
+ }
+
+ void _checkForImplicitDynamicTypedLiteral(TypedLiteral node) {
+ if (_options.implicitDynamic || node.typeArguments != null) {
+ return;
+ }
+ DartType type = node.staticType;
+ // It's an error if either the key or value was inferred as dynamic.
+ if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
+ ErrorCode errorCode = node is ListLiteral
+ ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
+ : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
+ _errorReporter.reportErrorForNode(errorCode, node);
+ }
+ }
+
/**
* Verify that if the given [identifier] is part of a constructor initializer,
* then it does not implicitly reference 'this' expression.
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 37d3801..77907db 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -9,9 +9,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/ast/token.dart';
@@ -38,824 +36,6 @@
import 'package:analyzer/task/model.dart';
/**
- * If `true`, an attempt to resolve API-changing modifications is made.
- */
-bool _resolveApiChanges = false;
-
-/**
- * This method is used to enable/disable API-changing modifications resolution.
- */
-void set test_resolveApiChanges(bool value) {
- _resolveApiChanges = value;
-}
-
-/**
- * Instances of the class [DeclarationMatcher] determine whether the element
- * model defined by a given AST structure matches an existing element model.
- */
-class DeclarationMatcher extends RecursiveAstVisitor {
- /**
- * The library containing the AST nodes being visited.
- */
- LibraryElement _enclosingLibrary;
-
- /**
- * The compilation unit containing the AST nodes being visited.
- */
- CompilationUnitElement _enclosingUnit;
-
- /**
- * The function type alias containing the AST nodes being visited, or `null` if we are not
- * in the scope of a function type alias.
- */
- FunctionTypeAliasElement _enclosingAlias;
-
- /**
- * The class containing the AST nodes being visited, or `null` if we are not
- * in the scope of a class.
- */
- ClassElementImpl _enclosingClass;
-
- /**
- * The enum containing the AST nodes being visited, or `null` if we are not
- * in the scope of an enum.
- */
- EnumElementImpl _enclosingEnum;
-
- /**
- * The parameter containing the AST nodes being visited, or `null` if we are not in the
- * scope of a parameter.
- */
- ParameterElement _enclosingParameter;
-
- FieldDeclaration _enclosingFieldNode = null;
- bool _inTopLevelVariableDeclaration = false;
-
- /**
- * Is `true` if the current class declaration has a constructor.
- */
- bool _hasConstructor = false;
-
- /**
- * A set containing all of the elements in the element model that were defined by the old AST node
- * corresponding to the AST node being visited.
- */
- HashSet<Element> _allElements = new HashSet<Element>();
-
- /**
- * A set containing all of the elements were defined in the old element model,
- * but are not defined in the new element model.
- */
- HashSet<Element> _removedElements = new HashSet<Element>();
-
- /**
- * A set containing all of the elements are defined in the new element model,
- * but were not defined in the old element model.
- */
- HashSet<Element> _addedElements = new HashSet<Element>();
-
- /**
- * Determines how elements model corresponding to the given [node] differs
- * from the [element].
- */
- DeclarationMatchKind matches(AstNode node, Element element) {
- logger.enter('match $element @ ${element.nameOffset}');
- try {
- _captureEnclosingElements(element);
- _gatherElements(element);
- node.accept(this);
- } on _DeclarationMismatchException {
- logger.log("mismatched");
- return DeclarationMatchKind.MISMATCH;
- } finally {
- logger.exit();
- }
- // no API changes
- if (_removedElements.isEmpty && _addedElements.isEmpty) {
- logger.log("no API changes");
- return DeclarationMatchKind.MATCH;
- }
- // simple API change
- logger.log('_removedElements: $_removedElements');
- logger.log('_addedElements: $_addedElements');
- _removedElements.forEach(_removeElement);
- if (_removedElements.length <= 1 && _addedElements.length == 1) {
- return DeclarationMatchKind.MISMATCH_OK;
- }
- // something more complex
- return DeclarationMatchKind.MISMATCH;
- }
-
- @override
- visitBlockFunctionBody(BlockFunctionBody node) {
- // ignore bodies
- }
-
- @override
- visitClassDeclaration(ClassDeclaration node) {
- String name = node.name.name;
- ClassElement element = _findElement(_enclosingUnit.types, name);
- _enclosingClass = element;
- _processElement(element);
- _assertSameAnnotations(node, element);
- _assertSameTypeParameters(node.typeParameters, element.typeParameters);
- // check for missing clauses
- if (node.extendsClause == null) {
- _assertTrue(element.supertype.name == 'Object');
- }
- if (node.implementsClause == null) {
- _assertTrue(element.interfaces.isEmpty);
- }
- if (node.withClause == null) {
- _assertTrue(element.mixins.isEmpty);
- }
- // process clauses and members
- _hasConstructor = false;
- super.visitClassDeclaration(node);
- // process default constructor
- if (!_hasConstructor) {
- ConstructorElement constructor = element.unnamedConstructor;
- _processElement(constructor);
- if (!constructor.isSynthetic) {
- _assertEquals(constructor.parameters.length, 0);
- }
- }
- // matches, set the element
- node.name.staticElement = element;
- }
-
- @override
- visitClassTypeAlias(ClassTypeAlias node) {
- String name = node.name.name;
- ClassElement element = _findElement(_enclosingUnit.types, name);
- _enclosingClass = element;
- _processElement(element);
- _assertSameTypeParameters(node.typeParameters, element.typeParameters);
- super.visitClassTypeAlias(node);
- }
-
- @override
- visitCompilationUnit(CompilationUnit node) {
- _processElement(_enclosingUnit);
- super.visitCompilationUnit(node);
- }
-
- @override
- visitConstructorDeclaration(ConstructorDeclaration node) {
- _hasConstructor = true;
- SimpleIdentifier constructorName = node.name;
- ConstructorElementImpl element = constructorName == null
- ? _enclosingClass.unnamedConstructor
- : _enclosingClass.getNamedConstructor(constructorName.name);
- _processElement(element);
- _assertEquals(node.constKeyword != null, element.isConst);
- _assertEquals(node.factoryKeyword != null, element.isFactory);
- _assertCompatibleParameters(node.parameters, element.parameters);
- // matches, update the existing element
- ExecutableElement newElement = node.element;
- node.element = element;
- _setLocalElements(element, newElement);
- }
-
- @override
- visitEnumConstantDeclaration(EnumConstantDeclaration node) {
- String name = node.name.name;
- FieldElement element = _findElement(_enclosingEnum.fields, name);
- _processElement(element);
- }
-
- @override
- visitEnumDeclaration(EnumDeclaration node) {
- String name = node.name.name;
- ClassElement element = _findElement(_enclosingUnit.enums, name);
- _enclosingEnum = element;
- _processElement(element);
- _assertTrue(element.isEnum);
- super.visitEnumDeclaration(node);
- }
-
- @override
- visitExportDirective(ExportDirective node) {
- String uri = _getStringValue(node.uri);
- if (uri != null) {
- ExportElement element =
- _findUriReferencedElement(_enclosingLibrary.exports, uri);
- _processElement(element);
- _assertCombinators(node.combinators, element.combinators);
- }
- }
-
- @override
- visitExpressionFunctionBody(ExpressionFunctionBody node) {
- // ignore bodies
- }
-
- @override
- visitExtendsClause(ExtendsClause node) {
- _assertSameType(node.superclass, _enclosingClass.supertype);
- }
-
- @override
- visitFieldDeclaration(FieldDeclaration node) {
- _enclosingFieldNode = node;
- try {
- super.visitFieldDeclaration(node);
- } finally {
- _enclosingFieldNode = null;
- }
- }
-
- @override
- visitFunctionDeclaration(FunctionDeclaration node) {
- // prepare element name
- String name = node.name.name;
- if (node.isSetter) {
- name += '=';
- }
- // prepare element
- Token property = node.propertyKeyword;
- ExecutableElementImpl element;
- if (property == null) {
- element = _findElement(_enclosingUnit.functions, name);
- } else {
- element = _findElement(_enclosingUnit.accessors, name);
- }
- // process element
- _processElement(element);
- _assertSameAnnotations(node, element);
- _assertFalse(element.isSynthetic);
- _assertSameType(node.returnType, element.returnType);
- _assertCompatibleParameters(
- node.functionExpression.parameters, element.parameters);
- _assertBody(node.functionExpression.body, element);
- // matches, update the existing element
- ExecutableElement newElement = node.element;
- node.name.staticElement = element;
- node.functionExpression.element = element;
- _setLocalElements(element, newElement);
- }
-
- @override
- visitFunctionTypeAlias(FunctionTypeAlias node) {
- String name = node.name.name;
- FunctionTypeAliasElement element =
- _findElement(_enclosingUnit.functionTypeAliases, name);
- _processElement(element);
- _assertSameTypeParameters(node.typeParameters, element.typeParameters);
- _assertSameType(node.returnType, element.returnType);
- _assertCompatibleParameters(node.parameters, element.parameters);
- }
-
- @override
- visitImplementsClause(ImplementsClause node) {
- List<TypeName> nodes = node.interfaces;
- List<InterfaceType> types = _enclosingClass.interfaces;
- _assertSameTypes(nodes, types);
- }
-
- @override
- visitImportDirective(ImportDirective node) {
- String uri = _getStringValue(node.uri);
- if (uri != null) {
- ImportElement element =
- _findUriReferencedElement(_enclosingLibrary.imports, uri);
- _processElement(element);
- // match the prefix
- SimpleIdentifier prefixNode = node.prefix;
- PrefixElement prefixElement = element.prefix;
- if (prefixNode == null) {
- _assertNull(prefixElement);
- } else {
- _assertNotNull(prefixElement);
- _assertEquals(prefixNode.name, prefixElement.name);
- }
- // match combinators
- _assertCombinators(node.combinators, element.combinators);
- }
- }
-
- @override
- visitMethodDeclaration(MethodDeclaration node) {
- // prepare element name
- String name = node.name.name;
- if (name == TokenType.MINUS.lexeme &&
- node.parameters.parameters.length == 0) {
- name = "unary-";
- }
- if (node.isSetter) {
- name += '=';
- }
- // prepare element
- Token property = node.propertyKeyword;
- ExecutableElementImpl element;
- if (property == null) {
- element = _findElement(_enclosingClass.methods, name);
- } else {
- element = _findElement(_enclosingClass.accessors, name);
- }
- // process element
- ExecutableElement newElement = node.element;
- try {
- _assertNotNull(element);
- _assertSameAnnotations(node, element);
- _assertEquals(node.isStatic, element.isStatic);
- _assertSameType(node.returnType, element.returnType);
- _assertCompatibleParameters(node.parameters, element.parameters);
- _assertBody(node.body, element);
- _removedElements.remove(element);
- // matches, update the existing element
- node.name.staticElement = element;
- _setLocalElements(element, newElement);
- } on _DeclarationMismatchException {
- _removeElement(element);
- // add new element
- if (newElement != null) {
- _addedElements.add(newElement);
- if (newElement is MethodElement) {
- List<MethodElement> methods = _enclosingClass.methods.toList();
- methods.add(newElement);
- _enclosingClass.methods = methods;
- } else {
- List<PropertyAccessorElement> accessors =
- _enclosingClass.accessors.toList();
- accessors.add(newElement);
- _enclosingClass.accessors = accessors;
- }
- }
- }
- }
-
- @override
- visitPartDirective(PartDirective node) {
- String uri = _getStringValue(node.uri);
- if (uri != null) {
- CompilationUnitElement element =
- _findUriReferencedElement(_enclosingLibrary.parts, uri);
- _processElement(element);
- }
- super.visitPartDirective(node);
- }
-
- @override
- visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- _inTopLevelVariableDeclaration = true;
- try {
- super.visitTopLevelVariableDeclaration(node);
- } finally {
- _inTopLevelVariableDeclaration = false;
- }
- }
-
- @override
- visitVariableDeclaration(VariableDeclaration node) {
- // prepare variable
- String name = node.name.name;
- PropertyInducingElement element;
- if (_inTopLevelVariableDeclaration) {
- element = _findElement(_enclosingUnit.topLevelVariables, name);
- } else {
- element = _findElement(_enclosingClass.fields, name);
- }
- // verify
- PropertyInducingElement newElement = node.name.staticElement;
- _processElement(element);
- _assertSameAnnotations(node, element);
- _assertEquals(node.isConst, element.isConst);
- _assertEquals(node.isFinal, element.isFinal);
- if (_enclosingFieldNode != null) {
- _assertEquals(_enclosingFieldNode.isStatic, element.isStatic);
- }
- _assertSameType(
- (node.parent as VariableDeclarationList).type, element.type);
- // matches, restore the existing element
- node.name.staticElement = element;
- Element variable = element;
- if (variable is VariableElementImpl) {
- variable.initializer = newElement.initializer;
- }
- }
-
- @override
- visitWithClause(WithClause node) {
- List<TypeName> nodes = node.mixinTypes;
- List<InterfaceType> types = _enclosingClass.mixins;
- _assertSameTypes(nodes, types);
- }
-
- /**
- * Assert that the given [body] is compatible with the given [element].
- * It should not be empty if the [element] is not an abstract class member.
- * If it is present, it should have the same async / generator modifiers.
- */
- void _assertBody(FunctionBody body, ExecutableElementImpl element) {
- if (body is EmptyFunctionBody) {
- _assertTrue(element.isAbstract);
- } else {
- _assertFalse(element.isAbstract);
- _assertEquals(body.isSynchronous, element.isSynchronous);
- _assertEquals(body.isGenerator, element.isGenerator);
- }
- }
-
- void _assertCombinators(List<Combinator> nodeCombinators,
- List<NamespaceCombinator> elementCombinators) {
- // prepare shown/hidden names in the element
- Set<String> showNames = new Set<String>();
- Set<String> hideNames = new Set<String>();
- for (NamespaceCombinator combinator in elementCombinators) {
- if (combinator is ShowElementCombinator) {
- showNames.addAll(combinator.shownNames);
- } else if (combinator is HideElementCombinator) {
- hideNames.addAll(combinator.hiddenNames);
- }
- }
- // match combinators with the node
- for (Combinator combinator in nodeCombinators) {
- if (combinator is ShowCombinator) {
- for (SimpleIdentifier nameNode in combinator.shownNames) {
- String name = nameNode.name;
- _assertTrue(showNames.remove(name));
- }
- } else if (combinator is HideCombinator) {
- for (SimpleIdentifier nameNode in combinator.hiddenNames) {
- String name = nameNode.name;
- _assertTrue(hideNames.remove(name));
- }
- }
- }
- _assertTrue(showNames.isEmpty);
- _assertTrue(hideNames.isEmpty);
- }
-
- void _assertCompatibleParameter(
- FormalParameter node, ParameterElement element) {
- _assertEquals(node.kind, element.parameterKind);
- if (node.kind == ParameterKind.NAMED ||
- element.enclosingElement is ConstructorElement) {
- _assertEquals(node.identifier.name, element.name);
- }
- // check parameter type specific properties
- if (node is DefaultFormalParameter) {
- Expression nodeDefault = node.defaultValue;
- if (nodeDefault == null) {
- _assertNull(element.defaultValueCode);
- } else {
- _assertEquals(nodeDefault.toSource(), element.defaultValueCode);
- }
- _assertCompatibleParameter(node.parameter, element);
- } else if (node is FieldFormalParameter) {
- _assertTrue(element.isInitializingFormal);
- DartType parameterType = element.type;
- if (node.type == null && node.parameters == null) {
- FieldFormalParameterElement parameterElement = element;
- if (!parameterElement.hasImplicitType) {
- _assertTrue(parameterType == null || parameterType.isDynamic);
- }
- if (parameterElement.field != null) {
- _assertEquals(node.identifier.name, element.name);
- }
- } else {
- if (node.parameters != null) {
- _assertTrue(parameterType is FunctionType);
- FunctionType parameterFunctionType = parameterType;
- _assertSameType(node.type, parameterFunctionType.returnType);
- } else {
- _assertSameType(node.type, parameterType);
- }
- }
- _assertCompatibleParameters(node.parameters, element.parameters);
- } else if (node is FunctionTypedFormalParameter) {
- _assertFalse(element.isInitializingFormal);
- _assertTrue(element.type is FunctionType);
- FunctionType elementType = element.type;
- _assertCompatibleParameters(node.parameters, element.parameters);
- _assertSameType(node.returnType, elementType.returnType);
- } else if (node is SimpleFormalParameter) {
- _assertFalse(element.isInitializingFormal);
- _assertSameType(node.type, element.type);
- }
- }
-
- void _assertCompatibleParameters(
- FormalParameterList nodes, List<ParameterElement> elements) {
- if (nodes == null) {
- return _assertEquals(elements.length, 0);
- }
- List<FormalParameter> parameters = nodes.parameters;
- int length = parameters.length;
- _assertEquals(length, elements.length);
- for (int i = 0; i < length; i++) {
- _assertCompatibleParameter(parameters[i], elements[i]);
- }
- }
-
- /**
- * Asserts that there is an import with the same prefix as the given
- * [prefixNode], which exposes the given [element].
- */
- void _assertElementVisibleWithPrefix(
- SimpleIdentifier prefixNode, Element element) {
- if (prefixNode == null) {
- return;
- }
- String prefixName = prefixNode.name;
- for (ImportElement import in _enclosingLibrary.imports) {
- if (import.prefix != null && import.prefix.name == prefixName) {
- Namespace namespace =
- new NamespaceBuilder().createImportNamespaceForDirective(import);
- Iterable<Element> visibleElements = namespace.definedNames.values;
- if (visibleElements.contains(element)) {
- return;
- }
- }
- }
- _assertTrue(false);
- }
-
- void _assertEquals(Object a, Object b) {
- if (a != b) {
- throw new _DeclarationMismatchException();
- }
- }
-
- void _assertFalse(bool condition) {
- if (condition) {
- throw new _DeclarationMismatchException();
- }
- }
-
- void _assertNotNull(Object object) {
- if (object == null) {
- throw new _DeclarationMismatchException();
- }
- }
-
- void _assertNull(Object object) {
- if (object != null) {
- throw new _DeclarationMismatchException();
- }
- }
-
- void _assertSameAnnotation(Annotation node, ElementAnnotation annotation) {
- Element element = annotation.element;
- if (element is ConstructorElement) {
- _assertTrue(node.name is SimpleIdentifier);
- _assertNull(node.constructorName);
- TypeName nodeType = new TypeName(node.name, null);
- _assertSameType(nodeType, element.returnType);
- // TODO(scheglov) validate arguments
- }
- if (element is PropertyAccessorElement) {
- _assertTrue(node.name is SimpleIdentifier);
- String nodeName = node.name.name;
- String elementName = element.displayName;
- _assertEquals(nodeName, elementName);
- }
- }
-
- void _assertSameAnnotations(AnnotatedNode node, Element element) {
- List<Annotation> nodeAnnotations = node.metadata;
- List<ElementAnnotation> elementAnnotations = element.metadata;
- int length = nodeAnnotations.length;
- _assertEquals(elementAnnotations.length, length);
- for (int i = 0; i < length; i++) {
- _assertSameAnnotation(nodeAnnotations[i], elementAnnotations[i]);
- }
- }
-
- void _assertSameType(TypeName node, DartType type) {
- // no type == dynamic
- if (node == null) {
- return _assertTrue(type == null || type.isDynamic);
- }
- if (type == null) {
- return _assertTrue(false);
- }
- // prepare name
- SimpleIdentifier prefixIdentifier = null;
- Identifier nameIdentifier = node.name;
- if (nameIdentifier is PrefixedIdentifier) {
- PrefixedIdentifier prefixedIdentifier = nameIdentifier;
- prefixIdentifier = prefixedIdentifier.prefix;
- nameIdentifier = prefixedIdentifier.identifier;
- }
- String nodeName = nameIdentifier.name;
- // check specific type kinds
- if (type is ParameterizedType) {
- _assertEquals(nodeName, type.name);
- _assertElementVisibleWithPrefix(prefixIdentifier, type.element);
- // check arguments
- TypeArgumentList nodeArgumentList = node.typeArguments;
- List<DartType> typeArguments = type.typeArguments;
- if (nodeArgumentList == null) {
- // Node doesn't have type arguments, so all type arguments of the
- // element must be "dynamic".
- for (DartType typeArgument in typeArguments) {
- _assertTrue(typeArgument.isDynamic);
- }
- } else {
- List<TypeName> nodeArguments = nodeArgumentList.arguments;
- _assertSameTypes(nodeArguments, typeArguments);
- }
- } else if (type is TypeParameterType) {
- _assertEquals(nodeName, type.name);
- // TODO(scheglov) it should be possible to rename type parameters
- } else if (type.isVoid) {
- _assertEquals(nodeName, 'void');
- } else if (type.isDynamic) {
- _assertEquals(nodeName, 'dynamic');
- } else {
- // TODO(scheglov) support other types
- logger.log('node: $node type: $type type.type: ${type.runtimeType}');
- _assertTrue(false);
- }
- }
-
- void _assertSameTypeParameter(
- TypeParameter node, TypeParameterElement element) {
- _assertSameType(node.bound, element.bound);
- }
-
- void _assertSameTypeParameters(
- TypeParameterList nodesList, List<TypeParameterElement> elements) {
- if (nodesList == null) {
- return _assertEquals(elements.length, 0);
- }
- List<TypeParameter> nodes = nodesList.typeParameters;
- int length = nodes.length;
- _assertEquals(length, elements.length);
- for (int i = 0; i < length; i++) {
- _assertSameTypeParameter(nodes[i], elements[i]);
- }
- }
-
- void _assertSameTypes(List<TypeName> nodes, List<DartType> types) {
- int length = nodes.length;
- _assertEquals(length, types.length);
- for (int i = 0; i < length; i++) {
- _assertSameType(nodes[i], types[i]);
- }
- }
-
- void _assertTrue(bool condition) {
- if (!condition) {
- throw new _DeclarationMismatchException();
- }
- }
-
- /**
- * Given that the comparison is to begin with the given [element], capture
- * the enclosing elements that might be used while performing the comparison.
- */
- void _captureEnclosingElements(Element element) {
- Element parent =
- element is CompilationUnitElement ? element : element.enclosingElement;
- while (parent != null) {
- if (parent is CompilationUnitElement) {
- _enclosingUnit = parent;
- _enclosingLibrary = element.library;
- } else if (parent is ClassElement) {
- if (_enclosingClass == null) {
- _enclosingClass = parent;
- }
- } else if (parent is FunctionTypeAliasElement) {
- if (_enclosingAlias == null) {
- _enclosingAlias = parent;
- }
- } else if (parent is ParameterElement) {
- if (_enclosingParameter == null) {
- _enclosingParameter = parent;
- }
- }
- parent = parent.enclosingElement;
- }
- }
-
- void _gatherElements(Element element) {
- _ElementsGatherer gatherer = new _ElementsGatherer(this);
- element.accept(gatherer);
- // TODO(scheglov) what if a change in a directive?
- if (identical(element, _enclosingLibrary.definingCompilationUnit)) {
- gatherer.addElements(_enclosingLibrary.imports);
- gatherer.addElements(_enclosingLibrary.exports);
- gatherer.addElements(_enclosingLibrary.parts);
- }
- }
-
- void _processElement(Element element) {
- _assertNotNull(element);
- if (!_allElements.contains(element)) {
- throw new _DeclarationMismatchException();
- }
- _removedElements.remove(element);
- }
-
- void _removeElement(Element element) {
- if (element != null) {
- Element enclosingElement = element.enclosingElement;
- if (element is MethodElement) {
- ClassElement classElement = enclosingElement;
- _removeIdenticalElement(classElement.methods, element);
- } else if (element is PropertyAccessorElement) {
- if (enclosingElement is ClassElement) {
- _removeIdenticalElement(enclosingElement.accessors, element);
- }
- if (enclosingElement is CompilationUnitElement) {
- _removeIdenticalElement(enclosingElement.accessors, element);
- }
- }
- }
- }
-
- /**
- * Return the [Element] in [elements] with the given [name].
- */
- static Element _findElement(List<Element> elements, String name) {
- for (Element element in elements) {
- if (element.name == name) {
- return element;
- }
- }
- return null;
- }
-
- /**
- * Return the [UriReferencedElement] from [elements] with the given [uri], or
- * `null` if there is no such element.
- */
- static UriReferencedElement _findUriReferencedElement(
- List<UriReferencedElement> elements, String uri) {
- for (UriReferencedElement element in elements) {
- if (element.uri == uri) {
- return element;
- }
- }
- return null;
- }
-
- /**
- * Return the value of [literal], or `null` if the string is not a constant
- * string without any string interpolation.
- */
- static String _getStringValue(StringLiteral literal) {
- if (literal is StringInterpolation) {
- return null;
- }
- return literal.stringValue;
- }
-
- /**
- * Removes the first element identical to the given [element] from [elements].
- */
- static void _removeIdenticalElement(List elements, Object element) {
- int length = elements.length;
- for (int i = 0; i < length; i++) {
- if (identical(elements[i], element)) {
- elements.removeAt(i);
- return;
- }
- }
- }
-
- static void _setLocalElements(
- ExecutableElementImpl to, ExecutableElement from) {
- if (from != null) {
- to.functions = from.functions;
- to.labels = from.labels;
- to.localVariables = from.localVariables;
- to.parameters = from.parameters;
- }
- }
-}
-
-/**
- * Describes how declarations match an existing elements model.
- */
-class DeclarationMatchKind {
- /**
- * Complete match, no API changes.
- */
- static const MATCH = const DeclarationMatchKind('MATCH');
-
- /**
- * Has API changes that we might be able to resolve incrementally.
- */
- static const MISMATCH_OK = const DeclarationMatchKind('MISMATCH_OK');
-
- /**
- * Has API changes that we cannot resolve incrementally.
- */
- static const MISMATCH = const DeclarationMatchKind('MISMATCH');
-
- final String name;
-
- const DeclarationMatchKind(this.name);
-
- @override
- String toString() => name;
-}
-
-/**
* The [Delta] implementation used by incremental resolver.
* It keeps Dart results that are either don't change or are updated.
*/
@@ -1062,103 +242,53 @@
_updateDelta = updateEndNew - updateEndOld;
/**
- * Resolve [node], reporting any errors or warnings to the given listener.
+ * Resolve [body], reporting any errors or warnings to the given listener.
*
- * [node] - the root of the AST structure to be resolved.
- *
- * Returns `true` if resolution was successful.
+ * [body] - the root of the AST structure to be resolved.
*/
- bool resolve(AstNode node) {
+ void resolve(BlockFunctionBody body) {
logger.enter('resolve: $_definingUnit');
try {
- AstNode rootNode = _findResolutionRoot(node);
- _prepareResolutionContext(rootNode);
+ Declaration executable = _findResolutionRoot(body);
+ _prepareResolutionContext(executable);
// update elements
_updateCache();
_updateElementNameOffsets();
- _buildElements(rootNode);
- if (!_canBeIncrementallyResolved(rootNode)) {
- return false;
- }
+ _buildElements(executable, body);
// resolve
- _resolveReferences(rootNode);
- _computeConstants(rootNode);
+ _resolveReferences(executable);
+ _computeConstants(executable);
_resolveErrors = errorListener.getErrorsForSource(_source);
// verify
- _verify(rootNode);
+ _verify(executable);
_context.invalidateLibraryHints(_librarySource);
// update entry errors
_updateEntry();
- // OK
- return true;
} finally {
logger.exit();
}
}
- void _buildElements(AstNode node) {
+ void _buildElements(Declaration executable, AstNode node) {
LoggingTimer timer = logger.startTimer();
try {
ElementHolder holder = new ElementHolder();
ElementBuilder builder = new ElementBuilder(holder, _definingUnit);
- if (_resolutionContext.enclosingClassDeclaration != null) {
- builder.visitClassDeclarationIncrementally(
- _resolutionContext.enclosingClassDeclaration);
- }
+ builder.initForFunctionBodyIncrementalResolution();
node.accept(builder);
+ // Move local elements into the ExecutableElementImpl.
+ ExecutableElementImpl executableElement =
+ executable.element as ExecutableElementImpl;
+ executableElement.localVariables = holder.localVariables;
+ executableElement.functions = holder.functions;
+ executableElement.labels = holder.labels;
+ holder.validate();
} finally {
timer.stop('build elements');
}
}
/**
- * Return `true` if [node] does not have element model changes, or these
- * changes can be incrementally propagated.
- */
- bool _canBeIncrementallyResolved(AstNode node) {
- // If we are replacing the whole declaration, this means that its signature
- // is changed. It might be an API change, or not.
- //
- // If, for example, a required parameter is changed, it is not an API
- // change, but we want to find the existing corresponding Element in the
- // enclosing one, set it for the node and update as needed.
- //
- // If, for example, the name of a method is changed, it is an API change,
- // we need to know the old Element and the new Element. Again, we need to
- // check the whole enclosing Element.
- if (node is Declaration) {
- node = node.parent;
- }
- Element element = _getElement(node);
- DeclarationMatcher matcher = new DeclarationMatcher();
- DeclarationMatchKind matchKind = matcher.matches(node, element);
- if (matchKind == DeclarationMatchKind.MATCH) {
- return true;
- }
- // mismatch that cannot be incrementally fixed
- return false;
- }
-
- /**
- * Return `true` if the given node can be resolved independently of any other
- * nodes.
- *
- * *Note*: This method needs to be kept in sync with
- * [ScopeBuilder.ContextBuilder].
- *
- * [node] - the node being tested.
- */
- bool _canBeResolved(AstNode node) =>
- node is ClassDeclaration ||
- node is ClassTypeAlias ||
- node is CompilationUnit ||
- node is ConstructorDeclaration ||
- node is FunctionDeclaration ||
- node is FunctionTypeAlias ||
- node is MethodDeclaration ||
- node is TopLevelVariableDeclaration;
-
- /**
* Compute a value for all of the constants in the given [node].
*/
void _computeConstants(AstNode node) {
@@ -1187,9 +317,11 @@
*
* Throws [AnalysisException] if there is no such node.
*/
- AstNode _findResolutionRoot(AstNode node) {
+ Declaration _findResolutionRoot(AstNode node) {
while (node != null) {
- if (_canBeResolved(node)) {
+ if (node is ConstructorDeclaration ||
+ node is FunctionDeclaration ||
+ node is MethodDeclaration) {
return node;
}
node = node.parent;
@@ -1197,19 +329,6 @@
throw new AnalysisException("Cannot resolve node: no resolvable node");
}
- /**
- * Return the element defined by [node], or `null` if the node does not
- * define an element.
- */
- Element _getElement(AstNode node) {
- if (node is Declaration) {
- return node.element;
- } else if (node is CompilationUnit) {
- return node.element;
- }
- return null;
- }
-
void _prepareResolutionContext(AstNode node) {
if (_resolutionContext == null) {
_resolutionContext =
@@ -1412,9 +531,7 @@
this._sourceEntry,
this._unitEntry,
this._oldUnit,
- bool resolveApiChanges) {
- _resolveApiChanges = resolveApiChanges;
- }
+ bool resolveApiChanges);
/**
* Attempts to update [_oldUnit] to the state corresponding to [newCode].
@@ -1532,13 +649,7 @@
newParent is ConstructorDeclaration ||
oldParent is MethodDeclaration &&
newParent is MethodDeclaration) {
- Element oldElement = (oldParent as Declaration).element;
- if (new DeclarationMatcher().matches(newParent, oldElement) ==
- DeclarationMatchKind.MATCH) {
- oldNode = oldParent;
- newNode = newParent;
- found = true;
- } else {
+ if (oldParents.length == i || newParents.length == i) {
return false;
}
} else if (oldParent is FunctionBody && newParent is FunctionBody) {
@@ -1603,12 +714,7 @@
_updateOffset,
_updateEndOld,
_updateEndNew);
- bool success = incrementalResolver.resolve(newNode);
- // check if success
- if (!success) {
- logger.log('Failure: element model changed.');
- return false;
- }
+ incrementalResolver.resolve(newNode);
// update DartEntry
_updateEntry();
logger.log('Success.');
@@ -2072,13 +1178,6 @@
}
/**
- * Instances of the class [_DeclarationMismatchException] represent an exception
- * that is thrown when the element model defined by a given AST structure does
- * not match an existing element model.
- */
-class _DeclarationMismatchException {}
-
-/**
* Adjusts the location of each Element that moved.
*
* Since `==` and `hashCode` of a local variable or function Element are based
@@ -2173,60 +1272,6 @@
}
}
-class _ElementsGatherer extends GeneralizingElementVisitor {
- final DeclarationMatcher matcher;
-
- _ElementsGatherer(this.matcher);
-
- void addElements(List<Element> elements) {
- for (Element element in elements) {
- if (!element.isSynthetic) {
- _addElement(element);
- }
- }
- }
-
- @override
- visitElement(Element element) {
- _addElement(element);
- super.visitElement(element);
- }
-
- @override
- visitExecutableElement(ExecutableElement element) {
- _addElement(element);
- }
-
- @override
- visitParameterElement(ParameterElement element) {}
-
- @override
- visitPropertyAccessorElement(PropertyAccessorElement element) {
- if (!element.isSynthetic) {
- _addElement(element);
- }
- // Don't visit children (such as synthetic setter parameters).
- }
-
- @override
- visitPropertyInducingElement(PropertyInducingElement element) {
- if (!element.isSynthetic) {
- _addElement(element);
- }
- // Don't visit children (such as property accessors).
- }
-
- @override
- visitTypeParameterElement(TypeParameterElement element) {}
-
- void _addElement(Element element) {
- if (element != null) {
- matcher._allElements.add(element);
- matcher._removedElements.add(element);
- }
- }
-}
-
/**
* Describes how two [Token]s are different.
*/
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index c90928f..2b7aa9f 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -5033,11 +5033,6 @@
String referenceSource, int sourceOffset) {
// TODO(brianwilkerson) The errors are not getting the right offset/length
// and are being duplicated.
- if (referenceSource.length == 0) {
- Token syntheticToken =
- new SyntheticStringToken(TokenType.IDENTIFIER, "", sourceOffset);
- return new CommentReference(null, new SimpleIdentifier(syntheticToken));
- }
try {
BooleanErrorListener listener = new BooleanErrorListener();
Scanner scanner = new Scanner(
@@ -5047,6 +5042,12 @@
if (listener.errorReported) {
return null;
}
+ if (firstToken.type == TokenType.EOF) {
+ Token syntheticToken =
+ new SyntheticStringToken(TokenType.IDENTIFIER, "", sourceOffset);
+ syntheticToken.setNext(firstToken);
+ return new CommentReference(null, new SimpleIdentifier(syntheticToken));
+ }
Token newKeyword = null;
if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) {
newKeyword = firstToken;
@@ -5134,20 +5135,21 @@
} else {
// terminating ']' is not typed yet
int charAfterLeft = comment.codeUnitAt(leftIndex + 1);
+ Token nameToken;
if (Character.isLetterOrDigit(charAfterLeft)) {
int nameEnd = StringUtilities.indexOfFirstNotLetterDigit(
comment, leftIndex + 1);
String name = comment.substring(leftIndex + 1, nameEnd);
- Token nameToken =
+ nameToken =
new StringToken(TokenType.IDENTIFIER, name, nameOffset);
- references.add(
- new CommentReference(null, new SimpleIdentifier(nameToken)));
} else {
- Token nameToken = new SyntheticStringToken(
- TokenType.IDENTIFIER, "", nameOffset);
- references.add(
- new CommentReference(null, new SimpleIdentifier(nameToken)));
+ nameToken = new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', nameOffset);
}
+ nameToken.setNext(new SimpleToken(TokenType.EOF, nameToken.end));
+ references.add(
+ new CommentReference(null, new SimpleIdentifier(nameToken)));
+ token.references.add(nameToken);
// next character
rightIndex = leftIndex + 1;
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 31ed260..33dc56e 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -91,6 +91,20 @@
_typeSystem = typeSystem ?? new TypeSystemImpl();
@override
+ Object visitAnnotation(Annotation node) {
+ if (node.elementAnnotation?.isFactory == true) {
+ AstNode parent = node.parent;
+ if (parent is MethodDeclaration) {
+ _checkForInvalidFactory(parent);
+ } else {
+ _errorReporter
+ .reportErrorForNode(HintCode.INVALID_FACTORY_ANNOTATION, node, []);
+ }
+ }
+ return super.visitAnnotation(node);
+ }
+
+ @override
Object visitArgumentList(ArgumentList node) {
for (Expression argument in node.arguments) {
ParameterElement parameter = argument.bestParameterElement;
@@ -674,6 +688,44 @@
return false;
}
+ void _checkForInvalidFactory(MethodDeclaration decl) {
+ // Check declaration.
+ // Note that null return types are expected to be flagged by other analyses.
+ DartType returnType = decl.returnType?.type;
+ if (returnType is VoidType) {
+ _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_DECL,
+ decl.name, [decl.name.toString()]);
+ return;
+ }
+
+ // Check implementation.
+
+ FunctionBody body = decl.body;
+ if (body is EmptyFunctionBody) {
+ // Abstract methods are OK.
+ return;
+ }
+
+ // `new Foo()` or `null`.
+ bool factoryExpression(Expression expression) =>
+ expression is InstanceCreationExpression || expression is NullLiteral;
+
+ if (body is ExpressionFunctionBody && factoryExpression(body.expression)) {
+ return;
+ } else if (body is BlockFunctionBody) {
+ NodeList<Statement> statements = body.block.statements;
+ if (statements.isNotEmpty) {
+ Statement last = statements.last;
+ if (last is ReturnStatement && factoryExpression(last.expression)) {
+ return;
+ }
+ }
+ }
+
+ _errorReporter.reportErrorForNode(HintCode.INVALID_FACTORY_METHOD_IMPL,
+ decl.name, [decl.name.toString()]);
+ }
+
/**
* Produces a hint if the given identifier is a protected closure, field or
* getter/setter, method closure or invocation accessed outside a subclass.
@@ -701,8 +753,13 @@
identifier.getAncestor((AstNode node) => node is CommentReference) !=
null;
+ bool inCurrentLibrary(Element element) =>
+ element.library == _currentLibrary;
+
Element element = identifier.bestElement;
- if (isProtected(element) && !inCommentReference(identifier)) {
+ if (isProtected(element) &&
+ !inCurrentLibrary(element) &&
+ !inCommentReference(identifier)) {
ClassElement definingClass = element.enclosingElement;
ClassDeclaration accessingClass =
identifier.getAncestor((AstNode node) => node is ClassDeclaration);
@@ -3556,7 +3613,7 @@
bool outerBreakValue = _enclosingBlockContainsBreak;
_enclosingBlockContainsBreak = false;
try {
- if (_nodeExits(node.body)) {
+ if (_nodeExits(node.body) && !_enclosingBlockContainsBreak) {
return true;
}
Expression conditionExpression = node.condition;
@@ -3858,13 +3915,21 @@
if (conditionExpression.accept(this)) {
return true;
}
- bool blockReturns = node.body.accept(this);
+ node.body.accept(this);
// TODO(jwren) Do we want to take all constant expressions into account?
if (conditionExpression is BooleanLiteral) {
- // If while(true), and the body doesn't return or the body doesn't have
- // a break, then return true.
- if (conditionExpression.value &&
- (blockReturns || !_enclosingBlockContainsBreak)) {
+ // If while(true), and the body doesn't have a break, then return true.
+ // The body might be found to exit, but if there are any break
+ // statements, then it is a faulty finding. In other words:
+ //
+ // * If the body exits, and does not contain a break statement, then
+ // it exits.
+ // * If the body does not exit, and does not contain a break statement,
+ // then it loops infinitely (also an exit).
+ //
+ // As both conditions forbid any break statements to be found, the logic
+ // just boils down to checking [_enclosingBlockContainsBreak].
+ if (conditionExpression.value && !_enclosingBlockContainsBreak) {
return true;
}
}
@@ -4775,7 +4840,7 @@
* Place an info node into the error stream indicating that a
* [type] has been inferred as the type of [node].
*/
- void recordInference(Expression node, DartType type) {
+ void recordInference(AstNode node, DartType type) {
if (!_inferenceHints) {
return;
}
@@ -5571,6 +5636,11 @@
bool resolveOnlyCommentInFunctionBody = false;
/**
+ * True if we're analyzing in strong mode.
+ */
+ bool _strongMode;
+
+ /**
* Body of the function currently being analyzed, if any.
*/
FunctionBody _currentFunctionBody;
@@ -5601,6 +5671,7 @@
this.typeSystem = definingLibrary.context.typeSystem;
bool strongModeHints = false;
AnalysisOptions options = definingLibrary.context.analysisOptions;
+ _strongMode = options.strongMode;
if (options is AnalysisOptionsImpl) {
strongModeHints = options.strongModeHints;
}
@@ -6291,13 +6362,24 @@
@override
Object visitDefaultFormalParameter(DefaultFormalParameter node) {
- InferenceContext.setType(node.defaultValue, node.parameter.element?.type);
- super.visitDefaultFormalParameter(node);
ParameterElement element = node.element;
+ InferenceContext.setType(node.defaultValue, element.type);
+ super.visitDefaultFormalParameter(node);
if (element.initializer != null && node.defaultValue != null) {
(element.initializer as FunctionElementImpl).returnType =
node.defaultValue.staticType;
}
+ if (_strongMode &&
+ node.defaultValue != null &&
+ element.hasImplicitType &&
+ element is! FieldFormalParameterElement) {
+
+ DartType type = node.defaultValue.staticType;
+ if (!type.isBottom && !type.isDynamic) {
+ (element as ParameterElementImpl).type = type;
+ inferenceContext.recordInference(node, type);
+ }
+ }
// Clone the ASTs for default formal parameters, so that we can use them
// during constant evaluation.
if (!LibraryElementImpl.hasResolutionCapability(
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 8705867..e46b644 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -9,8 +9,9 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/engine.dart'
- show AnalysisContext, AnalysisOptions;
+ show AnalysisContext, AnalysisOptions, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/utilities_general.dart';
/**
* A function used to create a new DartSdk with the given [options]. If the
@@ -96,20 +97,32 @@
*/
class DartSdkManager {
/**
+ * The absolute path to the directory containing the default SDK.
+ */
+ final String defaultSdkDirectory;
+
+ /**
+ * A flag indicating whether it is acceptable to use summaries when they are
+ * available.
+ */
+ final bool canUseSummaries;
+
+ /**
* The function used to create new SDK's.
*/
final SdkCreator sdkCreator;
/**
- * A table mapping (an encoding of) analysis options to the SDK that has been
- * configured with those options.
+ * A table mapping (an encoding of) analysis options and SDK locations to the
+ * DartSdk from that location that has been configured with those options.
*/
- Map<int, DartSdk> sdkMap = new HashMap<int, DartSdk>();
+ Map<SdkDescription, DartSdk> sdkMap = new HashMap<SdkDescription, DartSdk>();
/**
* Initialize a newly created manager.
*/
- DartSdkManager(this.sdkCreator);
+ DartSdkManager(
+ this.defaultSdkDirectory, this.canUseSummaries, this.sdkCreator);
/**
* Return any SDK that has been created, or `null` if no SDKs have been
@@ -123,13 +136,30 @@
}
/**
+ * Return a list of the descriptors of the SDKs that are currently being
+ * managed.
+ */
+ List<SdkDescription> get sdkDescriptors => sdkMap.keys.toList();
+
+ /**
+ * Return the Dart SDK that is appropriate for the given analysis [options].
+ * If such an SDK has not yet been created, then the [sdkCreator] will be
+ * invoked to create it.
+ */
+ DartSdk getSdk(SdkDescription description, DartSdk ifAbsent()) {
+ return sdkMap.putIfAbsent(description, ifAbsent);
+ }
+
+ /**
* Return the Dart SDK that is appropriate for the given analysis [options].
* If such an SDK has not yet been created, then the [sdkCreator] will be
* invoked to create it.
*/
DartSdk getSdkForOptions(AnalysisOptions options) {
- int encoding = options.encodeCrossContextOptions();
- return sdkMap.putIfAbsent(encoding, () => sdkCreator(options));
+ // TODO(brianwilkerson) Remove this method and the field sdkCreator.
+ SdkDescription description =
+ new SdkDescription(<String>[defaultSdkDirectory], options);
+ return getSdk(description, () => sdkCreator(options));
}
}
@@ -173,6 +203,82 @@
int size() => _libraryMap.length;
}
+/**
+ * A description of a [DartSdk].
+ */
+class SdkDescription {
+ /**
+ * The paths to the files or directories that define the SDK.
+ */
+ final List<String> paths;
+
+ /**
+ * The analysis options that will be used by the SDK's context.
+ */
+ final AnalysisOptions options;
+
+ /**
+ * Initialize a newly created SDK description to describe an SDK based on the
+ * files or directories at the given [paths] that is analyzed using the given
+ * [options].
+ */
+ SdkDescription(this.paths, this.options);
+
+ @override
+ int get hashCode {
+ int hashCode = options.encodeCrossContextOptions();
+ for (String path in paths) {
+ hashCode = JenkinsSmiHash.combine(hashCode, path.hashCode);
+ }
+ return JenkinsSmiHash.finish(hashCode);
+ }
+
+ @override
+ bool operator ==(Object other) {
+ if (other is SdkDescription) {
+ if (options.encodeCrossContextOptions() !=
+ other.options.encodeCrossContextOptions()) {
+ return false;
+ }
+ int length = paths.length;
+ if (other.paths.length != length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (other.paths[i] != paths[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ bool needsSeparator = false;
+ void add(String optionName) {
+ if (needsSeparator) {
+ buffer.write(', ');
+ }
+ buffer.write(optionName);
+ needsSeparator = true;
+ }
+ for (String path in paths) {
+ add(path);
+ }
+ if (needsSeparator) {
+ buffer.write(' ');
+ }
+ buffer.write('(');
+ buffer.write(AnalysisOptionsImpl
+ .decodeCrossContextOptions(options.encodeCrossContextOptions()));
+ buffer.write(')');
+ return buffer.toString();
+ }
+}
+
class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
/**
* The prefix added to the name of a library to form the URI used in code to
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 4492037..6412de3 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -484,6 +484,9 @@
*/
bool get isInSystemLibrary;
+ @override
+ Source get librarySource => null;
+
/**
* Return the modification stamp for this source, or a negative value if the
* source does not exist. A modification stamp is a non-negative integer with
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 0a5b904..1034bc5 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -142,8 +142,6 @@
}
class CacheAnalysisErrorBuilder extends Object with _CacheAnalysisErrorMixin implements idl.CacheAnalysisError {
- bool _finished = false;
-
String _correction;
String _errorCodeUniqueName;
int _length;
@@ -159,7 +157,6 @@
* the user can fix the error.
*/
void set correction(String _value) {
- assert(!_finished);
_correction = _value;
}
@@ -170,7 +167,6 @@
* The unique name of the error code.
*/
void set errorCodeUniqueName(String _value) {
- assert(!_finished);
_errorCodeUniqueName = _value;
}
@@ -181,7 +177,6 @@
* Length of the error range.
*/
void set length(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_length = _value;
}
@@ -194,7 +189,6 @@
* what is wrong and why it is wrong.
*/
void set message(String _value) {
- assert(!_finished);
_message = _value;
}
@@ -205,7 +199,6 @@
* Offset of the error range relative to the beginning of the file.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -224,8 +217,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_correction;
fb.Offset offset_errorCodeUniqueName;
fb.Offset offset_message;
@@ -334,8 +325,6 @@
}
class CacheSourceContentBuilder extends Object with _CacheSourceContentMixin implements idl.CacheSourceContent {
- bool _finished = false;
-
List<String> _exportedUris;
List<String> _importedUris;
idl.CacheSourceKind _kind;
@@ -349,7 +338,6 @@
* or `package:foo/bar.dart`. Empty if [kind] is [CacheSourceKind.part].
*/
void set exportedUris(List<String> _value) {
- assert(!_finished);
_exportedUris = _value;
}
@@ -361,7 +349,6 @@
* or `package:foo/bar.dart`. Empty if [kind] is [CacheSourceKind.part].
*/
void set importedUris(List<String> _value) {
- assert(!_finished);
_importedUris = _value;
}
@@ -372,7 +359,6 @@
* The kind of the source.
*/
void set kind(idl.CacheSourceKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -384,7 +370,6 @@
* [CacheSourceKind.part].
*/
void set partUris(List<String> _value) {
- assert(!_finished);
_partUris = _value;
}
@@ -406,8 +391,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_exportedUris;
fb.Offset offset_importedUris;
fb.Offset offset_partUris;
@@ -509,8 +492,6 @@
}
class CacheSourceErrorsInLibraryBuilder extends Object with _CacheSourceErrorsInLibraryMixin implements idl.CacheSourceErrorsInLibrary {
- bool _finished = false;
-
List<CacheAnalysisErrorBuilder> _errors;
@override
@@ -520,7 +501,6 @@
* The list of errors in the source in the library.
*/
void set errors(List<CacheAnalysisErrorBuilder> _value) {
- assert(!_finished);
_errors = _value;
}
@@ -540,8 +520,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_errors;
if (!(_errors == null || _errors.isEmpty)) {
offset_errors = fbBuilder.writeList(_errors.map((b) => b.finish(fbBuilder)).toList());
@@ -599,8 +577,6 @@
}
class CodeRangeBuilder extends Object with _CodeRangeMixin implements idl.CodeRange {
- bool _finished = false;
-
int _length;
int _offset;
@@ -611,7 +587,6 @@
* Length of the element code.
*/
void set length(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_length = _value;
}
@@ -623,7 +598,6 @@
* Offset of the element code relative to the beginning of the file.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -639,8 +613,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fbBuilder.startTable();
if (_length != null && _length != 0) {
fbBuilder.addUint32(1, _length);
@@ -701,8 +673,6 @@
}
class EntityRefBuilder extends Object with _EntityRefMixin implements idl.EntityRef {
- bool _finished = false;
-
List<int> _implicitFunctionTypeIndices;
int _paramReference;
int _reference;
@@ -737,7 +707,6 @@
* first to the class and then to the method.
*/
void set implicitFunctionTypeIndices(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_implicitFunctionTypeIndices = _value;
}
@@ -765,7 +734,6 @@
* zero.
*/
void set paramReference(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_paramReference = _value;
}
@@ -778,7 +746,6 @@
* zero if this is a reference to a type parameter.
*/
void set reference(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_reference = _value;
}
@@ -794,7 +761,6 @@
* Otherwise zero.
*/
void set slot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_slot = _value;
}
@@ -809,7 +775,6 @@
* empty.
*/
void set syntheticParams(List<UnlinkedParamBuilder> _value) {
- assert(!_finished);
_syntheticParams = _value;
}
@@ -823,7 +788,6 @@
* Otherwise `null`.
*/
void set syntheticReturnType(EntityRefBuilder _value) {
- assert(!_finished);
_syntheticReturnType = _value;
}
@@ -835,7 +799,6 @@
* type arguments used to instantiate it (if any).
*/
void set typeArguments(List<EntityRefBuilder> _value) {
- assert(!_finished);
_typeArguments = _value;
}
@@ -858,8 +821,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_implicitFunctionTypeIndices;
fb.Offset offset_syntheticParams;
fb.Offset offset_syntheticReturnType;
@@ -996,8 +957,6 @@
}
class LinkedDependencyBuilder extends Object with _LinkedDependencyMixin implements idl.LinkedDependency {
- bool _finished = false;
-
List<String> _parts;
String _uri;
@@ -1009,7 +968,6 @@
* These URIs are relative to the importing library.
*/
void set parts(List<String> _value) {
- assert(!_finished);
_parts = _value;
}
@@ -1024,7 +982,6 @@
* `b/d/e.dart`.
*/
void set uri(String _value) {
- assert(!_finished);
_uri = _value;
}
@@ -1039,8 +996,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_parts;
fb.Offset offset_uri;
if (!(_parts == null || _parts.isEmpty)) {
@@ -1109,8 +1064,6 @@
}
class LinkedExportNameBuilder extends Object with _LinkedExportNameMixin implements idl.LinkedExportName {
- bool _finished = false;
-
int _dependency;
idl.ReferenceKind _kind;
String _name;
@@ -1124,7 +1077,6 @@
* entity is defined.
*/
void set dependency(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_dependency = _value;
}
@@ -1136,7 +1088,6 @@
* The kind of the entity being referred to.
*/
void set kind(idl.ReferenceKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -1148,7 +1099,6 @@
* the trailing '='.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -1162,7 +1112,6 @@
* represent parts in the order of the corresponding `part` declarations.
*/
void set unit(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_unit = _value;
}
@@ -1180,8 +1129,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_name;
if (_name != null) {
offset_name = fbBuilder.writeString(_name);
@@ -1270,8 +1217,6 @@
}
class LinkedLibraryBuilder extends Object with _LinkedLibraryMixin implements idl.LinkedLibrary {
- bool _finished = false;
-
List<LinkedDependencyBuilder> _dependencies;
List<int> _exportDependencies;
List<LinkedExportNameBuilder> _exportNames;
@@ -1300,7 +1245,6 @@
* depends on the lack of a certain declaration in the library).
*/
void set dependencies(List<LinkedDependencyBuilder> _value) {
- assert(!_finished);
_dependencies = _value;
}
@@ -1312,7 +1256,6 @@
* of the library being exported.
*/
void set exportDependencies(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_exportDependencies = _value;
}
@@ -1328,7 +1271,6 @@
* Sorted by name.
*/
void set exportNames(List<LinkedExportNameBuilder> _value) {
- assert(!_finished);
_exportNames = _value;
}
@@ -1340,7 +1282,6 @@
* true, all other fields in the data structure have their default values.
*/
void set fallbackMode(bool _value) {
- assert(!_finished);
_fallbackMode = _value;
}
@@ -1352,7 +1293,6 @@
* of the library being imported.
*/
void set importDependencies(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_importDependencies = _value;
}
@@ -1366,7 +1306,6 @@
* the transitive closure of exports, plus the library itself).
*/
void set numPrelinkedDependencies(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_numPrelinkedDependencies = _value;
}
@@ -1381,7 +1320,6 @@
* declarations in the defining compilation unit.
*/
void set units(List<LinkedUnitBuilder> _value) {
- assert(!_finished);
_units = _value;
}
@@ -1409,8 +1347,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_dependencies;
fb.Offset offset_exportDependencies;
fb.Offset offset_exportNames;
@@ -1556,8 +1492,6 @@
}
class LinkedReferenceBuilder extends Object with _LinkedReferenceMixin implements idl.LinkedReference {
- bool _finished = false;
-
int _containingReference;
int _dependency;
idl.ReferenceKind _kind;
@@ -1581,7 +1515,6 @@
* LinkedUnit.references[i].containingReference < i.
*/
void set containingReference(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_containingReference = _value;
}
@@ -1597,7 +1530,6 @@
* member), or if [kind] is [ReferenceKind.prefix].
*/
void set dependency(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_dependency = _value;
}
@@ -1610,7 +1542,6 @@
* and `void`, the kind is [ReferenceKind.classOrEnum].
*/
void set kind(idl.ReferenceKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -1625,7 +1556,6 @@
* [UnlinkedExecutable.localVariables]. Otherwise zero.
*/
void set localIndex(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_localIndex = _value;
}
@@ -1639,7 +1569,6 @@
* string is "dynamic". For the pseudo-type `void`, the string is "void".
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -1652,7 +1581,6 @@
* Otherwise zero.
*/
void set numTypeParameters(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_numTypeParameters = _value;
}
@@ -1670,7 +1598,6 @@
* member).
*/
void set unit(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_unit = _value;
}
@@ -1691,8 +1618,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_name;
if (_name != null) {
offset_name = fbBuilder.writeString(_name);
@@ -1817,8 +1742,6 @@
}
class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.LinkedUnit {
- bool _finished = false;
-
List<int> _constCycles;
List<LinkedReferenceBuilder> _references;
List<EntityRefBuilder> _types;
@@ -1831,7 +1754,6 @@
* corresponding to const constructors that are part of cycles.
*/
void set constCycles(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_constCycles = _value;
}
@@ -1848,7 +1770,6 @@
* (e.g. elements involved in inferred or propagated types).
*/
void set references(List<LinkedReferenceBuilder> _value) {
- assert(!_finished);
_references = _value;
}
@@ -1860,7 +1781,6 @@
* compilation unit with propagated and inferred types.
*/
void set types(List<EntityRefBuilder> _value) {
- assert(!_finished);
_types = _value;
}
@@ -1878,8 +1798,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_constCycles;
fb.Offset offset_references;
fb.Offset offset_types;
@@ -1964,8 +1882,6 @@
}
class PackageBundleBuilder extends Object with _PackageBundleMixin implements idl.PackageBundle {
- bool _finished = false;
-
List<LinkedLibraryBuilder> _linkedLibraries;
List<String> _linkedLibraryUris;
int _majorVersion;
@@ -1981,7 +1897,6 @@
* Linked libraries.
*/
void set linkedLibraries(List<LinkedLibraryBuilder> _value) {
- assert(!_finished);
_linkedLibraries = _value;
}
@@ -1993,7 +1908,6 @@
* `package:foo/bar.dart`.
*/
void set linkedLibraryUris(List<String> _value) {
- assert(!_finished);
_linkedLibraryUris = _value;
}
@@ -2005,7 +1919,6 @@
* [PackageBundleAssembler.currentMajorVersion].
*/
void set majorVersion(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_majorVersion = _value;
}
@@ -2018,7 +1931,6 @@
* [PackageBundleAssembler.currentMinorVersion].
*/
void set minorVersion(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_minorVersion = _value;
}
@@ -2031,7 +1943,6 @@
* is encoded as a hexadecimal string using lower case letters.
*/
void set unlinkedUnitHashes(List<String> _value) {
- assert(!_finished);
_unlinkedUnitHashes = _value;
}
@@ -2042,7 +1953,6 @@
* Unlinked information for the compilation units constituting the package.
*/
void set unlinkedUnits(List<UnlinkedUnitBuilder> _value) {
- assert(!_finished);
_unlinkedUnits = _value;
}
@@ -2053,7 +1963,6 @@
* The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
*/
void set unlinkedUnitUris(List<String> _value) {
- assert(!_finished);
_unlinkedUnitUris = _value;
}
@@ -2081,8 +1990,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_linkedLibraries;
fb.Offset offset_linkedLibraryUris;
fb.Offset offset_unlinkedUnitHashes;
@@ -2228,8 +2135,6 @@
}
class PackageIndexBuilder extends Object with _PackageIndexMixin implements idl.PackageIndex {
- bool _finished = false;
-
List<idl.IndexSyntheticElementKind> _elementKinds;
List<int> _elementOffsets;
List<int> _elementUnits;
@@ -2246,7 +2151,6 @@
* the kind of the synthetic element.
*/
void set elementKinds(List<idl.IndexSyntheticElementKind> _value) {
- assert(!_finished);
_elementKinds = _value;
}
@@ -2260,7 +2164,6 @@
* whether an element is referenced in this [PackageIndex].
*/
void set elementOffsets(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_elementOffsets = _value;
}
@@ -2274,7 +2177,6 @@
* specific unit where the element is declared.
*/
void set elementUnits(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_elementUnits = _value;
}
@@ -2288,7 +2190,6 @@
* presence of a string in this [PackageIndex].
*/
void set strings(List<String> _value) {
- assert(!_finished);
_strings = _value;
}
@@ -2301,7 +2202,6 @@
* [strings] list.
*/
void set unitLibraryUris(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_unitLibraryUris = _value;
}
@@ -2313,7 +2213,6 @@
* List of indexes of each unit in this [PackageIndex].
*/
void set units(List<UnitIndexBuilder> _value) {
- assert(!_finished);
_units = _value;
}
@@ -2326,7 +2225,6 @@
* [strings] list.
*/
void set unitUnitUris(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_unitUnitUris = _value;
}
@@ -2353,8 +2251,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_elementKinds;
fb.Offset offset_elementOffsets;
fb.Offset offset_elementUnits;
@@ -2508,8 +2404,6 @@
}
class UnitIndexBuilder extends Object with _UnitIndexMixin implements idl.UnitIndex {
- bool _finished = false;
-
List<idl.IndexNameKind> _definedNameKinds;
List<int> _definedNameOffsets;
List<int> _definedNames;
@@ -2531,7 +2425,6 @@
* Each item of this list is the kind of an element defined in this unit.
*/
void set definedNameKinds(List<idl.IndexNameKind> _value) {
- assert(!_finished);
_definedNameKinds = _value;
}
@@ -2543,7 +2436,6 @@
* unit relative to the beginning of the file.
*/
void set definedNameOffsets(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_definedNameOffsets = _value;
}
@@ -2558,7 +2450,6 @@
* this [UnitIndex].
*/
void set definedNames(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_definedNames = _value;
}
@@ -2571,7 +2462,6 @@
* for the library specific unit that corresponds to this [UnitIndex].
*/
void set unit(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_unit = _value;
}
@@ -2584,7 +2474,6 @@
* is qualified with some prefix.
*/
void set usedElementIsQualifiedFlags(List<bool> _value) {
- assert(!_finished);
_usedElementIsQualifiedFlags = _value;
}
@@ -2595,7 +2484,6 @@
* Each item of this list is the kind of the element usage.
*/
void set usedElementKinds(List<idl.IndexRelationKind> _value) {
- assert(!_finished);
_usedElementKinds = _value;
}
@@ -2606,7 +2494,6 @@
* Each item of this list is the length of the element usage.
*/
void set usedElementLengths(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_usedElementLengths = _value;
}
@@ -2619,7 +2506,6 @@
* beginning of the file.
*/
void set usedElementOffsets(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_usedElementOffsets = _value;
}
@@ -2633,7 +2519,6 @@
* that the client can quickly find element references in this [UnitIndex].
*/
void set usedElements(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_usedElements = _value;
}
@@ -2646,7 +2531,6 @@
* is qualified with some prefix.
*/
void set usedNameIsQualifiedFlags(List<bool> _value) {
- assert(!_finished);
_usedNameIsQualifiedFlags = _value;
}
@@ -2657,7 +2541,6 @@
* Each item of this list is the kind of the name usage.
*/
void set usedNameKinds(List<idl.IndexRelationKind> _value) {
- assert(!_finished);
_usedNameKinds = _value;
}
@@ -2669,7 +2552,6 @@
* beginning of the file.
*/
void set usedNameOffsets(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_usedNameOffsets = _value;
}
@@ -2683,7 +2565,6 @@
* quickly find name uses in this [UnitIndex].
*/
void set usedNames(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_usedNames = _value;
}
@@ -2710,8 +2591,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_definedNameKinds;
fb.Offset offset_definedNameOffsets;
fb.Offset offset_definedNames;
@@ -2952,8 +2831,6 @@
}
class UnlinkedClassBuilder extends Object with _UnlinkedClassMixin implements idl.UnlinkedClass {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
CodeRangeBuilder _codeRange;
UnlinkedDocumentationCommentBuilder _documentationComment;
@@ -2976,7 +2853,6 @@
* Annotations for this class.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -2987,7 +2863,6 @@
* Code range of the class.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -2999,7 +2874,6 @@
* documentation comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -3010,7 +2884,6 @@
* Executable objects (methods, getters, and setters) contained in the class.
*/
void set executables(List<UnlinkedExecutableBuilder> _value) {
- assert(!_finished);
_executables = _value;
}
@@ -3021,7 +2894,6 @@
* Field declarations contained in the class.
*/
void set fields(List<UnlinkedVariableBuilder> _value) {
- assert(!_finished);
_fields = _value;
}
@@ -3033,7 +2905,6 @@
* supertype)
*/
void set hasNoSupertype(bool _value) {
- assert(!_finished);
_hasNoSupertype = _value;
}
@@ -3044,7 +2915,6 @@
* Interfaces appearing in an `implements` clause, if any.
*/
void set interfaces(List<EntityRefBuilder> _value) {
- assert(!_finished);
_interfaces = _value;
}
@@ -3055,7 +2925,6 @@
* Indicates whether the class is declared with the `abstract` keyword.
*/
void set isAbstract(bool _value) {
- assert(!_finished);
_isAbstract = _value;
}
@@ -3066,7 +2935,6 @@
* Indicates whether the class is declared using mixin application syntax.
*/
void set isMixinApplication(bool _value) {
- assert(!_finished);
_isMixinApplication = _value;
}
@@ -3077,7 +2945,6 @@
* Mixins appearing in a `with` clause, if any.
*/
void set mixins(List<EntityRefBuilder> _value) {
- assert(!_finished);
_mixins = _value;
}
@@ -3088,7 +2955,6 @@
* Name of the class.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -3099,7 +2965,6 @@
* Offset of the class name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -3113,7 +2978,6 @@
* the class *is* `Object` (and hence has no supertype).
*/
void set supertype(EntityRefBuilder _value) {
- assert(!_finished);
_supertype = _value;
}
@@ -3124,7 +2988,6 @@
* Type parameters of the class, if any.
*/
void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
- assert(!_finished);
_typeParameters = _value;
}
@@ -3161,8 +3024,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_codeRange;
fb.Offset offset_documentationComment;
@@ -3407,8 +3268,6 @@
}
class UnlinkedCombinatorBuilder extends Object with _UnlinkedCombinatorMixin implements idl.UnlinkedCombinator {
- bool _finished = false;
-
int _end;
List<String> _hides;
int _offset;
@@ -3422,7 +3281,6 @@
* names. Otherwise zero.
*/
void set end(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_end = _value;
}
@@ -3434,7 +3292,6 @@
* List of names which are hidden. Empty if this is a `show` combinator.
*/
void set hides(List<String> _value) {
- assert(!_finished);
_hides = _value;
}
@@ -3446,7 +3303,6 @@
* zero.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -3458,7 +3314,6 @@
* List of names which are shown. Empty if this is a `hide` combinator.
*/
void set shows(List<String> _value) {
- assert(!_finished);
_shows = _value;
}
@@ -3477,8 +3332,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_hides;
fb.Offset offset_shows;
if (!(_hides == null || _hides.isEmpty)) {
@@ -3571,8 +3424,6 @@
}
class UnlinkedConstBuilder extends Object with _UnlinkedConstMixin implements idl.UnlinkedConst {
- bool _finished = false;
-
List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
List<double> _doubles;
List<int> _ints;
@@ -3588,7 +3439,6 @@
* Sequence of operators used by assignment operations.
*/
void set assignmentOperators(List<idl.UnlinkedExprAssignOperator> _value) {
- assert(!_finished);
_assignmentOperators = _value;
}
@@ -3599,7 +3449,6 @@
* Sequence of 64-bit doubles consumed by the operation `pushDouble`.
*/
void set doubles(List<double> _value) {
- assert(!_finished);
_doubles = _value;
}
@@ -3612,7 +3461,6 @@
* `makeList`, and `makeMap`.
*/
void set ints(List<int> _value) {
- assert(!_finished);
assert(_value == null || _value.every((e) => e >= 0));
_ints = _value;
}
@@ -3625,7 +3473,6 @@
* expression.
*/
void set isValidConst(bool _value) {
- assert(!_finished);
_isValidConst = _value;
}
@@ -3637,7 +3484,6 @@
* the constant value.
*/
void set operations(List<idl.UnlinkedConstOperation> _value) {
- assert(!_finished);
_operations = _value;
}
@@ -3651,7 +3497,6 @@
* actual entity being referred to may be something other than a type.
*/
void set references(List<EntityRefBuilder> _value) {
- assert(!_finished);
_references = _value;
}
@@ -3663,7 +3508,6 @@
* `invokeConstructor`.
*/
void set strings(List<String> _value) {
- assert(!_finished);
_strings = _value;
}
@@ -3684,8 +3528,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_assignmentOperators;
fb.Offset offset_doubles;
fb.Offset offset_ints;
@@ -3830,8 +3672,6 @@
}
class UnlinkedConstructorInitializerBuilder extends Object with _UnlinkedConstructorInitializerMixin implements idl.UnlinkedConstructorInitializer {
- bool _finished = false;
-
List<String> _argumentNames;
List<UnlinkedConstBuilder> _arguments;
UnlinkedConstBuilder _expression;
@@ -3847,7 +3687,6 @@
* with the name at `n + i - m`.
*/
void set argumentNames(List<String> _value) {
- assert(!_finished);
_argumentNames = _value;
}
@@ -3859,7 +3698,6 @@
* invocation. Otherwise empty.
*/
void set arguments(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_arguments = _value;
}
@@ -3871,7 +3709,6 @@
* Otherwise `null`.
*/
void set expression(UnlinkedConstBuilder _value) {
- assert(!_finished);
_expression = _value;
}
@@ -3882,7 +3719,6 @@
* The kind of the constructor initializer (field, redirect, super).
*/
void set kind(idl.UnlinkedConstructorInitializerKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -3896,7 +3732,6 @@
* constructor, declared in the superclass, to invoke.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -3916,8 +3751,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_argumentNames;
fb.Offset offset_arguments;
fb.Offset offset_expression;
@@ -4030,8 +3863,6 @@
}
class UnlinkedDocumentationCommentBuilder extends Object with _UnlinkedDocumentationCommentMixin implements idl.UnlinkedDocumentationComment {
- bool _finished = false;
-
int _length;
int _offset;
String _text;
@@ -4043,7 +3874,6 @@
* Length of the documentation comment (prior to replacing '\r\n' with '\n').
*/
void set length(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_length = _value;
}
@@ -4056,7 +3886,6 @@
* beginning of the file.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -4071,7 +3900,6 @@
* specially encoded.
*/
void set text(String _value) {
- assert(!_finished);
_text = _value;
}
@@ -4087,8 +3915,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_text;
if (_text != null) {
offset_text = fbBuilder.writeString(_text);
@@ -4165,8 +3991,6 @@
}
class UnlinkedEnumBuilder extends Object with _UnlinkedEnumMixin implements idl.UnlinkedEnum {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
CodeRangeBuilder _codeRange;
UnlinkedDocumentationCommentBuilder _documentationComment;
@@ -4181,7 +4005,6 @@
* Annotations for this enum.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -4192,7 +4015,6 @@
* Code range of the enum.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -4204,7 +4026,6 @@
* comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -4215,7 +4036,6 @@
* Name of the enum type.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -4226,7 +4046,6 @@
* Offset of the enum name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -4238,7 +4057,6 @@
* Values listed in the enum declaration, in declaration order.
*/
void set values(List<UnlinkedEnumValueBuilder> _value) {
- assert(!_finished);
_values = _value;
}
@@ -4262,8 +4080,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_codeRange;
fb.Offset offset_documentationComment;
@@ -4392,8 +4208,6 @@
}
class UnlinkedEnumValueBuilder extends Object with _UnlinkedEnumValueMixin implements idl.UnlinkedEnumValue {
- bool _finished = false;
-
UnlinkedDocumentationCommentBuilder _documentationComment;
String _name;
int _nameOffset;
@@ -4406,7 +4220,6 @@
* documentation comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -4417,7 +4230,6 @@
* Name of the enumerated value.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -4428,7 +4240,6 @@
* Offset of the enum value name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -4447,8 +4258,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_documentationComment;
fb.Offset offset_name;
if (_documentationComment != null) {
@@ -4529,8 +4338,6 @@
}
class UnlinkedExecutableBuilder extends Object with _UnlinkedExecutableMixin implements idl.UnlinkedExecutable {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
UnlinkedConstBuilder _bodyExpr;
CodeRangeBuilder _codeRange;
@@ -4569,7 +4376,6 @@
* Annotations for this executable.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -4582,7 +4388,6 @@
* constant evaluation depends on the function body.
*/
void set bodyExpr(UnlinkedConstBuilder _value) {
- assert(!_finished);
_bodyExpr = _value;
}
@@ -4593,7 +4398,6 @@
* Code range of the executable.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -4605,7 +4409,6 @@
* initializers. Otherwise empty.
*/
void set constantInitializers(List<UnlinkedConstructorInitializerBuilder> _value) {
- assert(!_finished);
_constantInitializers = _value;
}
@@ -4621,7 +4424,6 @@
* Otherwise, zero.
*/
void set constCycleSlot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_constCycleSlot = _value;
}
@@ -4634,7 +4436,6 @@
* documentation comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -4649,7 +4450,6 @@
* `dynamic`.
*/
void set inferredReturnTypeSlot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_inferredReturnTypeSlot = _value;
}
@@ -4661,7 +4461,6 @@
* Indicates whether the executable is declared using the `abstract` keyword.
*/
void set isAbstract(bool _value) {
- assert(!_finished);
_isAbstract = _value;
}
@@ -4672,7 +4471,6 @@
* Indicates whether the executable has body marked as being asynchronous.
*/
void set isAsynchronous(bool _value) {
- assert(!_finished);
_isAsynchronous = _value;
}
@@ -4683,7 +4481,6 @@
* Indicates whether the executable is declared using the `const` keyword.
*/
void set isConst(bool _value) {
- assert(!_finished);
_isConst = _value;
}
@@ -4694,7 +4491,6 @@
* Indicates whether the executable is declared using the `external` keyword.
*/
void set isExternal(bool _value) {
- assert(!_finished);
_isExternal = _value;
}
@@ -4705,7 +4501,6 @@
* Indicates whether the executable is declared using the `factory` keyword.
*/
void set isFactory(bool _value) {
- assert(!_finished);
_isFactory = _value;
}
@@ -4716,7 +4511,6 @@
* Indicates whether the executable has body marked as being a generator.
*/
void set isGenerator(bool _value) {
- assert(!_finished);
_isGenerator = _value;
}
@@ -4727,7 +4521,6 @@
* Indicates whether the executable is a redirected constructor.
*/
void set isRedirectedConstructor(bool _value) {
- assert(!_finished);
_isRedirectedConstructor = _value;
}
@@ -4742,7 +4535,6 @@
* static for semantic purposes).
*/
void set isStatic(bool _value) {
- assert(!_finished);
_isStatic = _value;
}
@@ -4754,7 +4546,6 @@
* constructor).
*/
void set kind(idl.UnlinkedExecutableKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -4765,7 +4556,6 @@
* The list of local functions.
*/
void set localFunctions(List<UnlinkedExecutableBuilder> _value) {
- assert(!_finished);
_localFunctions = _value;
}
@@ -4776,7 +4566,6 @@
* The list of local labels.
*/
void set localLabels(List<UnlinkedLabelBuilder> _value) {
- assert(!_finished);
_localLabels = _value;
}
@@ -4787,7 +4576,6 @@
* The list of local variables.
*/
void set localVariables(List<UnlinkedVariableBuilder> _value) {
- assert(!_finished);
_localVariables = _value;
}
@@ -4800,7 +4588,6 @@
* For unnamed constructors, this is the empty string.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -4812,7 +4599,6 @@
* the offset of the end of the constructor name. Otherwise zero.
*/
void set nameEnd(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameEnd = _value;
}
@@ -4827,7 +4613,6 @@
* offset of the second "C" in "class C { C(); }").
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -4841,7 +4626,6 @@
* parameter.
*/
void set parameters(List<UnlinkedParamBuilder> _value) {
- assert(!_finished);
_parameters = _value;
}
@@ -4853,7 +4637,6 @@
* the offset of the period before the constructor name. Otherwise zero.
*/
void set periodOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_periodOffset = _value;
}
@@ -4866,7 +4649,6 @@
* constructor to which this constructor redirects; otherwise empty.
*/
void set redirectedConstructor(EntityRefBuilder _value) {
- assert(!_finished);
_redirectedConstructor = _value;
}
@@ -4879,7 +4661,6 @@
* empty.
*/
void set redirectedConstructorName(String _value) {
- assert(!_finished);
_redirectedConstructorName = _value;
}
@@ -4894,7 +4675,6 @@
* imports.
*/
void set returnType(EntityRefBuilder _value) {
- assert(!_finished);
_returnType = _value;
}
@@ -4906,7 +4686,6 @@
* method syntax is disabled.
*/
void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
- assert(!_finished);
_typeParameters = _value;
}
@@ -4917,7 +4696,6 @@
* If a local function, the length of the visible range; zero otherwise.
*/
void set visibleLength(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleLength = _value;
}
@@ -4929,7 +4707,6 @@
* If a local function, the beginning of the visible range; zero otherwise.
*/
void set visibleOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleOffset = _value;
}
@@ -4990,8 +4767,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_bodyExpr;
fb.Offset offset_codeRange;
@@ -5444,8 +5219,6 @@
}
class UnlinkedExportNonPublicBuilder extends Object with _UnlinkedExportNonPublicMixin implements idl.UnlinkedExportNonPublic {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
int _offset;
int _uriEnd;
@@ -5458,7 +5231,6 @@
* Annotations for this export directive.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -5469,7 +5241,6 @@
* Offset of the "export" keyword.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -5482,7 +5253,6 @@
* file.
*/
void set uriEnd(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriEnd = _value;
}
@@ -5495,7 +5265,6 @@
* the file.
*/
void set uriOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriOffset = _value;
}
@@ -5517,8 +5286,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
if (!(_annotations == null || _annotations.isEmpty)) {
offset_annotations = fbBuilder.writeList(_annotations.map((b) => b.finish(fbBuilder)).toList());
@@ -5607,8 +5374,6 @@
}
class UnlinkedExportPublicBuilder extends Object with _UnlinkedExportPublicMixin implements idl.UnlinkedExportPublic {
- bool _finished = false;
-
List<UnlinkedCombinatorBuilder> _combinators;
String _uri;
@@ -5619,7 +5384,6 @@
* Combinators contained in this import declaration.
*/
void set combinators(List<UnlinkedCombinatorBuilder> _value) {
- assert(!_finished);
_combinators = _value;
}
@@ -5630,7 +5394,6 @@
* URI used in the source code to reference the exported library.
*/
void set uri(String _value) {
- assert(!_finished);
_uri = _value;
}
@@ -5646,8 +5409,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_combinators;
fb.Offset offset_uri;
if (!(_combinators == null || _combinators.isEmpty)) {
@@ -5716,8 +5477,6 @@
}
class UnlinkedImportBuilder extends Object with _UnlinkedImportMixin implements idl.UnlinkedImport {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
List<UnlinkedCombinatorBuilder> _combinators;
bool _isDeferred;
@@ -5736,7 +5495,6 @@
* Annotations for this import declaration.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -5747,7 +5505,6 @@
* Combinators contained in this import declaration.
*/
void set combinators(List<UnlinkedCombinatorBuilder> _value) {
- assert(!_finished);
_combinators = _value;
}
@@ -5758,7 +5515,6 @@
* Indicates whether the import declaration uses the `deferred` keyword.
*/
void set isDeferred(bool _value) {
- assert(!_finished);
_isDeferred = _value;
}
@@ -5769,7 +5525,6 @@
* Indicates whether the import declaration is implicit.
*/
void set isImplicit(bool _value) {
- assert(!_finished);
_isImplicit = _value;
}
@@ -5781,7 +5536,6 @@
* is true, zero.
*/
void set offset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_offset = _value;
}
@@ -5794,7 +5548,6 @@
* if there is no prefix.
*/
void set prefixOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_prefixOffset = _value;
}
@@ -5809,7 +5562,6 @@
* Note that multiple imports can declare the same prefix.
*/
void set prefixReference(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_prefixReference = _value;
}
@@ -5821,7 +5573,6 @@
* URI used in the source code to reference the imported library.
*/
void set uri(String _value) {
- assert(!_finished);
_uri = _value;
}
@@ -5833,7 +5584,6 @@
* file. If [isImplicit] is true, zero.
*/
void set uriEnd(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriEnd = _value;
}
@@ -5846,7 +5596,6 @@
* the file. If [isImplicit] is true, zero.
*/
void set uriOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriOffset = _value;
}
@@ -5876,8 +5625,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_combinators;
fb.Offset offset_uri;
@@ -6046,8 +5793,6 @@
}
class UnlinkedLabelBuilder extends Object with _UnlinkedLabelMixin implements idl.UnlinkedLabel {
- bool _finished = false;
-
bool _isOnSwitchMember;
bool _isOnSwitchStatement;
String _name;
@@ -6061,7 +5806,6 @@
* `default`).
*/
void set isOnSwitchMember(bool _value) {
- assert(!_finished);
_isOnSwitchMember = _value;
}
@@ -6072,7 +5816,6 @@
* Return `true` if this label is associated with a `switch` statement.
*/
void set isOnSwitchStatement(bool _value) {
- assert(!_finished);
_isOnSwitchStatement = _value;
}
@@ -6083,7 +5826,6 @@
* Name of the label.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -6094,7 +5836,6 @@
* Offset of the label relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -6113,8 +5854,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_name;
if (_name != null) {
offset_name = fbBuilder.writeString(_name);
@@ -6203,8 +5942,6 @@
}
class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements idl.UnlinkedParam {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
CodeRangeBuilder _codeRange;
String _defaultValueCode;
@@ -6227,7 +5964,6 @@
* Annotations for this parameter.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -6238,7 +5974,6 @@
* Code range of the parameter.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -6250,7 +5985,6 @@
* expression in the default value. Otherwise the empty string.
*/
void set defaultValueCode(String _value) {
- assert(!_finished);
_defaultValueCode = _value;
}
@@ -6269,7 +6003,6 @@
* field.
*/
void set inferredTypeSlot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_inferredTypeSlot = _value;
}
@@ -6282,7 +6015,6 @@
* does not have an initializer.
*/
void set initializer(UnlinkedExecutableBuilder _value) {
- assert(!_finished);
_initializer = _value;
}
@@ -6293,7 +6025,6 @@
* Indicates whether this is a function-typed parameter.
*/
void set isFunctionTyped(bool _value) {
- assert(!_finished);
_isFunctionTyped = _value;
}
@@ -6305,7 +6036,6 @@
* declared using `this.` syntax).
*/
void set isInitializingFormal(bool _value) {
- assert(!_finished);
_isInitializingFormal = _value;
}
@@ -6316,7 +6046,6 @@
* Kind of the parameter.
*/
void set kind(idl.UnlinkedParamKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -6327,7 +6056,6 @@
* Name of the parameter.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -6338,7 +6066,6 @@
* Offset of the parameter name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -6350,7 +6077,6 @@
* If [isFunctionTyped] is `true`, the parameters of the function type.
*/
void set parameters(List<UnlinkedParamBuilder> _value) {
- assert(!_finished);
_parameters = _value;
}
@@ -6363,7 +6089,6 @@
* implicit.
*/
void set type(EntityRefBuilder _value) {
- assert(!_finished);
_type = _value;
}
@@ -6374,7 +6099,6 @@
* The length of the visible range.
*/
void set visibleLength(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleLength = _value;
}
@@ -6386,7 +6110,6 @@
* The beginning of the visible range.
*/
void set visibleOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleOffset = _value;
}
@@ -6421,8 +6144,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_codeRange;
fb.Offset offset_defaultValueCode;
@@ -6655,8 +6376,6 @@
}
class UnlinkedPartBuilder extends Object with _UnlinkedPartMixin implements idl.UnlinkedPart {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
int _uriEnd;
int _uriOffset;
@@ -6668,7 +6387,6 @@
* Annotations for this part declaration.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -6680,7 +6398,6 @@
* file.
*/
void set uriEnd(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriEnd = _value;
}
@@ -6693,7 +6410,6 @@
* the file.
*/
void set uriOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_uriOffset = _value;
}
@@ -6713,8 +6429,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
if (!(_annotations == null || _annotations.isEmpty)) {
offset_annotations = fbBuilder.writeList(_annotations.map((b) => b.finish(fbBuilder)).toList());
@@ -6791,8 +6505,6 @@
}
class UnlinkedPublicNameBuilder extends Object with _UnlinkedPublicNameMixin implements idl.UnlinkedPublicName {
- bool _finished = false;
-
idl.ReferenceKind _kind;
List<UnlinkedPublicNameBuilder> _members;
String _name;
@@ -6805,7 +6517,6 @@
* The kind of object referred to by the name.
*/
void set kind(idl.ReferenceKind _value) {
- assert(!_finished);
_kind = _value;
}
@@ -6821,7 +6532,6 @@
* separate name added to any namespace.
*/
void set members(List<UnlinkedPublicNameBuilder> _value) {
- assert(!_finished);
_members = _value;
}
@@ -6832,7 +6542,6 @@
* The name itself.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -6844,7 +6553,6 @@
* it accepts. Otherwise zero.
*/
void set numTypeParameters(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_numTypeParameters = _value;
}
@@ -6863,8 +6571,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_members;
fb.Offset offset_name;
if (!(_members == null || _members.isEmpty)) {
@@ -6957,8 +6663,6 @@
}
class UnlinkedPublicNamespaceBuilder extends Object with _UnlinkedPublicNamespaceMixin implements idl.UnlinkedPublicNamespace {
- bool _finished = false;
-
List<UnlinkedExportPublicBuilder> _exports;
List<UnlinkedPublicNameBuilder> _names;
List<String> _parts;
@@ -6970,7 +6674,6 @@
* Export declarations in the compilation unit.
*/
void set exports(List<UnlinkedExportPublicBuilder> _value) {
- assert(!_finished);
_exports = _value;
}
@@ -6984,7 +6687,6 @@
* relinking.
*/
void set names(List<UnlinkedPublicNameBuilder> _value) {
- assert(!_finished);
_names = _value;
}
@@ -6995,7 +6697,6 @@
* URIs referenced by part declarations in the compilation unit.
*/
void set parts(List<String> _value) {
- assert(!_finished);
_parts = _value;
}
@@ -7018,8 +6719,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_exports;
fb.Offset offset_names;
fb.Offset offset_parts;
@@ -7109,8 +6808,6 @@
}
class UnlinkedReferenceBuilder extends Object with _UnlinkedReferenceMixin implements idl.UnlinkedReference {
- bool _finished = false;
-
String _name;
int _prefixReference;
@@ -7123,7 +6820,6 @@
* For the pseudo-type `bottom`, the string is "*bottom*".
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -7139,7 +6835,6 @@
* UnlinkedUnit.references[i].prefixReference < i.
*/
void set prefixReference(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_prefixReference = _value;
}
@@ -7155,8 +6850,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_name;
if (_name != null) {
offset_name = fbBuilder.writeString(_name);
@@ -7221,8 +6914,6 @@
}
class UnlinkedTypedefBuilder extends Object with _UnlinkedTypedefMixin implements idl.UnlinkedTypedef {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
CodeRangeBuilder _codeRange;
UnlinkedDocumentationCommentBuilder _documentationComment;
@@ -7239,7 +6930,6 @@
* Annotations for this typedef.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -7250,7 +6940,6 @@
* Code range of the typedef.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -7262,7 +6951,6 @@
* documentation comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -7273,7 +6961,6 @@
* Name of the typedef.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -7284,7 +6971,6 @@
* Offset of the typedef name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -7296,7 +6982,6 @@
* Parameters of the executable, if any.
*/
void set parameters(List<UnlinkedParamBuilder> _value) {
- assert(!_finished);
_parameters = _value;
}
@@ -7307,7 +6992,6 @@
* Return type of the typedef.
*/
void set returnType(EntityRefBuilder _value) {
- assert(!_finished);
_returnType = _value;
}
@@ -7318,7 +7002,6 @@
* Type parameters of the typedef, if any.
*/
void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
- assert(!_finished);
_typeParameters = _value;
}
@@ -7346,8 +7029,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_codeRange;
fb.Offset offset_documentationComment;
@@ -7508,8 +7189,6 @@
}
class UnlinkedTypeParamBuilder extends Object with _UnlinkedTypeParamMixin implements idl.UnlinkedTypeParam {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
EntityRefBuilder _bound;
CodeRangeBuilder _codeRange;
@@ -7523,7 +7202,6 @@
* Annotations for this type parameter.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -7535,7 +7213,6 @@
* null.
*/
void set bound(EntityRefBuilder _value) {
- assert(!_finished);
_bound = _value;
}
@@ -7546,7 +7223,6 @@
* Code range of the type parameter.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -7557,7 +7233,6 @@
* Name of the type parameter.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -7568,7 +7243,6 @@
* Offset of the type parameter name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -7591,8 +7265,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_bound;
fb.Offset offset_codeRange;
@@ -7705,8 +7377,6 @@
}
class UnlinkedUnitBuilder extends Object with _UnlinkedUnitMixin implements idl.UnlinkedUnit {
- bool _finished = false;
-
List<UnlinkedClassBuilder> _classes;
CodeRangeBuilder _codeRange;
List<UnlinkedEnumBuilder> _enums;
@@ -7732,7 +7402,6 @@
* Classes declared in the compilation unit.
*/
void set classes(List<UnlinkedClassBuilder> _value) {
- assert(!_finished);
_classes = _value;
}
@@ -7743,7 +7412,6 @@
* Code range of the unit.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -7754,7 +7422,6 @@
* Enums declared in the compilation unit.
*/
void set enums(List<UnlinkedEnumBuilder> _value) {
- assert(!_finished);
_enums = _value;
}
@@ -7766,7 +7433,6 @@
* the compilation unit.
*/
void set executables(List<UnlinkedExecutableBuilder> _value) {
- assert(!_finished);
_executables = _value;
}
@@ -7777,7 +7443,6 @@
* Export declarations in the compilation unit.
*/
void set exports(List<UnlinkedExportNonPublicBuilder> _value) {
- assert(!_finished);
_exports = _value;
}
@@ -7792,7 +7457,6 @@
* their default values.
*/
void set fallbackModePath(String _value) {
- assert(!_finished);
_fallbackModePath = _value;
}
@@ -7803,7 +7467,6 @@
* Import declarations in the compilation unit.
*/
void set imports(List<UnlinkedImportBuilder> _value) {
- assert(!_finished);
_imports = _value;
}
@@ -7815,7 +7478,6 @@
* library declaration.
*/
void set libraryAnnotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_libraryAnnotations = _value;
}
@@ -7827,7 +7489,6 @@
* documentation comment.
*/
void set libraryDocumentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_libraryDocumentationComment = _value;
}
@@ -7838,7 +7499,6 @@
* Name of the library (from a "library" declaration, if present).
*/
void set libraryName(String _value) {
- assert(!_finished);
_libraryName = _value;
}
@@ -7850,7 +7510,6 @@
* library has no name).
*/
void set libraryNameLength(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_libraryNameLength = _value;
}
@@ -7863,7 +7522,6 @@
* the library has no name).
*/
void set libraryNameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_libraryNameOffset = _value;
}
@@ -7875,7 +7533,6 @@
* Part declarations in the compilation unit.
*/
void set parts(List<UnlinkedPartBuilder> _value) {
- assert(!_finished);
_parts = _value;
}
@@ -7886,7 +7543,6 @@
* Unlinked public namespace of this compilation unit.
*/
void set publicNamespace(UnlinkedPublicNamespaceBuilder _value) {
- assert(!_finished);
_publicNamespace = _value;
}
@@ -7901,7 +7557,6 @@
* UnlinkedImport.prefixReference]).
*/
void set references(List<UnlinkedReferenceBuilder> _value) {
- assert(!_finished);
_references = _value;
}
@@ -7912,7 +7567,6 @@
* Typedefs declared in the compilation unit.
*/
void set typedefs(List<UnlinkedTypedefBuilder> _value) {
- assert(!_finished);
_typedefs = _value;
}
@@ -7923,7 +7577,6 @@
* Top level variables declared in the compilation unit.
*/
void set variables(List<UnlinkedVariableBuilder> _value) {
- assert(!_finished);
_variables = _value;
}
@@ -7973,8 +7626,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_classes;
fb.Offset offset_codeRange;
fb.Offset offset_enums;
@@ -8280,8 +7931,6 @@
}
class UnlinkedVariableBuilder extends Object with _UnlinkedVariableMixin implements idl.UnlinkedVariable {
- bool _finished = false;
-
List<UnlinkedConstBuilder> _annotations;
CodeRangeBuilder _codeRange;
UnlinkedDocumentationCommentBuilder _documentationComment;
@@ -8304,7 +7953,6 @@
* Annotations for this variable.
*/
void set annotations(List<UnlinkedConstBuilder> _value) {
- assert(!_finished);
_annotations = _value;
}
@@ -8315,7 +7963,6 @@
* Code range of the variable.
*/
void set codeRange(CodeRangeBuilder _value) {
- assert(!_finished);
_codeRange = _value;
}
@@ -8327,7 +7974,6 @@
* documentation comment.
*/
void set documentationComment(UnlinkedDocumentationCommentBuilder _value) {
- assert(!_finished);
_documentationComment = _value;
}
@@ -8341,7 +7987,6 @@
* inferred for this variable, so its static type is `dynamic`.
*/
void set inferredTypeSlot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_inferredTypeSlot = _value;
}
@@ -8354,7 +7999,6 @@
* does not have an initializer.
*/
void set initializer(UnlinkedExecutableBuilder _value) {
- assert(!_finished);
_initializer = _value;
}
@@ -8365,7 +8009,6 @@
* Indicates whether the variable is declared using the `const` keyword.
*/
void set isConst(bool _value) {
- assert(!_finished);
_isConst = _value;
}
@@ -8376,7 +8019,6 @@
* Indicates whether the variable is declared using the `final` keyword.
*/
void set isFinal(bool _value) {
- assert(!_finished);
_isFinal = _value;
}
@@ -8391,7 +8033,6 @@
* static for semantic purposes).
*/
void set isStatic(bool _value) {
- assert(!_finished);
_isStatic = _value;
}
@@ -8402,7 +8043,6 @@
* Name of the variable.
*/
void set name(String _value) {
- assert(!_finished);
_name = _value;
}
@@ -8413,7 +8053,6 @@
* Offset of the variable name relative to the beginning of the file.
*/
void set nameOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_nameOffset = _value;
}
@@ -8430,7 +8069,6 @@
* Non-propagable variables have a [propagatedTypeSlot] of zero.
*/
void set propagatedTypeSlot(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_propagatedTypeSlot = _value;
}
@@ -8442,7 +8080,6 @@
* Declared type of the variable. Absent if the type is implicit.
*/
void set type(EntityRefBuilder _value) {
- assert(!_finished);
_type = _value;
}
@@ -8453,7 +8090,6 @@
* If a local variable, the length of the visible range; zero otherwise.
*/
void set visibleLength(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleLength = _value;
}
@@ -8465,7 +8101,6 @@
* If a local variable, the beginning of the visible range; zero otherwise.
*/
void set visibleOffset(int _value) {
- assert(!_finished);
assert(_value == null || _value >= 0);
_visibleOffset = _value;
}
@@ -8499,8 +8134,6 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- assert(!_finished);
- _finished = true;
fb.Offset offset_annotations;
fb.Offset offset_codeRange;
fb.Offset offset_documentationComment;
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 21102db..0055866 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -140,7 +140,7 @@
}
AnalysisTarget target = entry.target;
// Check whether there are results for the source.
- if (!hasResultsForSource(target.source)) {
+ if (!hasResultsForSource(target.librarySource ?? target.source)) {
return false;
}
// Constant expressions are always resolved in summaries.
@@ -184,9 +184,6 @@
return false;
}
} else if (target is LibrarySpecificUnit) {
- if (!hasResultsForSource(target.library)) {
- return false;
- }
if (result == CREATED_RESOLVED_UNIT1 ||
result == CREATED_RESOLVED_UNIT2 ||
result == CREATED_RESOLVED_UNIT3 ||
@@ -213,9 +210,6 @@
}
}
} else if (target is VariableElement) {
- if (!hasResultsForSource(target.library.source)) {
- return false;
- }
if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
entry.setValue(result, target, TargetedResult.EMPTY_LIST);
return true;
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 98e3de4..50e1bb6 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -902,10 +902,14 @@
DartType type = parameter.type;
if (parameter.hasImplicitType) {
Element contextParent = context.enclosingElement;
+ // Strong mode infers parameters in two cases:
+ // - instance members (i.e. not constructors or static members),
+ // - parameters with default values, except initializing formals
+ // (the type comes from the field).
if (!parameter.isInitializingFormal &&
contextParent is ExecutableElement &&
- !contextParent.isStatic &&
- contextParent is! ConstructorElement) {
+ (!contextParent.isStatic && contextParent is! ConstructorElement ||
+ parameter.parameterKind != ParameterKind.REQUIRED)) {
b.inferredTypeSlot = storeInferredType(type, context);
}
} else {
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 5d3d3b2..804744a 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -36,6 +36,7 @@
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/src/task/html.dart';
+import 'package:analyzer/src/task/incremental_element_builder.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/src/task/strong/checker.dart';
@@ -392,7 +393,7 @@
*
* Only non-empty in strongMode.
*
- * The result is only available for [LibrarySpecificUnit]s.
+ * The result is only available for [Source]s representing a library.
*/
final ListResultDescriptor<LibraryElement> LIBRARY_CYCLE =
new ListResultDescriptor<LibraryElement>('LIBRARY_CYCLE', null);
@@ -404,7 +405,7 @@
*
* Only non-empty in strongMode.
*
- * The result is only available for [LibrarySpecificUnit]s.
+ * The result is only available for [Source]s representing a library.
*/
final ListResultDescriptor<CompilationUnitElement> LIBRARY_CYCLE_DEPENDENCIES =
new ListResultDescriptor<CompilationUnitElement>(
@@ -417,7 +418,7 @@
*
* Only non-empty in strongMode.
*
- * The result is only available for [LibrarySpecificUnit]s.
+ * The result is only available for [Source]s representing a library.
*/
final ListResultDescriptor<CompilationUnitElement> LIBRARY_CYCLE_UNITS =
new ListResultDescriptor<CompilationUnitElement>(
@@ -438,7 +439,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * In addition to [LIBRARY_ELEMENT1] [LibraryElement.imports] and
+ * In addition to [LIBRARY_ELEMENT1] also [LibraryElement.imports] and
* [LibraryElement.exports] are set.
*
* The result is only available for [Source]s representing a library.
@@ -1384,6 +1385,7 @@
//
// Compute export namespace.
//
+ library.exportNamespace = null;
NamespaceBuilder builder = new NamespaceBuilder();
Namespace namespace = builder.createExportNamespaceForLibrary(library);
library.exportNamespace = namespace;
@@ -1448,7 +1450,8 @@
'BuildLibraryElementTask', createTask, buildInputs, <ResultDescriptor>[
BUILD_LIBRARY_ERRORS,
LIBRARY_ELEMENT1,
- IS_LAUNCHABLE
+ IS_LAUNCHABLE,
+ REFERENCED_NAMES
]);
/**
@@ -1620,12 +1623,19 @@
Directive directive = directivesToResolve[i];
directive.element = libraryElement;
}
+ // Compute referenced names.
+ ReferencedNames referencedNames = new ReferencedNames(librarySource);
+ new ReferencedNamesBuilder(referencedNames).build(definingCompilationUnit);
+ for (CompilationUnit partUnit in partUnits) {
+ new ReferencedNamesBuilder(referencedNames).build(partUnit);
+ }
//
// Record outputs.
//
outputs[BUILD_LIBRARY_ERRORS] = errors;
outputs[LIBRARY_ELEMENT1] = libraryElement;
outputs[IS_LAUNCHABLE] = entryPoint != null;
+ outputs[REFERENCED_NAMES] = referencedNames;
}
/**
@@ -2226,10 +2236,10 @@
* given [target].
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- LibrarySpecificUnit unit = target;
+ Source librarySource = target;
return <String, TaskInput>{
- LIBRARY_ELEMENT_INPUT: LIBRARY_ELEMENT2.of(unit.library),
- 'resolveReachableLibraries': READY_LIBRARY_ELEMENT2.of(unit.library),
+ LIBRARY_ELEMENT_INPUT: LIBRARY_ELEMENT2.of(librarySource),
+ 'resolveReachableLibraries': READY_LIBRARY_ELEMENT2.of(librarySource),
};
}
@@ -2476,36 +2486,162 @@
class DartDelta extends Delta {
bool hasDirectiveChange = false;
- final Set<String> addedNames = new Set<String>();
final Set<String> changedNames = new Set<String>();
- final Set<String> removedNames = new Set<String>();
+ final Map<Source, Set<String>> changedPrivateNames = <Source, Set<String>>{};
- final Set<Source> invalidatedSources = new Set<Source>();
+ final Map<String, ClassElementDelta> changedClasses =
+ <String, ClassElementDelta>{};
- DartDelta(Source source) : super(source) {
- invalidatedSources.add(source);
+ /**
+ * The cache of libraries in which all results are invalid.
+ */
+ final Set<Source> librariesWithInvalidResults = new Set<Source>();
+
+ /**
+ * The cache of libraries in which all results are valid.
+ */
+ final Set<Source> librariesWithValidResults = new Set<Source>();
+
+ DartDelta(Source source) : super(source);
+
+ /**
+ * Add names that are changed in the given [references].
+ */
+ void addChangedElements(ReferencedNames references) {
+ Source refLibrary = references.librarySource;
+ bool hasProgress = true;
+ while (hasProgress) {
+ hasProgress = false;
+ // Classes that extend changed classes are also changed.
+ // If there is a delta for a superclass, use it for the subclass.
+ // Otherwise mark the subclass as "general name change".
+ references.superToSubs.forEach((String superName, Set<String> subNames) {
+ ClassElementDelta superDelta = changedClasses[superName];
+ for (String subName in subNames) {
+ if (superDelta != null) {
+ ClassElementDelta subDelta = changedClasses.putIfAbsent(subName,
+ () => new ClassElementDelta(null, refLibrary, subName));
+ _log(() => '$subName in $refLibrary has delta because of its '
+ 'superclass $superName has delta');
+ if (subDelta.superDeltas.add(superDelta)) {
+ hasProgress = true;
+ }
+ } else if (isChanged(refLibrary, superName)) {
+ if (nameChanged(refLibrary, subName)) {
+ _log(() => '$subName in $refLibrary is changed because its '
+ 'superclass $superName is changed');
+ hasProgress = true;
+ }
+ }
+ }
+ });
+ // If a user element uses a changed top-level element, then the user is
+ // also changed. Note that if a changed class with delta is used, this
+ // does not make the user changed - classes with delta keep their
+ // original elements, so resolution of their names does not change.
+ references.userToDependsOn.forEach((user, dependencies) {
+ for (String dependency in dependencies) {
+ if (isChangedOrClassMember(refLibrary, dependency)) {
+ if (nameChanged(refLibrary, user)) {
+ _log(() => '$user in $refLibrary is changed because '
+ 'of $dependency in $dependencies');
+ hasProgress = true;
+ }
+ }
+ }
+ });
+ }
}
- void elementAdded(Element element) {
- addedNames.add(element.name);
+ void classChanged(ClassElementDelta classDelta) {
+ changedClasses[classDelta.name] = classDelta;
}
void elementChanged(Element element) {
- changedNames.add(element.name);
+ Source librarySource = element.library.source;
+ nameChanged(librarySource, element.name);
}
- void elementRemoved(Element element) {
- removedNames.add(element.name);
+ bool hasAffectedReferences(ReferencedNames references) {
+ Source refLibrary = references.librarySource;
+ // Verify errors must be recomputed when a superclass changes.
+ for (String superName in references.superToSubs.keys) {
+ if (isChangedOrClass(refLibrary, superName)) {
+ _log(() => '$refLibrary is affected because '
+ '${references.superToSubs[superName]} subclasses $superName');
+ return true;
+ }
+ }
+ // Verify errors must be recomputed when an instantiated class changes.
+ for (String name in references.instantiatedNames) {
+ if (isChangedOrClass(refLibrary, name)) {
+ _log(() => '$refLibrary is affected because $name is instantiated');
+ return true;
+ }
+ }
+ // Resolution must be performed when a referenced element changes.
+ for (String name in references.names) {
+ if (isChangedOrClassMember(refLibrary, name)) {
+ _log(() => '$refLibrary is affected by $name');
+ return true;
+ }
+ }
+ return false;
}
- bool isNameAffected(String name) {
- return addedNames.contains(name) ||
- changedNames.contains(name) ||
- removedNames.contains(name);
+ /**
+ * Return `true` if the given [name], used in a unit of the [librarySource],
+ * is affected by a changed top-level element, excluding classes.
+ */
+ bool isChanged(Source librarySource, String name) {
+ if (_isPrivateName(name)) {
+ if (changedPrivateNames[librarySource]?.contains(name) ?? false) {
+ return true;
+ }
+ }
+ return changedNames.contains(name);
}
- bool nameChanged(String name) {
- return changedNames.add(name);
+ /**
+ * Return `true` if the given [name], used in a unit of the [librarySource],
+ * is affected by a changed top-level element or a class.
+ */
+ bool isChangedOrClass(Source librarySource, String name) {
+ if (isChanged(librarySource, name)) {
+ return true;
+ }
+ return changedClasses[name] != null;
+ }
+
+ /**
+ * Return `true` if the given [name], used in a unit of the [librarySource],
+ * is affected by a changed top-level element or a class member.
+ */
+ bool isChangedOrClassMember(Source librarySource, String name) {
+ if (isChanged(librarySource, name)) {
+ return true;
+ }
+ // TODO(scheglov) Optimize this.
+ for (ClassElementDelta classDelta in changedClasses.values) {
+ if (classDelta.hasChanges(librarySource, name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Register the fact that the given [name], defined in the [librarySource]
+ * is changed. Return `true` if the [name] is a new name, not yet registered.
+ */
+ bool nameChanged(Source librarySource, String name) {
+ if (_isPrivateName(name)) {
+ return changedPrivateNames
+ .putIfAbsent(librarySource, () => new Set<String>())
+ .add(name);
+ } else {
+ return changedNames.add(name);
+ }
}
@override
@@ -2515,61 +2651,82 @@
return DeltaResult.INVALIDATE;
}
// Prepare target source.
- Source targetSource = null;
+ Source targetSource = target.source;
+ Source librarySource = target.librarySource;
if (target is Source) {
- targetSource = target;
+ if (context.getKindOf(target) == SourceKind.LIBRARY) {
+ librarySource = target;
+ }
}
- if (target is LibrarySpecificUnit) {
- targetSource = target.library;
+ // We don't know what to do with the given target, invalidate it.
+ if (targetSource == null) {
+ return DeltaResult.INVALIDATE;
}
- if (target is Element) {
- targetSource = target.source;
+ // Keep results that don't change: any library.
+ if (_isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(BuildDirectiveElementsTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(ResolveDirectiveElementsTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(BuildEnumMemberElementsTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(BuildSourceExportClosureTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(ReadyLibraryElement2Task.DESCRIPTOR, descriptor) ||
+ _isTaskResult(ComputeLibraryCycleTask.DESCRIPTOR, descriptor)) {
+ return DeltaResult.KEEP_CONTINUE;
}
- // Keep results that are updated incrementally.
- // If we want to analyze only some references to the source being changed,
- // we need to keep the same instances of CompilationUnitElement and
- // LibraryElement.
+ // Keep results that don't change: changed library.
if (targetSource == source) {
- if (ParseDartTask.DESCRIPTOR.results.contains(descriptor)) {
- return DeltaResult.KEEP_CONTINUE;
- }
- if (BuildCompilationUnitElementTask.DESCRIPTOR.results
- .contains(descriptor)) {
- return DeltaResult.KEEP_CONTINUE;
- }
- if (BuildLibraryElementTask.DESCRIPTOR.results.contains(descriptor)) {
- // Invalidate cached results.
- if (value is LibraryElementImpl) {
- value.exportNamespace = null;
- }
+ if (_isTaskResult(ScanDartTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(ParseDartTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(
+ BuildCompilationUnitElementTask.DESCRIPTOR, descriptor) ||
+ _isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor)) {
return DeltaResult.KEEP_CONTINUE;
}
return DeltaResult.INVALIDATE;
}
- // Use the target library dependency information to decide whether
- // the delta affects the library.
- if (targetSource != null) {
- List<Source> librarySources =
- context.getLibrariesContaining(targetSource);
- int length = librarySources.length;
- for (int i = 0; i < length; i++) {
- Source librarySource = librarySources[i];
- AnalysisCache cache = context.analysisCache;
- ReferencedNames referencedNames =
- cache.getValue(librarySource, REFERENCED_NAMES);
- if (referencedNames == null) {
- return DeltaResult.INVALIDATE;
- }
- referencedNames.addChangedElements(this);
- if (referencedNames.isAffectedBy(this)) {
- return DeltaResult.INVALIDATE;
- }
+ // Keep results that don't change: dependent library.
+ if (targetSource != source) {
+ if (_isTaskResult(BuildPublicNamespaceTask.DESCRIPTOR, descriptor)) {
+ return DeltaResult.KEEP_CONTINUE;
}
+ }
+ // Handle in-library results only for now.
+ if (librarySource != null) {
+ // Use cached library results.
+ if (librariesWithInvalidResults.contains(librarySource)) {
+ return DeltaResult.INVALIDATE;
+ }
+ if (librariesWithValidResults.contains(librarySource)) {
+ return DeltaResult.STOP;
+ }
+ // Compute the library result.
+ ReferencedNames referencedNames =
+ context.getResult(librarySource, REFERENCED_NAMES);
+ if (referencedNames == null) {
+ return DeltaResult.INVALIDATE_NO_DELTA;
+ }
+ addChangedElements(referencedNames);
+ if (hasAffectedReferences(referencedNames)) {
+ librariesWithInvalidResults.add(librarySource);
+ return DeltaResult.INVALIDATE;
+ }
+ librariesWithValidResults.add(librarySource);
return DeltaResult.STOP;
}
// We don't know what to do with the given target, invalidate it.
return DeltaResult.INVALIDATE;
}
+
+ void _log(String getMessage()) {
+// String message = getMessage();
+// print(message);
+ }
+
+ static bool _isPrivateName(String name) => name.startsWith('_');
+
+ static bool _isTaskResult(
+ TaskDescriptor taskDescriptor, ResultDescriptor result) {
+ return taskDescriptor.results.contains(result);
+ }
}
/**
@@ -3270,14 +3427,14 @@
// Require that field re-resolution be complete for all units in the
// current library cycle.
- 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
- 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
@@ -3549,7 +3706,7 @@
// Require that full inference be complete for all dependencies of the
// current library cycle.
- 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
@@ -4050,7 +4207,7 @@
// Require that full inference be complete for all dependencies of the
// current library cycle.
- 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
@@ -4530,39 +4687,45 @@
* with their externally visible dependencies.
*/
class ReferencedNames {
+ final Source librarySource;
+
+ /**
+ * The mapping from the name of a class to the set of names of other classes
+ * that extend, mix-in, or implement it.
+ *
+ * If the set of member of a class is changed, these changes might change
+ * the list of unimplemented inherited members in the class and classes that
+ * extend, mix-in, or implement it. So, we might need to report (or stop
+ * reporting) the corresponding warning.
+ */
+ final Map<String, Set<String>> superToSubs = <String, Set<String>>{};
+
+ /**
+ * The names of instantiated classes.
+ *
+ * If one of these classes changes its set of members, it might change
+ * its list of unimplemented inherited members. So, we might need to report
+ * (or stop reporting) the corresponding warning.
+ */
+ final Set<String> instantiatedNames = new Set<String>();
+
+ /**
+ * The set of names that are referenced by the library, both inside and
+ * outside of method bodies.
+ */
final Set<String> names = new Set<String>();
+
+ /**
+ * The mapping from the name of a top-level element to the set of names that
+ * the element uses in a way that is visible outside of the element, e.g.
+ * the return type, or a parameter type.
+ */
final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
- /**
- * Updates [delta] by adding names that are changed in this library.
- */
- void addChangedElements(DartDelta delta) {
- bool hasProgress = true;
- while (hasProgress) {
- hasProgress = false;
- userToDependsOn.forEach((user, dependencies) {
- for (String dependency in dependencies) {
- if (delta.isNameAffected(dependency)) {
- if (delta.nameChanged(user)) {
- hasProgress = true;
- }
- }
- }
- });
- }
- }
+ ReferencedNames(this.librarySource);
- /**
- * Returns `true` if the library described by this object is affected by
- * the given [delta].
- */
- bool isAffectedBy(DartDelta delta) {
- for (String name in names) {
- if (delta.isNameAffected(name)) {
- return true;
- }
- }
- return false;
+ void addSubclass(String subName, String superName) {
+ superToSubs.putIfAbsent(superName, () => new Set<String>()).add(subName);
}
}
@@ -4570,11 +4733,12 @@
* A builder for creating [ReferencedNames].
*/
class ReferencedNamesBuilder extends GeneralizingAstVisitor {
+ final Set<String> importPrefixNames = new Set<String>();
final ReferencedNames names;
ReferencedNamesScope scope = new ReferencedNamesScope(null);
- int bodyLevel = 0;
+ int localLevel = 0;
Set<String> dependsOn;
ReferencedNamesBuilder(this.names);
@@ -4602,7 +4766,11 @@
scope = new ReferencedNamesScope.forClass(scope, node);
dependsOn = new Set<String>();
super.visitClassDeclaration(node);
- names.userToDependsOn[node.name.name] = dependsOn;
+ String className = node.name.name;
+ names.userToDependsOn[className] = dependsOn;
+ _addSuperName(className, node.extendsClause?.superclass);
+ _addSuperNames(className, node.withClause?.mixinTypes);
+ _addSuperNames(className, node.implementsClause?.interfaces);
} finally {
dependsOn = null;
scope = outerScope;
@@ -4616,7 +4784,11 @@
scope = new ReferencedNamesScope.forClassTypeAlias(scope, node);
dependsOn = new Set<String>();
super.visitClassTypeAlias(node);
- names.userToDependsOn[node.name.name] = dependsOn;
+ String className = node.name.name;
+ names.userToDependsOn[className] = dependsOn;
+ _addSuperName(className, node.superclass);
+ _addSuperNames(className, node.withClause?.mixinTypes);
+ _addSuperNames(className, node.implementsClause?.interfaces);
} finally {
dependsOn = null;
scope = outerScope;
@@ -4624,6 +4796,16 @@
}
@override
+ visitComment(Comment node) {
+ try {
+ localLevel++;
+ super.visitComment(node);
+ } finally {
+ localLevel--;
+ }
+ }
+
+ @override
visitConstructorName(ConstructorName node) {
if (node.parent is! ConstructorDeclaration) {
super.visitConstructorName(node);
@@ -4633,16 +4815,16 @@
@override
visitFunctionBody(FunctionBody node) {
try {
- bodyLevel++;
+ localLevel++;
super.visitFunctionBody(node);
} finally {
- bodyLevel--;
+ localLevel--;
}
}
@override
visitFunctionDeclaration(FunctionDeclaration node) {
- if (bodyLevel == 0) {
+ if (localLevel == 0) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forFunction(scope, node);
@@ -4660,7 +4842,7 @@
@override
visitFunctionTypeAlias(FunctionTypeAlias node) {
- if (bodyLevel == 0) {
+ if (localLevel == 0) {
ReferencedNamesScope outerScope = scope;
try {
scope = new ReferencedNamesScope.forFunctionTypeAlias(scope, node);
@@ -4677,6 +4859,32 @@
}
@override
+ visitImportDirective(ImportDirective node) {
+ if (node.prefix != null) {
+ importPrefixNames.add(node.prefix.name);
+ }
+ super.visitImportDirective(node);
+ }
+
+ @override
+ visitInstanceCreationExpression(InstanceCreationExpression node) {
+ ConstructorName constructorName = node.constructorName;
+ Identifier typeName = constructorName.type.name;
+ if (typeName is SimpleIdentifier) {
+ names.instantiatedNames.add(typeName.name);
+ }
+ if (typeName is PrefixedIdentifier) {
+ String prefixName = typeName.prefix.name;
+ if (importPrefixNames.contains(prefixName)) {
+ names.instantiatedNames.add(typeName.identifier.name);
+ } else {
+ names.instantiatedNames.add(prefixName);
+ }
+ }
+ super.visitInstanceCreationExpression(node);
+ }
+
+ @override
visitMethodDeclaration(MethodDeclaration node) {
ReferencedNamesScope outerScope = scope;
try {
@@ -4701,12 +4909,17 @@
// Prepare name.
String name = node.name;
// Ignore unqualified names shadowed by local elements.
- if (!node.isQualified && scope.contains(name)) {
- return;
+ if (!node.isQualified) {
+ if (scope.contains(name)) {
+ return;
+ }
+ if (importPrefixNames.contains(name)) {
+ return;
+ }
}
// Do add the dependency.
names.names.add(name);
- if (dependsOn != null && bodyLevel == 0) {
+ if (dependsOn != null && localLevel == 0) {
dependsOn.add(name);
}
}
@@ -4727,6 +4940,22 @@
}
dependsOn = null;
}
+
+ void _addSuperName(String className, TypeName type) {
+ if (type != null) {
+ Identifier typeName = type.name;
+ if (typeName is SimpleIdentifier) {
+ names.addSubclass(className, typeName.name);
+ }
+ if (typeName is PrefixedIdentifier) {
+ names.addSubclass(className, typeName.identifier.name);
+ }
+ }
+ }
+
+ void _addSuperNames(String className, List<TypeName> types) {
+ types?.forEach((type) => _addSuperName(className, type));
+ }
}
class ReferencedNamesScope {
@@ -5044,14 +5273,14 @@
// Require that static variable inference be complete for all units in
// the current library cycle.
- 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
- 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
+ 'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
@@ -5080,18 +5309,13 @@
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the list of [RESOLVED_UNIT12] input.
- */
- static const String UNITS_INPUT = 'UNITS_INPUT';
-
- /**
* The task descriptor describing this kind of task.
*/
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'ResolveLibraryReferencesTask',
createTask,
buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT9, REFERENCED_NAMES]);
+ <ResultDescriptor>[LIBRARY_ELEMENT9]);
ResolveLibraryReferencesTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -5102,22 +5326,8 @@
@override
void internalPerform() {
- //
- // Prepare inputs.
- //
LibraryElement library = getRequiredInput(LIBRARY_INPUT);
- List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
- // Compute referenced names.
- ReferencedNames referencedNames = new ReferencedNames();
- int length = units.length;
- for (int i = 0; i < length; i++) {
- new ReferencedNamesBuilder(referencedNames).build(units[i]);
- }
- //
- // Record outputs.
- //
outputs[LIBRARY_ELEMENT9] = library;
- outputs[REFERENCED_NAMES] = referencedNames;
}
/**
@@ -5129,7 +5339,8 @@
Source source = target;
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
- UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT12),
+ 'resolvedUnits':
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT12),
};
}
@@ -5527,7 +5738,7 @@
// Require that inference be complete for all units in the
// current library cycle.
- 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
+ 'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
(CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 0478bdb..b56c4b4 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -74,6 +74,9 @@
bool get isInSystemLibrary => source.isInSystemLibrary;
@override
+ Source get librarySource => source;
+
+ @override
int get modificationStamp => source.modificationStamp;
@override
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 20c6a76..9bc30f8 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -21,7 +21,11 @@
* The change of a single [ClassElement].
*/
class ClassElementDelta {
- final ClassElement element;
+ final ClassElement _element;
+ final Source librarySource;
+ final String name;
+
+ final Set<ClassElementDelta> superDeltas = new Set<ClassElementDelta>();
final List<PropertyAccessorElement> addedAccessors =
<PropertyAccessorElement>[];
@@ -34,7 +38,27 @@
final List<MethodElement> addedMethods = <MethodElement>[];
final List<MethodElement> removedMethods = <MethodElement>[];
- ClassElementDelta(this.element);
+ ClassElementDelta(this._element, this.librarySource, this.name);
+
+ /**
+ * Return `true` if this delta has changes to the [name] visible in the
+ * given [librarySource].
+ */
+ bool hasChanges(Source librarySource, String name) {
+ if (Identifier.isPrivateName(name) && librarySource != this.librarySource) {
+ return false;
+ }
+ return _hasElementWithName(addedAccessors, name) ||
+ _hasElementWithName(removedAccessors, name) ||
+ _hasElementWithName(addedConstructors, name) ||
+ _hasElementWithName(removedConstructors, name) ||
+ _hasElementWithName(addedMethods, name) ||
+ _hasElementWithName(removedMethods, name);
+ }
+
+ static bool _hasElementWithName(List<Element> elements, String name) {
+ return elements.any((e) => e.displayName == name);
+ }
}
/**
@@ -57,9 +81,10 @@
final List<Element> removedDeclarations = <Element>[];
/**
- * The list of changed class elements.
+ * The map from names of changed classes to the change deltas.
*/
- final List<ClassElementDelta> classDeltas = <ClassElementDelta>[];
+ final Map<String, ClassElementDelta> classDeltas =
+ <String, ClassElementDelta>{};
}
/**
@@ -128,8 +153,19 @@
ClassElementDelta _processClassMembers(
ClassDeclaration oldClass, ClassDeclaration newClass) {
- // TODO(scheglov) Compare class structure: type parameters, supertype,
- // mixins and interfaces.
+ // If the class hierarchy or type parameters are changed,
+ // then the class changed too much - don't compute the delta.
+ if (TokenUtils.getFullCode(newClass.typeParameters) !=
+ TokenUtils.getFullCode(oldClass.typeParameters) ||
+ TokenUtils.getFullCode(newClass.extendsClause) !=
+ TokenUtils.getFullCode(oldClass.extendsClause) ||
+ TokenUtils.getFullCode(newClass.withClause) !=
+ TokenUtils.getFullCode(oldClass.withClause) ||
+ TokenUtils.getFullCode(newClass.implementsClause) !=
+ TokenUtils.getFullCode(oldClass.implementsClause)) {
+ return null;
+ }
+ // Build the old class members map.
Map<String, ClassMember> oldNodeMap = new HashMap<String, ClassMember>();
for (ClassMember oldNode in oldClass.members) {
String code = TokenUtils.getFullCode(oldNode);
@@ -141,12 +177,15 @@
// Use the old element for the new node.
newClass.name.staticElement = oldElement;
if (newElement is ClassElementImpl && oldElement is ClassElementImpl) {
+ oldElement.nameOffset = newElement.nameOffset;
oldElement.setCodeRange(newElement.codeOffset, newElement.codeLength);
+ oldElement.typeParameters = newElement.typeParameters;
}
// Prepare delta.
ClassElementImpl classElement = oldClass.element;
ElementHolder classElementHolder = new ElementHolder();
- ClassElementDelta classDelta = new ClassElementDelta(classElement);
+ ClassElementDelta classDelta =
+ new ClassElementDelta(classElement, librarySource, classElement.name);
// Prepare all old member elements.
var removedAccessors = new Set<PropertyAccessorElement>();
var removedConstructors = new Set<ConstructorElement>();
@@ -214,7 +253,18 @@
bool newHasConstructor = false;
for (ClassMember newNode in newClass.members) {
String code = TokenUtils.getFullCode(newNode);
- ClassMember oldNode = oldNodeMap[code];
+ ClassMember oldNode = oldNodeMap.remove(code);
+ // When we type a name before a constructor with a documentation
+ // comment, this makes the comment disappear from AST. So, even though
+ // tokens are the same, the nodes are not the same.
+ if (oldNode != null) {
+ if (oldNode.documentationComment == null &&
+ newNode.documentationComment != null ||
+ oldNode.documentationComment != null &&
+ newNode.documentationComment == null) {
+ oldNode = null;
+ }
+ }
// Add the new element.
if (oldNode == null) {
if (newNode is ConstructorDeclaration) {
@@ -257,9 +307,32 @@
classDelta.removedAccessors.addAll(removedAccessors);
classDelta.removedConstructors.addAll(removedConstructors);
classDelta.removedMethods.addAll(removedMethods);
+ // Prepare fields.
+ List<PropertyAccessorElement> newAccessors = classElementHolder.accessors;
+ Map<String, FieldElement> newFields = <String, FieldElement>{};
+ for (PropertyAccessorElement accessor in newAccessors) {
+ newFields[accessor.displayName] = accessor.variable;
+ }
+ // Update references to fields from constructors.
+ for (ClassMember member in newClass.members) {
+ if (member is ConstructorDeclaration) {
+ for (FormalParameter parameter in member.parameters.parameters) {
+ FormalParameter normalParameter = parameter;
+ if (parameter is DefaultFormalParameter) {
+ normalParameter = parameter.parameter;
+ }
+ if (normalParameter is FieldFormalParameter) {
+ FieldFormalParameterElementImpl parameterElement =
+ normalParameter.element as FieldFormalParameterElementImpl;
+ parameterElement.field = newFields[parameterElement.name];
+ }
+ }
+ }
+ }
// Update ClassElement.
- classElement.accessors = classElementHolder.accessors;
+ classElement.accessors = newAccessors;
classElement.constructors = classElementHolder.constructors;
+ classElement.fields = newFields.values.toList();
classElement.methods = classElementHolder.methods;
classElementHolder.validate();
// Ensure at least a default synthetic constructor.
@@ -337,10 +410,12 @@
ClassDeclaration oldClass = nameToOldClassMap[newNode.name.name];
if (oldClass != null) {
ClassElementDelta delta = _processClassMembers(oldClass, newNode);
- unitDelta.classDeltas.add(delta);
- _addElementToUnitHolder(delta.element);
- removedElements.remove(delta.element);
- continue;
+ if (delta != null) {
+ unitDelta.classDeltas[delta._element.name] = delta;
+ _addElementToUnitHolder(delta._element);
+ removedElements.remove(delta._element);
+ continue;
+ }
}
}
// Add the new node elements.
@@ -374,16 +449,14 @@
// Replace node.
NodeReplacer.replace(newNode, oldNode);
// Replace tokens.
- {
- Token oldBeginToken = TokenUtils.getBeginTokenNotComment(newNode);
- Token newBeginToken = TokenUtils.getBeginTokenNotComment(oldNode);
- oldBeginToken.previous.setNext(newBeginToken);
- oldNode.endToken.setNext(newNode.endToken.next);
- }
+ Token oldBeginToken = TokenUtils.getBeginTokenNotComment(oldNode);
+ Token newBeginToken = TokenUtils.getBeginTokenNotComment(newNode);
+ newBeginToken.previous.setNext(oldBeginToken);
+ oldNode.endToken.setNext(newNode.endToken.next);
// Change tokens offsets.
Map<int, int> offsetMap = new HashMap<int, int>();
- TokenUtils.copyTokenOffsets(offsetMap, oldNode.beginToken,
- newNode.beginToken, oldNode.endToken, newNode.endToken, true);
+ TokenUtils.copyTokenOffsets(offsetMap, oldBeginToken, newBeginToken,
+ oldNode.endToken, newNode.endToken);
// Change elements offsets.
{
var visitor = new _UpdateElementOffsetsVisitor(offsetMap);
@@ -449,6 +522,7 @@
to.declarations.addAll(from.declarations);
to.element = to.element;
to.lineInfo = from.lineInfo;
+ to.endToken = from.endToken;
}
}
@@ -462,13 +536,8 @@
* Copy offsets from [newToken]s to [oldToken]s.
*/
static void copyTokenOffsets(Map<int, int> offsetMap, Token oldToken,
- Token newToken, Token oldEndToken, Token newEndToken,
- [bool goUpComment = false]) {
+ Token newToken, Token oldEndToken, Token newEndToken) {
if (oldToken is CommentToken && newToken is CommentToken) {
- if (goUpComment) {
- copyTokenOffsets(offsetMap, (oldToken as CommentToken).parent,
- (newToken as CommentToken).parent, oldEndToken, newEndToken);
- }
// Update (otherwise unlinked) reference tokens in documentation.
if (oldToken is DocumentationCommentToken &&
newToken is DocumentationCommentToken) {
@@ -526,6 +595,9 @@
* Return the token string of all the [node] tokens.
*/
static String getFullCode(AstNode node) {
+ if (node == null) {
+ return '';
+ }
List<Token> tokens = getTokens(node);
return joinTokens(tokens);
}
@@ -572,7 +644,7 @@
if (element is LibraryElement) {
return;
}
- if (element.isSynthetic) {
+ if (element.isSynthetic && !_isVariableInitializer(element)) {
return;
}
if (element is ElementImpl) {
@@ -622,4 +694,9 @@
}
super.visitElement(element);
}
+
+ static bool _isVariableInitializer(Element element) {
+ return element is FunctionElement &&
+ element.enclosingElement is VariableElement;
+ }
}
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/task/dart.dart
index 3dbea46..4df1c28 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/task/dart.dart
@@ -167,6 +167,9 @@
}
@override
+ Source get librarySource => library;
+
+ @override
Source get source => unit;
@override
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index 4f64bc9..771d422 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -61,6 +61,9 @@
AnalysisContextTarget(this.context);
@override
+ Source get librarySource => null;
+
+ @override
Source get source => null;
}
@@ -73,6 +76,12 @@
*/
abstract class AnalysisTarget {
/**
+ * If this target is associated with a library, return the source of the
+ * library's defining compilation unit; otherwise return `null`.
+ */
+ Source get librarySource;
+
+ /**
* Return the source associated with this target, or `null` if this target is
* not associated with a source.
*/
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9124fe8..0723e30 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.27.4-alpha.13
+version: 0.27.4-alpha.14
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 925eb8d..f9c4c8b 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -3904,6 +3904,10 @@
_assertTrue("{ while (true) { throw ''; } }");
}
+ void test_whileStatement_true_break_and_throw() {
+ _assertFalse("{ while (true) { if (1==1) break; throw 'T'; } }");
+ }
+
void _assertFalse(String source) {
_assertHasReturn(false, source);
}
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 645ebeb..6644ccd 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -707,10 +707,10 @@
verify([source]);
}
- void test_deprecatedAnnotationUse_Deprecated() {
+ void test_deprecatedAnnotationUse_deprecated() {
Source source = addSource(r'''
class A {
- @Deprecated('0.9')
+ @deprecated
m() {}
n() {m();}
}''');
@@ -719,10 +719,10 @@
verify([source]);
}
- void test_deprecatedAnnotationUse_deprecated() {
+ void test_deprecatedAnnotationUse_Deprecated() {
Source source = addSource(r'''
class A {
- @deprecated
+ @Deprecated('0.9')
m() {}
n() {m();}
}''');
@@ -1002,6 +1002,186 @@
verify([source]);
}
+ void test_factory__expr_return_null_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ State createState() => null;
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_abstract_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+abstract class Stateful {
+ @factory
+ State createState();
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_bad_return() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ State _s = new State();
+
+ @factory
+ State createState() => _s;
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_IMPL]);
+ verify([source]);
+ }
+
+ void test_factory_block_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ State createState() {
+ return new State();
+ }
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_block_return_null_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ State createState() {
+ return null;
+ }
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_expr_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ State createState() => new State();
+}
+
+class State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_misplaced_annotation() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+@factory
+class X {
+ @factory
+ int x;
+}
+
+@factory
+main() { }
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ HintCode.INVALID_FACTORY_ANNOTATION,
+ HintCode.INVALID_FACTORY_ANNOTATION,
+ HintCode.INVALID_FACTORY_ANNOTATION
+ ]);
+ verify([source]);
+ }
+
+ void test_factory_no_return_type_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ createState() {
+ return new Stateful();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ // Null return types will get flagged elsewhere, no need to pile-on here.
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_subclass_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+abstract class Stateful {
+ @factory
+ State createState();
+}
+
+class MyThing extends Stateful {
+ @override
+ State createState() {
+ print('my state');
+ return new MyState();
+ }
+}
+
+class State { }
+class MyState extends State { }
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_factory_void_return() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+ @factory
+ void createState() {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_DECL]);
+ verify([source]);
+ }
+
void test_importDeferredLibraryWithLoadFunction() {
resolveWithErrors(<String>[
r'''
@@ -1088,35 +1268,55 @@
}
void test_invalidUseOfProtectedMember_closure() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
int a() => 42;
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
void main() {
var leak = new A().a;
print(leak);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
+}
+''');
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_field() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
int a;
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
abstract class B {
int b() => new A().a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
+}
+''');
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_field_OK() {
@@ -1135,6 +1335,31 @@
}
void test_invalidUseOfProtectedMember_function() {
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
+main() {
+ new A().a();
+}
+''');
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
+ }
+
+ void test_invalidUseOfProtectedMember_function_OK2() {
Source source = addSource(r'''
import 'package:meta/meta.dart';
class A {
@@ -1145,7 +1370,7 @@
new A().a();
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
verify([source]);
}
@@ -1166,19 +1391,29 @@
}
void test_invalidUseOfProtectedMember_getter() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
int get a => 42;
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
class B {
A a;
int b() => a.a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
+}
+''');
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_getter_OK() {
@@ -1218,34 +1453,55 @@
}
void test_invalidUseOfProtectedMember_message() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
void a(){ }
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
class B {
void b() => new A().a();
-}''');
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
+}
+''');
+ List<AnalysisError> errors = analysisContext2.computeErrors(source2);
expect(errors, hasLength(1));
expect(errors[0].message,
"The member 'a' can only be used within instance members of subclasses of 'A'");
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_method_1() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
void a(){ }
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
class B {
void b() => new A().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
+}
+''');
+
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_method_OK() {
@@ -1401,21 +1657,31 @@
}
void test_invalidUseOfProtectedMember_setter() {
- Source source = addSource(r'''
+ Source source = addNamedSource(
+ '/lib1.dart',
+ r'''
import 'package:meta/meta.dart';
class A {
@protected
void set a(int i) { }
}
+''');
+ Source source2 = addNamedSource(
+ '/lib2.dart',
+ r'''
+import 'lib1.dart';
+
class B{
A a;
b(int i) {
a.a = i;
}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
+}
+''');
+ computeLibrarySourceErrors(source2);
+ assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
+ verify([source, source2]);
}
void test_invalidUseOfProtectedMember_setter_OK() {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 03309dd..f0b0107 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -37,7 +36,6 @@
main() {
initializeTestEnvironment();
- runReflectiveTests(DeclarationMatcherTest);
runReflectiveTests(IncrementalResolverTest);
runReflectiveTests(PoorMansIncrementalResolutionTest);
runReflectiveTests(ResolutionContextBuilderTest);
@@ -138,2976 +136,6 @@
}
@reflectiveTest
-class DeclarationMatcherTest extends ResolverTestCase {
- void setUp() {
- super.setUp();
- test_resolveApiChanges = true;
- }
-
- void test_false_class_annotation_accessor_edit() {
- _assertDoesNotMatch(
- r'''
-const my_annotationA = const Object();
-const my_annotationB = const Object();
-@my_annotationA
-class A {
-}
-''',
- r'''
-const my_annotationA = const Object();
-const my_annotationB = const Object();
-@my_annotationB
-class A {
-}
-''');
- }
-
- void test_false_class_annotation_constructor_edit() {
- _assertDoesNotMatch(
- r'''
-class MyAnnotationA {
- const MyAnnotationA();
-}
-class MyAnnotationB {
- const MyAnnotationB();
-}
-@MyAnnotationA()
-class A {
-}
-''',
- r'''
-class MyAnnotationA {
- const MyAnnotationA();
-}
-class MyAnnotationB {
- const MyAnnotationB();
-}
-@MyAnnotationB()
-class A {
-}
-''');
- }
-
- void test_false_class_annotations_add() {
- _assertDoesNotMatch(
- r'''
-const my_annotation = const Object();
-class A {
-}
-''',
- r'''
-const my_annotation = const Object();
-@my_annotation
-class A {
-}
-''');
- }
-
- void test_false_class_annotations_remove() {
- _assertDoesNotMatch(
- r'''
-const my_annotation = const Object();
-@my_annotation
-class A {
-}
-''',
- r'''
-const my_annotation = const Object();
-class A {
-}
-''');
- }
-
- void test_false_class_list_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-''',
- r'''
-class A {}
-class B {}
-class C {}
-''');
- }
-
- void test_false_class_list_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-class C {}
-''',
- r'''
-class A {}
-class B {}
-''');
- }
-
- void test_false_class_typeParameters_bounds_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B<T> {
- T f;
-}
-''',
- r'''
-class A {}
-class B<T extends A> {
- T f;
-}
-''');
- }
-
- void test_false_class_typeParameters_bounds_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B<T extends A> {
- T f;
-}
-''',
- r'''
-class A {}
-class B<T> {
- T f;
-}
-''');
- }
-
- void test_false_classMemberAccessor_list_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- get a => 1;
- get b => 2;
-}
-''',
- r'''
-class A {
- get a => 1;
- get b => 2;
- get c => 3;
-}
-''');
- }
-
- void test_false_classMemberAccessor_list_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- get a => 1;
- get b => 2;
- get c => 3;
-}
-''',
- r'''
-class A {
- get a => 1;
- get b => 2;
-}
-''');
- }
-
- void test_false_classMemberAccessor_wasGetter() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- get a => 1;
-}
-''',
- r'''
-class A {
- set a(x) {}
-}
-''');
- }
-
- void test_false_classMemberAccessor_wasInstance() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- get a => 1;
-}
-''',
- r'''
-class A {
- static get a => 1;
-}
-''');
- }
-
- void test_false_classMemberAccessor_wasSetter() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- set a(x) {}
-}
-''',
- r'''
-class A {
- get a => 1;
-}
-''');
- }
-
- void test_false_classMemberAccessor_wasStatic() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- static get a => 1;
-}
-''',
- r'''
-class A {
- get a => 1;
-}
-''');
- }
-
- void test_false_classTypeAlias_list_add() {
- _assertDoesNotMatch(
- r'''
-class M {}
-class A = Object with M;
-''',
- r'''
-class M {}
-class A = Object with M;
-class B = Object with M;
-''');
- }
-
- void test_false_classTypeAlias_list_remove() {
- _assertDoesNotMatch(
- r'''
-class M {}
-class A = Object with M;
-class B = Object with M;
-''',
- r'''
-class M {}
-class A = Object with M;
-''');
- }
-
- void test_false_classTypeAlias_typeParameters_bounds_add() {
- _assertDoesNotMatch(
- r'''
-class M<T> {}
-class A {}
-class B<T> = Object with M<T>;
-''',
- r'''
-class M<T> {}
-class A {}
-class B<T extends A> = Object with M<T>;
-''');
- }
-
- void test_false_classTypeAlias_typeParameters_bounds_remove() {
- _assertDoesNotMatch(
- r'''
-class M<T> {}
-class A {}
-class B<T extends A> = Object with M<T>;
-''',
- r'''
-class M<T> {}
-class A {}
-class B<T> = Object with M<T>;
-''');
- }
-
- void test_false_constructor_keywordConst_add() {
- _assertDoesNotMatch(
- r'''
-class A {
- A();
-}
-''',
- r'''
-class A {
- const A();
-}
-''');
- }
-
- void test_false_constructor_keywordConst_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- const A();
-}
-''',
- r'''
-class A {
- A();
-}
-''');
- }
-
- void test_false_constructor_keywordFactory_add() {
- _assertDoesNotMatch(
- r'''
-class A {
- A();
- A.foo() {
- return new A();
- }
-}
-''',
- r'''
-class A {
- A();
- factory A.foo() {
- return new A();
- }
-}
-''');
- }
-
- void test_false_constructor_keywordFactory_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- A();
- factory A.foo() {
- return new A();
- }
-}
-''',
- r'''
-class A {
- A();
- A.foo() {
- return new A();
- }
-}
-''');
- }
-
- void test_false_constructor_parameters_list_add() {
- _assertDoesNotMatch(
- r'''
-class A {
- A();
-}
-''',
- r'''
-class A {
- A(int p);
-}
-''');
- }
-
- void test_false_constructor_parameters_list_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- A(int p);
-}
-''',
- r'''
-class A {
- A();
-}
-''');
- }
-
- void test_false_constructor_parameters_name() {
- _assertDoesNotMatch(
- r'''
-class A {
- A(int a);
-}
-''',
- r'''
-class A {
- A(int b);
-}
-''');
- }
-
- void test_false_constructor_parameters_type_edit() {
- _assertDoesNotMatch(
- r'''
-class A {
- A(int p);
-}
-''',
- r'''
-class A {
- A(String p);
-}
-''');
- }
-
- void test_false_constructor_unnamed_add_hadParameters() {
- _assertDoesNotMatch(
- r'''
-class A {
-}
-''',
- r'''
-class A {
- A(int p) {}
-}
-''');
- }
-
- void test_false_constructor_unnamed_remove_hadParameters() {
- _assertDoesNotMatch(
- r'''
-class A {
- A(int p) {}
-}
-''',
- r'''
-class A {
-}
-''');
- }
-
- void test_false_defaultFieldFormalParameterElement_wasSimple() {
- _assertDoesNotMatch(
- r'''
-class A {
- int field;
- A(int field);
-}
-''',
- r'''
-class A {
- int field;
- A([this.field = 0]);
-}
-''');
- }
-
- void test_false_enum_constants_add() {
- _assertDoesNotMatch(
- r'''
-enum E {A, B}
-''',
- r'''
-enum E {A, B, C}
-''');
- }
-
- void test_false_enum_constants_remove() {
- _assertDoesNotMatch(
- r'''
-enum E {A, B, C}
-''',
- r'''
-enum E {A, B}
-''');
- }
-
- void test_false_export_hide_add() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async' hide Future;
-''',
- r'''
-export 'dart:async' hide Future, Stream;
-''');
- }
-
- void test_false_export_hide_remove() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async' hide Future, Stream;
-''',
- r'''
-export 'dart:async' hide Future;
-''');
- }
-
- void test_false_export_list_add() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async';
-''',
- r'''
-export 'dart:async';
-export 'dart:math';
-''');
- }
-
- void test_false_export_list_remove() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async';
-export 'dart:math';
-''',
- r'''
-export 'dart:async';
-''');
- }
-
- void test_false_export_show_add() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async' show Future;
-''',
- r'''
-export 'dart:async' show Future, Stream;
-''');
- }
-
- void test_false_export_show_remove() {
- _assertDoesNotMatch(
- r'''
-export 'dart:async' show Future, Stream;
-''',
- r'''
-export 'dart:async' show Future;
-''');
- }
-
- void test_false_extendsClause_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-''',
- r'''
-class A {}
-class B extends A {}
-''');
- }
-
- void test_false_extendsClause_different() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-class C extends A {}
-''',
- r'''
-class A {}
-class B {}
-class C extends B {}
-''');
- }
-
- void test_false_extendsClause_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B extends A{}
-''',
- r'''
-class A {}
-class B {}
-''');
- }
-
- void test_false_field_list_add() {
- _assertDoesNotMatch(
- r'''
-class T {
- int A = 1;
- int C = 3;
-}
-''',
- r'''
-class T {
- int A = 1;
- int B = 2;
- int C = 3;
-}
-''');
- }
-
- void test_false_field_list_remove() {
- _assertDoesNotMatch(
- r'''
-class T {
- int A = 1;
- int B = 2;
- int C = 3;
-}
-''',
- r'''
-class T {
- int A = 1;
- int C = 3;
-}
-''');
- }
-
- void test_false_field_modifier_isConst() {
- _assertDoesNotMatch(
- r'''
-class T {
- static final A = 1;
-}
-''',
- r'''
-class T {
- static const A = 1;
-}
-''');
- }
-
- void test_false_field_modifier_isFinal() {
- _assertDoesNotMatch(
- r'''
-class T {
- int A = 1;
-}
-''',
- r'''
-class T {
- final int A = 1;
-}
-''');
- }
-
- void test_false_field_modifier_isStatic() {
- _assertDoesNotMatch(
- r'''
-class T {
- int A = 1;
-}
-''',
- r'''
-class T {
- static int A = 1;
-}
-''');
- }
-
- void test_false_field_modifier_wasConst() {
- _assertDoesNotMatch(
- r'''
-class T {
- static const A = 1;
-}
-''',
- r'''
-class T {
- static final A = 1;
-}
-''');
- }
-
- void test_false_field_modifier_wasFinal() {
- _assertDoesNotMatch(
- r'''
-class T {
- final int A = 1;
-}
-''',
- r'''
-class T {
- int A = 1;
-}
-''');
- }
-
- void test_false_field_modifier_wasStatic() {
- _assertDoesNotMatch(
- r'''
-class T {
- static int A = 1;
-}
-''',
- r'''
-class T {
- int A = 1;
-}
-''');
- }
-
- void test_false_field_type_differentArgs() {
- _assertDoesNotMatch(
- r'''
-class T {
- List<int> A;
-}
-''',
- r'''
-class T {
- List<String> A;
-}
-''');
- }
-
- void test_false_fieldFormalParameter_add() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(field);
-}
-''',
- r'''
-class A {
- final field;
- A(this.field);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_add_function() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(field(a));
-}
-''',
- r'''
-class A {
- final field;
- A(this.field(a));
-}
-''');
- }
-
- void test_false_fieldFormalParameter_changeName_wasUnresolvedField() {
- _assertDoesNotMatch(
- r'''
-class A {
- final fff;
- A(this.unresolved);
-}
-''',
- r'''
-class A {
- final fff;
- A(this.fff);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_differentField() {
- _assertDoesNotMatch(
- r'''
-class A {
- final aaa;
- final bbb;
- A(this.aaa, this.bbb);
-}
-''',
- r'''
-class A {
- final aaa;
- final bbb;
- A(this.bbb, this.aaa);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_parameters_add() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(this.field(a));
-}
-''',
- r'''
-class A {
- final field;
- A(this.field(a, b));
-}
-''');
- }
-
- void test_false_fieldFormalParameter_parameters_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(this.field(a, b));
-}
-''',
- r'''
-class A {
- final field;
- A(this.field(a));
-}
-''');
- }
-
- void test_false_fieldFormalParameter_parameters_typeEdit() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(this.field(int p));
-}
-''',
- r'''
-class A {
- final field;
- A(this.field(String p));
-}
-''');
- }
-
- void test_false_fieldFormalParameter_remove_default() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A([this.field = 0]);
-}
-''',
- r'''
-class A {
- final field;
- A([field = 0]);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_remove_function() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(this.field(a));
-}
-''',
- r'''
-class A {
- final field;
- A(field(a));
-}
-''');
- }
-
- void test_false_fieldFormalParameter_remove_normal() {
- _assertDoesNotMatch(
- r'''
-class A {
- final field;
- A(this.field);
-}
-''',
- r'''
-class A {
- final field;
- A(field);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_typeAdd() {
- _assertDoesNotMatch(
- r'''
-class A {
- final fff;
- A(this.fff);
-}
-''',
- r'''
-class A {
- final fff;
- A(int this.fff);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_typeEdit() {
- _assertDoesNotMatch(
- r'''
-class A {
- final fff;
- A(int this.fff);
-}
-''',
- r'''
-class A {
- final fff;
- A(String this.fff);
-}
-''');
- }
-
- void test_false_fieldFormalParameter_typeRemove() {
- _assertDoesNotMatch(
- r'''
-class A {
- final fff;
- A(int this.fff);
-}
-''',
- r'''
-class A {
- final fff;
- A(this.fff);
-}
-''');
- }
-
- void test_false_fieldFormalParameterElement_wasSimple() {
- _assertDoesNotMatch(
- r'''
-class A {
- int field;
- A(int field);
-}
-''',
- r'''
-class A {
- int field;
- A(this.field);
-}
-''');
- }
-
- void test_false_final_type_different() {
- _assertDoesNotMatch(
- r'''
-class T {
- int A;
-}
-''',
- r'''
-class T {
- String A;
-}
-''');
- }
-
- void test_false_function_async_add() {
- _assertDoesNotMatch(
- r'''
-main() {}
-''',
- r'''
-main() async {}
-''');
- }
-
- void test_false_function_async_remove() {
- _assertDoesNotMatch(
- r'''
-main() async {}
-''',
- r'''
-main() {}
-''');
- }
-
- void test_false_function_generator_add() {
- _assertDoesNotMatch(
- r'''
-main() async {}
-''',
- r'''
-main() async* {}
-''');
- }
-
- void test_false_function_generator_remove() {
- _assertDoesNotMatch(
- r'''
-main() async* {}
-''',
- r'''
-main() async {}
-''');
- }
-
- void test_false_functionTypeAlias_list_add() {
- _assertDoesNotMatch(
- r'''
-typedef A(int pa);
-typedef B(String pb);
-''',
- r'''
-typedef A(int pa);
-typedef B(String pb);
-typedef C(pc);
-''');
- }
-
- void test_false_functionTypeAlias_list_remove() {
- _assertDoesNotMatch(
- r'''
-typedef A(int pa);
-typedef B(String pb);
-typedef C(pc);
-''',
- r'''
-typedef A(int pa);
-typedef B(String pb);
-''');
- }
-
- void test_false_functionTypeAlias_parameters_list_add() {
- _assertDoesNotMatch(
- r'''
-typedef A(a);
-''',
- r'''
-typedef A(a, b);
-''');
- }
-
- void test_false_functionTypeAlias_parameters_list_remove() {
- _assertDoesNotMatch(
- r'''
-typedef A(a, b);
-''',
- r'''
-typedef A(a);
-''');
- }
-
- void test_false_functionTypeAlias_parameters_type_edit() {
- _assertDoesNotMatch(
- r'''
-typedef A(int p);
-''',
- r'''
-typedef A(String p);
-''');
- }
-
- void test_false_functionTypeAlias_returnType_edit() {
- _assertDoesNotMatch(
- r'''
-typedef int A();
-''',
- r'''
-typedef String A();
-''');
- }
-
- void test_false_functionTypeAlias_typeParameters_bounds_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-typedef F<T>();
-''',
- r'''
-class A {}
-typedef F<T extends A>();
-''');
- }
-
- void test_false_functionTypeAlias_typeParameters_bounds_edit() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-typedef F<T extends A>();
-''',
- r'''
-class A {}
-typedef F<T extends B>();
-''');
- }
-
- void test_false_functionTypeAlias_typeParameters_bounds_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-typedef F<T extends A>();
-''',
- r'''
-class A {}
-typedef F<T>();
-''');
- }
-
- void test_false_functionTypeAlias_typeParameters_list_add() {
- _assertDoesNotMatch(
- r'''
-typedef F<A>();
-''',
- r'''
-typedef F<A, B>();
-''');
- }
-
- void test_false_functionTypeAlias_typeParameters_list_remove() {
- _assertDoesNotMatch(
- r'''
-typedef F<A, B>();
-''',
- r'''
-typedef F<A>();
-''');
- }
-
- void test_false_FunctionTypedFormalParameter_parameters_list_add() {
- _assertDoesNotMatch(
- r'''
-main(int callback(int a)) {
-}
-''',
- r'''
-main(int callback(int a, String b)) {
-}
-''');
- }
-
- void test_false_FunctionTypedFormalParameter_parameters_list_remove() {
- _assertDoesNotMatch(
- r'''
-main(int callback(int a, String b)) {
-}
-''',
- r'''
-main(int callback(int a)) {
-}
-''');
- }
-
- void test_false_FunctionTypedFormalParameter_parameterType() {
- _assertDoesNotMatch(
- r'''
-main(int callback(int p)) {
-}
-''',
- r'''
-main(int callback(String p)) {
-}
-''');
- }
-
- void test_false_FunctionTypedFormalParameter_returnType() {
- _assertDoesNotMatch(
- r'''
-main(int callback()) {
-}
-''',
- r'''
-main(String callback()) {
-}
-''');
- }
-
- void test_false_FunctionTypedFormalParameter_wasSimple() {
- _assertDoesNotMatch(
- r'''
-main(int callback) {
-}
-''',
- r'''
-main(int callback(int a, String b)) {
-}
-''');
- }
-
- void test_false_getter_body_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- int get foo;
-}
-''',
- r'''
-class A {
- int get foo => 0;
-}
-''');
- }
-
- void test_false_getter_body_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- int get foo => 0;
-}
-''',
- r'''
-class A {
- int get foo;
-}
-''');
- }
-
- void test_false_implementsClause_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-''',
- r'''
-class A {}
-class B implements A {}
-''');
- }
-
- void test_false_implementsClause_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B implements A {}
-''',
- r'''
-class A {}
-class B {}
-''');
- }
-
- void test_false_implementsClause_reorder() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-class C implements A, B {}
-''',
- r'''
-class A {}
-class B {}
-class C implements B, A {}
-''');
- }
-
- void test_false_import_hide_add() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' hide Future;
-''',
- r'''
-import 'dart:async' hide Future, Stream;
-''');
- }
-
- void test_false_import_hide_remove() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' hide Future, Stream;
-''',
- r'''
-import 'dart:async' hide Future;
-''');
- }
-
- void test_false_import_list_add() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async';
-''',
- r'''
-import 'dart:async';
-import 'dart:math';
-''');
- }
-
- void test_false_import_list_remove() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async';
-import 'dart:math';
-''',
- r'''
-import 'dart:async';
-''');
- }
-
- void test_false_import_prefix_add() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async';
-''',
- r'''
-import 'dart:async' as async;
-''');
- }
-
- void test_false_import_prefix_edit() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' as oldPrefix;
-''',
- r'''
-import 'dart:async' as newPrefix;
-''');
- }
-
- void test_false_import_prefix_remove() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' as async;
-''',
- r'''
-import 'dart:async';
-''');
- }
-
- void test_false_import_show_add() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' show Future;
-''',
- r'''
-import 'dart:async' show Future, Stream;
-''');
- }
-
- void test_false_import_show_remove() {
- _assertDoesNotMatch(
- r'''
-import 'dart:async' show Future, Stream;
-''',
- r'''
-import 'dart:async' show Future;
-''');
- }
-
- void test_false_method_annotation_edit() {
- _assertDoesNotMatchOK(
- r'''
-const my_annotationA = const Object();
-const my_annotationB = const Object();
-class A {
- @my_annotationA
- void m() {}
-}
-''',
- r'''
-const my_annotationA = const Object();
-const my_annotationB = const Object();
-class A {
- @my_annotationB
- void m() {}
-}
-''');
- }
-
- void test_false_method_annotations_add() {
- _assertDoesNotMatchOK(
- r'''
-const my_annotation = const Object();
-class A {
- void m() {}
-}
-''',
- r'''
-const my_annotation = const Object();
-class A {
- @my_annotation
- void m() {}
-}
-''');
- }
-
- void test_false_method_annotations_remove() {
- _assertDoesNotMatchOK(
- r'''
-const my_annotation = const Object();
-class A {
- @my_annotation
- void m() {}
-}
-''',
- r'''
-const my_annotation = const Object();
-class A {
- void m() {}
-}
-''');
- }
-
- void test_false_method_async_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- m() {}
-}
-''',
- r'''
-class A {
- m() async {}
-}
-''');
- }
-
- void test_false_method_async_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- m() async {}
-}
-''',
- r'''
-class A {
- m() {}
-}
-''');
- }
-
- void test_false_method_body_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void foo();
-}
-''',
- r'''
-class A {
- void foo() {}
-}
-''');
- }
-
- void test_false_method_body_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void foo() {}
-}
-''',
- r'''
-class A {
- void foo();
-}
-''');
- }
-
- void test_false_method_generator_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- m() async {}
-}
-''',
- r'''
-class A {
- m() async* {}
-}
-''');
- }
-
- void test_false_method_generator_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- m() async* {}
-}
-''',
- r'''
-class A {
- m() async {}
-}
-''');
- }
-
- void test_false_method_getKeyword_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void foo() {}
-}
-''',
- r'''
-class A {
- void get foo {}
-}
-''');
- }
-
- void test_false_method_getKeyword_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void get foo {}
-}
-''',
- r'''
-class A {
- void foo() {}
-}
-''');
- }
-
- void test_false_method_list_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- a() {}
- b() {}
-}
-''',
- r'''
-class A {
- a() {}
- b() {}
- c() {}
-}
-''');
- }
-
- void test_false_method_list_remove() {
- _assertDoesNotMatch(
- r'''
-class A {
- a() {}
- b() {}
- c() {}
-}
-''',
- r'''
-class A {
- a() {}
- b() {}
-}
-''');
- }
-
- void test_false_method_parameters_type_edit() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- m(int p) {
- }
-}
-''',
- r'''
-class A {
- m(String p) {
- }
-}
-''');
- }
-
- void test_false_method_parameters_type_edit_insertImportPrefix() {
- _assertDoesNotMatchOK(
- r'''
-import 'dart:async' as a;
-
-class C {
- void foo(Future f) {}
-}
-
-class Future {}
-
-bar(C c, a.Future f) {
- c.foo(f);
-}
-''',
- r'''
-import 'dart:async' as a;
-
-class C {
- void foo(a.Future f) {}
-}
-
-class Future {}
-
-bar(C c, a.Future f) {
- c.foo(f);
-}
-''');
- }
-
- void test_false_method_returnType_edit() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- int m() {}
-}
-''',
- r'''
-class A {
- String m() {}
-}
-''');
- }
-
- void test_false_method_setKeyword_add() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void foo(x) {}
-}
-''',
- r'''
-class A {
- void set foo(x) {}
-}
-''');
- }
-
- void test_false_method_setKeyword_remove() {
- _assertDoesNotMatchOK(
- r'''
-class A {
- void set foo(x) {}
-}
-''',
- r'''
-class A {
- void foo(x) {}
-}
-''');
- }
-
- void test_false_part_list_add() {
- addNamedSource('/unitA.dart', 'part of lib; class A {}');
- addNamedSource('/unitB.dart', 'part of lib; class B {}');
- _assertDoesNotMatch(
- r'''
-library lib;
-part 'unitA.dart';
-''',
- r'''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''');
- }
-
- void test_false_part_list_remove() {
- addNamedSource('/unitA.dart', 'part of lib; class A {}');
- addNamedSource('/unitB.dart', 'part of lib; class B {}');
- _assertDoesNotMatch(
- r'''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''',
- r'''
-library lib;
-part 'unitA.dart';
-''');
- }
-
- void test_false_SimpleFormalParameter_named_differentName() {
- _assertDoesNotMatch(
- r'''
-main({int oldName}) {
-}
-''',
- r'''
-main({int newName}) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_namedDefault_addValue() {
- _assertDoesNotMatch(
- r'''
-main({int p}) {
-}
-''',
- r'''
-main({int p: 2}) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_namedDefault_differentValue() {
- _assertDoesNotMatch(
- r'''
-main({int p: 1}) {
-}
-''',
- r'''
-main({int p: 2}) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_namedDefault_removeValue() {
- _assertDoesNotMatch(
- r'''
-main({int p: 1}) {
-}
-''',
- r'''
-main({int p}) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_optionalDefault_addValue() {
- _assertDoesNotMatch(
- r'''
-main([int p]) {
-}
-''',
- r'''
-main([int p = 2]) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_optionalDefault_differentValue() {
- _assertDoesNotMatch(
- r'''
-main([int p = 1]) {
-}
-''',
- r'''
-main([int p = 2]) {
-}
-''');
- }
-
- void test_false_SimpleFormalParameter_optionalDefault_removeValue() {
- _assertDoesNotMatch(
- r'''
-main([int p = 1]) {
-}
-''',
- r'''
-main([int p]) {
-}
-''');
- }
-
- void test_false_topLevelAccessor_list_add() {
- _assertDoesNotMatch(
- r'''
-get a => 1;
-get b => 2;
-''',
- r'''
-get a => 1;
-get b => 2;
-get c => 3;
-''');
- }
-
- void test_false_topLevelAccessor_list_remove() {
- _assertDoesNotMatch(
- r'''
-get a => 1;
-get b => 2;
-get c => 3;
-''',
- r'''
-get a => 1;
-get b => 2;
-''');
- }
-
- void test_false_topLevelAccessor_wasGetter() {
- _assertDoesNotMatch(
- r'''
-get a => 1;
-''',
- r'''
-set a(x) {}
-''');
- }
-
- void test_false_topLevelAccessor_wasSetter() {
- _assertDoesNotMatch(
- r'''
-set a(x) {}
-''',
- r'''
-get a => 1;
-''');
- }
-
- void test_false_topLevelFunction_list_add() {
- _assertDoesNotMatch(
- r'''
-a() {}
-b() {}
-''',
- r'''
-a() {}
-b() {}
-c() {}
-''');
- }
-
- void test_false_topLevelFunction_list_remove() {
- _assertDoesNotMatch(
- r'''
-a() {}
-b() {}
-c() {}
-''',
- r'''
-a() {}
-b() {}
-''');
- }
-
- void test_false_topLevelFunction_parameters_list_add() {
- _assertDoesNotMatch(
- r'''
-main(int a, int b) {
-}
-''',
- r'''
-main(int a, int b, int c) {
-}
-''');
- }
-
- void test_false_topLevelFunction_parameters_list_remove() {
- _assertDoesNotMatch(
- r'''
-main(int a, int b, int c) {
-}
-''',
- r'''
-main(int a, int b) {
-}
-''');
- }
-
- void test_false_topLevelFunction_parameters_type_edit() {
- _assertDoesNotMatch(
- r'''
-main(int a, int b, int c) {
-}
-''',
- r'''
-main(int a, String b, int c) {
-}
-''');
- }
-
- void test_false_topLevelFunction_returnType_edit() {
- _assertDoesNotMatch(
- r'''
-int a() {}
-''',
- r'''
-String a() {}
-''');
- }
-
- void test_false_topLevelVariable_list_add() {
- _assertDoesNotMatch(
- r'''
-const int A = 1;
-const int C = 3;
-''',
- r'''
-const int A = 1;
-const int B = 2;
-const int C = 3;
-''');
- }
-
- void test_false_topLevelVariable_list_remove() {
- _assertDoesNotMatch(
- r'''
-const int A = 1;
-const int B = 2;
-const int C = 3;
-''',
- r'''
-const int A = 1;
-const int C = 3;
-''');
- }
-
- void test_false_topLevelVariable_modifier_isConst() {
- _assertDoesNotMatch(
- r'''
-final int A = 1;
-''',
- r'''
-const int A = 1;
-''');
- }
-
- void test_false_topLevelVariable_modifier_isFinal() {
- _assertDoesNotMatch(
- r'''
-int A = 1;
-''',
- r'''
-final int A = 1;
-''');
- }
-
- void test_false_topLevelVariable_modifier_wasConst() {
- _assertDoesNotMatch(
- r'''
-const int A = 1;
-''',
- r'''
-final int A = 1;
-''');
- }
-
- void test_false_topLevelVariable_modifier_wasFinal() {
- _assertDoesNotMatch(
- r'''
-final int A = 1;
-''',
- r'''
-int A = 1;
-''');
- }
-
- void test_false_topLevelVariable_synthetic_wasGetter() {
- _assertDoesNotMatch(
- r'''
-int get A => 1;
-''',
- r'''
-final int A = 1;
-''');
- }
-
- void test_false_topLevelVariable_type_different() {
- _assertDoesNotMatch(
- r'''
-int A;
-''',
- r'''
-String A;
-''');
- }
-
- void test_false_topLevelVariable_type_differentArgs() {
- _assertDoesNotMatch(
- r'''
-List<int> A;
-''',
- r'''
-List<String> A;
-''');
- }
-
- void test_false_type_noTypeArguments_hadTypeArguments() {
- _assertDoesNotMatch(
- r'''
-class A<T> {}
-A<int> main() {
-}
-''',
- r'''
-class A<T> {}
-A main() {
-}
-''');
- }
-
- void test_false_withClause_add() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-''',
- r'''
-class A {}
-class B extends Object with A {}
-''');
- }
-
- void test_false_withClause_remove() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B extends Object with A {}
-''',
- r'''
-class A {}
-class B {}
-''');
- }
-
- void test_false_withClause_reorder() {
- _assertDoesNotMatch(
- r'''
-class A {}
-class B {}
-class C extends Object with A, B {}
-''',
- r'''
-class A {}
-class B {}
-class C extends Object with B, A {}
-''');
- }
-
- void test_true_class_annotations_same() {
- _assertMatches(
- r'''
-const my_annotation = const Object();
-@my_annotation
-class A {
-}
-''',
- r'''
-const my_annotation = const Object();
-@my_annotation
-class A {
-}
-''');
- }
-
- void test_true_class_list_reorder() {
- _assertMatches(
- r'''
-class A {}
-class B {}
-class C {}
-''',
- r'''
-class C {}
-class A {}
-class B {}
-''');
- }
-
- void test_true_class_list_same() {
- _assertMatches(
- r'''
-class A {}
-class B {}
-class C {}
-''',
- r'''
-class A {}
-class B {}
-class C {}
-''');
- }
-
- void test_true_class_typeParameters_same() {
- _assertMatches(
- r'''
-class A<T> {}
-''',
- r'''
-class A<T> {}
-''');
- }
-
- void test_true_classMemberAccessor_getterSetter() {
- _assertMatches(
- r'''
-class A {
- int _test;
- get test => _test;
- set test(v) {
- _test = v;
- }
-}
-''',
- r'''
-class A {
- int _test;
- get test => _test;
- set test(v) {
- _test = v;
- }
-}
-''');
- }
-
- void test_true_classMemberAccessor_list_reorder() {
- _assertMatches(
- r'''
-class A {
- get a => 1;
- get b => 2;
- get c => 3;
-}
-''',
- r'''
-class A {
- get c => 3;
- get a => 1;
- get b => 2;
-}
-''');
- }
-
- void test_true_classMemberAccessor_list_same() {
- _assertMatches(
- r'''
-class A {
- get a => 1;
- get b => 2;
- get c => 3;
-}
-''',
- r'''
-class A {
- get a => 1;
- get b => 2;
- get c => 3;
-}
-''');
- }
-
- void test_true_classTypeAlias_list_reorder() {
- _assertMatches(
- r'''
-class M {}
-class A = Object with M;
-class B = Object with M;
-class C = Object with M;
-''',
- r'''
-class M {}
-class C = Object with M;
-class A = Object with M;
-class B = Object with M;
-''');
- }
-
- void test_true_classTypeAlias_list_same() {
- _assertMatches(
- r'''
-class M {}
-class A = Object with M;
-class B = Object with M;
-class C = Object with M;
-''',
- r'''
-class M {}
-class A = Object with M;
-class B = Object with M;
-class C = Object with M;
-''');
- }
-
- void test_true_classTypeAlias_typeParameters_same() {
- _assertMatches(
- r'''
-class M<T> {}
-class A<T> {}
-class B<T> = A<T> with M<T>;
-''',
- r'''
-class M<T> {}
-class A<T> {}
-class B<T> = A<T> with M<T>;
-''');
- }
-
- void test_true_constructor_body_add() {
- _assertMatches(
- r'''
-class A {
- A(int p);
-}
-''',
- r'''
-class A {
- A(int p) {}
-}
-''');
- }
-
- void test_true_constructor_body_remove() {
- _assertMatches(
- r'''
-class A {
- A(int p) {}
-}
-''',
- r'''
-class A {
- A(int p);
-}
-''');
- }
-
- void test_true_constructor_named_same() {
- _assertMatches(
- r'''
-class A {
- A.name(int p);
-}
-''',
- r'''
-class A {
- A.name(int p);
-}
-''');
- }
-
- void test_true_constructor_unnamed_add_noParameters() {
- _assertMatches(
- r'''
-class A {
-}
-''',
- r'''
-class A {
- A() {}
-}
-''');
- }
-
- void test_true_constructor_unnamed_remove_noParameters() {
- _assertMatches(
- r'''
-class A {
- A() {}
-}
-''',
- r'''
-class A {
-}
-''');
- }
-
- void test_true_constructor_unnamed_same() {
- _assertMatches(
- r'''
-class A {
- A(int p);
-}
-''',
- r'''
-class A {
- A(int p);
-}
-''');
- }
-
- void test_true_defaultFieldFormalParameterElement() {
- _assertMatches(
- r'''
-class A {
- int field;
- A([this.field = 0]);
-}
-''',
- r'''
-class A {
- int field;
- A([this.field = 0]);
-}
-''');
- }
-
- void test_true_enum_constants_reorder() {
- _assertMatches(
- r'''
-enum E {A, B, C}
-''',
- r'''
-enum E {C, A, B}
-''');
- }
-
- void test_true_enum_list_reorder() {
- _assertMatches(
- r'''
-enum A {A1, A2, A3}
-enum B {B1, B2, B3}
-enum C {C1, C2, C3}
-''',
- r'''
-enum C {C1, C2, C3}
-enum A {A1, A2, A3}
-enum B {B1, B2, B3}
-''');
- }
-
- void test_true_enum_list_same() {
- _assertMatches(
- r'''
-enum A {A1, A2, A3}
-enum B {B1, B2, B3}
-enum C {C1, C2, C3}
-''',
- r'''
-enum A {A1, A2, A3}
-enum B {B1, B2, B3}
-enum C {C1, C2, C3}
-''');
- }
-
- void test_true_executable_same_hasLabel() {
- _assertMatches(
- r'''
-main() {
- label: return 42;
-}
-''',
- r'''
-main() {
- label: return 42;
-}
-''');
- }
-
- void test_true_executable_same_hasLocalVariable() {
- _assertMatches(
- r'''
-main() {
- int a = 42;
-}
-''',
- r'''
-main() {
- int a = 42;
-}
-''');
- }
-
- void test_true_export_hide_reorder() {
- _assertMatches(
- r'''
-export 'dart:async' hide Future, Stream;
-''',
- r'''
-export 'dart:async' hide Stream, Future;
-''');
- }
-
- void test_true_export_list_reorder() {
- _assertMatches(
- r'''
-export 'dart:async';
-export 'dart:math';
-''',
- r'''
-export 'dart:math';
-export 'dart:async';
-''');
- }
-
- void test_true_export_list_same() {
- _assertMatches(
- r'''
-export 'dart:async';
-export 'dart:math';
-''',
- r'''
-export 'dart:async';
-export 'dart:math';
-''');
- }
-
- void test_true_export_show_reorder() {
- _assertMatches(
- r'''
-export 'dart:async' show Future, Stream;
-''',
- r'''
-export 'dart:async' show Stream, Future;
-''');
- }
-
- void test_true_extendsClause_same() {
- _assertMatches(
- r'''
-class A {}
-class B extends A {}
-''',
- r'''
-class A {}
-class B extends A {}
-''');
- }
-
- void test_true_field_list_reorder() {
- _assertMatches(
- r'''
-class T {
- int A = 1;
- int B = 2;
- int C = 3;
-}
-''',
- r'''
-class T {
- int C = 3;
- int A = 1;
- int B = 2;
-}
-''');
- }
-
- void test_true_field_list_same() {
- _assertMatches(
- r'''
-class T {
- int A = 1;
- int B = 2;
- int C = 3;
-}
-''',
- r'''
-class T {
- int A = 1;
- int B = 2;
- int C = 3;
-}
-''');
- }
-
- void test_true_fieldFormalParameter() {
- _assertMatches(
- r'''
-class A {
- int field;
- A(this.field);
-}
-''',
- r'''
-class A {
- int field;
- A(this.field);
-}
-''');
- }
-
- void test_true_fieldFormalParameter_function() {
- _assertMatches(
- r'''
-class A {
- final field;
- A(this.field(int a, String b));
-}
-''',
- r'''
-class A {
- final field;
- A(this.field(int a, String b));
-}
-''');
- }
-
- void test_true_functionTypeAlias_list_reorder() {
- _assertMatches(
- r'''
-typedef A(int pa);
-typedef B(String pb);
-typedef C(pc);
-''',
- r'''
-typedef C(pc);
-typedef A(int pa);
-typedef B(String pb);
-''');
- }
-
- void test_true_functionTypeAlias_list_same() {
- _assertMatches(
- r'''
-typedef String A(int pa);
-typedef int B(String pb);
-typedef C(pc);
-''',
- r'''
-typedef String A(int pa);
-typedef int B(String pb);
-typedef C(pc);
-''');
- }
-
- void test_true_functionTypeAlias_typeParameters_list_same() {
- _assertMatches(
- r'''
-typedef F<A, B, C>();
-''',
- r'''
-typedef F<A, B, C>();
-''');
- }
-
- void test_true_FunctionTypedFormalParameter() {
- _assertMatches(
- r'''
-main(int callback(int a, String b)) {
-}
-''',
- r'''
-main(int callback(int a, String b)) {
-}
-''');
- }
-
- void test_true_implementsClause_same() {
- _assertMatches(
- r'''
-class A {}
-class B implements A {}
-''',
- r'''
-class A {}
-class B implements A {}
-''');
- }
-
- void test_true_import_hide_reorder() {
- _assertMatches(
- r'''
-import 'dart:async' hide Future, Stream;
-''',
- r'''
-import 'dart:async' hide Stream, Future;
-''');
- }
-
- void test_true_import_list_reorder() {
- _assertMatches(
- r'''
-import 'dart:async';
-import 'dart:math';
-''',
- r'''
-import 'dart:math';
-import 'dart:async';
-''');
- }
-
- void test_true_import_list_same() {
- _assertMatches(
- r'''
-import 'dart:async';
-import 'dart:math';
-''',
- r'''
-import 'dart:async';
-import 'dart:math';
-''');
- }
-
- void test_true_import_prefix() {
- _assertMatches(
- r'''
-import 'dart:async' as async;
-''',
- r'''
-import 'dart:async' as async;
-''');
- }
-
- void test_true_import_show_reorder() {
- _assertMatches(
- r'''
-import 'dart:async' show Future, Stream;
-''',
- r'''
-import 'dart:async' show Stream, Future;
-''');
- }
-
- void test_true_method_annotation_accessor_same() {
- _assertMatches(
- r'''
-const my_annotation = const Object();
-class A {
- @my_annotation
- void m() {}
-}
-''',
- r'''
-const my_annotation = const Object();
-class A {
- @my_annotation
- void m() {}
-}
-''');
- }
-
- void test_true_method_annotation_constructor_same() {
- _assertMatches(
- r'''
-class MyAnnotation {
- const MyAnnotation();
-}
-class A {
- @MyAnnotation()
- void m() {}
-}
-''',
- r'''
-class MyAnnotation {
- const MyAnnotation();
-}
-class A {
- @MyAnnotation()
- void m() {}
-}
-''');
- }
-
- void test_true_method_async() {
- _assertMatches(
- r'''
-class A {
- m() async {}
-}
-''',
- r'''
-class A {
- m() async {}
-}
-''');
- }
-
- void test_true_method_list_reorder() {
- _assertMatches(
- r'''
-class A {
- a() {}
- b() {}
- c() {}
-}
-''',
- r'''
-class A {
- c() {}
- a() {}
- b() {}
-}
-''');
- }
-
- void test_true_method_list_same() {
- _assertMatches(
- r'''
-class A {
- a() {}
- b() {}
- c() {}
-}
-''',
- r'''
-class A {
- a() {}
- b() {}
- c() {}
-}
-''');
- }
-
- void test_true_method_operator_minus() {
- _assertMatches(
- r'''
-class A {
- operator -(other) {}
-}
-''',
- r'''
-class A {
- operator -(other) {}
-}
-''');
- }
-
- void test_true_method_operator_minusUnary() {
- _assertMatches(
- r'''
-class A {
- operator -() {}
-}
-''',
- r'''
-class A {
- operator -() {}
-}
-''');
- }
-
- void test_true_method_operator_plus() {
- _assertMatches(
- r'''
-class A {
- operator +(other) {}
-}
-''',
- r'''
-class A {
- operator +(other) {}
-}
-''');
- }
-
- void test_true_method_parameters_type_functionType() {
- _assertMatches(
- r'''
-typedef F();
-class A {
- m(F p) {}
-}
-''',
- r'''
-typedef F();
-class A {
- m(F p) {}
-}
-''');
- }
-
- void test_true_method_parameters_type_sameImportPrefix() {
- _assertMatches(
- r'''
-import 'dart:async' as a;
-
-bar(a.Future f) {
- print(f);
-}
-''',
- r'''
-import 'dart:async' as a;
-
-bar(a.Future ff) {
- print(ff);
-}
-''');
- }
-
- void test_true_part_list_reorder() {
- addNamedSource('/unitA.dart', 'part of lib; class A {}');
- addNamedSource('/unitB.dart', 'part of lib; class B {}');
- _assertMatches(
- r'''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''',
- r'''
-library lib;
-part 'unitB.dart';
-part 'unitA.dart';
-''');
- }
-
- void test_true_part_list_same() {
- addNamedSource('/unitA.dart', 'part of lib; class A {}');
- addNamedSource('/unitB.dart', 'part of lib; class B {}');
- _assertMatches(
- r'''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''',
- r'''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''');
- }
-
- void test_true_SimpleFormalParameter_optional_differentName() {
- _assertMatches(
- r'''
-main([int oldName]) {
-}
-''',
- r'''
-main([int newName]) {
-}
-''');
- }
-
- void test_true_SimpleFormalParameter_optionalDefault_differentName() {
- _assertMatches(
- r'''
-main([int oldName = 1]) {
-}
-''',
- r'''
-main([int newName = 1]) {
-}
-''');
- }
-
- void test_true_SimpleFormalParameter_required_differentName() {
- _assertMatches(
- r'''
-main(int oldName) {
-}
-''',
- r'''
-main(int newName) {
-}
-''');
- }
-
- void test_true_topLevelAccessor_list_reorder() {
- _assertMatches(
- r'''
-set a(x) {}
-set b(x) {}
-set c(x) {}
-''',
- r'''
-set c(x) {}
-set a(x) {}
-set b(x) {}
-''');
- }
-
- void test_true_topLevelAccessor_list_same() {
- _assertMatches(
- r'''
-get a => 1;
-get b => 2;
-get c => 3;
-''',
- r'''
-get a => 1;
-get b => 2;
-get c => 3;
-''');
- }
-
- void test_true_topLevelFunction_list_reorder() {
- _assertMatches(
- r'''
-a() {}
-b() {}
-c() {}
-''',
- r'''
-c() {}
-a() {}
-b() {}
-''');
- }
-
- void test_true_topLevelFunction_list_same() {
- _assertMatches(
- r'''
-a() {}
-b() {}
-c() {}
-''',
- r'''
-a() {}
-b() {}
-c() {}
-''');
- }
-
- void test_true_topLevelVariable_list_reorder() {
- _assertMatches(
- r'''
-const int A = 1;
-const int B = 2;
-const int C = 3;
-''',
- r'''
-const int C = 3;
-const int A = 1;
-const int B = 2;
-''');
- }
-
- void test_true_topLevelVariable_list_same() {
- _assertMatches(
- r'''
-const int A = 1;
-const int B = 2;
-const int C = 3;
-''',
- r'''
-const int A = 1;
-const int B = 2;
-const int C = 3;
-''');
- }
-
- void test_true_topLevelVariable_type_sameArgs() {
- _assertMatches(
- r'''
-Map<int, String> A;
-''',
- r'''
-Map<int, String> A;
-''');
- }
-
- void test_true_type_dynamic() {
- _assertMatches(
- r'''
-dynamic a() {}
-''',
- r'''
-dynamic a() {}
-''');
- }
-
- void test_true_type_hasImportPrefix() {
- _assertMatches(
- r'''
-import 'dart:async' as async;
-async.Future F;
-''',
- r'''
-import 'dart:async' as async;
-async.Future F;
-''');
- }
-
- void test_true_type_noTypeArguments_implyAllDynamic() {
- _assertMatches(
- r'''
-class A<T> {}
-A main() {
-}
-''',
- r'''
-class A<T> {}
-A main() {
-}
-''');
- }
-
- void test_true_type_void() {
- _assertMatches(
- r'''
-void a() {}
-''',
- r'''
-void a() {}
-''');
- }
-
- void test_true_withClause_same() {
- _assertMatches(
- r'''
-class A {}
-class B extends Object with A {}
-''',
- r'''
-class A {}
-class B extends Object with A {}
-''');
- }
-
- void _assertDoesNotMatch(String oldContent, String newContent) {
- _assertMatchKind(DeclarationMatchKind.MISMATCH, oldContent, newContent);
- }
-
- void _assertDoesNotMatchOK(String oldContent, String newContent) {
- _assertMatchKind(DeclarationMatchKind.MISMATCH_OK, oldContent, newContent);
- }
-
- void _assertMatches(String oldContent, String newContent) {
- _assertMatchKind(DeclarationMatchKind.MATCH, oldContent, newContent);
- }
-
- void _assertMatchKind(
- DeclarationMatchKind expectMatch, String oldContent, String newContent) {
- Source source = addSource(oldContent);
- LibraryElement library = resolve2(source);
- CompilationUnit oldUnit = resolveCompilationUnit(source, library);
- // parse
- CompilationUnit newUnit = IncrementalResolverTest._parseUnit(newContent);
- // build elements
- {
- ElementHolder holder = new ElementHolder();
- ElementBuilder builder = new ElementBuilder(holder, oldUnit.element);
- newUnit.accept(builder);
- }
- // match
- DeclarationMatcher matcher = new DeclarationMatcher();
- DeclarationMatchKind matchKind = matcher.matches(newUnit, oldUnit.element);
- expect(matchKind, same(expectMatch));
- }
-}
-
-@reflectiveTest
class IncrementalResolverTest extends ResolverTestCase {
Source source;
String code;
@@ -3126,7 +154,6 @@
void setUp() {
super.setUp();
- test_resolveApiChanges = true;
logging.logger = logging.NULL_LOGGER;
}
@@ -3166,26 +193,6 @@
_resolve(_editString('+', '*'), _isFunctionBody);
}
- void test_constructor_fieldInitializer_add() {
- _resolveUnit(r'''
-class A {
- int f;
- A(int a, int b);
-}''');
- _resolve(_editString(');', ') : f = a + b;'), _isClassMember);
- }
-
- void test_constructor_fieldInitializer_edit() {
- _resolveUnit(r'''
-class A {
- int f;
- A(int a, int b) : f = a + b {
- int a = 42;
- }
-}''');
- _resolve(_editString('+', '*'), _isExpression);
- }
-
void test_constructor_label_add() {
_resolveUnit(r'''
class A {
@@ -3208,18 +215,6 @@
_resolve(_editString('42;', 'var res = 42;'), _isBlock);
}
- void test_constructor_superConstructorInvocation() {
- _resolveUnit(r'''
-class A {
- A(int p);
-}
-class B extends A {
- B(int a, int b) : super(a + b);
-}
-''');
- _resolve(_editString('+', '*'), _isExpression);
- }
-
void test_function_localFunction_add() {
_resolveUnit(r'''
int main() {
@@ -3238,13 +233,6 @@
_resolve(_editString('+', '*'), _isFunctionBody);
}
- void test_functionBody_expression() {
- _resolveUnit(r'''
-main(int a, int b) => a + b;
-''');
- _resolve(_editString('+', '*'), _isExpression);
- }
-
void test_functionBody_statement() {
_resolveUnit(r'''
main(int a, int b) {
@@ -3304,23 +292,6 @@
_isBlock);
}
- void test_method_parameter_rename() {
- _resolveUnit(r'''
-class A {
- int m(int a, int b, int c) {
- return a + b + c;
- }
-}
-''');
- _resolve(
- _editString(
- r'''(int a, int b, int c) {
- return a + b + c;''',
- r'''(int a, int second, int c) {
- return a + second + c;'''),
- _isDeclaration);
- }
-
void test_superInvocation() {
_resolveUnit(r'''
class A {
@@ -3386,36 +357,6 @@
_resolve(_editString('int res = a * b;', ''), _isBlock);
}
- void test_topLevelFunction_parameter_inFunctionTyped_rename() {
- _resolveUnit(r'''
-test(f(int a, int b)) {
-}
-''');
- _resolve(_editString('test(f(int a', 'test(f2(int a2'), _isDeclaration);
- }
-
- void test_topLevelFunction_parameter_rename() {
- _resolveUnit(r'''
-int main(int a, int b) {
- return a + b;
-}
-''');
- _resolve(
- _editString(
- r'''(int a, int b) {
- return a + b;''',
- r'''(int first, int b) {
- return first + b;'''),
- _isDeclaration);
- }
-
- void test_topLevelVariable_initializer() {
- _resolveUnit(r'''
-int C = 1 + 2;
-''');
- _resolve(_editString('+', '*'), _isExpression);
- }
-
void test_updateElementOffset() {
_resolveUnit(r'''
class A {
@@ -3487,8 +428,11 @@
LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
resolver = new IncrementalResolver(cache, cache.get(source), cache.get(lsu),
unit.element, updateOffset, updateEndOld, updateOldNew);
- bool success = resolver.resolve(newNode);
- expect(success, isTrue);
+
+ BlockFunctionBody body = newNode.getAncestor((n) => n is BlockFunctionBody);
+ expect(body, isNotNull);
+
+ resolver.resolve(body);
_checkCacheEntries(cache);
List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -3536,12 +480,6 @@
static bool _isBlock(AstNode node) => node is Block;
- static bool _isClassMember(AstNode node) => node is ClassMember;
-
- static bool _isDeclaration(AstNode node) => node is Declaration;
-
- static bool _isExpression(AstNode node) => node is Expression;
-
static bool _isFunctionBody(AstNode node) => node is FunctionBody;
static bool _isStatement(AstNode node) => node is Statement;
@@ -3582,23 +520,6 @@
CompilationUnit oldUnit;
CompilationUnitElement oldUnitElement;
- void fail_updateErrors_removeExisting_duplicateMethodDeclaration() {
- // TODO(scheglov) We fail to remove the second "foo" declaration.
- // So, we still have the same duplicate declaration problem.
- _resolveUnit(r'''
-class A {
- void foo() {}
- void foo() {}
-}
-''');
- _updateAndValidate(r'''
-class A {
- void foo() {}
- void foo2() {}
-}
-''');
- }
-
@override
void setUp() {
super.setUp();
@@ -4177,6 +1098,59 @@
expectedSuccess: false);
}
+ void test_false_wholeConstructor_addInitializer() {
+ _resolveUnit(r'''
+class A {
+ int field;
+ A();
+}
+''');
+ _updateAndValidate(
+ r'''
+class A {
+ int field;
+ A() : field = 5;
+}
+''',
+ expectedSuccess: false);
+ }
+
+ void test_false_wholeFunction() {
+ _resolveUnit(r'''
+foo() {}
+main(int a) {
+ print(a);
+}
+''');
+ _updateAndValidate(
+ r'''
+foo() {}
+main(int b) {
+ print(b);
+}
+''',
+ expectedSuccess: false);
+ }
+
+ void test_false_wholeMethod() {
+ _resolveUnit(r'''
+class A {
+ main(int a) {
+ print(a);
+ }
+}
+''');
+ _updateAndValidate(
+ r'''
+class A {
+ main(int b) {
+ print(b);
+ }
+}
+''',
+ expectedSuccess: false);
+ }
+
void test_fieldClassField_propagatedType() {
_resolveUnit(r'''
class A {
@@ -4414,66 +1388,6 @@
_assertEqualErrors(newErrors, oldErrors);
}
- void test_true_wholeConstructor_addInitializer() {
- _resolveUnit(r'''
-class A {
- int field;
- A();
-}
-''');
- _updateAndValidate(r'''
-class A {
- int field;
- A() : field = 5;
-}
-''');
- }
-
- void test_true_wholeFunction() {
- _resolveUnit(r'''
-foo() {}
-main(int a) {
- print(a);
-}
-''');
- _updateAndValidate(r'''
-foo() {}
-main(int b) {
- print(b);
-}
-''');
- }
-
- void test_true_wholeFunction_firstTokenInUnit() {
- _resolveUnit(r'''
-main(int a) {
- print(a);
-}
-''');
- _updateAndValidate(r'''
-main(int b) {
- print(b);
-}
-''');
- }
-
- void test_true_wholeMethod() {
- _resolveUnit(r'''
-class A {
- main(int a) {
- print(a);
- }
-}
-''');
- _updateAndValidate(r'''
-class A {
- main(int b) {
- print(b);
- }
-}
-''');
- }
-
void test_unusedHint_add_wasUsedOnlyInPart() {
Source partSource = addNamedSource(
'/my_unit.dart',
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 0e0ee77..0674039 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -6263,6 +6263,10 @@
expect(identifier.token, isNotNull);
expect(identifier.name, "");
expect(identifier.offset, 5);
+ // Should end with EOF token.
+ Token nextToken = identifier.token.next;
+ expect(nextToken, isNotNull);
+ expect(nextToken.type, TokenType.EOF);
}
void test_parseCommentReferences_multiLine() {
@@ -6298,35 +6302,50 @@
}
void test_parseCommentReferences_notClosed_noIdentifier() {
- List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
- new DocumentationCommentToken(
- TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5)
- ];
- List<CommentReference> references =
- parse("parseCommentReferences", <Object>[tokens], "")
- as List<CommentReference>;
+ DocumentationCommentToken docToken = new DocumentationCommentToken(
+ TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5);
+ List<CommentReference> references = parse(
+ "parseCommentReferences",
+ <Object>[
+ <DocumentationCommentToken>[docToken]
+ ],
+ "") as List<CommentReference>;
+ expect(docToken.references, hasLength(1));
expect(references, hasLength(1));
+ Token referenceToken = docToken.references[0];
CommentReference reference = references[0];
expect(reference, isNotNull);
+ expect(docToken.references[0], same(reference.beginToken));
expect(reference.identifier, isNotNull);
expect(reference.identifier.isSynthetic, isTrue);
expect(reference.identifier.name, "");
+ // Should end with EOF token.
+ Token nextToken = referenceToken.next;
+ expect(nextToken, isNotNull);
+ expect(nextToken.type, TokenType.EOF);
}
void test_parseCommentReferences_notClosed_withIdentifier() {
- List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
- new DocumentationCommentToken(
- TokenType.MULTI_LINE_COMMENT, "/** [namePrefix some text", 5)
- ];
+ DocumentationCommentToken docToken = new DocumentationCommentToken(
+ TokenType.MULTI_LINE_COMMENT, "/** [namePrefix some text", 5);
List<CommentReference> references =
- parse("parseCommentReferences", <Object>[tokens], "")
+ parse("parseCommentReferences", <Object>[<DocumentationCommentToken>[
+ docToken
+ ]], "")
as List<CommentReference>;
+ expect(docToken.references, hasLength(1));
expect(references, hasLength(1));
+ Token referenceToken = docToken.references[0];
CommentReference reference = references[0];
expect(reference, isNotNull);
+ expect(referenceToken, same(reference.beginToken));
expect(reference.identifier, isNotNull);
expect(reference.identifier.isSynthetic, isFalse);
expect(reference.identifier.name, "namePrefix");
+ // Should end with EOF token.
+ Token nextToken = referenceToken.next;
+ expect(nextToken, isNotNull);
+ expect(nextToken.type, TokenType.EOF);
}
void test_parseCommentReferences_singleLine() {
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
new file mode 100644
index 0000000..8976b9c
--- /dev/null
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.generated.sdk_test;
+
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../src/context/mock_sdk.dart';
+import '../utils.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(DartSdkManagerTest);
+ runReflectiveTests(SdkDescriptionTest);
+}
+
+@reflectiveTest
+class DartSdkManagerTest extends EngineTestCase {
+ void test_anySdk() {
+ DartSdkManager manager =
+ new DartSdkManager('/a/b/c', false, _failIfCreated);
+ expect(manager.anySdk, isNull);
+
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription description = new SdkDescription(<String>['/c/d'], options);
+ DartSdk sdk = new MockSdk();
+ manager.getSdk(description, () => sdk);
+ expect(manager.anySdk, same(sdk));
+ }
+
+ void test_getSdk_differentDescriptors() {
+ DartSdkManager manager =
+ new DartSdkManager('/a/b/c', false, _failIfCreated);
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription description1 = new SdkDescription(<String>['/c/d'], options);
+ DartSdk sdk1 = new MockSdk();
+ DartSdk result1 = manager.getSdk(description1, () => sdk1);
+ expect(result1, same(sdk1));
+ SdkDescription description2 = new SdkDescription(<String>['/e/f'], options);
+ DartSdk sdk2 = new MockSdk();
+ DartSdk result2 = manager.getSdk(description2, () => sdk2);
+ expect(result2, same(sdk2));
+
+ manager.getSdk(description1, _failIfAbsent);
+ manager.getSdk(description2, _failIfAbsent);
+ }
+
+ void test_getSdk_sameDescriptor() {
+ DartSdkManager manager =
+ new DartSdkManager('/a/b/c', false, _failIfCreated);
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription description = new SdkDescription(<String>['/c/d'], options);
+ DartSdk sdk = new MockSdk();
+ DartSdk result = manager.getSdk(description, () => sdk);
+ expect(result, same(sdk));
+ manager.getSdk(description, _failIfAbsent);
+ }
+
+ DartSdk _failIfAbsent() {
+ fail('Use of ifAbsent function');
+ return null;
+ }
+
+ DartSdk _failIfCreated(_) {
+ fail('Use of sdkCreator');
+ return null;
+ }
+}
+
+@reflectiveTest
+class SdkDescriptionTest extends EngineTestCase {
+ void test_equals_differentPaths_nested() {
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription left = new SdkDescription(<String>['/a/b/c'], options);
+ SdkDescription right = new SdkDescription(<String>['/a/b'], options);
+ expect(left == right, isFalse);
+ }
+
+ void test_equals_differentPaths_unrelated() {
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription left = new SdkDescription(<String>['/a/b/c'], options);
+ SdkDescription right = new SdkDescription(<String>['/d/e'], options);
+ expect(left == right, isFalse);
+ }
+
+ void test_equals_noPaths() {
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription left = new SdkDescription(<String>[], options);
+ SdkDescription right = new SdkDescription(<String>[], options);
+ expect(left == right, isTrue);
+ }
+
+ void test_equals_samePaths_differentOptions() {
+ String path = '/a/b/c';
+ AnalysisOptionsImpl leftOptions = new AnalysisOptionsImpl();
+ AnalysisOptionsImpl rightOptions = new AnalysisOptionsImpl();
+ rightOptions.strongMode = !leftOptions.strongMode;
+ SdkDescription left = new SdkDescription(<String>[path], leftOptions);
+ SdkDescription right = new SdkDescription(<String>[path], rightOptions);
+ expect(left == right, isFalse);
+ }
+
+ void test_equals_samePaths_sameOptions_multiple() {
+ String leftPath = '/a/b/c';
+ String rightPath = '/d/e';
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription left =
+ new SdkDescription(<String>[leftPath, rightPath], options);
+ SdkDescription right =
+ new SdkDescription(<String>[leftPath, rightPath], options);
+ expect(left == right, isTrue);
+ }
+
+ void test_equals_samePaths_sameOptions_single() {
+ String path = '/a/b/c';
+ AnalysisOptions options = new AnalysisOptionsImpl();
+ SdkDescription left = new SdkDescription(<String>[path], options);
+ SdkDescription right = new SdkDescription(<String>[path], options);
+ expect(left == right, isTrue);
+ }
+}
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 96e525e..01ccba9 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -28,6 +28,7 @@
import 'parser_test.dart' as parser_test;
import 'resolver_test.dart' as resolver_test;
import 'scanner_test.dart' as scanner_test;
+import 'sdk_test.dart' as sdk_test;
import 'simple_resolver_test.dart' as simple_resolver_test;
import 'source_factory_test.dart' as source_factory_test;
import 'static_type_analyzer_test.dart' as static_type_analyzer_test;
@@ -61,6 +62,7 @@
parser_test.main();
resolver_test.main();
scanner_test.main();
+ sdk_test.main();
simple_resolver_test.main();
source_factory_test.main();
static_type_analyzer_test.main();
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 2726eef..b03791a 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -1188,5 +1188,8 @@
class _TestAnalysisTarget implements AnalysisTarget {
@override
+ Source get librarySource => null;
+
+ @override
Source get source => null;
}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index c9c8c28..a2f3cb3 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -26,6 +26,7 @@
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
import 'package:unittest/unittest.dart';
@@ -300,6 +301,39 @@
expect(context.sourcesNeedingProcessing, hasLength(0));
}
+ void test_applyChanges_recompute_exportNamespace() {
+ Source libSource = addSource(
+ "/lib.dart",
+ r'''
+class A {}
+''');
+ Source exporterSource = addSource(
+ "/exporter.dart",
+ r'''
+export 'lib.dart';
+''');
+ _performPendingAnalysisTasks();
+ // initially: A
+ {
+ LibraryElement libraryElement =
+ context.getResult(exporterSource, LIBRARY_ELEMENT1) as LibraryElement;
+ expect(libraryElement.exportNamespace.definedNames.keys,
+ unorderedEquals(['A']));
+ }
+ // after update: B
+ context.setContents(
+ libSource,
+ r'''
+class B {}''');
+ _performPendingAnalysisTasks();
+ {
+ LibraryElement libraryElement =
+ context.getResult(exporterSource, LIBRARY_ELEMENT1) as LibraryElement;
+ expect(libraryElement.exportNamespace.definedNames.keys,
+ unorderedEquals(['B']));
+ }
+ }
+
Future test_applyChanges_remove() {
SourcesChangedListener listener = new SourcesChangedListener();
context.onSourcesChanged.listen(listener.onData);
@@ -1464,6 +1498,44 @@
expect(context.getLibraryElement(source), isNull);
}
+ void test_handleContentsChanged_noOriginal_sameAsFile() {
+ ContentCache contentCache = new ContentCache();
+ context.contentCache = contentCache;
+ // Add the source.
+ String code = 'foo() {}';
+ Source source = addSource("/test.dart", code);
+ _analyzeAll_assertFinished();
+ expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
+ // Update the content cache, and notify that we updated the source.
+ // We pass "null" as "originalContents" because the was no one.
+ contentCache.setContents(source, code);
+ context.handleContentsChanged(source, null, code, true);
+ expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
+ }
+
+ void test_handleContentsChanged_noOriginal_sameAsFile_butFileUpdated() {
+ ContentCache contentCache = new ContentCache();
+ context.contentCache = contentCache;
+ // Add the source.
+ String oldCode = 'foo() {}';
+ String newCode = 'bar() {}';
+ var file = resourceProvider.newFile('/test.dart', oldCode);
+ Source source = file.createSource();
+ context.applyChanges(new ChangeSet()..addedSource(source));
+ _analyzeAll_assertFinished();
+ expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
+ // Test for the race condition.
+ // 1. Update the file.
+ // 2. Update the content cache.
+ // 3. Notify the context, and because this is the first time when we
+ // update the content cache, we don't know "originalContents".
+ // The source must be invalidated, because it has different contents now.
+ resourceProvider.updateFile('/test.dart', newCode);
+ contentCache.setContents(source, newCode);
+ context.handleContentsChanged(source, null, newCode, true);
+ expect(context.getResolvedCompilationUnit2(source, source), isNull);
+ }
+
Future test_implicitAnalysisEvents_added() async {
AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
context.implicitAnalysisEvents.listen(listener.onData);
@@ -1826,7 +1898,7 @@
reason: "part resolved 1");
// update and analyze #1
context.setContents(partSource, "part of lib; // 1");
- if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ if (context.analysisOptions.finerGrainedInvalidation) {
expect(
context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
reason: "library changed 2");
@@ -1848,7 +1920,7 @@
}
// update and analyze #2
context.setContents(partSource, "part of lib; // 12");
- if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ if (context.analysisOptions.finerGrainedInvalidation) {
expect(
context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
reason: "library changed 3");
@@ -2004,7 +2076,7 @@
_changeSource(source, "");
source.generateExceptionOnRead = true;
_analyzeAll_assertFinished();
- if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ if (context.analysisOptions.finerGrainedInvalidation) {
expect(source.readCount, 7);
} else {
expect(source.readCount, 4);
@@ -2592,26 +2664,345 @@
}
@reflectiveTest
-/**
- * TODO(scheglov) After changes that affect only resolution in method bodies,
- * it is theoretically possible to keep the same element model and resolve
- * only corresponding method bodies.
- */
class LimitedInvalidateTest extends AbstractContextTest {
@override
void setUp() {
- AnalysisEngine.instance.limitInvalidationInTaskModel = true;
super.setUp();
AnalysisOptionsImpl options =
new AnalysisOptionsImpl.from(context.analysisOptions);
options.incremental = true;
+ options.finerGrainedInvalidation = true;
context.analysisOptions = options;
}
- @override
- void tearDown() {
- AnalysisEngine.instance.limitInvalidationInTaskModel = false;
- super.tearDown();
+ void test_class_addMethod_useClass() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {}
+class B extends A {
+ foo() {}
+}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+B b = null;
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: remove add A.bar.
+ // b.dart is valid, because though it uses A, it has the same element.
+ context.setContents(
+ a,
+ r'''
+class A {}
+class B extends A {
+ foo() {}
+ bar() {}
+}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_class_method_change_notUsed() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {
+ foo() {}
+ bar() {}
+}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main(A a) {
+ a.foo();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: remove A.bar, add A.bar2.
+ // b.dart is valid, because it doesn't references 'bar' or 'bar2'.
+ context.setContents(
+ a,
+ r'''
+class A {
+ foo() {}
+ bar2() {}
+}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_class_method_change_notUsed_throughSubclass_extends() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {
+ foo() {}
+ bar() {}
+}
+class B extends A {}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main(B b) {
+ a.foo();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: remove A.bar, add A.bar2.
+ // b.dart is valid, because it doesn't references 'bar' or 'bar2'.
+ context.setContents(
+ a,
+ r'''
+class A {
+ foo() {}
+ bar2() {}
+}
+class B extends A {}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_class_method_definedInSuper_sameLibrary() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {
+ m() {}
+}
+class B extends A {}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main(B b) {
+ b.m();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: change A.m
+ // This makes B changed.
+ // b.dart is invalid, because it references B.
+ context.setContents(
+ a,
+ r'''
+class A {
+ m2() {}
+}
+class B extends A {}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertValidForDependentLibrary(b);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertInvalid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_class_private_member() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {
+ A();
+ A._privateConstructor();
+
+ foo() {}
+
+ int _privateField;
+ _privateMethod() {}
+ int get _privateGetter => null;
+ void set _privateSetter(_) {}
+}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main(A a) {
+ a.foo();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: rename private members of A
+ // b.dart is valid, it cannot see these private members.
+ context.setContents(
+ a,
+ r'''
+class A {
+ A();
+ A._privateConstructor2();
+
+ foo() {}
+
+ int _privateField2;
+ _privateMethod2() {}
+ int get _privateGetter2 => null;
+ void set _privateSetter2(_) {}
+}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_class_super_makeAbstract_instantiate() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+abstract class I {
+ void m();
+}
+class A implements I {
+ void m() {}
+}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+class B extends A {}
+''');
+ Source c = addSource(
+ '/c.dart',
+ r'''
+import 'b.dart';
+main() {
+ new B();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: remove A.bar, add A.bar2.
+ // b.dart is valid, because it doesn't references 'bar' or 'bar2'.
+ context.setContents(
+ a,
+ r'''
+abstract class I {
+ void m();
+}
+class A implements I {
+ void m2() {}
+}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+
+ _assertValidForDependentLibrary(b);
+ _assertInvalid(b, LIBRARY_ERRORS_READY);
+
+ _assertValidForDependentLibrary(c);
+ _assertInvalid(c, LIBRARY_ERRORS_READY);
+ }
+
+ void test_private_class() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class _A {}
+class _B2 {}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main() {
+ new _A();
+ new _B();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: change _A and _B2
+ // b.dart is valid, because _A, _B, _A2 and _B2 are all private,
+ // so b.dart cannot see them.
+ context.setContents(
+ a,
+ r'''
+class _A2 {}
+class _B {}
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_private_topLevelVariable() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+int _V = 1;
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main() {
+ print(_A);
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: change _V
+ // b.dart is valid, because _V is private and b.dart cannot see it.
+ context.setContents(
+ a,
+ r'''
+int _V = 2;
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
+ void test_private_topLevelVariable_throughPublic() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+int _A = 1;
+int B = _A + 1;
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main() {
+ print(B);
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update a.dart: change _A
+ // b.dart is invalid, because it uses B, which uses _A.
+ context.setContents(
+ a,
+ r'''
+int _A = 2;
+int B = _A + 1;
+''');
+ _assertValidForChangedLibrary(a);
+ _assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertInvalid(b, LIBRARY_ERRORS_READY);
}
void test_sequence_class_give_take() {
@@ -2642,9 +3033,11 @@
class B {}
class C2 {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertUnitInvalid(b, RESOLVED_UNIT);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
// Now b.dart is analyzed and the error is fixed.
_performPendingAnalysisTasks();
expect(context.getErrors(b).errors, hasLength(0));
@@ -2657,8 +3050,11 @@
class B {}
class C {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
_assertInvalid(b, LIBRARY_ERRORS_READY);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
// Now b.dart is analyzed and it again has the error.
_performPendingAnalysisTasks();
expect(context.getErrors(b).errors, hasLength(1));
@@ -2671,6 +3067,7 @@
class A {
A();
}
+
class B {
B();
}
@@ -2700,8 +3097,11 @@
B();
}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
- _assertValid(b, LIBRARY_ELEMENT);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
// The a.dart's unit and element are updated incrementally.
// They are the same instances as initially.
// So, all the references from other units are still valid.
@@ -2735,8 +3135,11 @@
B();
}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
- _assertInvalid(b, LIBRARY_ELEMENT);
+ _assertValidForDependentLibrary(b);
+ _assertInvalid(b, LIBRARY_ERRORS_READY);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
// The a.dart's unit and element are the same.
{
LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
@@ -2750,6 +3153,40 @@
expect(context.getErrors(b).errors, hasLength(0));
}
+ void test_sequence_useAnyResolvedUnit() {
+ Source a = addSource(
+ '/a.dart',
+ r'''
+class A {}
+class B {}
+''');
+ Source b = addSource(
+ '/b.dart',
+ r'''
+import 'a.dart';
+main() {
+ new A();
+}
+''');
+ _performPendingAnalysisTasks();
+ _assertValid(a, LIBRARY_ERRORS_READY);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ // Invalidate RESOLVED_UNIT
+ CacheEntry entryA = context.getCacheEntry(new LibrarySpecificUnit(a, a));
+ entryA.setState(RESOLVED_UNIT, CacheState.FLUSHED);
+ entryA.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
+ entryA.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
+ entryA.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
+ context.setContents(
+ a,
+ r'''
+class A {}
+class B2 {}
+''');
+ _assertValidAllLibraryUnitResults(b);
+ _assertValid(b, LIBRARY_ERRORS_READY);
+ }
+
void test_unusedName_class_add() {
Source a = addSource(
'/a.dart',
@@ -2768,6 +3205,7 @@
}
''');
_performPendingAnalysisTasks();
+ _assertValid(a, LINE_INFO);
// The class B is not referenced.
// a.dart is invalid.
// b.dart is valid.
@@ -2778,11 +3216,12 @@
class B2 {}
class C {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
- _assertUnitValid(a, RESOLVED_UNIT1);
_assertUnitInvalid(a, RESOLVED_UNIT);
+ _assertValidForDependentLibrary(b);
+ _assertValidAllLibraryUnitResults(b);
_assertValid(b, LIBRARY_ERRORS_READY);
- _assertUnitValid(b, RESOLVED_UNIT);
}
void test_usedName_class_name_asHole_inBody() {
@@ -2812,10 +3251,11 @@
class B {}
class C2 {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
}
void test_usedName_class_name_asSuper() {
@@ -2838,10 +3278,11 @@
r'''
class A2 {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
}
void test_usedName_class_name_asTypeBound() {
@@ -2866,10 +3307,11 @@
r'''
class A2 {}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
}
void test_usedName_class_name_inBody() {
@@ -2899,10 +3341,11 @@
class B {}
class C2 {}
''');
+ _assertValidForChangedLibrary(a);
+ _assertValidForDependentLibrary(b);
_assertInvalid(a, LIBRARY_ERRORS_READY);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
}
void test_usedName_classMethod_name_inBody() {
@@ -2923,8 +3366,8 @@
}
''');
_performPendingAnalysisTasks();
- // Update a.dart: remove C.m, add C.m2.
- // b.dart is invalid, because it references c.m.
+ // Update a.dart: remove A.m, add A.m2.
+ // b.dart is invalid, because it references 'm'.
context.setContents(
a,
r'''
@@ -2932,10 +3375,12 @@
m2() {}
}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+ _assertValidForDependentLibrary(b);
+ _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
}
void test_usedName_indirect_classMethod_name_inBody() {
@@ -2962,7 +3407,7 @@
}
''');
_performPendingAnalysisTasks();
- // Update a.dart: remove C.m, add C.m2.
+ // Update a.dart: remove A.m, add A.m2.
// b.dart is invalid, because B extends A.
// c.dart is invalid, because 'main' references B.
context.setContents(
@@ -2972,13 +3417,18 @@
m2() {}
}
''');
+ _assertValidForChangedLibrary(a);
_assertInvalid(a, LIBRARY_ERRORS_READY);
+
+ _assertValidForDependentLibrary(b);
+ _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
_assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalid(c, LIBRARY_ERRORS_READY);
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
- _assertInvalidUnits(c, RESOLVED_UNIT4);
+
+ _assertValidForDependentLibrary(c);
_assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
+ _assertInvalidUnits(c, RESOLVED_UNIT4);
+ _assertInvalid(c, LIBRARY_ERRORS_READY);
}
void test_usedName_indirect_classMethod_returnType_inBody() {
@@ -3007,9 +3457,9 @@
}
''');
_performPendingAnalysisTasks();
- // Update a.dart: remove C.m, add C.m2.
+ // Update a.dart: remove A.m, add A.m2.
// b.dart is invalid, because B extends A.
- // c.dart is invalid, because 'main' references B.m.
+ // c.dart is invalid, because 'main' references 'm'.
context.setContents(
a,
r'''
@@ -3020,14 +3470,18 @@
}
''');
_assertInvalid(a, LIBRARY_ERRORS_READY);
- _assertInvalid(b, LIBRARY_ERRORS_READY);
- _assertInvalid(c, LIBRARY_ERRORS_READY);
+
// TODO(scheglov) In theory b.dart is not affected, because it does not
// call A.m, does not override it, etc.
- _assertInvalidUnits(b, RESOLVED_UNIT2);
- _assertInvalidLibraryElements(b, LIBRARY_ELEMENT2);
- _assertInvalidUnits(c, RESOLVED_UNIT4);
+ _assertValidForDependentLibrary(b);
+ _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
+ _assertInvalidUnits(b, RESOLVED_UNIT4);
+ _assertInvalid(b, LIBRARY_ERRORS_READY);
+
+ _assertValidForDependentLibrary(c);
_assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
+ _assertInvalidUnits(c, RESOLVED_UNIT4);
+ _assertInvalid(c, LIBRARY_ERRORS_READY);
}
void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
@@ -3077,9 +3531,62 @@
new LibrarySpecificUnit(librarySource, unitSource), descriptor);
}
+ void _assertUnitValidTaskResults(Source unitSource, TaskDescriptor descriptor,
+ {Source librarySource}) {
+ librarySource ??= unitSource;
+ for (ResultDescriptor result in descriptor.results) {
+ _assertUnitValid(unitSource, result, librarySource: librarySource);
+ }
+ }
+
void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) {
CacheState state = analysisCache.getState(target, descriptor);
- expect(state, CacheState.VALID, reason: '$descriptor in $target');
+ expect(state, isIn([CacheState.VALID, CacheState.FLUSHED]),
+ reason: '$descriptor in $target');
+ }
+
+ void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
+ for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
+ _assertValid(source, result);
+ }
+ library ??= source;
+ LibrarySpecificUnit target = new LibrarySpecificUnit(library, source);
+ for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
+ _assertValid(target, result);
+ }
+ }
+
+ void _assertValidForAnyLibrary(Source source) {
+ // Source results.
+ _assertValidTaskResults(source, ScanDartTask.DESCRIPTOR);
+ // Library results.
+ _assertValidTaskResults(source, BuildLibraryElementTask.DESCRIPTOR);
+ _assertValidTaskResults(source, BuildDirectiveElementsTask.DESCRIPTOR);
+ _assertValidTaskResults(source, BuildSourceExportClosureTask.DESCRIPTOR);
+ _assertValidTaskResults(source, ReadyLibraryElement2Task.DESCRIPTOR);
+ _assertValidTaskResults(source, ComputeLibraryCycleTask.DESCRIPTOR);
+ // Unit results.
+ _assertUnitValidTaskResults(
+ source, BuildCompilationUnitElementTask.DESCRIPTOR);
+ _assertUnitValidTaskResults(
+ source, ResolveDirectiveElementsTask.DESCRIPTOR);
+ _assertUnitValidTaskResults(source, BuildEnumMemberElementsTask.DESCRIPTOR);
+ }
+
+ void _assertValidForChangedLibrary(Source source) {
+ _assertValidForAnyLibrary(source);
+ }
+
+ void _assertValidForDependentLibrary(Source source) {
+ _assertValidForAnyLibrary(source);
+ // Library results.
+ _assertValidTaskResults(source, BuildPublicNamespaceTask.DESCRIPTOR);
+ }
+
+ void _assertValidTaskResults(AnalysisTarget target, TaskDescriptor task) {
+ for (ResultDescriptor result in task.results) {
+ _assertValid(target, result);
+ }
}
void _performPendingAnalysisTasks([int maxTasks = 512]) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 1adaae0..3cf454f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -510,6 +510,12 @@
@override
@failingTest
+ void test_inferDefaultFormalParameter() {
+ super.test_inferDefaultFormalParameter();
+ }
+
+ @override
+ @failingTest
void test_inferenceInCyclesIsDeterministic() {
super.test_inferenceInCyclesIsDeterministic();
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index 881ad8f..d31dcd4 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -4107,9 +4107,7 @@
checkLibrary('class C { bool operator<=(C other) => false; }');
}
- test_parameterTypeNotInferred_constructor() {
- // Strong mode doesn't do type inference on constructor parameters, so it's
- // ok that we don't store inferred type info for them in summaries.
+ test_parameterType_inferred_constructor() {
checkLibrary('''
class C {
C.positional([x = 1]);
@@ -4118,6 +4116,22 @@
''');
}
+ test_parameterType_inferred_staticMethod() {
+ checkLibrary('''
+class C {
+ static void positional([x = 1]) {}
+ static void named({x: 1}) {}
+}
+''');
+ }
+
+ test_parameterType_inferred_topLevelFunction() {
+ checkLibrary('''
+void positional([x = 1]) {}
+void named({x: 1}) {}
+''');
+ }
+
test_parameterTypeNotInferred_initializingFormal() {
// Strong mode doesn't do type inference on initializing formals, so it's
// ok that we don't store inferred type info for them in summaries.
@@ -4130,27 +4144,6 @@
''');
}
- test_parameterTypeNotInferred_staticMethod() {
- // Strong mode doesn't do type inference on parameters of static methods,
- // so it's ok that we don't store inferred type info for them in summaries.
- checkLibrary('''
-class C {
- static void positional([x = 1]) {}
- static void named({x: 1}) {}
-}
-''');
- }
-
- test_parameterTypeNotInferred_topLevelFunction() {
- // Strong mode doesn't do type inference on parameters of top level
- // functions, so it's ok that we don't store inferred type info for them in
- // summaries.
- checkLibrary('''
-void positional([x = 1]) {}
-void named({x: 1}) {}
-''');
- }
-
test_parts() {
addSource('/a.dart', 'part of my.lib;');
addSource('/b.dart', 'part of my.lib;');
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 33bd37b..25a6bef 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -66,9 +66,9 @@
runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
runReflectiveTests(PropagateVariableTypeTaskTest);
+ runReflectiveTests(ReferencedNamesBuilderTest);
runReflectiveTests(ResolveDirectiveElementsTaskTest);
runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
- runReflectiveTests(ResolveLibraryReferencesTaskTest);
runReflectiveTests(ResolveLibraryTaskTest);
runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
runReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
@@ -772,10 +772,11 @@
part of lib;
'''
});
- expect(outputs, hasLength(3));
+ expect(outputs, hasLength(4));
// simple outputs
expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
expect(outputs[IS_LAUNCHABLE], isFalse);
+ expect(outputs[REFERENCED_NAMES], isNotNull);
// LibraryElement output
expect(libraryElement, isNotNull);
expect(libraryElement.entryPoint, isNull);
@@ -1573,15 +1574,12 @@
library my_lib3;
import 'my_lib2.dart';
''');
- AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
- AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
- AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
- computeResult(lib1Target, LIBRARY_CYCLE);
+ computeResult(lib1Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
- computeResult(lib2Target, LIBRARY_CYCLE);
+ computeResult(lib2Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
- computeResult(lib3Target, LIBRARY_CYCLE);
+ computeResult(lib3Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
// create a cycle
@@ -1591,15 +1589,15 @@
library my_lib1;
import 'my_lib3.dart';
''');
- _expectInvalid(lib1Target);
- _expectInvalid(lib2Target);
- _expectInvalid(lib3Target);
+ _expectInvalid(lib1Source);
+ _expectInvalid(lib2Source);
+ _expectInvalid(lib3Source);
- computeResult(lib1Target, LIBRARY_CYCLE);
+ computeResult(lib1Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
- computeResult(lib2Target, LIBRARY_CYCLE);
+ computeResult(lib2Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
- computeResult(lib3Target, LIBRARY_CYCLE);
+ computeResult(lib3Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
// break the cycle again
@@ -1608,15 +1606,15 @@
'''
library my_lib1;
''');
- _expectInvalid(lib1Target);
- _expectInvalid(lib2Target);
- _expectInvalid(lib3Target);
+ _expectInvalid(lib1Source);
+ _expectInvalid(lib2Source);
+ _expectInvalid(lib3Source);
- computeResult(lib1Target, LIBRARY_CYCLE);
+ computeResult(lib1Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
- computeResult(lib2Target, LIBRARY_CYCLE);
+ computeResult(lib2Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
- computeResult(lib3Target, LIBRARY_CYCLE);
+ computeResult(lib3Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
}
@@ -1639,13 +1637,10 @@
library my_lib3;
import 'my_lib2.dart';
''');
- AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
- AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
- AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
- computeResult(lib1Target, LIBRARY_CYCLE);
+ computeResult(lib1Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
- computeResult(lib2Target, LIBRARY_CYCLE);
+ computeResult(lib2Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(1));
// lib3 is not reachable, so we have not yet computed its library
// cycles
@@ -1657,17 +1652,17 @@
library my_lib1;
import 'my_lib3.dart';
''');
- _expectInvalid(lib1Target);
- _expectInvalid(lib2Target);
- _expectInvalid(lib3Target);
+ _expectInvalid(lib1Source);
+ _expectInvalid(lib2Source);
+ _expectInvalid(lib3Source);
// Ensure that invalidation correctly invalidated everything reachable
// through lib3
- computeResult(lib1Target, LIBRARY_CYCLE);
+ computeResult(lib1Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
- computeResult(lib2Target, LIBRARY_CYCLE);
+ computeResult(lib2Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
- computeResult(lib3Target, LIBRARY_CYCLE);
+ computeResult(lib3Source, LIBRARY_CYCLE);
expect(outputs[LIBRARY_CYCLE], hasLength(3));
}
@@ -1780,9 +1775,9 @@
import 'my_lib3.dart';
var foo = 123;
''');
- _expectInvalid(lib1Target);
- _expectInvalid(lib2Target);
- _expectInvalid(lib3Target);
+ _expectInvalid(lib1Source);
+ _expectInvalid(lib2Source);
+ _expectInvalid(lib3Source);
computeResult(lib1Target, RESOLVED_UNIT);
computeResult(lib2Target, RESOLVED_UNIT);
@@ -1817,7 +1812,7 @@
'''
import 'dart:core';
''');
- computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE);
+ computeResult(source, LIBRARY_CYCLE);
List<LibraryElement> component = getLibraryCycle(outputs);
List<CompilationUnitElement> units = getLibraryCycleUnits(outputs);
List<CompilationUnitElement> deps = getLibraryCycleDependencies(outputs);
@@ -1942,86 +1937,46 @@
'/db.dart': '''
'''
});
- computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), LIBRARY_CYCLE);
+ computeResult(sources[0], LIBRARY_CYCLE);
Map<ResultDescriptor, dynamic> results0 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), LIBRARY_CYCLE);
+ computeResult(sources[1], LIBRARY_CYCLE);
Map<ResultDescriptor, dynamic> results1 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[0], sources[2]), LIBRARY_CYCLE);
- Map<ResultDescriptor, dynamic> results2 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[0], sources[3]), LIBRARY_CYCLE);
- Map<ResultDescriptor, dynamic> results3 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[4], sources[4]), LIBRARY_CYCLE);
+ computeResult(sources[4], LIBRARY_CYCLE);
Map<ResultDescriptor, dynamic> results4 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[5], sources[5]), LIBRARY_CYCLE);
+ computeResult(sources[5], LIBRARY_CYCLE);
Map<ResultDescriptor, dynamic> results5 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[5], sources[6]), LIBRARY_CYCLE);
- Map<ResultDescriptor, dynamic> results6 = outputs;
- computeResult(
- new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE);
- Map<ResultDescriptor, dynamic> results7 = outputs;
List<LibraryElement> component0 = getLibraryCycle(results0);
List<LibraryElement> component1 = getLibraryCycle(results1);
- List<LibraryElement> component2 = getLibraryCycle(results2);
- List<LibraryElement> component3 = getLibraryCycle(results3);
List<LibraryElement> component4 = getLibraryCycle(results4);
List<LibraryElement> component5 = getLibraryCycle(results5);
- List<LibraryElement> component6 = getLibraryCycle(results6);
- List<LibraryElement> component7 = getLibraryCycle(results7);
expect(component0, hasLength(2));
expect(component1, hasLength(2));
- expect(component2, hasLength(2));
- expect(component3, hasLength(2));
expect(component4, hasLength(2));
expect(component5, hasLength(2));
- expect(component6, hasLength(2));
- expect(component7, hasLength(2));
List<CompilationUnitElement> units0 = getLibraryCycleUnits(results0);
List<CompilationUnitElement> units1 = getLibraryCycleUnits(results1);
- List<CompilationUnitElement> units2 = getLibraryCycleUnits(results2);
- List<CompilationUnitElement> units3 = getLibraryCycleUnits(results3);
List<CompilationUnitElement> units4 = getLibraryCycleUnits(results4);
List<CompilationUnitElement> units5 = getLibraryCycleUnits(results5);
- List<CompilationUnitElement> units6 = getLibraryCycleUnits(results6);
- List<CompilationUnitElement> units7 = getLibraryCycleUnits(results7);
expect(units0, hasLength(4));
expect(units1, hasLength(4));
- expect(units2, hasLength(4));
- expect(units3, hasLength(4));
expect(units4, hasLength(4));
expect(units5, hasLength(4));
- expect(units6, hasLength(4));
- expect(units7, hasLength(4));
List<CompilationUnitElement> dep0 = getLibraryCycleDependencies(results0);
List<CompilationUnitElement> dep1 = getLibraryCycleDependencies(results1);
- List<CompilationUnitElement> dep2 = getLibraryCycleDependencies(results2);
- List<CompilationUnitElement> dep3 = getLibraryCycleDependencies(results3);
List<CompilationUnitElement> dep4 = getLibraryCycleDependencies(results4);
List<CompilationUnitElement> dep5 = getLibraryCycleDependencies(results5);
- List<CompilationUnitElement> dep6 = getLibraryCycleDependencies(results6);
- List<CompilationUnitElement> dep7 = getLibraryCycleDependencies(results7);
expect(dep0, hasLength(1)); // dart:core
expect(dep1, hasLength(1)); // dart:core
- expect(dep2, hasLength(1)); // dart:core
- expect(dep3, hasLength(1)); // dart:core
expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
- expect(dep6, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
- expect(dep7, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
}
- void _expectInvalid(LibrarySpecificUnit target) {
- CacheEntry entry = context.getCacheEntry(target);
+ void _expectInvalid(Source librarySource) {
+ CacheEntry entry = context.getCacheEntry(librarySource);
expect(entry.getState(LIBRARY_CYCLE), CacheState.INVALID);
}
}
@@ -3711,6 +3666,452 @@
}
@reflectiveTest
+class ReferencedNamesBuilderTest extends _AbstractDartTaskTest {
+ void setUp() {
+ super.setUp();
+ context.analysisOptions = new AnalysisOptionsImpl()
+ ..enableGenericMethods = true
+ ..strongMode = true;
+ }
+
+ test_class_constructor() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ U.named(A a, B b) {
+ C c = null;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
+ }
+
+ test_class_field() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ A f = new B();
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['B']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
+ }
+
+ test_class_getter() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ A get a => new B();
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['B']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A']));
+ }
+
+ test_class_members() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ int a;
+ int get b;
+ set c(_) {}
+ m(D d) {
+ a;
+ b;
+ c = 1;
+ m();
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['int', 'D']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
+ }
+
+ test_class_members_dontHideQualified() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ int a;
+ int get b;
+ set c(_) {}
+ m(D d) {
+ d.a;
+ d.b;
+ d.c;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['int', 'D', 'a', 'b', 'c']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
+ }
+
+ test_class_method() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ A m(B p) {
+ C v = 0;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
+ }
+
+ test_class_method_localVariables() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ A m() {
+ B b = null;
+ b;
+ {
+ C c = null;
+ b;
+ c;
+ }
+ d;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A']));
+ }
+
+ test_class_method_parameters() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ m(A a) {
+ a;
+ b;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'b']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A']));
+ }
+
+ test_class_method_typeParameters() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ A m<T>(B b, T t) {
+ C c = 0;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
+ }
+
+ test_class_setter() {
+ ReferencedNames info = _computeReferencedNames('''
+class U {
+ set a(A a) {
+ B b = null;
+ }
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A']));
+ }
+
+ test_class_typeParameters() {
+ ReferencedNames info = _computeReferencedNames('''
+class U<T> {
+ T f = new A<T>();
+}
+''');
+ expect(info.names, unorderedEquals(['A']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['A']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A']));
+ }
+
+ test_instantiatedNames_importPrefix() {
+ ReferencedNames info = _computeReferencedNames('''
+import 'a.dart' as p1;
+import 'b.dart' as p2;
+main() {
+ new p1.A();
+ new p1.A.c1();
+ new p1.B();
+ new p2.C();
+ new D();
+ new D.c2();
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'D', 'c1', 'c2']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['A', 'B', 'C', 'D']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['main']));
+ expect(info.userToDependsOn['main'], isEmpty);
+ }
+
+ test_localFunction() {
+ ReferencedNames info = _computeReferencedNames('''
+f(A a) {
+ g(B b) {}
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A']));
+ }
+
+ test_superToSubs_importPrefix() {
+ ReferencedNames info = _computeReferencedNames('''
+import 'a.dart' as p1;
+import 'b.dart' as p2;
+class U extends p1.A with p2.B implements p2.C {}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs['A'], unorderedEquals(['U']));
+ expect(info.superToSubs['B'], unorderedEquals(['U']));
+ expect(info.superToSubs['C'], unorderedEquals(['U']));
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
+ }
+
+ test_topLevelVariable() {
+ ReferencedNames info = _computeReferencedNames('''
+A v = new B(c);
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'c']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['B']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['v']));
+ expect(info.userToDependsOn['v'], unorderedEquals(['A', 'B', 'c']));
+ }
+
+ test_topLevelVariable_multiple() {
+ ReferencedNames info = _computeReferencedNames('''
+A v1 = new B(c), v2 = new D<E>(f);
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'c', 'D', 'E', 'f']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['B', 'D']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['v1', 'v2']));
+ expect(info.userToDependsOn['v1'], unorderedEquals(['A', 'B', 'c']));
+ expect(info.userToDependsOn['v2'], unorderedEquals(['A', 'D', 'E', 'f']));
+ }
+
+ test_unit_classTypeAlias() {
+ ReferencedNames info = _computeReferencedNames('''
+class U = A with B implements C;
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs['A'], unorderedEquals(['U']));
+ expect(info.superToSubs['B'], unorderedEquals(['U']));
+ expect(info.superToSubs['C'], unorderedEquals(['U']));
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
+ }
+
+ test_unit_classTypeAlias_typeParameters() {
+ ReferencedNames info = _computeReferencedNames('''
+class U<T1, T2 extends D> = A<T1> with B<T2> implements C<T1, T2>;
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
+ expect(info.superToSubs.keys, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs['A'], unorderedEquals(['U']));
+ expect(info.superToSubs['B'], unorderedEquals(['U']));
+ expect(info.superToSubs['C'], unorderedEquals(['U']));
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['U']));
+ expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C', 'D']));
+ }
+
+ test_unit_function() {
+ ReferencedNames info = _computeReferencedNames('''
+A f(B b) {
+ C c = 0;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_function_doc() {
+ ReferencedNames info = _computeReferencedNames('''
+/**
+ * Documentation [C.d] reference.
+ */
+A f(B b) {}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_function_localFunctions() {
+ ReferencedNames info = _computeReferencedNames('''
+A f() {
+ B b = null;
+ C g() {}
+ g();
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A']));
+ }
+
+ test_unit_function_localsDontHideQualified() {
+ ReferencedNames info = _computeReferencedNames('''
+f(A a, B b) {
+ var v = 0;
+ a.v;
+ a.b;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'v', 'b']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_function_localVariables() {
+ ReferencedNames info = _computeReferencedNames('''
+A f() {
+ B b = null;
+ b;
+ {
+ C c = null;
+ b;
+ c;
+ }
+ d;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A']));
+ }
+
+ test_unit_function_parameters() {
+ ReferencedNames info = _computeReferencedNames('''
+A f(B b) {
+ C c = 0;
+ b;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_function_typeParameters() {
+ ReferencedNames info = _computeReferencedNames('''
+A f<T>(B b, T t) {
+ C c = 0;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['f']));
+ expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_functionTypeAlias() {
+ ReferencedNames info = _computeReferencedNames('''
+typedef A F(B B, C c(D d));
+''');
+ expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['F']));
+ expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B', 'C', 'D']));
+ }
+
+ test_unit_functionTypeAlias_typeParameters() {
+ ReferencedNames info = _computeReferencedNames('''
+typedef A F<T>(B b, T t);
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['F']));
+ expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B']));
+ }
+
+ test_unit_getter() {
+ ReferencedNames info = _computeReferencedNames('''
+A get aaa {
+ return new B();
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, unorderedEquals(['B']));
+ expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
+ expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
+ }
+
+ test_unit_setter() {
+ ReferencedNames info = _computeReferencedNames('''
+set aaa(A a) {
+ B b = null;
+}
+''');
+ expect(info.names, unorderedEquals(['A', 'B']));
+ expect(info.superToSubs.keys, isEmpty);
+ expect(info.instantiatedNames, isEmpty);
+ expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
+ expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
+ }
+
+ ReferencedNames _computeReferencedNames(String code) {
+ Source source = newSource('/test.dart', code);
+ computeResult(source, REFERENCED_NAMES, matcher: isBuildLibraryElementTask);
+ return outputs[REFERENCED_NAMES];
+ }
+}
+
+@reflectiveTest
class ResolveDirectiveElementsTaskTest extends _AbstractDartTaskTest {
test_perform() {
List<Source> sources = newSources({
@@ -3999,345 +4400,6 @@
}
@reflectiveTest
-class ResolveLibraryReferencesTaskTest extends _AbstractDartTaskTest {
- void setUp() {
- super.setUp();
- context.analysisOptions = new AnalysisOptionsImpl()
- ..enableGenericMethods = true
- ..strongMode = true;
- }
-
- test_referencedNames_class_constructor() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- U.named(A a, B b) {
- C c = null;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_class_field() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- A f = new B();
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_class_getter() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- A get a => new B();
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A']));
- }
-
- test_referencedNames_class_members() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- int a;
- int get b;
- set c(_) {}
- m(D d) {
- a;
- b;
- c = 1;
- m();
- }
-}
-''');
- expect(info.names, unorderedEquals(['int', 'D']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
- }
-
- test_referencedNames_class_members_dontHideQualified() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- int a;
- int get b;
- set c(_) {}
- m(D d) {
- d.a;
- d.b;
- d.c;
- }
-}
-''');
- expect(info.names, unorderedEquals(['int', 'D', 'a', 'b', 'c']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['int', 'D']));
- }
-
- test_referencedNames_class_method() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- A m(B p) {
- C v = 0;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_class_method_localVariables() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- A m() {
- B b = null;
- b;
- {
- C c = null;
- b;
- c;
- }
- d;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A']));
- }
-
- test_referencedNames_class_method_parameters() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- m(A a) {
- a;
- b;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'b']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A']));
- }
-
- test_referencedNames_class_method_typeParameters() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- A m<T>(B b, T t) {
- C c = 0;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_class_setter() {
- ReferencedNames info = _computeReferencedNames('''
-class U {
- set a(A a) {
- B b = null;
- }
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A']));
- }
-
- test_referencedNames_class_typeParameters() {
- ReferencedNames info = _computeReferencedNames('''
-class U<T> {
- T f = new A<T>();
-}
-''');
- expect(info.names, unorderedEquals(['A']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A']));
- }
-
- test_referencedNames_localFunction() {
- ReferencedNames info = _computeReferencedNames('''
-f(A a) {
- g(B b) {}
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A']));
- }
-
- test_referencedNames_topLevelVariable() {
- ReferencedNames info = _computeReferencedNames('''
-A v = new B(c);
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'c']));
- expect(info.userToDependsOn.keys, unorderedEquals(['v']));
- expect(info.userToDependsOn['v'], unorderedEquals(['A', 'B', 'c']));
- }
-
- test_referencedNames_topLevelVariable_multiple() {
- ReferencedNames info = _computeReferencedNames('''
-A v1 = new B(c), v2 = new D<E>(f);
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'c', 'D', 'E', 'f']));
- expect(info.userToDependsOn.keys, unorderedEquals(['v1', 'v2']));
- expect(info.userToDependsOn['v1'], unorderedEquals(['A', 'B', 'c']));
- expect(info.userToDependsOn['v2'], unorderedEquals(['A', 'D', 'E', 'f']));
- }
-
- test_referencedNames_unit_classTypeAlias() {
- ReferencedNames info = _computeReferencedNames('''
-class U = A with B implements C;
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C']));
- }
-
- test_referencedNames_unit_classTypeAlias_typeParameters() {
- ReferencedNames info = _computeReferencedNames('''
-class U<T1, T2 extends D> = A<T1> with B<T2> implements C<T1, T2>;
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
- expect(info.userToDependsOn.keys, unorderedEquals(['U']));
- expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B', 'C', 'D']));
- }
-
- test_referencedNames_unit_function() {
- ReferencedNames info = _computeReferencedNames('''
-A f(B b) {
- C c = 0;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_unit_function_localFunctions() {
- ReferencedNames info = _computeReferencedNames('''
-A f() {
- B b = null;
- C g() {}
- g();
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A']));
- }
-
- test_referencedNames_unit_function_localsDontHideQualified() {
- ReferencedNames info = _computeReferencedNames('''
-f(A a, B b) {
- var v = 0;
- a.v;
- a.b;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'v', 'b']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_unit_function_localVariables() {
- ReferencedNames info = _computeReferencedNames('''
-A f() {
- B b = null;
- b;
- {
- C c = null;
- b;
- c;
- }
- d;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C', 'd']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A']));
- }
-
- test_referencedNames_unit_function_parameters() {
- ReferencedNames info = _computeReferencedNames('''
-A f(B b) {
- C c = 0;
- b;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_unit_function_typeParameters() {
- ReferencedNames info = _computeReferencedNames('''
-A f<T>(B b, T t) {
- C c = 0;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C']));
- expect(info.userToDependsOn.keys, unorderedEquals(['f']));
- expect(info.userToDependsOn['f'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_unit_functionTypeAlias() {
- ReferencedNames info = _computeReferencedNames('''
-typedef A F(B B, C c(D d));
-''');
- expect(info.names, unorderedEquals(['A', 'B', 'C', 'D']));
- expect(info.userToDependsOn.keys, unorderedEquals(['F']));
- expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B', 'C', 'D']));
- }
-
- test_referencedNames_unit_functionTypeAlias_typeParameters() {
- ReferencedNames info = _computeReferencedNames('''
-typedef A F<T>(B b, T t);
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['F']));
- expect(info.userToDependsOn['F'], unorderedEquals(['A', 'B']));
- }
-
- test_referencedNames_unit_getter() {
- ReferencedNames info = _computeReferencedNames('''
-A get aaa {
- return new B();
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
- expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
- }
-
- test_referencedNames_unit_setter() {
- ReferencedNames info = _computeReferencedNames('''
-set aaa(A a) {
- B b = null;
-}
-''');
- expect(info.names, unorderedEquals(['A', 'B']));
- expect(info.userToDependsOn.keys, unorderedEquals(['aaa']));
- expect(info.userToDependsOn['aaa'], unorderedEquals(['A']));
- }
-
- ReferencedNames _computeReferencedNames(String code) {
- Source source = newSource('/test.dart', code);
- computeResult(source, REFERENCED_NAMES,
- matcher: isResolveLibraryReferencesTask);
- return outputs[REFERENCED_NAMES];
- }
-}
-
-@reflectiveTest
class ResolveLibraryTaskTest extends _AbstractDartTaskTest {
test_perform() {
Source sourceLib = newSource(
@@ -5672,8 +5734,7 @@
List<Source> sources, ResultDescriptor result,
{isInstanceOf matcher: null}) {
Map<ResultDescriptor, dynamic> compute(Source source) {
- computeResult(new LibrarySpecificUnit(source, source), result,
- matcher: matcher);
+ computeResult(source, result, matcher: matcher);
return outputs;
}
return sources.map(compute).toList();
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index 975de87..8d495af 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/incremental_element_builder.dart';
@@ -219,6 +220,134 @@
expect(helper.delta.removedMethods, isEmpty);
}
+ test_classDelta_constructor_fieldReference_initializer() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ final int f;
+ A() : f = 1 {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ final int f;
+ A() : f = 1;
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ }
+
+ test_classDelta_constructor_fieldReference_parameter() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ final int f;
+ A(this.f) {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ final int f;
+ A(this.f);
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ }
+
+ test_classDelta_constructor_fieldReference_parameter_default() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ final int f;
+ A([this.f = 1]) {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ final int f;
+ A([this.f = 1]);
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ }
+
+ test_classDelta_duplicate_constructor() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ A() {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ A() {}
+ A() {}
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ // nodes
+ ConstructorDeclaration oldNode = helper.oldMembers[0];
+ ConstructorDeclaration newNode1 = helper.newMembers[0];
+ ConstructorDeclaration newNode2 = helper.newMembers[1];
+ // elements
+ ConstructorElement oldElement = oldNode.element;
+ ConstructorElement newElement1 = newNode1.element;
+ ConstructorElement newElement2 = newNode2.element;
+ expect(newElement1, same(oldElement));
+ expect(newElement2, isNot(same(oldElement)));
+ expect(oldElement.name, '');
+ expect(newElement1.name, '');
+ expect(newElement2.name, '');
+ // verify delta
+ expect(helper.delta.addedConstructors, unorderedEquals([newElement2]));
+ expect(helper.delta.removedConstructors, isEmpty);
+ expect(helper.delta.addedAccessors, isEmpty);
+ expect(helper.delta.removedAccessors, isEmpty);
+ expect(helper.delta.addedMethods, isEmpty);
+ expect(helper.delta.removedMethods, isEmpty);
+ }
+
+ test_classDelta_duplicate_method() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ m() {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ m() {}
+ m() {}
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ // nodes
+ MethodDeclaration oldNode = helper.oldMembers[0];
+ MethodDeclaration newNode1 = helper.newMembers[0];
+ MethodDeclaration newNode2 = helper.newMembers[1];
+ // elements
+ MethodElement oldElement = oldNode.element;
+ MethodElement newElement1 = newNode1.element;
+ MethodElement newElement2 = newNode2.element;
+ expect(newElement1, same(oldElement));
+ expect(newElement2, isNot(same(oldElement)));
+ expect(oldElement.name, 'm');
+ expect(newElement1.name, 'm');
+ expect(newElement2.name, 'm');
+ // verify delta
+ expect(helper.delta.addedConstructors, isEmpty);
+ expect(helper.delta.removedConstructors, isEmpty);
+ expect(helper.delta.addedAccessors, isEmpty);
+ expect(helper.delta.removedAccessors, isEmpty);
+ expect(helper.delta.addedMethods, unorderedEquals([newElement2]));
+ expect(helper.delta.removedMethods, isEmpty);
+ }
+
test_classDelta_field_add() {
var helper = new _ClassDeltaHelper('A');
_buildOldUnit(r'''
@@ -253,47 +382,6 @@
expect(helper.delta.removedMethods, isEmpty);
}
- test_classDelta_field_changeName() {
- var helper = new _ClassDeltaHelper('A');
- _buildOldUnit(r'''
-class A {
- int aaa;
- int bbb;
-}
-''');
- helper.initOld(oldUnit);
- _buildNewUnit(r'''
-class A {
- int aaa2;
- int bbb;
-}
-''');
- helper.initNew(newUnit, unitDelta);
- // nodes
- FieldDeclaration oldNodeA = helper.oldMembers[0];
- FieldDeclaration newNodeA = helper.newMembers[0];
- List<VariableDeclaration> oldFieldsA = oldNodeA.fields.variables;
- List<VariableDeclaration> newFieldsA = newNodeA.fields.variables;
- expect(oldFieldsA, hasLength(1));
- expect(newFieldsA, hasLength(1));
- FieldDeclaration nodeB = helper.newMembers[1];
- expect(nodeB, same(helper.oldMembers[1]));
- // elements
- FieldElement oldFieldElementA = oldFieldsA[0].name.staticElement;
- FieldElement newFieldElementA = newFieldsA[0].name.staticElement;
- expect(oldFieldElementA.name, 'aaa');
- expect(newFieldElementA.name, 'aaa2');
- // verify delta
- expect(helper.delta.addedConstructors, isEmpty);
- expect(helper.delta.removedConstructors, isEmpty);
- expect(helper.delta.addedAccessors,
- unorderedEquals([newFieldElementA.getter, newFieldElementA.setter]));
- expect(helper.delta.removedAccessors,
- unorderedEquals([oldFieldElementA.getter, oldFieldElementA.setter]));
- expect(helper.delta.addedMethods, isEmpty);
- expect(helper.delta.removedMethods, isEmpty);
- }
-
test_classDelta_field_remove() {
var helper = new _ClassDeltaHelper('A');
_buildOldUnit(r'''
@@ -597,6 +685,154 @@
expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
}
+ test_classDelta_null_extendsClause_add() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class B {}
+''',
+ r'''
+class A {}
+class B extends A {}
+''');
+ }
+
+ test_classDelta_null_extendsClause_change() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A1 {}
+class A2 {}
+class B extends A1 {}
+''',
+ r'''
+class A1 {}
+class A2 {}
+class B extends A2 {}
+''');
+ }
+
+ test_classDelta_null_extendsClause_remove() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class B extends A {}
+''',
+ r'''
+class A {}
+class B {}
+''');
+ }
+
+ test_classDelta_null_implementsClause_add() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class B {}
+''',
+ r'''
+class A {}
+class B implements A {}
+''');
+ }
+
+ test_classDelta_null_implementsClause_change() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A1 {}
+class A2 {}
+class B implements A1 {}
+''',
+ r'''
+class A1 {}
+class A2 {}
+class B implements A2 {}
+''');
+ }
+
+ test_classDelta_null_implementsClause_remove() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class B implements A {}
+''',
+ r'''
+class A {}
+class B {}
+''');
+ }
+
+ test_classDelta_null_typeParameters_change() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class B<T> {}
+''',
+ r'''
+class A {}
+class B<T extends A> {}
+''');
+ }
+
+ test_classDelta_null_withClause_add() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class M {}
+class B extends A {}
+''',
+ r'''
+class A {}
+class M {}
+class B extends A with M {}
+''');
+ }
+
+ test_classDelta_null_withClause_change1() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class M1 {}
+class M2 {}
+class B extends A with M1 {}
+''',
+ r'''
+class A {}
+class M1 {}
+class M2 {}
+class B extends A with M2 {}
+''');
+ }
+
+ test_classDelta_null_withClause_change2() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class M1 {}
+class M2 {}
+class B extends A with M1, M2 {}
+''',
+ r'''
+class A {}
+class M1 {}
+class M2 {}
+class B extends A with M2, M1 {}
+''');
+ }
+
+ test_classDelta_null_withClause_remove() {
+ _verifyNoClassDeltaForTheLast(
+ r'''
+class A {}
+class M {}
+class B extends A with M {}
+''',
+ r'''
+class A {}
+class M {}
+class B extends A {}
+''');
+ }
+
test_classDelta_setter_add() {
var helper = new _ClassDeltaHelper('A');
_buildOldUnit(r'''
@@ -665,6 +901,19 @@
expect(helper.delta.removedMethods, isEmpty);
}
+ test_classDelta_typeParameter_same() {
+ _buildOldUnit(r'''
+class A<T> {
+ m() {}
+}
+''');
+ _buildNewUnit(r'''
+class A<T> {
+ m2() {}
+}
+''');
+ }
+
test_directives_add() {
_buildOldUnit(r'''
library test;
@@ -1299,27 +1548,160 @@
expect(unitDelta.removedDeclarations, unorderedEquals([]));
}
+ test_update_addIdentifier_beforeConstructorWithComment() {
+ _buildOldUnit(r'''
+class A {
+ /// CCC
+ A();
+}
+''');
+ _buildNewUnit(r'''
+class A {
+ b
+
+ /// CCC
+ A();
+}
+''');
+ }
+
+ test_update_beforeClassWithDelta_nameOffset() {
+ _buildOldUnit(r'''
+class A {}
+
+class B {
+ A a;
+}
+''');
+ _buildNewUnit(r'''
+class A2 {}
+
+class B {
+ A2 a;
+}
+''');
+ }
+
+ test_update_changeDuplicatingOffsetsMapping() {
+ _buildOldUnit(r'''
+class A {
+ m() {
+ }
+}
+
+/// X
+class C {}
+''');
+ _buildNewUnit(r'''
+class A {
+ m2() {
+ b
+ }
+}
+
+/// X
+class C {}
+''');
+ }
+
+ test_update_closuresOfSyntheticInitializer() {
+ _buildOldUnit(r'''
+f1() {
+ print(1);
+}
+f2() {
+ B b = new B((C c) {});
+}
+''');
+ _buildNewUnit(r'''
+f1() {
+ print(12);
+}
+f2() {
+ B b = new B((C c) {});
+}
+''');
+ }
+
+ test_update_commentReference_empty() {
+ _buildOldUnit(r'''
+/// Empty [] reference.
+class A {}
+''');
+ _buildNewUnit(r'''
+/// Empty [] reference.
+class A {}
+''');
+ }
+
+ test_update_commentReference_notClosed() {
+ _buildOldUnit(r'''
+/// [c)
+class A {}
+''');
+ _buildNewUnit(r'''
+int a;
+/// [c)
+class A {}
+''');
+ }
+
+ test_update_rewrittenConstructorName() {
+ _buildOldUnit(r'''
+class A {
+ A();
+ A.named();
+}
+
+foo() {}
+
+main() {
+ new A();
+ new A.named();
+}
+''');
+ _buildNewUnit(r'''
+class A {
+ A();
+ A.named();
+}
+
+bar() {}
+
+main() {
+ new A();
+ new A.named();
+}
+''');
+ }
+
void _buildNewUnit(String newCode) {
this.newCode = newCode;
- context.setContents(source, newCode);
- newUnit = context.parseCompilationUnit(source);
- IncrementalCompilationUnitElementBuilder builder =
- new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
- builder.build();
- unitDelta = builder.unitDelta;
- expect(newUnit.element, unitElement);
- // Flush all tokens, ASTs and elements.
- context.analysisCache.flush((target, result) {
- return result == TOKEN_STREAM ||
- result == PARSED_UNIT ||
- RESOLVED_UNIT_RESULTS.contains(result) ||
- LIBRARY_ELEMENT_RESULTS.contains(result);
- });
- // Compute a new AST with built elements.
- CompilationUnit newUnitFull = context.computeResult(
- new LibrarySpecificUnit(source, source), RESOLVED_UNIT1);
- expect(newUnitFull, isNot(same(newUnit)));
- new _BuiltElementsValidator().isEqualNodes(newUnitFull, newUnit);
+ AnalysisOptionsImpl analysisOptions = context.analysisOptions;
+ analysisOptions.finerGrainedInvalidation = false;
+ try {
+ context.setContents(source, newCode);
+ newUnit = context.parseCompilationUnit(source);
+ IncrementalCompilationUnitElementBuilder builder =
+ new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
+ builder.build();
+ unitDelta = builder.unitDelta;
+ expect(newUnit.element, unitElement);
+ // Flush all tokens, ASTs and elements.
+ context.analysisCache.flush((target, result) {
+ return result == TOKEN_STREAM ||
+ result == PARSED_UNIT ||
+ RESOLVED_UNIT_RESULTS.contains(result) ||
+ LIBRARY_ELEMENT_RESULTS.contains(result);
+ });
+ // Compute a new AST with built elements.
+ CompilationUnit newUnitFull = context.computeResult(
+ new LibrarySpecificUnit(source, source), RESOLVED_UNIT1);
+ expect(newUnitFull, isNot(same(newUnit)));
+ new _BuiltElementsValidator().isEqualNodes(newUnitFull, newUnit);
+ } finally {
+ analysisOptions.finerGrainedInvalidation = true;
+ }
}
void _buildOldUnit(String oldCode, [Source libSource]) {
@@ -1332,6 +1714,19 @@
unitElement = oldUnit.element;
expect(unitElement, isNotNull);
}
+
+ void _verifyNoClassDeltaForTheLast(String oldCode, String newCode) {
+ _buildOldUnit(oldCode);
+ List<CompilationUnitMember> oldMembers = oldUnit.declarations.toList();
+ Element oldElementLast = oldMembers.last.element;
+ _buildNewUnit(newCode);
+ List<CompilationUnitMember> newMembers = newUnit.declarations;
+ Element newElementLast = newMembers.last.element;
+ expect(newElementLast, isNot(same(oldElementLast)));
+ expect(unitDelta.classDeltas, isEmpty);
+ expect(unitDelta.removedDeclarations, unorderedEquals([oldElementLast]));
+ expect(unitDelta.addedDeclarations, unorderedEquals([newElementLast]));
+ }
}
/**
@@ -1340,13 +1735,43 @@
class _BuiltElementsValidator extends AstComparator {
@override
bool isEqualNodes(AstNode expected, AstNode actual) {
- // Elements of constructors must be linked to the elements of the
- // corresponding enclosing classes.
- if (actual is ConstructorDeclaration) {
- ConstructorElement actualConstructorElement = actual.element;
- ClassDeclaration actualClassNode = actual.parent;
- expect(actualConstructorElement.enclosingElement,
- same(actualClassNode.element));
+ // Elements of nodes which are children of ClassDeclaration(s) must be
+ // linked to the corresponding ClassElement(s).
+ if (actual is TypeParameter) {
+ TypeParameterElement element = actual.element;
+ ClassDeclaration classNode = actual.parent.parent;
+ expect(element.enclosingElement, same(classNode.element));
+ } else if (actual is FieldDeclaration) {
+ for (VariableDeclaration field in actual.fields.variables) {
+ Element element = field.element;
+ ClassDeclaration classNode = actual.parent;
+ expect(element.enclosingElement, same(classNode.element));
+ }
+ } else if (actual is ClassMember) {
+ Element element = actual.element;
+ ClassDeclaration classNode = actual.parent;
+ expect(element.enclosingElement, same(classNode.element));
+ }
+ // Field elements referenced by field formal parameters of constructors
+ // must by fields of the enclosing class element.
+ if (actual is FieldFormalParameter) {
+ FieldFormalParameterElement parameterElement = actual.element;
+ FieldElement element = parameterElement.field;
+ ClassDeclaration classNode =
+ actual.getAncestor((n) => n is ClassDeclaration);
+ expect(element.enclosingElement, same(classNode.element));
+ }
+ // Identifiers like 'a.b' in 'new a.b()' might be rewritten if resolver
+ // sees that 'a' is actually a class name, so 'b' is a constructor name.
+ //
+ if (expected is ConstructorName && actual is ConstructorName) {
+ Identifier expectedTypeName = expected.type.name;
+ Identifier actualTypeName = actual.type.name;
+ if (expectedTypeName is PrefixedIdentifier &&
+ actualTypeName is SimpleIdentifier) {
+ return isEqualNodes(expectedTypeName.prefix, actualTypeName) &&
+ isEqualNodes(expectedTypeName.identifier, actual.name);
+ }
}
// Compare nodes.
bool result = super.isEqualNodes(expected, actual);
@@ -1418,12 +1843,8 @@
ClassDeclaration newClass = _findClassNode(newUnit, name);
expect(newClass, isNotNull);
newMembers = newClass.members.toList();
- for (ClassElementDelta delta in unitDelta.classDeltas) {
- if (delta.element.name == name) {
- this.delta = delta;
- }
- }
- expect(this.delta, isNotNull, reason: 'No delta for class: $name');
+ delta = unitDelta.classDeltas[name];
+ expect(delta, isNotNull, reason: 'No delta for class: $name');
}
void initOld(CompilationUnit oldUnit) {
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a86658c..77145e9 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -19,7 +19,7 @@
import 'dart:async';
main() async {
// Don't choke if sequence is not stream.
- await for (var i in /*severe:FOR_IN_OF_INVALID_TYPE*/1234) {}
+ await for (var i in /*error:FOR_IN_OF_INVALID_TYPE*/1234) {}
// Dynamic cast.
await for (String /*info:DYNAMIC_CAST*/s in new Stream<dynamic>()) {}
@@ -81,9 +81,9 @@
a = a ~/ b;
a = a % b;
a = a + b;
- a = a + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
+ a = a + /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a = a - b;
- b = /*severe:INVALID_ASSIGNMENT*/b - b;
+ b = /*error:INVALID_ASSIGNMENT*/b - b;
a = a << b;
a = a >> b;
a = a & b;
@@ -95,20 +95,20 @@
int y = 42;
x = x + x;
x = x + /*info:DYNAMIC_CAST*/c;
- x = x + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
+ x = x + /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
bool p = true;
p = p && p;
p = p && /*info:DYNAMIC_CAST*/c;
p = (/*info:DYNAMIC_CAST*/c) && p;
p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
- p = /*severe:NON_BOOL_OPERAND*/y && p;
+ p = /*error:NON_BOOL_OPERAND*/y && p;
p = c == y;
a = a[b];
a = a[/*info:DYNAMIC_CAST*/c];
c = (/*info:DYNAMIC_INVOKE*/c[b]);
- a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
+ a[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
}
''');
}
@@ -131,7 +131,7 @@
static const num n = 3.0;
// The severe error is from constant evaluation where we know the
// concrete type.
- static const int /*severe:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n;
+ static const int /*error:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n;
final int fi;
const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
}
@@ -139,7 +139,7 @@
const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
}
void foo(Object o) {
- var a = const A(/*info:DOWN_CAST_IMPLICIT, severe:CONST_WITH_NON_CONSTANT_ARGUMENT, severe:INVALID_CONSTANT*/o);
+ var a = const A(/*info:DOWN_CAST_IMPLICIT, error:CONST_WITH_NON_CONSTANT_ARGUMENT, error:INVALID_CONSTANT*/o);
}
''');
}
@@ -155,8 +155,8 @@
abstract class Base implements I1 {}
class T1 extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -170,14 +170,14 @@
m(A a);
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
implements I1 {}
class T1 extends Base {
// not reported technically because if the class is concrete,
// it should implement all its interfaces and hence it is
// sufficient to check overrides against it.
- m(/*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ m(/*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -193,8 +193,8 @@
abstract class I2 implements I1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -210,8 +210,8 @@
abstract class I2 extends Object with M1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -227,8 +227,8 @@
abstract class I2 extends I1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -264,7 +264,7 @@
test() {
int x = 0;
x += 5;
- /*severe:STATIC_TYPE_ERROR*/x += 3.14;
+ /*error:STATIC_TYPE_ERROR*/x += 3.14;
double y = 0.0;
y += 5;
@@ -294,9 +294,9 @@
a ~/= b;
a %= b;
a += b;
- a += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
+ a += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a -= b;
- /*severe:STATIC_TYPE_ERROR*/b -= /*severe:INVALID_ASSIGNMENT*/b;
+ /*error:STATIC_TYPE_ERROR*/b -= /*error:INVALID_ASSIGNMENT*/b;
a <<= b;
a >>= b;
a &= b;
@@ -307,14 +307,24 @@
var d = new D();
a[b] += d;
a[/*info:DYNAMIC_CAST*/c] += d;
- a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
+ a[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
a[b] += /*info:DYNAMIC_CAST*/c;
- a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
+ a[b] += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
/*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
}
''');
}
+ void test_constructorInvalid() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/26695
+ checkFile('''
+class A {
+ B({ /*error:FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR*/this.test: 1.0 }) {}
+ final double test = 0.0;
+}
+''');
+ }
+
void test_constructors() {
checkFile('''
const num z = 25;
@@ -324,37 +334,27 @@
int x;
String y;
- A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
+ A(this.x) : this.y = /*error:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/p;
A.c2(this.x, this.y);
- A.c3(/*severe:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
+ A.c3(/*error:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
}
class B extends A {
- B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ B() : super(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
- B.c2(int x, String y) : super.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
+ B.c2(int x, String y) : super.c2(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
}
void main() {
- A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z);
- var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
-}
-''');
- }
-
- void test_constructorInvalid() {
- // Regression test for https://github.com/dart-lang/sdk/issues/26695
- checkFile('''
-class A {
- B({ /*severe:FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR*/this.test: 1.0 }) {}
- final double test = 0.0;
+ A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z);
+ var b = new B.c2(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
}
''');
}
@@ -454,11 +454,11 @@
int x;
double y;
x = f(3);
- x = /*severe:INVALID_ASSIGNMENT*/f.col(3.0);
- y = /*severe:INVALID_ASSIGNMENT*/f(3);
+ x = /*error:INVALID_ASSIGNMENT*/f.col(3.0);
+ y = /*error:INVALID_ASSIGNMENT*/f(3);
y = f.col(3.0);
- f(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
- f.col(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
+ f.col(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{
Function f = new B();
@@ -490,7 +490,7 @@
A f = new B();
/*info:DYNAMIC_INVOKE*/f.col(42.0);
/*info:DYNAMIC_INVOKE*/f.foo(42.0);
- /*info:DYNAMIC_INVOKE*/f./*severe:UNDEFINED_GETTER*/x;
+ /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
}
}
''');
@@ -507,7 +507,7 @@
void main() {
Cat c = /*info:ASSIGNMENT_CAST*/new Animal.cat();
- c = /*severe:STATIC_TYPE_ERROR*/new Animal();
+ c = /*error:STATIC_TYPE_ERROR*/new Animal();
}''');
}
@@ -525,17 +525,17 @@
}
class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
- /*severe:INVALID_FIELD_OVERRIDE*/var f3;
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
+ /*error:INVALID_FIELD_OVERRIDE*/var f3;
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/dynamic f4;
}
class Child2 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
- /*severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
+ /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+ /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
var f3;
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
+ /*error:INVALID_METHOD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/dynamic f4;
}
''');
}
@@ -554,17 +554,17 @@
}
class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/C get f2 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/get f3 => null;
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/C get f2 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/get f3 => null;
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
+ /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null;
C get f2 => null;
get f3 => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+ /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
}
''');
}
@@ -578,13 +578,13 @@
}
class G extends F {
- /*severe:INVALID_FIELD_OVERRIDE*/final ToVoid<int> f = null;
- /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
+ /*error:INVALID_FIELD_OVERRIDE*/final ToVoid<int> f = null;
+ /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
}
class H implements F {
final ToVoid<int> f = null;
- /*severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
+ /*error:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
}
''');
}
@@ -604,17 +604,17 @@
}
class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE*/B get f1 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f2 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f3 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f4 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f5 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/B get f1 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/B get f2 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/B get f3 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/B get f4 => null;
+ /*error:INVALID_FIELD_OVERRIDE*/B get f5 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
- /*severe:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
- /*severe:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
+ /*error:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ /*error:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
+ /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ /*error:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
}
class Child2 implements Base {
@@ -625,9 +625,9 @@
B get f5 => null;
void set f1(A value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
void set f3(value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
set f5(B value) {}
}
''');
@@ -637,7 +637,7 @@
checkFile('''
main() {
// Don't choke if sequence is not iterable.
- for (var i in /*severe:FOR_IN_OF_INVALID_TYPE*/1234) {}
+ for (var i in /*error:FOR_IN_OF_INVALID_TYPE*/1234) {}
// Dynamic cast.
for (String /*info:DYNAMIC_CAST*/s in <dynamic>[]) {}
@@ -670,7 +670,7 @@
checkFile('''
foo() {
for (int i = 0; i < 10; i++) {
- i = /*severe:INVALID_ASSIGNMENT*/"hi";
+ i = /*error:INVALID_ASSIGNMENT*/"hi";
}
}
bar() {
@@ -693,14 +693,14 @@
Future<int> foo3() async => /*info:DYNAMIC_CAST*/x;
Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
Future<int> foo5() async =>
- /*severe:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
+ /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
bar1() async { return x; }
Future bar2() async { return x; }
Future<int> bar3() async { return /*info:DYNAMIC_CAST*/x; }
Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
Future<int> bar5() async {
- return /*severe:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
+ return /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
}
int y;
@@ -710,7 +710,7 @@
int a = /*info:DYNAMIC_CAST*/await x;
int b = await y;
int c = await z;
- String d = /*severe:INVALID_ASSIGNMENT*/await z;
+ String d = /*error:INVALID_ASSIGNMENT*/await z;
}
Future<bool> get issue_264 async {
@@ -733,7 +733,7 @@
bar1() async* { yield x; }
Stream bar2() async* { yield x; }
Stream<int> bar3() async* { yield /*info:DYNAMIC_CAST*/x; }
-Stream<int> bar4() async* { yield /*severe:YIELD_OF_INVALID_TYPE*/new Stream<int>(); }
+Stream<int> bar4() async* { yield /*error:YIELD_OF_INVALID_TYPE*/new Stream<int>(); }
baz1() async* { yield* /*info:DYNAMIC_CAST*/x; }
Stream baz2() async* { yield* /*info:DYNAMIC_CAST*/x; }
@@ -750,7 +750,7 @@
bar1() sync* { yield x; }
Iterable bar2() sync* { yield x; }
Iterable<int> bar3() sync* { yield /*info:DYNAMIC_CAST*/x; }
-Iterable<int> bar4() sync* { yield /*severe:YIELD_OF_INVALID_TYPE*/bar3(); }
+Iterable<int> bar4() sync* { yield /*error:YIELD_OF_INVALID_TYPE*/bar3(); }
baz1() sync* { yield* /*info:DYNAMIC_CAST*/x; }
Iterable baz2() sync* { yield* /*info:DYNAMIC_CAST*/x; }
@@ -791,23 +791,23 @@
}
{
Left f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/top;
f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
{
Right f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
f = right;
f = bot;
}
{
Bot f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
}
@@ -926,14 +926,14 @@
f = topTop;
f = aa;
f = aTop;
- f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
+ f = /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA;
f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
apply/*<ATop>*/(
topA,
topTop,
aa,
aTop,
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
apply/*<ATop>*/(
@@ -941,31 +941,31 @@
(dynamic x) => (x as Object),
(A x) => x,
(A x) => null,
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
}
{
BotA f;
f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop;
+ f = /*error:STATIC_TYPE_ERROR*/topTop;
f = aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop;
+ f = /*error:STATIC_TYPE_ERROR*/aTop;
f = botA;
f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
apply/*<BotA>*/(
topA,
- /*severe:STATIC_TYPE_ERROR*/topTop,
+ /*error:STATIC_TYPE_ERROR*/topTop,
aa,
- /*severe:STATIC_TYPE_ERROR*/aTop,
+ /*error:STATIC_TYPE_ERROR*/aTop,
botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
apply/*<BotA>*/(
(dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+ /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
(A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object),
+ /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object),
botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
@@ -973,24 +973,24 @@
{
AA f;
f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop;
+ f = /*error:STATIC_TYPE_ERROR*/topTop;
f = aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
f = /*warning:DOWN_CAST_COMPOSITE*/botA;
f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
apply/*<AA>*/(
topA,
- /*severe:STATIC_TYPE_ERROR*/topTop,
+ /*error:STATIC_TYPE_ERROR*/topTop,
aa,
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
+ /*error:STATIC_TYPE_ERROR*/aTop, // known function
/*warning:DOWN_CAST_COMPOSITE*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
apply/*<AA>*/(
(dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+ /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
(A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
/*warning:DOWN_CAST_COMPOSITE*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
@@ -999,48 +999,48 @@
TopTop f;
f = topA;
f = topTop;
- f = /*severe:STATIC_TYPE_ERROR*/aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
- f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
+ f = /*error:STATIC_TYPE_ERROR*/aa;
+ f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA;
f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
apply/*<TopTop>*/(
topA,
topTop,
- /*severe:STATIC_TYPE_ERROR*/aa,
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*error:STATIC_TYPE_ERROR*/aa,
+ /*error:STATIC_TYPE_ERROR*/aTop, // known function
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
apply/*<TopTop>*/(
(dynamic x) => new A(),
(dynamic x) => (x as Object),
- /*severe:STATIC_TYPE_ERROR*/(A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*error:STATIC_TYPE_ERROR*/(A x) => x,
+ /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
}
{
TopA f;
f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop; // known function
- f = /*severe:STATIC_TYPE_ERROR*/aa; // known function
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*error:STATIC_TYPE_ERROR*/topTop; // known function
+ f = /*error:STATIC_TYPE_ERROR*/aa; // known function
+ f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
f = /*warning:DOWN_CAST_COMPOSITE*/botA;
f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
apply/*<TopA>*/(
topA,
- /*severe:STATIC_TYPE_ERROR*/topTop, // known function
- /*severe:STATIC_TYPE_ERROR*/aa, // known function
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
+ /*error:STATIC_TYPE_ERROR*/topTop, // known function
+ /*error:STATIC_TYPE_ERROR*/aa, // known function
+ /*error:STATIC_TYPE_ERROR*/aTop, // known function
/*warning:DOWN_CAST_COMPOSITE*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
apply/*<TopA>*/(
(dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known function
- /*severe:STATIC_TYPE_ERROR*/(A x) => x, // known function
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known function
+ /*error:STATIC_TYPE_ERROR*/(A x) => x, // known function
+ /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
/*warning:DOWN_CAST_COMPOSITE*/botA,
/*warning:DOWN_CAST_COMPOSITE*/botTop
);
@@ -1128,23 +1128,23 @@
}
{
Function2<B, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/top;
f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
{
Function2<A, A> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
f = right;
f = bot;
}
{
Function2<A, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
}
@@ -1215,24 +1215,24 @@
}
{
Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/top;
f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
{
Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
f = right;
f = bot;
}
{
Function2<BToA, AToB> f; // Bot
f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
}
}
''');
@@ -1264,24 +1264,24 @@
}
{
Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/top;
f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
{
Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
f = right;
f = bot;
}
{
Function2<BToA, AToB> f; // Bot
f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
}
}
''');
@@ -1313,24 +1313,24 @@
}
{
Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/top;
f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = /*error:STATIC_TYPE_ERROR*/right;
f = bot;
}
{
Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
f = right;
f = bot;
}
{
Function2<BToA, AToB> f; // Bot
f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/left;
+ f = /*error:STATIC_TYPE_ERROR*/top;
+ f = /*error:STATIC_TYPE_ERROR*/left;
}
}
''');
@@ -1358,12 +1358,12 @@
left = /*warning:DOWN_CAST_COMPOSITE*/top;
left = left;
left =
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/right;
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/right;
left = bot;
right = /*warning:DOWN_CAST_COMPOSITE*/top;
right =
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/left;
+ /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/left;
right = right;
right = bot;
@@ -1509,91 +1509,91 @@
r = r;
r = o;
- r = /*severe:INVALID_ASSIGNMENT*/n;
- r = /*severe:INVALID_ASSIGNMENT*/rr;
+ r = /*error:INVALID_ASSIGNMENT*/n;
+ r = /*error:INVALID_ASSIGNMENT*/rr;
r = ro;
r = rn;
r = oo;
- r = /*severe:INVALID_ASSIGNMENT*/nn;
- r = /*severe:INVALID_ASSIGNMENT*/nnn;
+ r = /*error:INVALID_ASSIGNMENT*/nn;
+ r = /*error:INVALID_ASSIGNMENT*/nnn;
o = /*warning:DOWN_CAST_COMPOSITE*/r;
o = o;
- o = /*severe:INVALID_ASSIGNMENT*/n;
- o = /*severe:INVALID_ASSIGNMENT*/rr;
- o = /*severe:INVALID_ASSIGNMENT*/ro;
- o = /*severe:INVALID_ASSIGNMENT*/rn;
+ o = /*error:INVALID_ASSIGNMENT*/n;
+ o = /*error:INVALID_ASSIGNMENT*/rr;
+ o = /*error:INVALID_ASSIGNMENT*/ro;
+ o = /*error:INVALID_ASSIGNMENT*/rn;
o = oo;
- o = /*severe:INVALID_ASSIGNMENT*/nn;
- o = /*severe:INVALID_ASSIGNMENT*/nnn;
+ o = /*error:INVALID_ASSIGNMENT*/nn;
+ o = /*error:INVALID_ASSIGNMENT*/nnn;
- n = /*severe:INVALID_ASSIGNMENT*/r;
- n = /*severe:INVALID_ASSIGNMENT*/o;
+ n = /*error:INVALID_ASSIGNMENT*/r;
+ n = /*error:INVALID_ASSIGNMENT*/o;
n = n;
- n = /*severe:INVALID_ASSIGNMENT*/rr;
- n = /*severe:INVALID_ASSIGNMENT*/ro;
- n = /*severe:INVALID_ASSIGNMENT*/rn;
- n = /*severe:INVALID_ASSIGNMENT*/oo;
+ n = /*error:INVALID_ASSIGNMENT*/rr;
+ n = /*error:INVALID_ASSIGNMENT*/ro;
+ n = /*error:INVALID_ASSIGNMENT*/rn;
+ n = /*error:INVALID_ASSIGNMENT*/oo;
n = nn;
n = nnn;
- rr = /*severe:INVALID_ASSIGNMENT*/r;
- rr = /*severe:INVALID_ASSIGNMENT*/o;
- rr = /*severe:INVALID_ASSIGNMENT*/n;
+ rr = /*error:INVALID_ASSIGNMENT*/r;
+ rr = /*error:INVALID_ASSIGNMENT*/o;
+ rr = /*error:INVALID_ASSIGNMENT*/n;
rr = rr;
rr = ro;
- rr = /*severe:INVALID_ASSIGNMENT*/rn;
+ rr = /*error:INVALID_ASSIGNMENT*/rn;
rr = oo;
- rr = /*severe:INVALID_ASSIGNMENT*/nn;
- rr = /*severe:INVALID_ASSIGNMENT*/nnn;
+ rr = /*error:INVALID_ASSIGNMENT*/nn;
+ rr = /*error:INVALID_ASSIGNMENT*/nnn;
ro = /*warning:DOWN_CAST_COMPOSITE*/r;
- ro = /*severe:INVALID_ASSIGNMENT*/o;
- ro = /*severe:INVALID_ASSIGNMENT*/n;
+ ro = /*error:INVALID_ASSIGNMENT*/o;
+ ro = /*error:INVALID_ASSIGNMENT*/n;
ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
ro = ro;
- ro = /*severe:INVALID_ASSIGNMENT*/rn;
+ ro = /*error:INVALID_ASSIGNMENT*/rn;
ro = oo;
- ro = /*severe:INVALID_ASSIGNMENT*/nn;
- ro = /*severe:INVALID_ASSIGNMENT*/nnn;
+ ro = /*error:INVALID_ASSIGNMENT*/nn;
+ ro = /*error:INVALID_ASSIGNMENT*/nnn;
rn = /*warning:DOWN_CAST_COMPOSITE*/r;
- rn = /*severe:INVALID_ASSIGNMENT*/o;
- rn = /*severe:INVALID_ASSIGNMENT*/n;
- rn = /*severe:INVALID_ASSIGNMENT*/rr;
- rn = /*severe:INVALID_ASSIGNMENT*/ro;
+ rn = /*error:INVALID_ASSIGNMENT*/o;
+ rn = /*error:INVALID_ASSIGNMENT*/n;
+ rn = /*error:INVALID_ASSIGNMENT*/rr;
+ rn = /*error:INVALID_ASSIGNMENT*/ro;
rn = rn;
- rn = /*severe:INVALID_ASSIGNMENT*/oo;
- rn = /*severe:INVALID_ASSIGNMENT*/nn;
- rn = /*severe:INVALID_ASSIGNMENT*/nnn;
+ rn = /*error:INVALID_ASSIGNMENT*/oo;
+ rn = /*error:INVALID_ASSIGNMENT*/nn;
+ rn = /*error:INVALID_ASSIGNMENT*/nnn;
oo = /*warning:DOWN_CAST_COMPOSITE*/r;
oo = /*warning:DOWN_CAST_COMPOSITE*/o;
- oo = /*severe:INVALID_ASSIGNMENT*/n;
+ oo = /*error:INVALID_ASSIGNMENT*/n;
oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
- oo = /*severe:INVALID_ASSIGNMENT*/rn;
+ oo = /*error:INVALID_ASSIGNMENT*/rn;
oo = oo;
- oo = /*severe:INVALID_ASSIGNMENT*/nn;
- oo = /*severe:INVALID_ASSIGNMENT*/nnn;
+ oo = /*error:INVALID_ASSIGNMENT*/nn;
+ oo = /*error:INVALID_ASSIGNMENT*/nnn;
- nn = /*severe:INVALID_ASSIGNMENT*/r;
- nn = /*severe:INVALID_ASSIGNMENT*/o;
+ nn = /*error:INVALID_ASSIGNMENT*/r;
+ nn = /*error:INVALID_ASSIGNMENT*/o;
nn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nn = /*severe:INVALID_ASSIGNMENT*/rr;
- nn = /*severe:INVALID_ASSIGNMENT*/ro;
- nn = /*severe:INVALID_ASSIGNMENT*/rn;
- nn = /*severe:INVALID_ASSIGNMENT*/oo;
+ nn = /*error:INVALID_ASSIGNMENT*/rr;
+ nn = /*error:INVALID_ASSIGNMENT*/ro;
+ nn = /*error:INVALID_ASSIGNMENT*/rn;
+ nn = /*error:INVALID_ASSIGNMENT*/oo;
nn = nn;
nn = nnn;
- nnn = /*severe:INVALID_ASSIGNMENT*/r;
- nnn = /*severe:INVALID_ASSIGNMENT*/o;
+ nnn = /*error:INVALID_ASSIGNMENT*/r;
+ nnn = /*error:INVALID_ASSIGNMENT*/o;
nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nnn = /*severe:INVALID_ASSIGNMENT*/rr;
- nnn = /*severe:INVALID_ASSIGNMENT*/ro;
- nnn = /*severe:INVALID_ASSIGNMENT*/rn;
- nnn = /*severe:INVALID_ASSIGNMENT*/oo;
+ nnn = /*error:INVALID_ASSIGNMENT*/rr;
+ nnn = /*error:INVALID_ASSIGNMENT*/ro;
+ nnn = /*error:INVALID_ASSIGNMENT*/rn;
+ nnn = /*error:INVALID_ASSIGNMENT*/oo;
nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
nnn = nnn;
}
@@ -1616,17 +1616,17 @@
{
I2I f;
f = new A();
- f = /*severe:INVALID_ASSIGNMENT*/new B();
+ f = /*error:INVALID_ASSIGNMENT*/new B();
f = i2i;
- f = /*severe:STATIC_TYPE_ERROR*/n2n;
+ f = /*error:STATIC_TYPE_ERROR*/n2n;
f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
}
{
N2N f;
- f = /*severe:INVALID_ASSIGNMENT*/new A();
+ f = /*error:INVALID_ASSIGNMENT*/new A();
f = new B();
- f = /*severe:STATIC_TYPE_ERROR*/i2i;
+ f = /*error:STATIC_TYPE_ERROR*/i2i;
f = n2n;
f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
@@ -1634,18 +1634,18 @@
{
A f;
f = new A();
- f = /*severe:INVALID_ASSIGNMENT*/new B();
- f = /*severe:INVALID_ASSIGNMENT*/i2i;
- f = /*severe:INVALID_ASSIGNMENT*/n2n;
+ f = /*error:INVALID_ASSIGNMENT*/new B();
+ f = /*error:INVALID_ASSIGNMENT*/i2i;
+ f = /*error:INVALID_ASSIGNMENT*/n2n;
f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
}
{
B f;
- f = /*severe:INVALID_ASSIGNMENT*/new A();
+ f = /*error:INVALID_ASSIGNMENT*/new A();
f = new B();
- f = /*severe:INVALID_ASSIGNMENT*/i2i;
- f = /*severe:INVALID_ASSIGNMENT*/n2n;
+ f = /*error:INVALID_ASSIGNMENT*/i2i;
+ f = /*error:INVALID_ASSIGNMENT*/n2n;
f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
}
@@ -1686,23 +1686,23 @@
}
{
Function2<B, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
+ f = /*error:STATIC_TYPE_ERROR*/C.top;
f = C.left;
- f = /*severe:STATIC_TYPE_ERROR*/C.right;
+ f = /*error:STATIC_TYPE_ERROR*/C.right;
f = C.bot;
}
{
Function2<A, A> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
- f = /*severe:STATIC_TYPE_ERROR*/C.left;
+ f = /*error:STATIC_TYPE_ERROR*/C.top;
+ f = /*error:STATIC_TYPE_ERROR*/C.left;
f = C.right;
f = C.bot;
}
{
Function2<A, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
- f = /*severe:STATIC_TYPE_ERROR*/C.left;
- f = /*severe:STATIC_TYPE_ERROR*/C.right;
+ f = /*error:STATIC_TYPE_ERROR*/C.top;
+ f = /*error:STATIC_TYPE_ERROR*/C.left;
+ f = /*error:STATIC_TYPE_ERROR*/C.right;
f = C.bot;
}
}
@@ -1721,8 +1721,8 @@
local = g; // valid
// Non-generic function cannot subtype a generic one.
- local = /*severe:INVALID_ASSIGNMENT*/(x) => null;
- local = /*severe:INVALID_ASSIGNMENT*/nonGenericFn;
+ local = /*error:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*error:INVALID_ASSIGNMENT*/nonGenericFn;
}
{
Iterable/*<R>*/ f/*<P, R>*/(List/*<P>*/ p) => null;
@@ -1733,12 +1733,12 @@
var local2 = g;
local = local2;
- local2 = /*severe:STATIC_TYPE_ERROR*/f;
+ local2 = /*error:STATIC_TYPE_ERROR*/f;
local2 = /*warning:DOWN_CAST_COMPOSITE*/local;
// Non-generic function cannot subtype a generic one.
- local = /*severe:INVALID_ASSIGNMENT*/(x) => null;
- local = /*severe:INVALID_ASSIGNMENT*/nonGenericFn;
+ local = /*error:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*error:INVALID_ASSIGNMENT*/nonGenericFn;
}
}
''');
@@ -1748,7 +1748,7 @@
checkFile('''
typedef num Num2Num(num x);
void main() {
- Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
+ Num2Num g = /*info:INFERRED_TYPE_CLOSURE,error:STATIC_TYPE_ERROR*/(int x) { return x; };
print(g(42));
}
''');
@@ -1773,8 +1773,8 @@
}
class Derived<S extends A> extends Base<B> {
- /*severe:INVALID_METHOD_OVERRIDE*/S
- /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/foo() => null;
+ /*error:INVALID_METHOD_OVERRIDE*/S
+ /*error:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/foo() => null;
}
class Derived2<S extends B> extends Base<B> {
@@ -1791,19 +1791,19 @@
main() {
String x;
// resolving these shouldn't crash.
- foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
- x = foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
- foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
- x = foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
- x = /*info:DYNAMIC_CAST*/foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
- x = /*info:DYNAMIC_CAST*/foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
+ foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+ x = foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
+ foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
+ x = foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
+ x = /*info:DYNAMIC_CAST*/foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+ x = /*info:DYNAMIC_CAST*/foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
// named arguments
- bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
- x = bar(/*warning:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
+ bar(y: 1, x: 2, /*error:UNDEFINED_NAMED_PARAMETER*/z: 3);
+ x = bar(/*error:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
bar(y: 1);
- x = bar(x: '1', /*warning:UNDEFINED_NAMED_PARAMETER*/z: 42);
- x = /*info:DYNAMIC_CAST*/bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
+ x = bar(x: '1', /*error:UNDEFINED_NAMED_PARAMETER*/z: 42);
+ x = /*info:DYNAMIC_CAST*/bar(y: 1, x: 2, /*error:UNDEFINED_NAMED_PARAMETER*/z: 3);
x = /*info:DYNAMIC_CAST*/bar(x: 1);
}
''');
@@ -1847,10 +1847,10 @@
}
class Child extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+ /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null;
C get f2 => null;
get f3 => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+ /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
}
''');
}
@@ -1866,12 +1866,12 @@
class G extends F {
ToVoid<int> get f => null;
- /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+ /*error:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
}
class H implements F {
ToVoid<int> get f => null;
- /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+ /*error:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
}
''');
}
@@ -1887,22 +1887,22 @@
if (b) {}
if (/*info:DYNAMIC_CAST*/dyn) {}
if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- if (/*severe:NON_BOOL_CONDITION*/i) {}
+ if (/*error:NON_BOOL_CONDITION*/i) {}
while (b) {}
while (/*info:DYNAMIC_CAST*/dyn) {}
while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- while (/*severe:NON_BOOL_CONDITION*/i) {}
+ while (/*error:NON_BOOL_CONDITION*/i) {}
do {} while (b);
do {} while (/*info:DYNAMIC_CAST*/dyn);
do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
- do {} while (/*severe:NON_BOOL_CONDITION*/i);
+ do {} while (/*error:NON_BOOL_CONDITION*/i);
for (;b;) {}
for (;/*info:DYNAMIC_CAST*/dyn;) {}
for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
- for (;/*severe:NON_BOOL_CONDITION*/i;) {}
+ for (;/*error:NON_BOOL_CONDITION*/i;) {}
}
''');
}
@@ -1911,11 +1911,233 @@
addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;');
check();
// TODO(jmesserly): should not be emitting the hint as well as the error.
+ // It is a "strong mode hint" however, so it will not be user visible.
addFile(
- 'num n; int i = /*info:ASSIGNMENT_CAST,severe:INVALID_ASSIGNMENT*/n;');
+ 'num n; int i = /*info:ASSIGNMENT_CAST,error:INVALID_ASSIGNMENT*/n;');
check(implicitCasts: false);
}
+ void test_implicitDynamic_field() {
+ addFile(r'''
+class C {
+ var /*error:IMPLICIT_DYNAMIC_FIELD*/x0;
+ var /*error:IMPLICIT_DYNAMIC_FIELD*/x1 = (<dynamic>[])[0];
+ var /*error:IMPLICIT_DYNAMIC_FIELD*/x2,
+ x3 = 42,
+ /*error:IMPLICIT_DYNAMIC_FIELD*/x4;
+ dynamic y0;
+ dynamic y1 = (<dynamic>[])[0];
+}
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_function() {
+ addFile(r'''
+/*=T*/ a/*<T>*/(/*=T*/ t) => t;
+/*=T*/ b/*<T>*/() => null;
+
+void main/*<S>*/() {
+ dynamic d;
+ int i;
+ /*error:IMPLICIT_DYNAMIC_FUNCTION*/a(d);
+ a(42);
+ /*error:IMPLICIT_DYNAMIC_FUNCTION*/b();
+ d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/b();
+ i = b();
+
+ void f/*<T>*/(/*=T*/ t) {};
+ /*=T*/ g/*<T>*/() => null;
+
+ /*error:IMPLICIT_DYNAMIC_FUNCTION*/f(d);
+ f(42);
+ /*error:IMPLICIT_DYNAMIC_FUNCTION*/g();
+ d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/g();
+ i = g();
+
+ /*error:IMPLICIT_DYNAMIC_INVOKE*/(/*<T>*/(/*=T*/ t) => t)(d);
+ (/*<T>*/(/*=T*/ t) => t)(42);
+ (/*<T>*/() => null as dynamic/*=T*/)/*<int>*/();
+}
+ ''');
+ check(implicitDynamic: false);
+ }
+ void test_implicitDynamic_listLiteral() {
+ addFile(r'''
+
+var l0 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
+List l1 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
+List<dynamic> l2 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
+dynamic d = 42;
+var l3 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[d, d];
+
+var l4 = <dynamic>[];
+var l5 = <int>[];
+List<int> l6 = /*info:INFERRED_TYPE_LITERAL*/[];
+var l7 = /*info:INFERRED_TYPE_LITERAL*/[42];
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_mapLiteral() {
+ addFile(r'''
+var m0 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
+Map m1 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
+Map<dynamic, dynamic> m2 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
+dynamic d = 42;
+var m3 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: d};
+var m4 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{'x': d, 'y': d};
+var m5 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: 'x'};
+
+var m6 = <dynamic, dynamic>{};
+var m7 = <String, String>{};
+Map<String, String> m8 = /*info:INFERRED_TYPE_LITERAL*/{};
+var m9 = /*info:INFERRED_TYPE_LITERAL*/{'hi': 'there'};
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_method() {
+ addFile(r'''
+class C {
+ /*=T*/ m/*<T>*/(/*=T*/ s) => s;
+ /*=T*/ n/*<T>*/() => null;
+}
+class D<E> {
+ /*=T*/ m/*<T>*/(/*=T*/ s) => s;
+ /*=T*/ n/*<T>*/() => null;
+}
+void f() {
+ dynamic d;
+ int i;
+ new C()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d);
+ new C().m(42);
+ new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
+ d = new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
+ i = new C().n();
+
+ new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d);
+ new D<int>().m(42);
+ new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
+ d = new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
+ i = new D<int>().n();
+}
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_parameter() {
+ addFile(r'''
+const dynamic DYNAMIC_VALUE = 42;
+
+// simple formal
+void f0(/*error:IMPLICIT_DYNAMIC_PARAMETER*/x) {}
+void f1(dynamic x) {}
+
+// default formal
+void df0([/*error:IMPLICIT_DYNAMIC_PARAMETER*/x = DYNAMIC_VALUE]) {}
+void df1([dynamic x = DYNAMIC_VALUE]) {}
+void df2([/*info:INFERRED_TYPE*/x = 42]) {}
+
+// default formal (named)
+void nf0({/*error:IMPLICIT_DYNAMIC_PARAMETER*/x: DYNAMIC_VALUE}) {}
+void nf1({dynamic x: DYNAMIC_VALUE}) {}
+void nf2({/*info:INFERRED_TYPE*/x: 42}) {}
+
+// field formal
+class C {
+ var /*error:IMPLICIT_DYNAMIC_FIELD*/x;
+ C(this.x);
+}
+
+// function typed formal
+void ftf0(void x(/*error:IMPLICIT_DYNAMIC_PARAMETER*/y)) {}
+void ftf1(void x(int y)) {}
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_return() {
+ addFile(r'''
+// function
+/*error:IMPLICIT_DYNAMIC_RETURN*/f0() {}
+dynamic f1() { return 42; }
+
+// nested function
+void main() {
+ /*error:IMPLICIT_DYNAMIC_RETURN*/g0() {}
+ dynamic g1() { return 42; }
+}
+
+// methods
+class B {
+ int m1() => 42;
+}
+class C extends B {
+ /*error:IMPLICIT_DYNAMIC_RETURN*/m0() => 123;
+ m1() => 123;
+ dynamic m2() => 'hi';
+}
+
+// accessors
+set x(int value) {}
+/*error:IMPLICIT_DYNAMIC_RETURN*/get y0 => 42;
+dynamic get y1 => 42;
+
+// function typed formals
+void ftf0(/*error:IMPLICIT_DYNAMIC_RETURN*/f(int x)) {}
+void ftf1(dynamic f(int x)) {}
+
+// function expressions
+var fe0 = (int x) => x as dynamic;
+var fe1 = (int x) => x;
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_type() {
+ addFile(r'''
+class C<T> {}
+class M1<T extends /*error:IMPLICIT_DYNAMIC_TYPE*/List> {}
+class M2<T> {}
+class I<T> {}
+class D<T, S> extends /*error:IMPLICIT_DYNAMIC_TYPE*/C
+ with M1, /*error:IMPLICIT_DYNAMIC_TYPE*/M2
+ implements /*error:IMPLICIT_DYNAMIC_TYPE*/I {}
+
+C f(D d) {
+ D x = new /*error:IMPLICIT_DYNAMIC_TYPE*/D();
+ D<int, dynamic> y = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNAMIC_TYPE*/D();
+ D<dynamic, int> z = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNAMIC_TYPE*/D();
+ return new /*error:IMPLICIT_DYNAMIC_TYPE*/C();
+}
+
+class A<T extends num> {}
+class N1<T extends List<int>> {}
+class N2<T extends Object> {}
+class J<T extends Object> {}
+class B<T extends Object> extends A with N1, N2 implements J {}
+A g(B b) {
+ B y = /*info:INFERRED_TYPE_ALLOCATION*/new B();
+ return /*info:INFERRED_TYPE_ALLOCATION*/new A();
+}
+ ''');
+ check(implicitDynamic: false);
+ }
+
+ void test_implicitDynamic_variable() {
+ addFile(r'''
+var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x0;
+var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x1 = (<dynamic>[])[0];
+var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x2,
+ x3 = 42,
+ /*error:IMPLICIT_DYNAMIC_VARIABLE*/x4;
+dynamic y0;
+dynamic y1 = (<dynamic>[])[0];
+ ''');
+ check(implicitDynamic: false);
+ }
+
void test_invalidOverrides_baseClassOverrideToChildInterface() {
checkFile('''
class A {}
@@ -1929,8 +2151,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I {}
''');
}
@@ -1944,43 +2166,43 @@
}
class T1 extends Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B get
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B get
+ /*error:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
}
class T2 extends Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/set f(
- /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/set f(
+ /*error:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
}
class T3 extends Base {
- /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final B
- /*warning:FINAL_NOT_INITIALIZED, warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f;
+ /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/final B
+ /*warning:FINAL_NOT_INITIALIZED, error:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f;
}
class T4 extends Base {
// two: one for the getter one for the setter.
- /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
+ /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B
+ /*error:INVALID_GETTER_OVERRIDE_RETURN_TYPE, error:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/B get
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_OVERRIDE*/B get
+ /*error:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/set f(
- /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_METHOD_OVERRIDE*/set f(
+ /*error:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/final B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f = null;
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
+ /*error:INVALID_METHOD_OVERRIDE*/final B
+ /*error:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f = null;
}
class T8 implements Base {
// two: one for the getter one for the setter.
- /*severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
+ /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B
+ /*error:INVALID_GETTER_OVERRIDE_RETURN_TYPE, error:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
}
''');
}
@@ -1995,8 +2217,8 @@
}
class Test extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -2011,8 +2233,8 @@
}
class T1 implements I {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -2031,8 +2253,8 @@
class Test extends Parent {
// Reported only once
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -2046,8 +2268,8 @@
m(A a) {}
}
class Parent extends Grandparent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class Test extends Parent {
@@ -2069,9 +2291,9 @@
}
class Test extends Parent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- /*severe:INVALID_FIELD_OVERRIDE*/int x;
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_FIELD_OVERRIDE*/int x;
}
''');
}
@@ -2089,8 +2311,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I {}
''');
}
@@ -2113,12 +2335,12 @@
int x;
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
- with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
+ with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1, /*error:INVALID_FIELD_OVERRIDE*/M2 {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
+ with /*error:INVALID_FIELD_OVERRIDE*/M2, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {}
''');
}
@@ -2140,9 +2362,9 @@
int x;
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
with M1,
- /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN,severe:INVALID_FIELD_OVERRIDE*/M2 {}
+ /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN,error:INVALID_FIELD_OVERRIDE*/M2 {}
''');
}
@@ -2170,8 +2392,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with M1, /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3 {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M1, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3 {}
''');
}
@@ -2191,16 +2413,16 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
implements I1 {}
class T2 extends Base implements I1 {
m(a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T3
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base
implements I1 {}
class T4 extends Object with Base implements I1 {
@@ -2273,9 +2495,9 @@
S s;
T t;
if (b) {
- return /*severe:RETURN_OF_INVALID_TYPE*/b ? s : t;
+ return /*error:RETURN_OF_INVALID_TYPE*/b ? s : t;
} else {
- return /*severe:RETURN_OF_INVALID_TYPE*/s ?? t;
+ return /*error:RETURN_OF_INVALID_TYPE*/s ?? t;
}
}
}
@@ -2284,7 +2506,7 @@
T t;
S s;
int test(bool b) {
- return /*severe:RETURN_OF_INVALID_TYPE*/b ? t : s;
+ return /*error:RETURN_OF_INVALID_TYPE*/b ? t : s;
}
}
@@ -2295,7 +2517,7 @@
int test1(bool b) {
List<int> li;
List<double> ld;
- return /*severe:RETURN_OF_INVALID_TYPE*/b ? li : ld;
+ return /*error:RETURN_OF_INVALID_TYPE*/b ? li : ld;
}
// TODO(leafp): This case isn't handled yet. This test checks
// the case where two related classes are instantiated with related
@@ -2304,7 +2526,7 @@
List<int> li;
Iterable<double> id;
int x =
- /*info:ASSIGNMENT_CAST should be severe:INVALID_ASSIGNMENT*/
+ /*info:ASSIGNMENT_CAST should be error:INVALID_ASSIGNMENT*/
b ? li : id;
return /*warning:DOWN_CAST_COMPOSITE should be pass*/b ? li : id;
}
@@ -2338,12 +2560,12 @@
}
class Child extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
+ /*error:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
+ /*error:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
+ /*error:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
C m4(A value) => null;
m5(value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
+ /*error:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
}
''');
}
@@ -2362,12 +2584,12 @@
}
class G extends F {
- /*severe:INVALID_METHOD_OVERRIDE*/void f(int x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {}
void g(dynamic x) {}
}
class H implements F {
- /*severe:INVALID_METHOD_OVERRIDE*/void f(int x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {}
void g(dynamic x) {}
}
''');
@@ -2387,8 +2609,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M {}
''');
}
@@ -2401,14 +2623,14 @@
m(A a);
}
-class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
implements I1 {}
class M {
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
with M {}
''');
}
@@ -2427,8 +2649,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I2 {}
''');
}
@@ -2447,8 +2669,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I2 {}
''');
}
@@ -2467,8 +2689,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I2 {}
''');
}
@@ -2494,9 +2716,9 @@
// Here we want to report both, because the error location is
// different.
// TODO(sigmund): should we merge these as well?
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
- with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
+ with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I1 {}
''');
}
@@ -2521,11 +2743,11 @@
class Parent2 extends Grandparent {}
// Note: otherwise both errors would be reported on this line
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent1
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent1
implements I1 {}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T2
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent2
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent2
implements I1 {}
''');
}
@@ -2551,9 +2773,9 @@
// Here we want to report both, because the error location is
// different.
// TODO(sigmund): should we merge these as well?
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
- with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1,
- /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
+ with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1,
+ /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2
implements I1 {}
''');
}
@@ -2575,14 +2797,14 @@
// Note: no error reported in `extends Base` to avoid duplicating
// the error in T1.
class T1 extends Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
// If there is no error in the class, we do report the error at
// the base class:
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T2
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
implements I1 {}
''');
}
@@ -2602,12 +2824,12 @@
}
class T1 extends Object with M implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T2
- extends Object with /*severe:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
+ extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
implements I1 {}
''');
}
@@ -2628,8 +2850,8 @@
class Base {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
}
@@ -2666,12 +2888,12 @@
}
class GrandChild extends main.Child {
- /*severe:INVALID_FIELD_OVERRIDE*/var _f2;
- /*severe:INVALID_FIELD_OVERRIDE*/var _f3;
+ /*error:INVALID_FIELD_OVERRIDE*/var _f2;
+ /*error:INVALID_FIELD_OVERRIDE*/var _f3;
var _f4;
- /*severe:INVALID_METHOD_OVERRIDE*/String
- /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/_m1() => null;
+ /*error:INVALID_METHOD_OVERRIDE*/String
+ /*error:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/_m1() => null;
}
''',
name: '/helper.dart');
@@ -2679,7 +2901,7 @@
import 'helper.dart' as helper;
class Child extends helper.Base {
- /*severe:INVALID_FIELD_OVERRIDE*/var f1;
+ /*error:INVALID_FIELD_OVERRIDE*/var f1;
var _f2;
var _f4;
@@ -2692,7 +2914,7 @@
checkFile('''
class A {
A(A x) {}
- A.two() : this(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ A.two() : this(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
''');
}
@@ -2741,7 +2963,7 @@
}
{
lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
- lOfAs = /*severe:INVALID_ASSIGNMENT*/mOfOs;
+ lOfAs = /*error:INVALID_ASSIGNMENT*/mOfOs;
lOfAs = mOfAs;
lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
@@ -2763,7 +2985,7 @@
mOfOs = mOfAs;
mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- mOfOs = /*severe:INVALID_ASSIGNMENT*/lOfAs;
+ mOfOs = /*error:INVALID_ASSIGNMENT*/lOfAs;
mOfOs = new M<Object>(); // Reset type propagation.
}
{
@@ -2789,17 +3011,17 @@
}
class G extends F {
- /*severe:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
void set g(ToVoid<dynamic> x) {}
void set h(int x) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
}
class H implements F {
- /*severe:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
void set g(ToVoid<dynamic> x) {}
void set h(int x) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
}
''');
}
@@ -2810,13 +3032,13 @@
class A {
set a(y) => 4;
set b(y) => voidFn();
- void set c(y) => /*severe:RETURN_OF_INVALID_TYPE*/4;
+ void set c(y) => /*error:RETURN_OF_INVALID_TYPE*/4;
void set d(y) => voidFn();
/*warning:NON_VOID_RETURN_FOR_SETTER*/int set e(y) => 4;
/*warning:NON_VOID_RETURN_FOR_SETTER*/int set f(y) =>
- /*severe:RETURN_OF_INVALID_TYPE*/voidFn();
- set g(y) {return /*severe:RETURN_OF_INVALID_TYPE*/4;}
- void set h(y) {return /*severe:RETURN_OF_INVALID_TYPE*/4;}
+ /*error:RETURN_OF_INVALID_TYPE*/voidFn();
+ set g(y) {return /*error:RETURN_OF_INVALID_TYPE*/4;}
+ void set h(y) {return /*error:RETURN_OF_INVALID_TYPE*/4;}
/*warning:NON_VOID_RETURN_FOR_SETTER*/int set i(y) {return 4;}
}
''');
@@ -2838,9 +3060,9 @@
class Child extends Base {
void set f1(A value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
void set f3(value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ /*error:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
set f5(B value) {}
}
''');
@@ -2857,7 +3079,7 @@
var y, z;
Derived()
: y = print('Derived.1'),
- /*severe:INVALID_SUPER_INVOCATION*/super(),
+ /*error:INVALID_SUPER_INVOCATION*/super(),
z = print('Derived.2') {
print('Derived.3');
}
@@ -2891,8 +3113,8 @@
}
abstract class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class T1 extends Base {
@@ -2901,7 +3123,7 @@
// TODO(sigmund): consider tracking overrides in a fine-grain
// manner, then this and the double-overrides would not be
// reported.
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
}
''');
}
@@ -2916,8 +3138,8 @@
}
class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*error:INVALID_METHOD_OVERRIDE*/m(
+ /*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class T1 extends Base {
@@ -2940,8 +3162,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {}
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {}
''');
}
@@ -2959,8 +3181,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
implements I2 {}
''');
}
@@ -2979,8 +3201,8 @@
m(B a) {}
}
-class /*severe:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
+class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
implements I2 {}
''');
}
@@ -2989,7 +3211,7 @@
checkFile('''
class A { A(A x) {} }
class B extends A {
- B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ B() : super(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
''');
}
@@ -3035,7 +3257,7 @@
int i = 42;
// Check the boolean conversion of the condition.
- print(/*severe:NON_BOOL_CONDITION*/i ? false : true);
+ print(/*error:NON_BOOL_CONDITION*/i ? false : true);
print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
}
@@ -3050,9 +3272,9 @@
String s = "hello";
{
List<int> l = <int>[i];
- l = <int>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
+ l = <int>[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
- l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
+ l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
}
{
List l = /*info:INFERRED_TYPE_LITERAL*/[i];
@@ -3062,11 +3284,11 @@
}
{
Map<String, int> m = <String, int>{s: i};
- m = <String, int>{s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
+ m = <String, int>{s: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
m = <String, int>{s: i,
s: /*info:DOWN_CAST_IMPLICIT*/n,
- s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
+ s: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
}
// TODO(leafp): We can't currently test for key errors since the
// error marker binds to the entire entry.
@@ -3093,14 +3315,14 @@
dynamic x;
if (x is int) {
int y = x;
- String z = /*severe:INVALID_ASSIGNMENT*/x;
+ String z = /*error:INVALID_ASSIGNMENT*/x;
}
}
g() {
Object x;
if (x is int) {
int y = x;
- String z = /*severe:INVALID_ASSIGNMENT*/x;
+ String z = /*error:INVALID_ASSIGNMENT*/x;
}
}
''');
@@ -3121,9 +3343,9 @@
B b;
y = a;
o = a;
- i = /*severe:INVALID_ASSIGNMENT*/a;
- d = /*severe:INVALID_ASSIGNMENT*/a;
- n = /*severe:INVALID_ASSIGNMENT*/a;
+ i = /*error:INVALID_ASSIGNMENT*/a;
+ d = /*error:INVALID_ASSIGNMENT*/a;
+ n = /*error:INVALID_ASSIGNMENT*/a;
a = a;
b = /*info:DOWN_CAST_IMPLICIT*/a;
}
@@ -3147,12 +3369,12 @@
C c;
y = b;
o = b;
- i = /*severe:INVALID_ASSIGNMENT*/b;
- d = /*severe:INVALID_ASSIGNMENT*/b;
- n = /*severe:INVALID_ASSIGNMENT*/b;
+ i = /*error:INVALID_ASSIGNMENT*/b;
+ d = /*error:INVALID_ASSIGNMENT*/b;
+ n = /*error:INVALID_ASSIGNMENT*/b;
a = b;
b = b;
- c = /*severe:INVALID_ASSIGNMENT*/b;
+ c = /*error:INVALID_ASSIGNMENT*/b;
}
''');
}
@@ -3224,12 +3446,12 @@
{
left = /*info:DOWN_CAST_IMPLICIT*/top;
left = left;
- left = /*severe:INVALID_ASSIGNMENT*/right;
+ left = /*error:INVALID_ASSIGNMENT*/right;
left = bot;
}
{
right = /*info:DOWN_CAST_IMPLICIT*/top;
- right = /*severe:INVALID_ASSIGNMENT*/left;
+ right = /*error:INVALID_ASSIGNMENT*/left;
right = right;
right = bot;
}
@@ -3262,7 +3484,7 @@
~a;
(/*info:DYNAMIC_INVOKE*/~d);
- !/*severe:NON_BOOL_NEGATION_EXPRESSION*/a;
+ !/*error:NON_BOOL_NEGATION_EXPRESSION*/a;
!/*info:DYNAMIC_CAST*/d;
-a;
@@ -3284,7 +3506,7 @@
// This is a regression test for https://github.com/dart-lang/sdk/issues/25071
checkFile('''
class Foo {
- Foo() : /*severe:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
+ Foo() : /*error:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
}
''');
}
@@ -3292,7 +3514,7 @@
void test_unboundTypeName() {
checkFile('''
void main() {
- /*warning:UNDEFINED_CLASS should be error*/AToB y;
+ /*error:UNDEFINED_CLASS*/AToB y;
}
''');
}
@@ -3300,7 +3522,7 @@
void test_unboundVariable() {
checkFile('''
void main() {
- dynamic y = /*warning:UNDEFINED_IDENTIFIER should be error*/unboundVariable;
+ dynamic y = /*error:UNDEFINED_IDENTIFIER*/unboundVariable;
}
''');
}
@@ -3311,7 +3533,7 @@
typedef int Foo();
void foo() {}
void main () {
- Foo x = /*severe:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
+ Foo x = /*error:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
}
''');
}
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index d11b584..1c5847f 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -318,7 +318,7 @@
main() {
String f() => null;
var g = f;
- g = /*info:INFERRED_TYPE_CLOSURE*/() { return /*severe:RETURN_OF_INVALID_TYPE*/1; };
+ g = /*info:INFERRED_TYPE_CLOSURE*/() { return /*error:RETURN_OF_INVALID_TYPE*/1; };
}
''');
var f = mainUnit.functions[0].localVariables[0];
@@ -546,12 +546,12 @@
}
class C1 implements A, B {
- /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
+ /*error:INVALID_METHOD_OVERRIDE*/get a => null;
}
// Still ambiguous
class C2 implements B, A {
- /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
+ /*error:INVALID_METHOD_OVERRIDE*/get a => null;
}
''');
}
@@ -583,7 +583,7 @@
}
class C2 implements A, B {
- /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
+ /*error:INVALID_METHOD_OVERRIDE*/get a => null;
}
''');
}
@@ -595,7 +595,7 @@
}
class B implements A {
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
+ /*error:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
}
foo() {
@@ -619,11 +619,11 @@
test() {
x = "hi";
- y = /*severe:INVALID_ASSIGNMENT*/"hi";
+ y = /*error:INVALID_ASSIGNMENT*/"hi";
A.x = "hi";
- A.y = /*severe:INVALID_ASSIGNMENT*/"hi";
+ A.y = /*error:INVALID_ASSIGNMENT*/"hi";
new A().x2 = "hi";
- new A().y2 = /*severe:INVALID_ASSIGNMENT*/"hi";
+ new A().y2 = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -686,7 +686,7 @@
checkFile('''
void main() {
List<int> l;
- l = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ l = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
l = (l = /*info:INFERRED_TYPE_LITERAL*/[1]);
}
''');
@@ -723,7 +723,7 @@
}
void f([List<int> l = /*info:INFERRED_TYPE_LITERAL*/const [1]]) {}
// We do this inference in an early task but don't preserve the infos.
-Function2<List<int>, String> g = /*pass should be info:INFERRED_TYPE_CLOSURE*/([llll = /*info:INFERRED_TYPE_LITERAL*/const [1]]) => "hello";
+Function2<List<int>, String> g = /*pass should be info:INFERRED_TYPE_CLOSURE*/([/*info:INFERRED_TYPE*/llll = /*info:INFERRED_TYPE_LITERAL*/const [1]]) => "hello";
''');
}
@@ -747,30 +747,30 @@
void main() {
new F0(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ new F0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ new F2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
@@ -786,28 +786,28 @@
void main() {
f0(/*info:INFERRED_TYPE_LITERAL*/[]);
f0(/*info:INFERRED_TYPE_LITERAL*/[3]);
- f0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- f0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ f0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f2(/*info:INFERRED_TYPE_LITERAL*/[]);
f2(/*info:INFERRED_TYPE_LITERAL*/[3]);
- f2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- f2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ f2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f3(/*info:INFERRED_TYPE_LITERAL*/[]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
+ f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
+ f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
}
@@ -820,28 +820,28 @@
{
Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
Function2<int, String> l1 = (int x) => "hello";
- Function2<int, String> l2 = /*severe:INVALID_ASSIGNMENT*/(String x) => "hello";
- Function2<int, String> l3 = /*severe:INVALID_ASSIGNMENT*/(int x) => 3;
- Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*severe:RETURN_OF_INVALID_TYPE*/3;};
+ Function2<int, String> l2 = /*error:INVALID_ASSIGNMENT*/(String x) => "hello";
+ Function2<int, String> l3 = /*error:INVALID_ASSIGNMENT*/(int x) => 3;
+ Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
}
{
Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => null;
Function2<int, String> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => "hello";
- Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:INVALID_ASSIGNMENT*/(x) => 3;
- Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:RETURN_OF_INVALID_TYPE*/3;};
- Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:RETURN_OF_INVALID_TYPE*/x;};
+ Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/(x) => 3;
+ Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE*/(x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
+ Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(x) {return /*error:RETURN_OF_INVALID_TYPE*/x;};
}
{
Function2<int, List<String>> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
Function2<int, List<String>> l1 = (int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- Function2<int, List<String>> l2 = /*severe:INVALID_ASSIGNMENT*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
- Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
+ Function2<int, List<String>> l2 = /*error:INVALID_ASSIGNMENT*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+ Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
+ Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
Function2<int, int> l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x;
Function2<int, int> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x+1;
- Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:INVALID_ASSIGNMENT*/(x) => x;
+ Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/(x) => x;
Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/x.substring(3);
Function2<String, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x.substring(3);
}
@@ -891,30 +891,30 @@
void main() {
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
- new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
+ new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
- new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
@@ -940,27 +940,27 @@
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
v = /*<T>*/(int x) => "hello";
- v = /*severe:INVALID_ASSIGNMENT*//*<T>*/(String x) => "hello";
- v = /*severe:INVALID_ASSIGNMENT*//*<T>*/(int x) => 3;
- v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*severe:RETURN_OF_INVALID_TYPE*/3;};
+ v = /*error:INVALID_ASSIGNMENT*//*<T>*/(String x) => "hello";
+ v = /*error:INVALID_ASSIGNMENT*//*<T>*/(int x) => 3;
+ v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
}
{
String f/*<S>*/(int x) => null;
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => null;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => "hello";
- v = /*info:INFERRED_TYPE_CLOSURE, severe:INVALID_ASSIGNMENT*//*<T>*/(x) => 3;
- v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*severe:RETURN_OF_INVALID_TYPE*/3;};
- v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*severe:RETURN_OF_INVALID_TYPE*/x;};
+ v = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*//*<T>*/(x) => 3;
+ v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*error:RETURN_OF_INVALID_TYPE*/3;};
+ v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*error:RETURN_OF_INVALID_TYPE*/x;};
}
{
List<String> f/*<S>*/(int x) => null;
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- v = /*severe:INVALID_ASSIGNMENT*//*<T>*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
- v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
+ v = /*error:INVALID_ASSIGNMENT*//*<T>*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+ v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
+ v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
int int2int/*<S>*/(int x) => null;
@@ -970,7 +970,7 @@
x = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x;
x = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x+1;
var y = int2String;
- y = /*info:INFERRED_TYPE_CLOSURE, severe:INVALID_ASSIGNMENT*//*<T>*/(x) => x;
+ y = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*//*<T>*/(x) => x;
y = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => /*info:DYNAMIC_INVOKE, info:DYNAMIC_CAST*/x.substring(3);
var z = string2String;
z = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x.substring(3);
@@ -1018,77 +1018,77 @@
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new A.named(3, "hello");
A<int, String> a2 = new A<int, String>(3, "hello");
A<int, String> a3 = new A<int, String>.named(3, "hello");
- A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new A<int, dynamic>(3, "hello");
- A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new A<dynamic, dynamic>.named(3, "hello");
+ A<int, String> a4 = /*error:STATIC_TYPE_ERROR*/new A<int, dynamic>(3, "hello");
+ A<int, String> a5 = /*error:STATIC_TYPE_ERROR*/new A<dynamic, dynamic>.named(3, "hello");
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new A(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new A.named(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B("hello", 3);
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new B.named("hello", 3);
A<int, String> a2 = new B<String, int>("hello", 3);
A<int, String> a3 = new B<String, int>.named("hello", 3);
- A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new B<String, dynamic>("hello", 3);
- A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new B<dynamic, dynamic>.named("hello", 3);
+ A<int, String> a4 = /*error:STATIC_TYPE_ERROR*/new B<String, dynamic>("hello", 3);
+ A<int, String> a5 = /*error:STATIC_TYPE_ERROR*/new B<dynamic, dynamic>.named("hello", 3);
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new B.named(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
{
A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(3);
A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(3);
A<int, int> a2 = new C<int>(3);
A<int, int> a3 = new C<int>.named(3);
- A<int, int> a4 = /*severe:STATIC_TYPE_ERROR*/new C<dynamic>(3);
- A<int, int> a5 = /*severe:STATIC_TYPE_ERROR*/new C<dynamic>.named(3);
+ A<int, int> a4 = /*error:STATIC_TYPE_ERROR*/new C<dynamic>(3);
+ A<int, int> a5 = /*error:STATIC_TYPE_ERROR*/new C<dynamic>.named(3);
}
{
A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D("hello");
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named("hello");
A<int, String> a2 = new D<int, String>("hello");
A<int, String> a3 = new D<String, String>.named("hello");
- A<int, String> a4 = /*severe:STATIC_TYPE_ERROR*/new D<num, dynamic>("hello");
- A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new D<dynamic, dynamic>.named("hello");
+ A<int, String> a4 = /*error:STATIC_TYPE_ERROR*/new D<num, dynamic>("hello");
+ A<int, String> a5 = /*error:STATIC_TYPE_ERROR*/new D<dynamic, dynamic>.named("hello");
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{ // Currently we only allow variable constraints. Test that we reject.
- A<C<int>, String> a0 = /*severe:STATIC_TYPE_ERROR*/new E("hello");
+ A<C<int>, String> a0 = /*error:STATIC_TYPE_ERROR*/new E("hello");
}
{ // Check named and optional arguments
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
a: /*info:INFERRED_TYPE_LITERAL*/[3],
b: /*info:INFERRED_TYPE_LITERAL*/["hello"]);
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
- a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
- b: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]);
+ a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ b: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]);
A<int, String> a2 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", 3, "hello");
A<int, String> a3 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello");
A<int, String> a4 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello",
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
A<int, String> a5 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello",
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
}
''');
@@ -1097,15 +1097,15 @@
void test_downwardsInferenceOnListLiterals_inferDownwards() {
checkFile('''
void foo([List<String> list1 = /*info:INFERRED_TYPE_LITERAL*/const [],
- List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) {
+ List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) {
}
void main() {
{
List<int> l0 = /*info:INFERRED_TYPE_LITERAL*/[];
List<int> l1 = /*info:INFERRED_TYPE_LITERAL*/[3];
- List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
- List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
+ List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
List<dynamic> l0 = [];
@@ -1114,22 +1114,22 @@
List<dynamic> l3 = /*info:INFERRED_TYPE_LITERAL*/["hello", 3];
}
{
- List<int> l0 = /*severe:STATIC_TYPE_ERROR*/<num>[];
- List<int> l1 = /*severe:STATIC_TYPE_ERROR*/<num>[3];
- List<int> l2 = /*severe:STATIC_TYPE_ERROR*/<num>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
- List<int> l3 = /*severe:STATIC_TYPE_ERROR*/<num>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
+ List<int> l0 = /*error:STATIC_TYPE_ERROR*/<num>[];
+ List<int> l1 = /*error:STATIC_TYPE_ERROR*/<num>[3];
+ List<int> l2 = /*error:STATIC_TYPE_ERROR*/<num>[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ List<int> l3 = /*error:STATIC_TYPE_ERROR*/<num>[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
Iterable<int> i0 = /*info:INFERRED_TYPE_LITERAL*/[];
Iterable<int> i1 = /*info:INFERRED_TYPE_LITERAL*/[3];
- Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
- Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
+ Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
const List<int> c0 = /*info:INFERRED_TYPE_LITERAL*/const [];
const List<int> c1 = /*info:INFERRED_TYPE_LITERAL*/const [3];
- const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
- const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
+ const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
}
''');
@@ -1198,9 +1198,8 @@
checkFile('''
void foo([Map<int, String> m1 = /*info:INFERRED_TYPE_LITERAL*/const {1: "hello"},
Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL*/const {
- // The warning is the type error, and the severe is the compile time
- // error from const evaluation.
- /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ // One error is from type checking and the other is from const evaluation.
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
"world"
}]) {
}
@@ -1209,15 +1208,15 @@
Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{
- /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
};
Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
- 3: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ 3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
3: "hello",
- /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
- /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
}
{
@@ -1232,44 +1231,44 @@
Map<dynamic, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<dynamic, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{"hello": "hello"};
Map<dynamic, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
- 3: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ 3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
Map<dynamic, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
3: "hello",
- "hello": /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ "hello": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
}
{
Map<int, dynamic> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, dynamic> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<int, dynamic> l2 = /*info:INFERRED_TYPE_LITERAL*/{
- /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
};
Map<int, dynamic> l3 = /*info:INFERRED_TYPE_LITERAL*/{3: 3};
Map<int, dynamic> l4 = /*info:INFERRED_TYPE_LITERAL*/{
3:"hello",
- /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": 3
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": 3
};
}
{
- Map<int, String> l0 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{};
- Map<int, String> l1 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{3: "hello"};
- Map<int, String> l3 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{3: 3};
+ Map<int, String> l0 = /*error:STATIC_TYPE_ERROR*/<num, dynamic>{};
+ Map<int, String> l1 = /*error:STATIC_TYPE_ERROR*/<num, dynamic>{3: "hello"};
+ Map<int, String> l3 = /*error:STATIC_TYPE_ERROR*/<num, dynamic>{3: 3};
}
{
const Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/const {};
const Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/const {3: "hello"};
const Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/const {
- /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
"hello"
};
const Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/const {
- 3: /*severe:MAP_VALUE_TYPE_NOT_ASSIGNABLE,warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ 3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
const Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/const {
3:"hello",
- /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
- /*severe:MAP_VALUE_TYPE_NOT_ASSIGNABLE,warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
}
}
@@ -1281,15 +1280,15 @@
import 'dart:async';
Stream<List<int>> foo() async* {
yield /*info:INFERRED_TYPE_LITERAL*/[];
- yield /*severe:YIELD_OF_INVALID_TYPE*/new Stream();
- yield* /*severe:YIELD_OF_INVALID_TYPE*/[];
+ yield /*error:YIELD_OF_INVALID_TYPE*/new Stream();
+ yield* /*error:YIELD_OF_INVALID_TYPE*/[];
yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream();
}
Iterable<Map<int, int>> bar() sync* {
yield /*info:INFERRED_TYPE_LITERAL*/{};
- yield /*severe:YIELD_OF_INVALID_TYPE*/new List();
- yield* /*severe:YIELD_OF_INVALID_TYPE*/{};
+ yield /*error:YIELD_OF_INVALID_TYPE*/new List();
+ yield* /*error:YIELD_OF_INVALID_TYPE*/{};
yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
}
''');
@@ -1348,7 +1347,7 @@
new Foo<String>().method("str");
new Foo().method("str");
- new Foo<String>().method(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/42);
+ new Foo<String>().method(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/42);
}
''');
}
@@ -1382,8 +1381,8 @@
// Types other than int and double are not accepted.
printInt(
/*info:DOWN_CAST_IMPLICIT*/min(
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hi",
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"there"));
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hi",
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"there"));
}
''');
}
@@ -1394,10 +1393,10 @@
/*=T*/ m/*<T>*/(/*=T*/ x) => x;
}
class D extends C {
-/*severe:INVALID_METHOD_OVERRIDE*/m(x) => x;
+/*error:INVALID_METHOD_OVERRIDE*/m(x) => x;
}
main() {
- int y = /*info:DYNAMIC_CAST*/new D()./*severe:WRONG_NUMBER_OF_TYPE_ARGUMENTS*/m/*<int>*/(42);
+ int y = /*info:DYNAMIC_CAST*/new D()./*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS*/m/*<int>*/(42);
print(y);
}
''');
@@ -1408,7 +1407,7 @@
/*=T*/ f/*<T>*/(List/*<T>*/ s) => null;
main() {
String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
- String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
+ String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
}
''');
}
@@ -1513,11 +1512,11 @@
takeIIO(math.max);
takeDDO(math.max);
-takeOOI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeIDI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeDID(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeOON(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeOOO(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOOI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeIDI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeDID(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOON(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOOO(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
// Also test SimpleIdentifier
takeIII(min);
@@ -1530,11 +1529,11 @@
takeIIO(min);
takeDDO(min);
-takeOOI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeIDI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeDID(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeOON(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeOOO(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOOI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeIDI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeDID(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOON(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOOO(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
// Also PropertyAccess
takeIII(new C().m);
@@ -1556,14 +1555,14 @@
//
// That's legal because we're loosening parameter types.
//
-takeOON(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeOOO(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOON(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOOO(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
// Note: this is a warning because a downcast of a method tear-off could work
// in "normal" Dart, due to bivariance.
-takeOOI(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeIDI(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeDID(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOOI(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeIDI(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeDID(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
}
void takeIII(int fn(int a, int b)) {}
@@ -1605,10 +1604,10 @@
checkFile('''
import 'dart:_foreign_helper' show JS;
main() {
- String x = /*severe:INVALID_ASSIGNMENT*/JS('int', '42');
+ String x = /*error:INVALID_ASSIGNMENT*/JS('int', '42');
var y = JS('String', '"hello"');
y = "world";
- y = /*severe:INVALID_ASSIGNMENT*/42;
+ y = /*error:INVALID_ASSIGNMENT*/42;
}
''');
}
@@ -1901,18 +1900,45 @@
int i;
s = /*info:DYNAMIC_CAST*/new B().x;
- s = /*severe:INVALID_ASSIGNMENT*/new B().y;
+ s = /*error:INVALID_ASSIGNMENT*/new B().y;
s = new B().z;
- s = /*severe:INVALID_ASSIGNMENT*/new B().w;
+ s = /*error:INVALID_ASSIGNMENT*/new B().w;
i = /*info:DYNAMIC_CAST*/new B().x;
i = new B().y;
- i = /*severe:INVALID_ASSIGNMENT*/new B().z;
+ i = /*error:INVALID_ASSIGNMENT*/new B().z;
i = new B().w;
}
''');
}
+ void test_inferDefaultFormalParameter() {
+ var unit = checkFile('''
+f([/*info:INFERRED_TYPE*/x = 42]) {}
+g({/*info:INFERRED_TYPE*/x: 'hi'}) {}
+''');
+ expect(unit.functions[0].parameters[0].type.toString(), 'int');
+ expect(unit.functions[1].parameters[0].type.toString(), 'String');
+ }
+
+ void test_inferDefaultFormalParameter_fieldFormal() {
+ checkFile('''
+class C {
+ int x;
+ var y;
+ C({this.x: /*error:INVALID_ASSIGNMENT*/0.0, this.y: 'hi'}) {
+ String z = /*info:DYNAMIC_CAST*/y;
+ }
+ C.c([this.x =/*error:INVALID_ASSIGNMENT*/0.0, this.y = 'hi']) {
+ String z = /*info:DYNAMIC_CAST*/y;
+ }
+ m() {
+ String z = /*info:DYNAMIC_CAST*/y;
+ }
+}
+''');
+ }
+
void test_inferedType_usesSyntheticFunctionType() {
var mainUnit = checkFile('''
int f() => null;
@@ -2068,8 +2094,8 @@
class B extends A { B(ignore); }
var a = new A();
// Note: it doesn't matter that some of these refer to 'x'.
-var b = new B(/*warning:UNDEFINED_IDENTIFIER*/x); // allocations
-var c1 = [/*warning:UNDEFINED_IDENTIFIER*/x]; // list literals
+var b = new B(/*error:UNDEFINED_IDENTIFIER*/x); // allocations
+var c1 = [/*error:UNDEFINED_IDENTIFIER*/x]; // list literals
var c2 = const [];
var d = <dynamic, dynamic>{'a': 'b'}; // map literals
var e = new A()..x = 3; // cascades
@@ -2078,32 +2104,32 @@
// conected component.
var g = -3;
var h = new A() + 3;
-var i = /*severe:UNDEFINED_OPERATOR*/- new A();
+var i = /*error:UNDEFINED_OPERATOR*/- new A();
var j = null as B;
test1() {
- a = /*severe:INVALID_ASSIGNMENT*/"hi";
+ a = /*error:INVALID_ASSIGNMENT*/"hi";
a = new B(3);
- b = /*severe:INVALID_ASSIGNMENT*/"hi";
+ b = /*error:INVALID_ASSIGNMENT*/"hi";
b = new B(3);
c1 = [];
- c1 = /*severe:INVALID_ASSIGNMENT*/{};
+ c1 = /*error:INVALID_ASSIGNMENT*/{};
c2 = [];
- c2 = /*severe:INVALID_ASSIGNMENT*/{};
+ c2 = /*error:INVALID_ASSIGNMENT*/{};
d = {};
- d = /*severe:INVALID_ASSIGNMENT*/3;
+ d = /*error:INVALID_ASSIGNMENT*/3;
e = new A();
- e = /*severe:INVALID_ASSIGNMENT*/{};
+ e = /*error:INVALID_ASSIGNMENT*/{};
f = 3;
- f = /*severe:INVALID_ASSIGNMENT*/false;
+ f = /*error:INVALID_ASSIGNMENT*/false;
g = 1;
- g = /*severe:INVALID_ASSIGNMENT*/false;
- h = /*severe:INVALID_ASSIGNMENT*/false;
+ g = /*error:INVALID_ASSIGNMENT*/false;
+ h = /*error:INVALID_ASSIGNMENT*/false;
h = new B('b');
i = false;
j = new B('b');
- j = /*severe:INVALID_ASSIGNMENT*/false;
- j = /*severe:INVALID_ASSIGNMENT*/[];
+ j = /*error:INVALID_ASSIGNMENT*/false;
+ j = /*error:INVALID_ASSIGNMENT*/[];
}
''');
}
@@ -2136,7 +2162,7 @@
}
foo() {
- String y = /*severe:INVALID_ASSIGNMENT*/new B().x;
+ String y = /*error:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -2191,8 +2217,8 @@
var y = x;
test1() {
- x = /*severe:INVALID_ASSIGNMENT*/"hi";
- y = /*severe:INVALID_ASSIGNMENT*/"hi";
+ x = /*error:INVALID_ASSIGNMENT*/"hi";
+ y = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -2208,8 +2234,8 @@
class B { static var y = A.x; }
test1() {
- A.x = /*severe:INVALID_ASSIGNMENT*/"hi";
- B.y = /*severe:INVALID_ASSIGNMENT*/"hi";
+ A.x = /*error:INVALID_ASSIGNMENT*/"hi";
+ B.y = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -2353,7 +2379,7 @@
checkFile('''
class Foo {
var x = 1;
- Foo([this.x = /*severe:INVALID_ASSIGNMENT*/"1"]);
+ Foo([this.x = /*error:INVALID_ASSIGNMENT*/"1"]);
}''');
}
@@ -2794,11 +2820,11 @@
}
class B extends A {
- /*severe:INVALID_FIELD_OVERRIDE*/get x => 3;
+ /*error:INVALID_FIELD_OVERRIDE*/get x => 3;
}
foo() {
- String y = /*severe:INVALID_ASSIGNMENT*/new B().x;
+ String y = /*error:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -2815,7 +2841,7 @@
}
foo() {
- String y = /*severe:INVALID_ASSIGNMENT*/new B().x;
+ String y = /*error:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -2826,7 +2852,7 @@
checkFile('''
test1() {
int x = 3;
- x = /*severe:INVALID_ASSIGNMENT*/"hi";
+ x = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -2835,7 +2861,7 @@
checkFile('''
test2() {
var x = 3;
- x = /*severe:INVALID_ASSIGNMENT*/"hi";
+ x = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -2847,13 +2873,13 @@
test1() {
var a = x;
- a = /*severe:INVALID_ASSIGNMENT*/"hi";
+ a = /*error:INVALID_ASSIGNMENT*/"hi";
a = 3;
var b = y;
- b = /*severe:INVALID_ASSIGNMENT*/"hi";
+ b = /*error:INVALID_ASSIGNMENT*/"hi";
b = 4;
var c = z;
- c = /*severe:INVALID_ASSIGNMENT*/"hi";
+ c = /*error:INVALID_ASSIGNMENT*/"hi";
c = 4;
}
@@ -2869,13 +2895,13 @@
test1() {
var a = x;
- a = /*severe:INVALID_ASSIGNMENT*/"hi";
+ a = /*error:INVALID_ASSIGNMENT*/"hi";
a = 3;
var b = y;
- b = /*severe:INVALID_ASSIGNMENT*/"hi";
+ b = /*error:INVALID_ASSIGNMENT*/"hi";
b = 4;
var c = z;
- c = /*severe:INVALID_ASSIGNMENT*/"hi";
+ c = /*error:INVALID_ASSIGNMENT*/"hi";
c = 4;
}
@@ -2902,7 +2928,7 @@
}
foo() {
int y = new C().x;
- String z = /*severe:INVALID_ASSIGNMENT*/new C().x;
+ String z = /*error:INVALID_ASSIGNMENT*/new C().x;
}
''');
}
@@ -2916,11 +2942,11 @@
class B implements A<int> {
get x => 3;
- get w => /*severe:RETURN_OF_INVALID_TYPE*/"hello";
+ get w => /*error:RETURN_OF_INVALID_TYPE*/"hello";
}
foo() {
- String y = /*severe:INVALID_ASSIGNMENT*/new B().x;
+ String y = /*error:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -2934,11 +2960,11 @@
class B<E> extends A<E> {
E y;
- /*severe:INVALID_FIELD_OVERRIDE*/get x => y;
+ /*error:INVALID_FIELD_OVERRIDE*/get x => y;
}
foo() {
- int y = /*severe:INVALID_ASSIGNMENT*/new B<String>().x;
+ int y = /*error:INVALID_ASSIGNMENT*/new B<String>().x;
String z = new B<String>().x;
}
''');
@@ -2967,7 +2993,7 @@
}
foo () {
- int y = /*severe:INVALID_ASSIGNMENT*/new B().m(null, null);
+ int y = /*error:INVALID_ASSIGNMENT*/new B().m(null, null);
String z = new B().m(null, null);
}
''');
@@ -2980,7 +3006,7 @@
}
class B implements A<int> {
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
+ /*error:INVALID_METHOD_OVERRIDE*/dynamic get x => 3;
}
foo() {
@@ -3023,7 +3049,7 @@
}
foo () {
- int y = /*severe:INVALID_ASSIGNMENT*/new B<String>().m(null, null).value;
+ int y = /*error:INVALID_ASSIGNMENT*/new B<String>().m(null, null).value;
String z = new B<String>().m(null, null).value;
}
''');
@@ -3038,7 +3064,7 @@
class Bar<T extends Iterable<String>> {
void foo(T t) {
for (var i in t) {
- int x = /*severe:INVALID_ASSIGNMENT*/i;
+ int x = /*error:INVALID_ASSIGNMENT*/i;
}
}
}
@@ -3046,7 +3072,7 @@
class Baz<T, E extends Iterable<T>, S extends E> {
void foo(S t) {
for (var i in t) {
- int x = /*severe:INVALID_ASSIGNMENT*/i;
+ int x = /*error:INVALID_ASSIGNMENT*/i;
T y = i;
}
}
@@ -3055,7 +3081,7 @@
test() {
var list = <Foo>[];
for (var x in list) {
- String y = /*severe:INVALID_ASSIGNMENT*/x;
+ String y = /*error:INVALID_ASSIGNMENT*/x;
}
for (dynamic x in list) {
@@ -3064,7 +3090,7 @@
String y = /*info:DYNAMIC_CAST,info:INVALID_ASSIGNMENT*/x;
}
- for (String x in /*severe:FOR_IN_OF_INVALID_ELEMENT_TYPE*/list) {
+ for (String x in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/list) {
String y = x;
}
@@ -3085,7 +3111,7 @@
var map = <String, Foo>{};
// Error: map must be an Iterable.
- for (var x in /*severe:FOR_IN_OF_INVALID_TYPE*/map) {
+ for (var x in /*error:FOR_IN_OF_INVALID_TYPE*/map) {
String y = /*info:DYNAMIC_CAST*/x;
}
@@ -3132,7 +3158,7 @@
import 'a.dart';
import 'b.dart';
main() {
- new A().x = /*severe:INVALID_ASSIGNMENT*/'foo';
+ new A().x = /*error:INVALID_ASSIGNMENT*/'foo';
new B().x = 'foo';
}
''');
@@ -3243,14 +3269,14 @@
checkFile(r'''
test1() {
var x = /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3];
- x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
- x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0);
+ x.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+ x.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0);
x.add(4);
List<num> y = x;
}
test2() {
var x = /*info:INFERRED_TYPE_LITERAL*/[1, 2.0, 3];
- x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+ x.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
x.add(4.0);
List<int> y = /*info:ASSIGNMENT_CAST*/x;
}
@@ -3261,14 +3287,14 @@
checkFile(r'''
var x1 = /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3];
test1() {
- x1.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
- x1.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0);
+ x1.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+ x1.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0);
x1.add(4);
List<num> y = x1;
}
var x2 = /*info:INFERRED_TYPE_LITERAL*/[1, 2.0, 3];
test2() {
- x2.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+ x2.add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
x2.add(4.0);
List<int> y = /*info:ASSIGNMENT_CAST*/x2;
}
@@ -3302,18 +3328,18 @@
test1() {
var x = /*info:INFERRED_TYPE_LITERAL*/{ 1: 'x', 2: 'y' };
x[3] = 'z';
- x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
- x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0] = 'u';
- x[3] = /*severe:INVALID_ASSIGNMENT*/42;
+ x[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
+ x[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0] = 'u';
+ x[3] = /*error:INVALID_ASSIGNMENT*/42;
Map<num, String> y = x;
}
test2() {
var x = /*info:INFERRED_TYPE_LITERAL*/{ 1: 'x', 2: 'y', 3.0: new RegExp('.') };
x[3] = 'z';
- x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
+ x[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
x[4.0] = 'u';
- x[3] = /*severe:INVALID_ASSIGNMENT*/42;
+ x[3] = /*error:INVALID_ASSIGNMENT*/42;
Pattern p = null;
x[2] = p;
Map<int, String> y = /*info:ASSIGNMENT_CAST*/x;
@@ -3326,18 +3352,18 @@
var x1 = /*info:INFERRED_TYPE_LITERAL*/{ 1: 'x', 2: 'y' };
test1() {
x1[3] = 'z';
- x1[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
- x1[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0] = 'u';
- x1[3] = /*severe:INVALID_ASSIGNMENT*/42;
+ x1[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
+ x1[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0] = 'u';
+ x1[3] = /*error:INVALID_ASSIGNMENT*/42;
Map<num, String> y = x1;
}
var x2 = /*info:INFERRED_TYPE_LITERAL*/{ 1: 'x', 2: 'y', 3.0: new RegExp('.') };
test2() {
x2[3] = 'z';
- x2[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
+ x2[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
x2[4.0] = 'u';
- x2[3] = /*severe:INVALID_ASSIGNMENT*/42;
+ x2[3] = /*error:INVALID_ASSIGNMENT*/42;
Pattern p = null;
x2[2] = p;
Map<int, String> y = /*info:ASSIGNMENT_CAST*/x2;
@@ -3487,10 +3513,10 @@
test5() {
var a1 = new A();
- a1.x = /*severe:INVALID_ASSIGNMENT*/"hi";
+ a1.x = /*error:INVALID_ASSIGNMENT*/"hi";
A a2 = new A();
- a2.x = /*severe:INVALID_ASSIGNMENT*/"hi";
+ a2.x = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -3643,7 +3669,7 @@
checkFile('''
import 'a.dart';
test() {
- x = /*severe:INVALID_ASSIGNMENT*/"hi";
+ x = /*error:INVALID_ASSIGNMENT*/"hi";
}
''');
}
@@ -3732,7 +3758,7 @@
/// create a file like:
///
/// addFile('''
- /// String x = /*severe:STATIC_TYPE_ERROR*/3;
+ /// String x = /*error:STATIC_TYPE_ERROR*/3;
/// ''');
/// check();
///
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 d9778c7..82829eb 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -16,7 +16,6 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:logging/logging.dart';
import 'package:source_span/source_span.dart';
import 'package:unittest/unittest.dart';
@@ -38,7 +37,7 @@
/// create a file like:
///
/// addFile('''
-/// String x = /*severe:STATIC_TYPE_ERROR*/3;
+/// String x = /*error:STATIC_TYPE_ERROR*/3;
/// ''');
/// check();
///
@@ -55,7 +54,7 @@
/// the file text.
///
/// Returns the main resolved library. This can be used for further checks.
-CompilationUnit check({bool implicitCasts: true}) {
+CompilationUnit check({bool implicitCasts: true, bool implicitDynamic: true}) {
_checkCalled = true;
expect(files.getFile('/main.dart').exists, true,
@@ -68,6 +67,7 @@
options.strongMode = true;
options.strongModeHints = true;
options.implicitCasts = implicitCasts;
+ options.implicitDynamic = implicitDynamic;
var mockSdk = new MockSdk();
mockSdk.context.analysisOptions.strongMode = true;
context.sourceFactory =
@@ -132,14 +132,6 @@
});
}
-Level _actualErrorLevel(AnalysisContext context, AnalysisError actual) {
- return const <ErrorSeverity, Level>{
- ErrorSeverity.ERROR: Level.SEVERE,
- ErrorSeverity.WARNING: Level.WARNING,
- ErrorSeverity.INFO: Level.INFO
- }[_errorSeverity(context, actual)];
-}
-
SourceSpanWithContext _createSpanHelper(
LineInfo lineInfo, int start, Source source, String content,
{int end}) {
@@ -200,7 +192,7 @@
int delta = x.offset.compareTo(y.offset);
if (delta != 0) return delta;
- delta = x.level.compareTo(y.level);
+ delta = x.severity.compareTo(y.severity);
if (delta != 0) return delta;
return x.typeName.compareTo(y.typeName);
@@ -213,7 +205,7 @@
for (var expected in expectedErrors) {
AnalysisError actual = expected._removeMatchingActual(actualErrors);
if (actual != null) {
- if (_actualErrorLevel(context, actual) != expected.level ||
+ if (_errorSeverity(context, actual) != expected.severity ||
_errorCodeName(actual.errorCode) != expected.typeName) {
different[expected] = actual;
}
@@ -233,7 +225,7 @@
List<_ErrorExpectation> _findExpectedErrors(Token beginToken) {
var expectedErrors = <_ErrorExpectation>[];
- // Collect expectations like "severe:STATIC_TYPE_ERROR" from comment tokens.
+ // Collect expectations like "error:STATIC_TYPE_ERROR" from comment tokens.
for (Token t = beginToken; t.type != TokenType.EOF; t = t.next) {
for (CommentToken c = t.precedingComments; c != null; c = c.next) {
if (c.type == TokenType.MULTI_LINE_COMMENT) {
@@ -295,7 +287,7 @@
var span = _createSpanHelper(
unit.lineInfo, offset, unit.element.source, sourceCode,
end: offset + length);
- var levelName = _actualErrorLevel(context, error).name.toLowerCase();
+ var levelName = _errorSeverity(context, error).displayName;
return '@$offset $levelName:${_errorCodeName(error.errorCode)}\n' +
span.message(error.message);
}
@@ -304,8 +296,8 @@
int offset = error.offset;
var span = _createSpanHelper(
unit.lineInfo, offset, unit.element.source, sourceCode);
- var levelName = error.level.toString().toLowerCase();
- return '@$offset $levelName:${error.typeName}\n' + span.message('');
+ var severity = error.severity.displayName;
+ return '@$offset $severity:${error.typeName}\n' + span.message('');
}
var message = new StringBuffer();
@@ -349,13 +341,12 @@
/// Describes an expected message that should be produced by the checker.
class _ErrorExpectation {
final int offset;
- final Level level;
+ final ErrorSeverity severity;
final String typeName;
- _ErrorExpectation(this.offset, this.level, this.typeName);
+ _ErrorExpectation(this.offset, this.severity, this.typeName);
- String toString() =>
- '@$offset ${level.toString().toLowerCase()}: [$typeName]';
+ String toString() => '@$offset ${severity.displayName}: [$typeName]';
AnalysisError _removeMatchingActual(List<AnalysisError> actualErrors) {
for (var actual in actualErrors) {
@@ -386,10 +377,10 @@
var name = tokens[0].toUpperCase();
var typeName = tokens[1];
- var level =
- Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
+ var level = ErrorSeverity.values
+ .firstWhere((l) => l.name == name, orElse: () => null);
expect(level, isNotNull,
- reason: 'invalid level in error descriptor: `${tokens[0]}`');
+ reason: 'invalid severity in error descriptor: `${tokens[0]}`');
expect(typeName, isNotNull,
reason: 'invalid type in error descriptor: ${tokens[1]}');
return new _ErrorExpectation(offset, level, typeName);
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 4f9018e..869b38d 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -544,9 +544,7 @@
out('class $builderName extends Object with $mixinName '
'implements ${idlPrefix(name)} {');
indent(() {
- out('bool _finished = false;');
// Generate fields.
- out();
for (idlModel.FieldDeclaration field in cls.fields) {
String fieldName = field.name;
idlModel.FieldType type = field.type;
@@ -572,7 +570,6 @@
out('void set $fieldName($typeStr _value) {');
indent(() {
String stateFieldName = '_' + fieldName;
- out('assert(!_finished);');
// Validate that int(s) are non-negative.
if (fieldType.typeName == 'int') {
if (!fieldType.isList) {
@@ -637,8 +634,6 @@
out();
out('fb.Offset finish(fb.Builder fbBuilder) {');
indent(() {
- out('assert(!_finished);');
- out('_finished = true;');
// Write objects and remember Offset(s).
for (idlModel.FieldDeclaration field in cls.fields) {
idlModel.FieldType fieldType = field.type;
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index e134a09..11040b1 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -25,6 +25,7 @@
BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
BuildLibraryElementTask -> IS_LAUNCHABLE
BuildLibraryElementTask -> LIBRARY_ELEMENT1
+ BuildLibraryElementTask -> REFERENCED_NAMES
BuildPublicNamespaceTask -> LIBRARY_ELEMENT3
BuildSourceExportClosureTask -> EXPORT_SOURCE_CLOSURE
BuildTypeProviderTask -> TYPE_PROVIDER
@@ -300,7 +301,6 @@
ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
- ResolveLibraryReferencesTask -> REFERENCED_NAMES
ResolveLibraryTask -> LIBRARY_ELEMENT
ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
ResolveTopLevelLibraryTypeBoundsTask -> LIBRARY_ELEMENT5
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 12b39df..da846c2 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -259,14 +259,12 @@
static ErrorSeverity computeSeverity(
AnalysisError error, CommandLineOptions options,
[AnalysisContext context]) {
- bool isStrongMode = false;
if (context != null) {
ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
// If there is a processor for this error, defer to it.
if (processor != null) {
return processor.severity;
}
- isStrongMode = context.analysisOptions.strongMode;
}
if (!options.enableTypeChecks &&
@@ -276,10 +274,6 @@
return ErrorSeverity.ERROR;
} else if (options.lintsAreFatal && error.errorCode is LintCode) {
return ErrorSeverity.ERROR;
- } else if (isStrongMode &&
- error is StaticWarningCode &&
- (error as StaticWarningCode).isStrongModeError) {
- return ErrorSeverity.ERROR;
}
return error.errorCode.errorSeverity;
}
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 879ec69..f79e401 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -184,8 +184,10 @@
// Write summary.
assembler = new PackageBundleAssembler(
- excludeHashes: options.buildSummaryExcludeInformative);
- if (options.buildSummaryOutput != null) {
+ excludeHashes: options.buildSummaryExcludeInformative &&
+ options.buildSummaryOutputSemantic == null);
+ if (options.buildSummaryOutput != null ||
+ options.buildSummaryOutputSemantic != null) {
if (options.buildSummaryOnlyAst && !options.buildSummaryFallback) {
_serializeAstBasedSummary(explicitSources);
} else {
@@ -209,8 +211,17 @@
if (options.buildSummaryExcludeInformative) {
sdkBundle.flushInformative();
}
- io.File file = new io.File(options.buildSummaryOutput);
- file.writeAsBytesSync(sdkBundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
+ if (options.buildSummaryOutput != null) {
+ io.File file = new io.File(options.buildSummaryOutput);
+ file.writeAsBytesSync(sdkBundle.toBuffer(),
+ mode: io.FileMode.WRITE_ONLY);
+ }
+ if (options.buildSummaryOutputSemantic != null) {
+ sdkBundle.flushInformative();
+ io.File file = new io.File(options.buildSummaryOutputSemantic);
+ file.writeAsBytesSync(sdkBundle.toBuffer(),
+ mode: io.FileMode.WRITE_ONLY);
+ }
}
if (options.buildSummaryOnly) {
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index c43fcd8..e0c9a8e 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -105,9 +105,13 @@
/// The two format options are a user consumable format and a machine consumable
/// format.
class ErrorFormatter {
+ static final int _pipeCodeUnit = '|'.codeUnitAt(0);
+ static final int _slashCodeUnit = '\\'.codeUnitAt(0);
+
final StringSink out;
final CommandLineOptions options;
final AnalysisStats stats;
+
final _SeverityProcessor processSeverity;
ErrorFormatter(this.out, this.options, this.stats,
@@ -167,7 +171,6 @@
}
out.writeln();
}
-
void formatErrors(List<AnalysisErrorInfo> errorInfos) {
stats.unfilteredCount += errorInfos.length;
@@ -223,9 +226,9 @@
}
static String escapePipe(String input) {
- var result = new StringBuffer();
- for (var c in input.codeUnits) {
- if (c == '\\' || c == '|') {
+ StringBuffer result = new StringBuffer();
+ for (int c in input.codeUnits) {
+ if (c == _slashCodeUnit || c == _pipeCodeUnit) {
result.write('\\');
}
result.writeCharCode(c);
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 4cd4c6c..3706464 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -62,6 +62,10 @@
/// The path to output the summary when creating summaries in build mode.
final String buildSummaryOutput;
+ /// The path to output the semantic-only summary when creating summaries in
+ /// build mode.
+ final String buildSummaryOutputSemantic;
+
/// Whether to output a summary in "fallback mode".
final bool buildSummaryFallback;
@@ -163,6 +167,7 @@
buildSummaryExcludeInformative =
args['build-summary-exclude-informative'],
buildSummaryOutput = args['build-summary-output'],
+ buildSummaryOutputSemantic = args['build-summary-output-semantic'],
buildSuppressExitCode = args['build-suppress-exit-code'],
dartSdkPath = args['dart-sdk'],
dartSdkSummaryPath = args['dart-sdk-summary'],
@@ -385,8 +390,12 @@
allowMultiple: true,
hide: true)
..addOption('build-summary-output',
- help: 'Specifies the path to the file where the summary information '
- 'should be written.',
+ help: 'Specifies the path to the file where the full summary '
+ 'information should be written.',
+ hide: true)
+ ..addOption('build-summary-output-semantic',
+ help: 'Specifies the path to the file where the semantic summary '
+ 'information should be written.',
hide: true)
..addFlag('build-summary-only',
help: 'Disable analysis (only generate summaries).',
@@ -404,7 +413,8 @@
negatable: false,
hide: true)
..addFlag('build-summary-exclude-informative',
- help: 'Exclude @informative information (docs, offsets, etc).',
+ help: 'Exclude @informative information (docs, offsets, etc). '
+ 'Deprecated: please use --build-summary-output-semantic instead.',
defaultsTo: false,
negatable: false,
hide: true)
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 29bde19..50ee98c 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -25,6 +25,7 @@
expect(options.buildSummaryInputs, isEmpty);
expect(options.buildSummaryOnly, isFalse);
expect(options.buildSummaryOutput, isNull);
+ expect(options.buildSummaryOutputSemantic, isNull);
expect(options.buildSuppressExitCode, isFalse);
expect(options.dartSdkPath, isNotNull);
expect(options.disableHints, isFalse);
@@ -318,6 +319,16 @@
expect(options.buildSummaryOutput, '//path/to/output.sum');
}
+ test_buildSummaryOutputSemantic() {
+ _parse([
+ '--build-mode',
+ '--build-summary-output-semantic=//path/to/output.sum',
+ 'package:p/foo.dart|/path/to/p/lib/foo.dart'
+ ]);
+ expect(options.buildMode, isTrue);
+ expect(options.buildSummaryOutputSemantic, '//path/to/output.sum');
+ }
+
test_buildSuppressExitCode() {
_parse([
'--build-mode',
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index ced831b..5707bdc 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -810,7 +810,14 @@
supportSerialization: serialization.supportSerialization);
phase = PHASE_RESOLVING;
- if (analyzeAll) {
+ if (options.resolveOnly) {
+ libraryLoader.libraries.where((LibraryElement library) {
+ return !serialization.isDeserialized(library);
+ }).forEach((LibraryElement library) {
+ reporter.log('Enqueuing ${library.canonicalUri}');
+ fullyEnqueueLibrary(library, enqueuer.resolution);
+ });
+ } else if (analyzeAll) {
libraryLoader.libraries.forEach((LibraryElement library) {
reporter.log('Enqueuing ${library.canonicalUri}');
fullyEnqueueLibrary(library, enqueuer.resolution);
@@ -846,9 +853,11 @@
if (options.resolveOnly) {
reporter.log('Serializing to ${options.resolutionOutput}');
- serialization.serializeToSink(
- userOutputProvider.createEventSink('', 'data'),
- libraryLoader.libraries);
+ serialization
+ .serializeToSink(userOutputProvider.createEventSink('', 'data'),
+ libraryLoader.libraries.where((LibraryElement library) {
+ return !serialization.isDeserialized(library);
+ }));
}
if (options.analyzeOnly) {
if (!analyzeAll && !compilationFailed) {
diff --git a/pkg/compiler/lib/src/constants/constant_constructors.dart b/pkg/compiler/lib/src/constants/constant_constructors.dart
index c389eef..874dab7 100644
--- a/pkg/compiler/lib/src/constants/constant_constructors.dart
+++ b/pkg/compiler/lib/src/constants/constant_constructors.dart
@@ -285,6 +285,11 @@
}
@override
+ ConstantExpression visitLiteralDouble(LiteralDouble node) {
+ return new DoubleConstantExpression(node.value);
+ }
+
+ @override
ConstantExpression visitLiteralBool(LiteralBool node) {
return new BoolConstantExpression(node.value);
}
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 2deb866..922ae06 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -870,9 +870,18 @@
@override
ConstantValue evaluate(
Environment environment, ConstantSystem constantSystem) {
- return constantSystem.lookupBinary(operator).fold(
- left.evaluate(environment, constantSystem),
- right.evaluate(environment, constantSystem));
+ ConstantValue leftValue = left.evaluate(environment, constantSystem);
+ ConstantValue rightValue = right.evaluate(environment, constantSystem);
+ switch (operator.kind) {
+ case BinaryOperatorKind.NOT_EQ:
+ BoolConstantValue equals =
+ constantSystem.equal.fold(leftValue, rightValue);
+ return equals.negate();
+ default:
+ return constantSystem
+ .lookupBinary(operator)
+ .fold(leftValue, rightValue);
+ }
}
ConstantExpression apply(NormalizedArguments arguments) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 7d19ec0..b82ad53 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -471,6 +471,11 @@
api.Diagnostic.INFO);
}
if (resolveOnly) {
+ if (resolutionInputs.contains(resolutionOutput)) {
+ helpAndFail("Resolution input '${resolutionOutput}' can't be used as "
+ "resolution output. Use the '--out' option to specify another "
+ "resolution output.");
+ }
analyzeOnly = analyzeAll = true;
} else if (analyzeAll) {
analyzeOnly = true;
@@ -835,60 +840,162 @@
});
}
+// TODO(johnniwinther): Add corresponding options to the test script and change
+// these to use 'bool.fromEnvironment'.
final bool USE_SERIALIZED_DART_CORE =
Platform.environment['USE_SERIALIZED_DART_CORE'] == 'true';
-/// Mock URI used only in testing when [USE_SERIALIZED_DART_CORE] is enabled.
-final Uri _SERIALIZED_URI = Uri.parse('file:fake.data');
+final bool SERIALIZED_COMPILATION =
+ Platform.environment['SERIALIZED_COMPILATION'] == 'true';
+
+/// Mock URI used only in testing when [USE_SERIALIZED_DART_CORE] or
+/// [SERIALIZED_COMPILATION] is enabled.
+final Uri _SERIALIZED_DART_CORE_URI = Uri.parse('file:core.data');
+final Uri _SERIALIZED_TEST_URI = Uri.parse('file:test.data');
void _useSerializedDataForDartCore(CompileFunc oldCompileFunc) {
- String serializedData;
-
+ /// Run the [oldCompileFunc] with [serializedData] added as resolution input.
Future<api.CompilationResult> compileWithSerializedData(
CompilerOptions compilerOptions,
api.CompilerInput compilerInput,
api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput) async {
- CompilerImpl compiler = new CompilerImpl(
- compilerInput, compilerOutput, compilerDiagnostics, compilerOptions);
- compiler.serialization.deserializeFromText(_SERIALIZED_URI, serializedData);
- return compiler.run(compilerOptions.entryPoint).then((bool success) {
- return new api.CompilationResult(compiler, isSuccess: success);
- });
+ api.CompilerOutput compilerOutput,
+ List<_SerializedData> serializedData) {
+ api.CompilerInput input = compilerInput;
+ CompilerOptions options = compilerOptions;
+ if (serializedData != null && serializedData.isNotEmpty) {
+ Map<Uri, String> dataMap = <Uri, String>{};
+ for (_SerializedData data in serializedData) {
+ dataMap[data.uri] = data.data;
+ }
+ input = new _CompilerInput(input, dataMap);
+ List<Uri> resolutionInputs = dataMap.keys.toList();
+ if (compilerOptions.resolutionInputs != null) {
+ for (Uri uri in compilerOptions.resolutionInputs) {
+ if (!dataMap.containsKey(uri)) {
+ resolutionInputs.add(uri);
+ }
+ }
+ }
+ options = options.copy(resolutionInputs: resolutionInputs);
+ }
+ return oldCompileFunc(options, input, compilerDiagnostics, compilerOutput);
}
+ /// Serialize [entryPoint] using [serializedData] if provided.
+ Future<api.CompilationResult> serialize(
+ Uri entryPoint,
+ Uri serializedUri,
+ CompilerOptions compilerOptions,
+ api.CompilerInput compilerInput,
+ api.CompilerDiagnostics compilerDiagnostics,
+ api.CompilerOutput compilerOutput,
+ [List<_SerializedData> serializedData]) {
+ CompilerOptions options = new CompilerOptions.parse(
+ entryPoint: entryPoint,
+ libraryRoot: compilerOptions.libraryRoot,
+ packageRoot: compilerOptions.packageRoot,
+ packageConfig: compilerOptions.packageConfig,
+ packagesDiscoveryProvider: compilerOptions.packagesDiscoveryProvider,
+ environment: compilerOptions.environment,
+ resolutionOutput: serializedUri,
+ options: [Flags.resolveOnly]);
+ return compileWithSerializedData(options, compilerInput,
+ compilerDiagnostics, compilerOutput, serializedData);
+ }
+
+ // Local cache for the serialized data for dart:core.
+ _SerializedData serializedDartCore;
+
+ /// Serialize the entry point using serialized data from dart:core and run
+ /// [oldCompileFunc] using serialized data for whole program.
+ Future<api.CompilationResult> compileFromSerializedData(
+ CompilerOptions compilerOptions,
+ api.CompilerInput compilerInput,
+ api.CompilerDiagnostics compilerDiagnostics,
+ api.CompilerOutput compilerOutput) async {
+ _CompilerOutput output = new _CompilerOutput(_SERIALIZED_TEST_URI);
+ api.CompilationResult result = await serialize(
+ compilerOptions.entryPoint,
+ output.uri,
+ compilerOptions,
+ compilerInput,
+ compilerDiagnostics,
+ output,
+ [serializedDartCore]);
+ if (!result.isSuccess) {
+ return result;
+ }
+ return compileWithSerializedData(
+ compilerOptions,
+ compilerInput,
+ compilerDiagnostics,
+ compilerOutput,
+ [serializedDartCore, output.serializedData]);
+ }
+
+ /// Compiles the entry point using the serialized data from dart:core.
+ Future<api.CompilationResult> compileWithSerializedDartCoreData(
+ CompilerOptions compilerOptions,
+ api.CompilerInput compilerInput,
+ api.CompilerDiagnostics compilerDiagnostics,
+ api.CompilerOutput compilerOutput) async {
+ return compileWithSerializedData(compilerOptions, compilerInput,
+ compilerDiagnostics, compilerOutput, [serializedDartCore]);
+ }
+
+ /// Serialize dart:core data into [serializedDartCore] and setup the
+ /// [compileFunc] to run the compiler using this data.
Future<api.CompilationResult> generateSerializedDataForDartCore(
CompilerOptions compilerOptions,
api.CompilerInput compilerInput,
api.CompilerDiagnostics compilerDiagnostics,
api.CompilerOutput compilerOutput) async {
- _CompilerOutput output = new _CompilerOutput();
- api.CompilationResult result = await oldCompileFunc(
- new CompilerOptions.parse(
- entryPoint: Uris.dart_core,
- libraryRoot: compilerOptions.libraryRoot,
- packageRoot: compilerOptions.packageRoot,
- packageConfig: compilerOptions.packageConfig,
- packagesDiscoveryProvider:
- compilerOptions.packagesDiscoveryProvider,
- environment: compilerOptions.environment,
- resolutionOutput: _SERIALIZED_URI,
- options: [Flags.resolveOnly]),
- compilerInput,
- compilerDiagnostics,
- output);
- serializedData = output.serializedData;
- compileFunc = compileWithSerializedData;
- return compileWithSerializedData(
+ _CompilerOutput output = new _CompilerOutput(_SERIALIZED_DART_CORE_URI);
+ await serialize(Uris.dart_core, output.uri, compilerOptions, compilerInput,
+ compilerDiagnostics, output);
+ serializedDartCore = output.serializedData;
+ if (SERIALIZED_COMPILATION) {
+ compileFunc = compileFromSerializedData;
+ } else {
+ compileFunc = compileWithSerializedDartCoreData;
+ }
+ return compileFunc(
compilerOptions, compilerInput, compilerDiagnostics, compilerOutput);
}
compileFunc = generateSerializedDataForDartCore;
}
+class _CompilerInput implements api.CompilerInput {
+ final api.CompilerInput _input;
+ final Map<Uri, String> _data;
+
+ _CompilerInput(this._input, this._data);
+
+ @override
+ Future readFromUri(Uri uri) {
+ String data = _data[uri];
+ if (data != null) {
+ return new Future.value(data);
+ }
+ return _input.readFromUri(uri);
+ }
+}
+
+class _SerializedData {
+ final Uri uri;
+ final String data;
+
+ _SerializedData(this.uri, this.data);
+}
+
class _CompilerOutput extends NullCompilerOutput {
+ final Uri uri;
_BufferedEventSink sink;
+ _CompilerOutput(this.uri);
+
@override
EventSink<String> createEventSink(String name, String extension) {
if (name == '' && extension == 'data') {
@@ -897,7 +1004,9 @@
return super.createEventSink(name, extension);
}
- String get serializedData => sink.sb.toString();
+ _SerializedData get serializedData {
+ return new _SerializedData(uri, sink.sb.toString());
+ }
}
class _BufferedEventSink implements EventSink<String> {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 8ddc535..dbcab63 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -687,6 +687,26 @@
main() {
new C(4, 2);
}
+""",
+ """
+class C {
+ int x;
+ C(int x, this.x);
+}
+
+main() {
+ new C(4, 2);
+}
+""",
+ """
+class C {
+ int x;
+ C(this.x, this.x);
+}
+
+main() {
+ new C(4, 2);
+}
"""
]),
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 4cbc011..d9e8681 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -193,8 +193,16 @@
// At this point we know that this is signature-compatible with
// Object.noSuchMethod, but it may have more than one argument as long as
// it only has one required argument.
+ if (!element.hasResolvedAst) {
+ // TODO(johnniwinther): Why do we see unresolved elements here?
+ return false;
+ }
+ ResolvedAst resolvedAst = element.resolvedAst;
+ if (resolvedAst.kind != ResolvedAstKind.PARSED) {
+ return false;
+ }
String param = element.parameters.first.name;
- Statement body = element.node.body;
+ Statement body = resolvedAst.body;
Expression expr;
if (body is Return && body.isArrowBody) {
expr = body.expression;
@@ -231,7 +239,15 @@
}
bool _hasThrowingSyntax(FunctionElement element) {
- Statement body = element.node.body;
+ if (!element.hasResolvedAst) {
+ // TODO(johnniwinther): Why do we see unresolved elements here?
+ return false;
+ }
+ ResolvedAst resolvedAst = element.resolvedAst;
+ if (resolvedAst.kind != ResolvedAstKind.PARSED) {
+ return false;
+ }
+ Statement body = resolvedAst.body;
if (body is Return && body.isArrowBody) {
if (body.expression is Throw) {
return true;
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index f2997aa..ae4cbba 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -76,8 +76,8 @@
FunctionElement method, FunctionType type) {
assert(method.isImplementation);
jsAst.Expression thisAccess = new jsAst.This();
- ClosureClassMap closureData =
- compiler.closureToClassMapper.closureMappingCache[method.node];
+ ClosureClassMap closureData = compiler
+ .closureToClassMapper.closureMappingCache[method.resolvedAst.node];
if (closureData != null) {
ClosureFieldElement thisLocal =
closureData.freeVariableMap[closureData.thisLocal];
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 846ce8b..1b7beca 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -833,6 +833,9 @@
// TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole].
if (method.optionalParameterDefaultValues is List) {
List<ConstantValue> defaultValues = method.optionalParameterDefaultValues;
+ if (defaultValues.isEmpty) {
+ return new js.LiteralNull();
+ }
Iterable<js.Expression> elements =
defaultValues.map(generateConstantReference);
return js.js('function() { return #; }',
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 9da31d6..be0cb41 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -649,10 +649,16 @@
handler.registerNewLibrary(library);
return listener.onLibraryScanned(library, handler).then((_) {
return Future.forEach(library.imports, (ImportElement import) {
- return createLibrary(handler, library, import.uri);
+ Uri resolvedUri = library.canonicalUri.resolveUri(import.uri);
+ return createLibrary(handler, library, resolvedUri);
}).then((_) {
return Future.forEach(library.exports, (ExportElement export) {
- return createLibrary(handler, library, export.uri);
+ Uri resolvedUri = library.canonicalUri.resolveUri(export.uri);
+ return createLibrary(handler, library, resolvedUri);
+ }).then((_) {
+ // TODO(johnniwinther): Shouldn't there be an [ImportElement] for the
+ // implicit import of dart:core?
+ return createLibrary(handler, library, Uris.dart_core);
}).then((_) => library);
});
});
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 2d235c1..ee3370e 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -525,6 +525,131 @@
this.verbose: false})
: _shownPackageWarnings = shownPackageWarnings;
+ /// Creates a copy of the [CompilerOptions] where the provided non-null
+ /// option values replace existing.
+ CompilerOptions copy(
+ {entryPoint,
+ libraryRoot,
+ packageRoot,
+ packageConfig,
+ packagesDiscoveryProvider,
+ environment,
+ allowMockCompilation,
+ allowNativeExtensions,
+ analyzeAll,
+ analyzeMain,
+ analyzeOnly,
+ analyzeSignaturesOnly,
+ buildId,
+ dart2dartMultiFile,
+ deferredMapUri,
+ fatalWarnings,
+ terseDiagnostics,
+ suppressWarnings,
+ suppressHints,
+ List<String> shownPackageWarnings,
+ disableInlining,
+ disableTypeInference,
+ dumpInfo,
+ emitJavaScript,
+ enableAssertMessage,
+ enableGenericMethodSyntax,
+ enableInitializingFormalAccess,
+ enableExperimentalMirrors,
+ enableMinification,
+ enableNativeLiveTypeAnalysis,
+ enableTypeAssertions,
+ enableUserAssertions,
+ generateCodeWithCompileTimeErrors,
+ generateSourceMap,
+ hasIncrementalSupport,
+ outputUri,
+ platformConfigUri,
+ preserveComments,
+ preserveUris,
+ resolutionInputs,
+ resolutionOutput,
+ resolveOnly,
+ sourceMapUri,
+ strips,
+ testMode,
+ trustJSInteropTypeAnnotations,
+ trustPrimitives,
+ trustTypeAnnotations,
+ useContentSecurityPolicy,
+ useCpsIr,
+ useFrequencyNamer,
+ useNewSourceInfo,
+ useStartupEmitter,
+ verbose}) {
+ return new CompilerOptions._(
+ entryPoint ?? this.entryPoint,
+ libraryRoot ?? this.libraryRoot,
+ packageRoot ?? this.packageRoot,
+ packageConfig ?? this.packageConfig,
+ packagesDiscoveryProvider ?? this.packagesDiscoveryProvider,
+ environment ?? this.environment,
+ allowMockCompilation: allowMockCompilation ?? this.allowMockCompilation,
+ allowNativeExtensions:
+ allowNativeExtensions ?? this.allowNativeExtensions,
+ analyzeAll: analyzeAll ?? this.analyzeAll,
+ analyzeMain: analyzeMain ?? this.analyzeMain,
+ analyzeOnly: analyzeOnly ?? this.analyzeOnly,
+ analyzeSignaturesOnly:
+ analyzeSignaturesOnly ?? this.analyzeSignaturesOnly,
+ buildId: buildId ?? this.buildId,
+ dart2dartMultiFile: dart2dartMultiFile ?? this.dart2dartMultiFile,
+ deferredMapUri: deferredMapUri ?? this.deferredMapUri,
+ fatalWarnings: fatalWarnings ?? this.fatalWarnings,
+ terseDiagnostics: terseDiagnostics ?? this.terseDiagnostics,
+ suppressWarnings: suppressWarnings ?? this.suppressWarnings,
+ suppressHints: suppressHints ?? this.suppressHints,
+ shownPackageWarnings:
+ shownPackageWarnings ?? this._shownPackageWarnings,
+ disableInlining: disableInlining ?? this.disableInlining,
+ disableTypeInference: disableTypeInference ?? this.disableTypeInference,
+ dumpInfo: dumpInfo ?? this.dumpInfo,
+ emitJavaScript: emitJavaScript ?? this.emitJavaScript,
+ enableAssertMessage: enableAssertMessage ?? this.enableAssertMessage,
+ enableGenericMethodSyntax:
+ enableGenericMethodSyntax ?? this.enableGenericMethodSyntax,
+ enableInitializingFormalAccess: enableInitializingFormalAccess ??
+ this.enableInitializingFormalAccess,
+ enableExperimentalMirrors:
+ enableExperimentalMirrors ?? this.enableExperimentalMirrors,
+ enableMinification: enableMinification ?? this.enableMinification,
+ enableNativeLiveTypeAnalysis:
+ enableNativeLiveTypeAnalysis ?? this.enableNativeLiveTypeAnalysis,
+ enableTypeAssertions: enableTypeAssertions ?? this.enableTypeAssertions,
+ enableUserAssertions: enableUserAssertions ?? this.enableUserAssertions,
+ generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors ??
+ this.generateCodeWithCompileTimeErrors,
+ generateSourceMap: generateSourceMap ?? this.generateSourceMap,
+ hasIncrementalSupport:
+ hasIncrementalSupport ?? this.hasIncrementalSupport,
+ outputUri: outputUri ?? this.outputUri,
+ platformConfigUri: platformConfigUri ?? this.platformConfigUri,
+ preserveComments: preserveComments ?? this.preserveComments,
+ preserveUris: preserveUris ?? this.preserveUris,
+ resolutionInputs: resolutionInputs ?? this.resolutionInputs,
+ resolutionOutput: resolutionOutput ?? this.resolutionOutput,
+ resolveOnly: resolveOnly ?? this.resolveOnly,
+ sourceMapUri: sourceMapUri ?? this.sourceMapUri,
+ strips: strips ?? this.strips,
+ testMode: testMode ?? this.testMode,
+ trustJSInteropTypeAnnotations:
+ trustJSInteropTypeAnnotations ?? this.trustJSInteropTypeAnnotations,
+ trustPrimitives: trustPrimitives ?? this.trustPrimitives,
+ trustTypeAnnotations: trustTypeAnnotations ?? this.trustTypeAnnotations,
+ useContentSecurityPolicy:
+ useContentSecurityPolicy ?? this.useContentSecurityPolicy,
+ useCpsIr: useCpsIr ?? this.useCpsIr,
+ useFrequencyNamer: useFrequencyNamer ?? this.useFrequencyNamer,
+ useNewSourceInfo: useNewSourceInfo ?? this.useNewSourceInfo,
+ useStartupEmitter: useStartupEmitter ?? this.useStartupEmitter,
+ verbose: verbose ?? this.verbose);
+ }
+
/// Returns `true` if warnings and hints are shown for all packages.
bool get showAllPackageWarnings {
return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 7a4dbc6..e30cfdc 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -32,6 +32,7 @@
import 'registry.dart' show ResolutionRegistry;
import 'resolution_common.dart' show CommonResolverVisitor;
import 'resolution_result.dart';
+import 'scope.dart' show Scope, ExtensionScope;
class InitializerResolver {
final ResolverVisitor visitor;
@@ -294,14 +295,30 @@
* Resolve all initializers of this constructor. In the case of a redirecting
* constructor, the resolved constructor's function element is returned.
*/
- ConstructorElement resolveInitializers() {
+ ConstructorElement resolveInitializers(
+ {bool enableInitializingFormalAccess: false}) {
Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
<dynamic /*String|int*/, ConstantExpression>{};
ConstructedConstantExpression constructorInvocation;
// Keep track of all "this.param" parameters specified for constructor so
// that we can ensure that fields are initialized only once.
FunctionSignature functionParameters = constructor.functionSignature;
+ Scope oldScope = visitor.scope;
+ if (enableInitializingFormalAccess) {
+ // In order to get the correct detection of name clashes between all
+ // parameters (regular ones and initializing formals) we must extend
+ // the parameter scope rather than adding a new nested scope.
+ visitor.scope = new ExtensionScope(visitor.scope);
+ }
+ Link<Node> parameterNodes = (functionNode.parameters == null)
+ ? const Link<Node>()
+ : functionNode.parameters.nodes;
functionParameters.forEachParameter((ParameterElementX element) {
+ List<Element> optionals = functionParameters.optionalParameters;
+ if (!optionals.isEmpty && element == optionals.first) {
+ NodeList nodes = parameterNodes.head;
+ parameterNodes = nodes.nodes;
+ }
if (isConst) {
if (element.isOptional) {
if (element.constantCache == null) {
@@ -325,9 +342,15 @@
}
}
if (element.isInitializingFormal) {
+ VariableDefinitions variableDefinitions = parameterNodes.head;
+ Node parameterNode = variableDefinitions.definitions.nodes.head;
InitializingFormalElementX initializingFormal = element;
FieldElement field = initializingFormal.fieldElement;
checkForDuplicateInitializers(field, element.initializer);
+ if (enableInitializingFormalAccess) {
+ visitor.defineLocalVariable(parameterNode, initializingFormal);
+ visitor.addToScope(initializingFormal);
+ }
if (isConst) {
if (element.isNamed) {
fieldInitializers[field] = new NamedArgumentReference(element.name);
@@ -339,6 +362,7 @@
isValidAsConstant = false;
}
}
+ parameterNodes = parameterNodes.tail;
});
if (functionNode.initializers == null) {
@@ -430,6 +454,7 @@
fieldInitializers,
constructorInvocation);
}
+ visitor.scope = oldScope;
return null; // If there was no redirection always return null.
}
}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 871f6af..b12218b 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -444,11 +444,6 @@
// fields they reference are visible, but must be resolved independently.
if (element.isInitializingFormal) {
registry.useElement(parameterNode, element);
- if (compiler.options.enableInitializingFormalAccess) {
- InitializingFormalElementX initializingFormalElementX = element;
- defineLocalVariable(parameterNode, initializingFormalElementX);
- addToScope(initializingFormalElementX);
- }
} else {
LocalParameterElementX parameterElement = element;
defineLocalVariable(parameterNode, parameterElement);
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 2fd4e685..05e1cf0 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -53,6 +53,7 @@
import 'constructors.dart';
import 'members.dart';
import 'registry.dart';
+import 'scope.dart' show MutableScope;
import 'signatures.dart';
import 'tree_elements.dart';
import 'typedefs.dart';
@@ -236,7 +237,7 @@
ResolverVisitor visitor = visitorFor(element);
ResolutionRegistry registry = visitor.registry;
registry.defineFunction(tree, element);
- visitor.setupFunction(tree, element);
+ visitor.setupFunction(tree, element); // Modifies the scope.
processAsyncMarker(compiler, element, registry);
if (element.isGenerativeConstructor) {
@@ -244,7 +245,9 @@
// resolution in case there is an implicit super constructor call.
InitializerResolver resolver =
new InitializerResolver(visitor, element, tree);
- FunctionElement redirection = resolver.resolveInitializers();
+ FunctionElement redirection = resolver.resolveInitializers(
+ enableInitializingFormalAccess:
+ compiler.options.enableInitializingFormalAccess);
if (redirection != null) {
resolveRedirectingConstructor(resolver, tree, element, redirection);
}
diff --git a/pkg/compiler/lib/src/resolution/scope.dart b/pkg/compiler/lib/src/resolution/scope.dart
index 75c3de9..e03304e 100644
--- a/pkg/compiler/lib/src/resolution/scope.dart
+++ b/pkg/compiler/lib/src/resolution/scope.dart
@@ -9,8 +9,11 @@
abstract class Scope {
/**
- * Adds [element] to this scope. This operation is only allowed on mutable
- * scopes such as [MethodScope] and [BlockScope].
+ * If an [Element] named `element.name` has already been added to this
+ * [Scope], return that element and make no changes. If no such element has
+ * been added, add the given [element] to this [Scope], and return [element].
+ * Note that this operation is only allowed on mutable scopes such as
+ * [MethodScope] and [BlockScope].
*/
Element add(Element element);
@@ -123,6 +126,46 @@
Element localLookup(String name) => elements[name];
}
+/**
+ * [ExtensionScope] enables the creation of an extended version of an
+ * existing [NestedScope], received during construction and stored in
+ * [extendee]. An [ExtensionScope] will treat an added `element` as conflicting
+ * if an element `e` where `e.name == element.name` exists among the elements
+ * added to this [ExtensionScope], or among the ones added to [extendee]
+ * (according to `extendee.localLookup`). In this sense, it represents the
+ * union of the bindings stored locally in [elements] and the bindings in
+ * [extendee], not a new scope which is nested inside [extendee].
+ *
+ * Note that it is required that no bindings are added to [extendee] during the
+ * lifetime of this [ExtensionScope]: That would enable duplicates to be
+ * introduced into the extended scope consisting of [this] plus [extendee]
+ * without detection.
+ */
+class ExtensionScope extends Scope {
+ final NestedScope extendee;
+ final Map<String, Element> elements;
+
+ ExtensionScope(this.extendee) : this.elements = new Map<String, Element>() {
+ assert(extendee != null);
+ }
+
+ Element lookup(String name) {
+ Element result = elements[name];
+ if (result != null) return result;
+ return extendee.lookup(name);
+ }
+
+ Element add(Element newElement) {
+ if (elements.containsKey(newElement.name)) {
+ return elements[newElement.name];
+ }
+ Element existing = extendee.localLookup(newElement.name);
+ if (existing != null) return existing;
+ elements[newElement.name] = newElement;
+ return newElement;
+ }
+}
+
class MethodScope extends MutableScope {
final Element element;
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index b025533..7069b51 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -8,7 +8,9 @@
import '../constants/constructors.dart';
import '../constants/expressions.dart';
import '../dart_types.dart';
+import '../diagnostics/messages.dart';
import '../elements/elements.dart';
+import '../elements/modelx.dart' show ErroneousElementX;
import 'constant_serialization.dart';
import 'keys.dart';
import 'modelz.dart';
@@ -17,6 +19,7 @@
/// Enum kinds used for encoding [Element]s.
enum SerializedElementKind {
+ ERROR,
LIBRARY,
COMPILATION_UNIT,
CLASS,
@@ -63,6 +66,7 @@
/// and [ConstantExpression] that the serialized [Element] depends upon are also
/// serialized.
const List<ElementSerializer> ELEMENT_SERIALIZERS = const [
+ const ErrorSerializer(),
const LibrarySerializer(),
const CompilationUnitSerializer(),
const ClassSerializer(),
@@ -193,6 +197,30 @@
}
}
+class ErrorSerializer implements ElementSerializer {
+ const ErrorSerializer();
+
+ SerializedElementKind getSerializedKind(Element element) {
+ if (element.isError) {
+ return SerializedElementKind.ERROR;
+ }
+ return null;
+ }
+
+ void serialize(ErroneousElement element, ObjectEncoder encoder,
+ SerializedElementKind kind) {
+ encoder.setElement(Key.ENCLOSING, element.enclosingElement);
+ encoder.setString(Key.NAME, element.name);
+ encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
+ if (element.messageArguments.isNotEmpty) {
+ MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
+ element.messageArguments.forEach((String key, var value) {
+ mapEncoder.setString(key, Message.convertToString(value));
+ });
+ }
+ }
+}
+
class LibrarySerializer implements ElementSerializer {
const LibrarySerializer();
@@ -705,6 +733,19 @@
static Element deserialize(
ObjectDecoder decoder, SerializedElementKind elementKind) {
switch (elementKind) {
+ case SerializedElementKind.ERROR:
+ Element enclosing = decoder.getElement(Key.ENCLOSING);
+ String name = decoder.getString(Key.NAME);
+ MessageKind messageKind =
+ decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
+ Map<String, String> arguments = <String, String>{};
+ MapDecoder mapDecoder = decoder.getMap(Key.ARGUMENTS, isOptional: true);
+ if (mapDecoder != null) {
+ mapDecoder.forEachKey((String key) {
+ arguments[key] = mapDecoder.getString(key);
+ });
+ }
+ return new ErroneousElementX(messageKind, arguments, name, enclosing);
case SerializedElementKind.LIBRARY:
return new LibraryElementZ(decoder);
case SerializedElementKind.COMPILATION_UNIT:
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
index fb5151b..2c70168 100644
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ b/pkg/compiler/lib/src/serialization/keys.dart
@@ -31,6 +31,7 @@
static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
static const Key ELEMENT = const Key('element');
static const Key ELEMENTS = const Key('elements');
+ static const Key ENCLOSING = const Key('enclosing');
static const Key EXECUTABLE_CONTEXT = const Key('executable-context');
static const Key EXPORTS = const Key('exports');
static const Key EXPORT_SCOPE = const Key('export-scope');
@@ -84,6 +85,7 @@
static const Key LISTS = const Key('lists');
static const Key MAPS = const Key('maps');
static const Key MEMBERS = const Key('members');
+ static const Key MESSAGE_KIND = const Key('messageKind');
static const Key METADATA = const Key('metadata');
static const Key MIXIN = const Key('mixin');
static const Key MIXINS = const Key('mixins');
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index ff8eef4..bca6d9e 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -108,10 +108,7 @@
/// Serialize [ResolvedAst] that is defined in terms of an AST together with
/// [TreeElements].
void serializeParsed() {
- objectEncoder.setUri(
- Key.URI,
- elements.analyzedElement.compilationUnit.script.resourceUri,
- elements.analyzedElement.compilationUnit.script.resourceUri);
+ objectEncoder.setUri(Key.URI, resolvedAst.sourceUri, resolvedAst.sourceUri);
AstKind kind;
if (element.enclosingClass is EnumClassElement) {
if (element.name == 'index') {
@@ -515,7 +512,7 @@
reporter.internalError(
element,
"No token found for $element in "
- "${objectDecoder.getUri(Key.URI)} @ $getOrSetOffset");
+ "${uri} @ $getOrSetOffset");
}
}
return doParse((parser) {
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
index 22ac66b..5e2a24b 100644
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ b/pkg/compiler/lib/src/serialization/system.dart
@@ -217,6 +217,7 @@
void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
assert(invariant(element, element.isDeclaration,
message: "Element $element must be the declaration"));
+ if (element.isError) return;
if (element is MemberElement) {
assert(invariant(element, resolution.hasResolvedAst(element),
message: "Element $element must have a resolved ast"));
diff --git a/pkg/compiler/lib/src/serialization/type_serialization.dart b/pkg/compiler/lib/src/serialization/type_serialization.dart
index 3d4cb9f..24a46ae 100644
--- a/pkg/compiler/lib/src/serialization/type_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/type_serialization.dart
@@ -35,7 +35,9 @@
encoder.setTypes(Key.NAMED_PARAMETER_TYPES, type.namedParameterTypes);
}
- void visitMalformedType(MalformedType type, ObjectEncoder encoder) {}
+ void visitMalformedType(MalformedType type, ObjectEncoder encoder) {
+ encoder.setElement(Key.ELEMENT, type.element);
+ }
void visitInterfaceType(InterfaceType type, ObjectEncoder encoder) {
encoder.setElement(Key.ELEMENT, type.element);
@@ -79,8 +81,11 @@
return new TypedefType(decoder.getElement(Key.ELEMENT),
decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
case TypeKind.STATEMENT:
- case TypeKind.MALFORMED_TYPE:
throw new UnsupportedError("Unexpected type kind '${typeKind}.");
+ case TypeKind.MALFORMED_TYPE:
+ // TODO(johnniwinther): Do we need the 'userProvidedBadType' or maybe
+ // just a toString of it?
+ return new MalformedType(decoder.getElement(Key.ELEMENT), null);
case TypeKind.DYNAMIC:
return const DynamicType();
case TypeKind.VOID:
diff --git a/pkg/pkg.status b/pkg/pkg.status
index a8fadfb..d0eca7c 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -75,6 +75,7 @@
analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/sdk_test: Skip # Issue 21628
analyzer/test/generated/simple_resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
analyzer/test/generated/static_type_analyzer_test: Pass, Slow # Issue 21628
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index fa11a2d..c7736e8 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -2,15 +2,13 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-samples/searchable_list: Pass, Slow
third_party/pkg/scheduled_test: Fail # Issue 26585
-[ $use_repository_packages ]
-samples/third_party/angular_todo: Fail # angular needs to be updated
-
[ $use_public_packages ]
pkg/compiler: SkipByDesign # js_ast is not published
-samples/third_party/angular_todo: Pass, Slow
-[ $builder_tag == russian ]
-samples/third_party/angular_todo: Fail # Issue 16356
+[ $use_repository_packages ]
+third_party/pkg/dartdoc: PubGetError # Issue 26696
+
+[ ($use_repository_packages || $use_public_packages) && ($system == windows || $system == linux) ]
+third_party/pkg/*: Pass, PubGetError # Issue 26696
diff --git a/runtime/observatory/HACKING.md b/runtime/observatory/HACKING.md
new file mode 100644
index 0000000..af74bda
--- /dev/null
+++ b/runtime/observatory/HACKING.md
@@ -0,0 +1,193 @@
+# Hacking Observatory
+
+These instructions will guide you through the Observatory development and
+testing workflow.
+
+## SDK Setup & Build
+Getting ready to start.
+
+Before you start to hack on Observatory, follow the [instructions][build_sdk] to
+have a working environment in which you are able to build and test the Dart SDK.
+
+### Develop with Dartium ~ Suggested
+If you want to avoid triggering a new compilation to JavaScript for each edit
+you do, you can use a modified version of Chromium named Dartium that will
+interpret you dart code directly.
+
+You can obtain Dartium in two different ways:
+1. [Download][download_dartium] the binaries
+2. [Build][build_dartium] Dartium from the source code
+
+
+## Run existing tests
+Before hacking Observatory let's run the existing Observatory tests.
+We suggest to run all the test in __debug__ mode.
+
+First build the sdk in debug mode
+```
+$ ./tools/build.py --mode debug create_sdk
+```
+
+From the root of the sdk repository run:
+```
+$ ./tools/test.py -mdebug service
+```
+
+## Serve Observatory
+Observatory is built as part of building the sdk, but when working on
+Observatory we recommend that you use __pub serve__ so you can avoid the
+overhead of building the sdk for each change.
+
+Use __pub__ to __serve__ Observatory:
+```
+[...]/runtime/observatory$ pub serve
+```
+
+## Open Observatory
+You can open the development version of Observatory from
+Chrome/Chromium/__Dartium__ by navigating to [localhost:8080][open_observatory]
+
+Every change you make to the Observatory source code will be visible by simply
+__refreshing__ the page in the browser.
+
+## Connect to a VM
+Start a Dart VM with the ``--observe`` flag (as explained in the
+[get started guide][observatory_get_started]) and connect your Observatory
+instance to that VM.
+
+Example script (file name ```clock.dart```):
+```dart
+import 'dart:async' show Timer, Duration;
+
+main() {
+ bool tick = true;
+ new Timer.periodic(const Duration(seconds: 1), (Timer t) {
+ print(tick ? 'tick' : 'tock');
+ tick = !tick;
+ });
+}
+```
+Start the script:
+```
+$ dart --observe clock.dart
+```
+
+## Code Reviews
+The development workflow of Dart (and Observatory) is based on code reviews.
+
+Follow the code review [instructions][code_review] to be able to successfully
+submit your code.
+
+The main reviewers for Observatory related CLs are:
+ - turnidge
+ - johnmccutchan
+ - rmacnak
+
+## Write a new service test
+All the service tests are located in the ```tests/service``` folder.
+Test file names follow the convention ```<description>_test.dart```
+(e.g. ```a_brief_description_test.dart```).
+
+The test is generally structured in the following way.
+```dart
+import 'package:test/test.dart';
+
+main() {
+ // Some code that you need to test.
+ var a = 1 + 2;
+
+ // Some assertions to check the results.
+ expect(a, equal(3));
+}
+```
+See the official [test library][test_library] instructions;
+
+The ```test_helper.dart``` file expose some functions that allow to run a part
+of the code into another __VM__.
+
+To test synchronous operations:
+```dart
+import 'test_helper.dart';
+
+code() {
+ // Write the code you want to be execute into another VM.
+}
+
+var tests = [
+ // A series of tests that you want to run against the above code.
+ (Isolate isolate) async {
+ await isolate.reload();
+ // Use the isolate to communicate to the VM.
+ }
+];
+
+main(args) => runIsolateTestsSynchronous(args,
+ tests,
+ testeeConcurrent: code);
+```
+
+In order to test asynchronous operations:
+```dart
+import 'test_helper.dart';
+
+code() async {
+ // Write the asynchronous code you want to be execute into another VM.
+}
+
+var tests = [
+ // A series of tests that you want to run against the above code.
+ (Isolate isolate) async {
+ await isolate.reload();
+ // Use the isolate to communicate to the VM.
+ }
+];
+
+main(args) async => runIsolateTests(args,
+ tests,
+ testeeConcurrent: code);
+```
+
+Both ```runIsolateTests``` and ```runIsolateTestsSynchronous``` have the
+following named parameters:
+ - __testeeBefore__ (void()) a function that is going to be executed before
+the test
+ - __testeeConcurrent__ (void()) test that is going to be executed
+ - __pause_on_start__ (bool, default: false) pause the Isolate before the first
+instruction
+ - __pause_on_exit__ (bool, default: false) pause the Isolate after the last
+instruction
+ - __pause_on_unhandled_exceptions__ (bool, default: false) pause the Isolate at
+an unhandled exception
+ - __trace_service__ (bool, default: false) trace VM service requests
+ - __trace_compiler__ (bool, default: false) trace compiler operations
+ - __verbose_vm__ (bool, default: false) verbose logging
+
+
+Some common and reusable test are available from ```service_test_common.dart```:
+ - hasPausedFor
+ - hasStoppedAtBreakpoint
+ - hasStoppedWithUnhandledException
+ - hasStoppedAtExit
+ - hasPausedAtStartcode_review
+and utility functions:
+ - subscribeToStream
+ - cancelStreamSubscription
+ - asyncStepOver
+ - setBreakpointAtLine
+ - resumeIsolate
+ - resumeAndAwaitEvent
+ - resumeIsolateAndAwaitEvent
+ - stepOver
+ - getClassFromRootLib
+ - rootLibraryFieldValue
+
+## Run your tests
+See: __Run existing tests__
+
+[build_sdk]: https://github.com/dart-lang/sdk/wiki/Building "Building the Dart SDK"
+[download_dartium]: https://www.dartlang.org/tools/dartium/ "Download Dartium"
+[build_dartium]: https://github.com/dart-lang/sdk/wiki/Building-Dartium "Build Dartium"
+[open_observatory]: http://localhost:8080/ "Open Observatory"
+[observatory_get_started]: https://dart-lang.github.io/observatory/get-started.html "Observatory get started"
+[code_review]: https://github.com/dart-lang/sdk/wiki/Code-review-workflow-with-GitHub-and-reitveld "Code Review"
+[test_library]: https://pub.dartlang.org/packages/test "Test Library"
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
new file mode 100644
index 0000000..4d08c8a
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -0,0 +1,6 @@
+# Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $browser == false ]
+*: SkipByDesign
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 1d2ea9d..0e8b6e9 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -310,7 +310,14 @@
await process.requestExit();
}, onError: (e, st) {
process.requestExit();
- if (!_isWebSocketDisconnect(e)) {
+ // TODO: remove this workaround.
+ // This is necessary due to non awaited operations.
+ // E.G. object.dart (398~402)
+ // When an exception is thrown inside a test (directly or via await) the
+ // stacktrace is non-null and shows where the exception has been thrown.
+ // If vice versa the exception is due to an error in a non-awaited
+ // Future the stacktrace is null.
+ if (st != null || !_isWebSocketDisconnect(e)) {
print('Unexpected exception in service tests: $e $st');
throw e;
}
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
index 1536dac..9cbb577 100644
--- a/runtime/platform/text_buffer.cc
+++ b/runtime/platform/text_buffer.cc
@@ -8,6 +8,7 @@
#include "platform/globals.h"
#include "platform/utils.h"
#include "vm/os.h"
+#include "vm/unicode.h"
namespace dart {
@@ -78,60 +79,52 @@
return len;
}
-
-// Write a UTF-16 code unit so it can be read by a JSON parser in a string
-// literal. Use escape sequences for characters other than printable ASCII.
+// Write a UTF-32 code unit so it can be read by a JSON parser in a string
+// literal. Use official encoding from JSON specification. http://json.org/
void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
switch (codeunit) {
case '"':
- Printf("%s", "\\\"");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\\""), 2);
break;
case '\\':
- Printf("%s", "\\\\");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\\\"), 2);
break;
case '/':
- Printf("%s", "\\/");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\/"), 2);
break;
case '\b':
- Printf("%s", "\\b");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\b"), 2);
break;
case '\f':
- Printf("%s", "\\f");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\f"), 2);
break;
case '\n':
- Printf("%s", "\\n");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\n"), 2);
break;
case '\r':
- Printf("%s", "\\r");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\r"), 2);
break;
case '\t':
- Printf("%s", "\\t");
+ AddRaw(reinterpret_cast<uint8_t const*>("\\t"), 2);
break;
default:
if (codeunit < 0x20) {
- // Encode character as \u00HH.
- uint32_t digit2 = (codeunit >> 4) & 0xf;
- uint32_t digit3 = (codeunit & 0xf);
- Printf("\\u00%c%c",
- digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
- digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
- } else if (codeunit > 127) {
- // Encode character as \uHHHH.
- uint32_t digit0 = (codeunit >> 12) & 0xf;
- uint32_t digit1 = (codeunit >> 8) & 0xf;
- uint32_t digit2 = (codeunit >> 4) & 0xf;
- uint32_t digit3 = (codeunit & 0xf);
- Printf("\\u%c%c%c%c",
- digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0,
- digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1,
- digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
- digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
+ EscapeAndAddUTF16CodeUnit(codeunit);
} else {
- AddChar(codeunit);
+ char encoded[6];
+ intptr_t length = Utf8::Length(codeunit);
+ Utf8::Encode(codeunit, encoded);
+ AddRaw(reinterpret_cast<uint8_t const*>(encoded), length);
}
}
}
+// Write an incomplete UTF-16 code unit so it can be read by a JSON parser in a
+// string literal.
+void TextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) {
+ Printf("\\u%04X", codeunit);
+}
+
void TextBuffer::AddString(const char* s) {
Printf("%s", s);
diff --git a/runtime/platform/text_buffer.h b/runtime/platform/text_buffer.h
index 1908ecb..6155cc4 100644
--- a/runtime/platform/text_buffer.h
+++ b/runtime/platform/text_buffer.h
@@ -20,6 +20,7 @@
intptr_t Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
void AddChar(char ch);
+ void EscapeAndAddUTF16CodeUnit(uint16_t cu);
void EscapeAndAddCodeUnit(uint32_t cu);
void AddString(const char* s);
void AddEscapedString(const char* s);
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 89d6b09..cdc4753 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -746,7 +746,8 @@
if (ic_data.NumberOfChecks() != 1) {
return false;
}
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
@@ -1629,50 +1630,6 @@
}
-bool AotOptimizer::TryReplaceInstanceCallWithInline(
- InstanceCallInstr* call) {
- Function& target = Function::Handle(Z);
- GrowableArray<intptr_t> class_ids;
- call->ic_data()->GetCheckAt(0, &class_ids, &target);
- const intptr_t receiver_cid = class_ids[0];
-
- TargetEntryInstr* entry;
- Definition* last;
- if (!FlowGraphInliner::TryInlineRecognizedMethod(flow_graph_,
- receiver_cid,
- target,
- call,
- call->ArgumentAt(0),
- call->token_pos(),
- *call->ic_data(),
- &entry, &last)) {
- return false;
- }
-
- // Insert receiver class check.
- AddReceiverCheck(call);
- // Remove the original push arguments.
- for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
- PushArgumentInstr* push = call->PushArgumentAt(i);
- push->ReplaceUsesWith(push->value()->definition());
- push->RemoveFromGraph();
- }
- // Replace all uses of this definition with the result.
- call->ReplaceUsesWith(last);
- // Finally insert the sequence other definition in place of this one in the
- // graph.
- call->previous()->LinkTo(entry->next());
- entry->UnuseAllInputs(); // Entry block is not in the graph.
- last->LinkTo(call);
- // Remove through the iterator.
- ASSERT(current_iterator()->Current() == call);
- current_iterator()->RemoveCurrentFromGraph();
- call->set_previous(NULL);
- call->set_next(NULL);
- return true;
-}
-
-
void AotOptimizer::ReplaceWithMathCFunction(
InstanceCallInstr* call,
MethodRecognizer::Kind recognized_kind) {
@@ -1728,49 +1685,15 @@
MethodRecognizer::Kind recognized_kind =
MethodRecognizer::RecognizeKind(target);
- if ((recognized_kind == MethodRecognizer::kGrowableArraySetData) &&
- (ic_data.NumberOfChecks() == 1) &&
- (class_ids[0] == kGrowableObjectArrayCid)) {
- // This is an internal method, no need to check argument types.
- Definition* array = call->ArgumentAt(0);
- Definition* value = call->ArgumentAt(1);
- StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
- GrowableObjectArray::data_offset(),
- new(Z) Value(array),
- new(Z) Value(value),
- kEmitStoreBarrier,
- call->token_pos());
- ReplaceCall(call, store);
- return true;
- }
-
- if ((recognized_kind == MethodRecognizer::kGrowableArraySetLength) &&
- (ic_data.NumberOfChecks() == 1) &&
- (class_ids[0] == kGrowableObjectArrayCid)) {
- // This is an internal method, no need to check argument types nor
- // range.
- Definition* array = call->ArgumentAt(0);
- Definition* value = call->ArgumentAt(1);
- StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
- GrowableObjectArray::length_offset(),
- new(Z) Value(array),
- new(Z) Value(value),
- kNoStoreBarrier,
- call->token_pos());
- ReplaceCall(call, store);
- return true;
- }
-
if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
(recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
(recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
- (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+ (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kGrowableArraySetData) ||
+ (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) {
ASSERT(ic_data.NumberOfChecks() == 1);
- ASSERT((class_ids[0] == kOneByteStringCid) ||
- (class_ids[0] == kTwoByteStringCid) ||
- (class_ids[0] == kExternalOneByteStringCid) ||
- (class_ids[0] == kExternalTwoByteStringCid));
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
@@ -1779,7 +1702,8 @@
(class_ids[0] == kTwoByteStringCid) ||
(class_ids[0] == kExternalOneByteStringCid) ||
(class_ids[0] == kExternalTwoByteStringCid));
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
@@ -1867,7 +1791,8 @@
case MethodRecognizer::kDoubleSub:
case MethodRecognizer::kDoubleMul:
case MethodRecognizer::kDoubleDiv:
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
default:
// Unsupported method.
return false;
@@ -1876,7 +1801,8 @@
if (IsSupportedByteArrayViewCid(class_ids[0]) &&
(ic_data.NumberOfChecks() == 1)) {
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
@@ -2292,6 +2218,24 @@
}
+bool AotOptimizer::TryInlineFieldAccess(InstanceCallInstr* call) {
+ const Token::Kind op_kind = call->token_kind();
+ if ((op_kind == Token::kGET) && TryInlineInstanceGetter(call)) {
+ return true;
+ }
+
+ const ICData& unary_checks =
+ ICData::Handle(Z, call->ic_data()->AsUnaryClassChecks());
+ if ((unary_checks.NumberOfChecks() > 0) &&
+ (op_kind == Token::kSET) &&
+ TryInlineInstanceSetter(call, unary_checks)) {
+ return true;
+ }
+
+ return false;
+}
+
+
// Tries to optimize instance call by replacing it with a faster instruction
// (e.g, binary op, field load, ..).
void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
@@ -2310,18 +2254,12 @@
return;
}
- if ((op_kind == Token::kGET) &&
- TryInlineInstanceGetter(instr)) {
- return;
- }
- const ICData& unary_checks =
- ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
- if ((unary_checks.NumberOfChecks() > 0) &&
- (op_kind == Token::kSET) &&
- TryInlineInstanceSetter(instr, unary_checks)) {
+ if (TryInlineFieldAccess(instr)) {
return;
}
+ const ICData& unary_checks =
+ ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
if (IsAllowedForInlining(instr->deopt_id()) &&
(unary_checks.NumberOfChecks() > 0)) {
if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) {
@@ -2347,6 +2285,10 @@
TryReplaceWithUnaryOp(instr, op_kind)) {
return;
}
+
+ if (TryInlineInstanceMethod(instr)) {
+ return;
+ }
}
bool has_one_target =
@@ -2404,9 +2346,7 @@
break;
}
- // No IC data checks. Try resolve target using the propagated type.
- // If the propagated type has a method with the target name and there are
- // no overrides with that name according to CHA, call the method directly.
+ // No IC data checks. Try resolve target using the propagated cid.
const intptr_t receiver_cid =
instr->PushArgumentAt(0)->value()->Type()->ToCid();
if (receiver_cid != kDynamicCid) {
@@ -2423,32 +2363,20 @@
instr->function_name(),
args_desc));
if (!function.IsNull()) {
- intptr_t subclasses = 0;
- if (!thread()->cha()->HasOverride(receiver_class,
- instr->function_name(),
- &subclasses)) {
- if (FLAG_trace_cha) {
- THR_Print(" **(CHA) Instance call needs no check, "
- "no overrides of '%s' '%s'\n",
- instr->function_name().ToCString(), receiver_class.ToCString());
- }
-
- // Create fake IC data with the resolved target.
- const ICData& ic_data = ICData::Handle(
- ICData::New(flow_graph_->function(),
- instr->function_name(),
- args_desc_array,
- Thread::kNoDeoptId,
- /* args_tested = */ 1,
- false));
- ic_data.AddReceiverCheck(receiver_class.id(), function);
- PolymorphicInstanceCallInstr* call =
- new(Z) PolymorphicInstanceCallInstr(instr, ic_data,
- /* with_checks = */ false,
- /* complete = */ true);
- instr->ReplaceWith(call, current_iterator());
- return;
- }
+ const ICData& ic_data = ICData::Handle(
+ ICData::New(flow_graph_->function(),
+ instr->function_name(),
+ args_desc_array,
+ Thread::kNoDeoptId,
+ /* args_tested = */ 1,
+ false));
+ ic_data.AddReceiverCheck(receiver_class.id(), function);
+ PolymorphicInstanceCallInstr* call =
+ new(Z) PolymorphicInstanceCallInstr(instr, ic_data,
+ /* with_checks = */ false,
+ /* complete = */ true);
+ instr->ReplaceWith(call, current_iterator());
+ return;
}
}
@@ -2527,6 +2455,26 @@
}
if (single_target.raw() != Function::null()) {
+ // If this is a getter or setter invocation try inlining it right away
+ // instead of replacing it with a static call.
+ if ((op_kind == Token::kGET) || (op_kind == Token::kSET)) {
+ // Create fake IC data with the resolved target.
+ const ICData& ic_data = ICData::Handle(
+ ICData::New(flow_graph_->function(),
+ instr->function_name(),
+ args_desc_array,
+ Thread::kNoDeoptId,
+ /* args_tested = */ 1,
+ false));
+ cls = single_target.Owner();
+ ic_data.AddReceiverCheck(cls.id(), single_target);
+ instr->set_ic_data(&ic_data);
+
+ if (TryInlineFieldAccess(instr)) {
+ return;
+ }
+ }
+
// We have computed that there is only a single target for this call
// within the whole hierarchy. Replace InstanceCall with StaticCall.
ZoneGrowableArray<PushArgumentInstr*>* args =
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
index 6902552..1afdadd 100644
--- a/runtime/vm/aot_optimizer.h
+++ b/runtime/vm/aot_optimizer.h
@@ -70,6 +70,7 @@
bool TryReplaceWithEqualityOp(InstanceCallInstr* call, Token::Kind op_kind);
bool TryReplaceWithRelationalOp(InstanceCallInstr* call, Token::Kind op_kind);
+ bool TryInlineFieldAccess(InstanceCallInstr* call);
bool TryInlineInstanceGetter(InstanceCallInstr* call);
bool TryInlineInstanceSetter(InstanceCallInstr* call,
const ICData& unary_ic_data);
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index fe775bf..8bb29ca 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -275,7 +275,7 @@
// If the object is not patchable, check if we've already got it in the
// object pool.
if (patchable == kNotPatchable) {
- intptr_t idx = object_pool_index_table_.Lookup(entry);
+ intptr_t idx = object_pool_index_table_.LookupValue(entry);
if (idx != ObjIndexPair::kNoIndex) {
return idx;
}
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index db3314d..bf5edce 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -1584,8 +1584,6 @@
Register pp) {
ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
- // Load common VM constants from the thread. This works also in places where
- // no constant pool is set up (e.g. intrinsic code).
if (Thread::CanLoadFromThread(object)) {
// Load common VM constants from the thread. This works also in places where
// no constant pool is set up (e.g. intrinsic code).
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
index 9e4e2cd..e97fdd7 100644
--- a/runtime/vm/assembler_dbc_test.cc
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -147,6 +147,55 @@
}
+// - OneByteStringFromCharCode rA, rX
+//
+// Load the one-character symbol with the char code given by the Smi
+// in FP[rX] into FP[rA].
+ASSEMBLER_TEST_GENERATE(OneByteStringFromCharCode, assembler) {
+ __ Frame(2);
+ __ LoadConstant(0, Smi::ZoneHandle(Smi::New(65)));
+ __ OneByteStringFromCharCode(1, 0);
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(OneByteStringFromCharCode, test) {
+ EXPECT_EQ(Symbols::New(Thread::Current(), "A"),
+ EXECUTE_TEST_CODE_OBJECT(test->code()).raw());
+}
+
+
+// - StringToCharCode rA, rX
+//
+// Load and smi-encode the single char code of the string in FP[rX] into
+// FP[rA]. If the string's length is not 1, load smi -1 instead.
+//
+ASSEMBLER_TEST_GENERATE(StringToCharCode, assembler) {
+ __ Frame(2);
+ __ LoadConstant(0, String::ZoneHandle(String::New("A", Heap::kOld)));
+ __ StringToCharCode(1, 0);
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(StringToCharCode, test) {
+ EXPECT_EQ(65, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(StringToCharCodeIllegalLength, assembler) {
+ __ Frame(2);
+ __ LoadConstant(0, String::ZoneHandle(String::New("AAA", Heap::kOld)));
+ __ StringToCharCode(1, 0);
+ __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(StringToCharCodeIllegalLength, test) {
+ EXPECT_EQ(-1, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
// - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
// GreaterThanTOS;
//
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index a15dca3..cc3b691 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1316,12 +1316,15 @@
}
if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
+ SafepointOperationScope safepoint_scope(thread);
Disassembler::DisassembleCode(function, optimized);
} else if (FLAG_disassemble_optimized &&
optimized &&
FlowGraphPrinter::ShouldPrint(function)) {
+ SafepointOperationScope safepoint_scope(thread);
Disassembler::DisassembleCode(function, true);
}
+
DEBUG_ONLY(CheckInliningIntervals(function));
return Error::null();
} else {
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 4f8aab9..02d86888 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -156,6 +156,16 @@
//
// Invoke native function SP[-1] with argc_tag SP[0].
//
+// - OneByteStringFromCharCode rA, rX
+//
+// Load the one-character symbol with the char code given by the Smi
+// in FP[rX] into FP[rA].
+//
+// - StringToCharCode rA, rX
+//
+// Load and smi-encode the single char code of the string in FP[rX] into
+// FP[rA]. If the string's length is not 1, load smi -1 instead.
+//
// - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
// GreaterThanTOS;
//
@@ -340,6 +350,12 @@
//
// Instantiate type arguments PP[D] with instantiator SP[0].
//
+// - InstanceOf A
+//
+// Test if instance SP[-3] with type arguments SP[-2] is (A = 0) or is not
+// (A = 1) a subtype of SP[-1] using SubtypeTestCache SP[0], with result
+// placed at top of stack.
+//
// - AssertAssignable D
//
// Assert that SP[-3] is assignable to variable named SP[0] of type
@@ -446,6 +462,8 @@
V(InstanceCall2Opt, A_D, num, num, ___) \
V(NativeCall, 0, ___, ___, ___) \
V(NativeBootstrapCall, 0, ___, ___, ___) \
+ V(OneByteStringFromCharCode, A_X, reg, xeg, ___) \
+ V(StringToCharCode, A_X, reg, xeg, ___) \
V(AddTOS, 0, ___, ___, ___) \
V(SubTOS, 0, ___, ___, ___) \
V(MulTOS, 0, ___, ___, ___) \
@@ -499,6 +517,7 @@
V(MoveSpecial, A_D, reg, num, ___) \
V(InstantiateType, D, lit, ___, ___) \
V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \
+ V(InstanceOf, A, num, ___, ___) \
V(AssertAssignable, D, num, lit, ___) \
V(AssertBoolean, A, num, ___, ___) \
V(CheckSmi, A, reg, ___, ___) \
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b9e9f55..597bae2 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5335,13 +5335,14 @@
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library) {
DARTSCOPE(Thread::Current());
- const Library& lib = Api::UnwrapLibraryHandle(Z, library);
- if (lib.IsNull()) {
- RETURN_TYPE_ERROR(Z, library, Library);
+ const Object& obj = Object::Handle(Z, Api::UnwrapHandle(library));
+ if (obj.IsNull() || obj.IsLibrary()) {
+ Library& lib = Library::Handle(Z);
+ lib ^= obj.raw();
+ T->isolate()->object_store()->set_root_library(lib);
+ return library;
}
- Isolate* isolate = Isolate::Current();
- isolate->object_store()->set_root_library(lib);
- return library;
+ RETURN_TYPE_ERROR(Z, library, Library);
}
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 5498bd7..1b5a537 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1207,6 +1207,28 @@
}
+// Helper class to ensure new gen GC is triggered without any side effects.
+// The normal call to CollectGarbage(Heap::kNew) could potentially trigger
+// an old gen collection if there is a promotion failure and this could
+// perturb the test.
+class GCTestHelper : public AllStatic {
+ public:
+ static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) {
+ bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks);
+ Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks);
+ }
+
+ static void WaitForFinalizationTasks() {
+ Thread* thread = Thread::Current();
+ Heap* heap = thread->isolate()->heap();
+ MonitorLocker ml(heap->finalization_tasks_lock());
+ while (heap->finalization_tasks() > 0) {
+ ml.WaitWithSafepointCheck(thread);
+ }
+ }
+};
+
+
static void ExternalStringCallbackFinalizer(void* peer) {
*static_cast<int*>(peer) *= 2;
}
@@ -1243,9 +1265,11 @@
EXPECT_EQ(40, peer8);
EXPECT_EQ(41, peer16);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT_EQ(40, peer8);
EXPECT_EQ(41, peer16);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT_EQ(80, peer8);
EXPECT_EQ(82, peer16);
}
@@ -2382,13 +2406,65 @@
TransitionNativeToVM transition(thread);
EXPECT(peer == 0);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(peer == 0);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(peer == 42);
}
}
+static Monitor* slow_finalizers_monitor = NULL;
+static intptr_t slow_finalizers_waiting = 0;
+
+
+static void SlowFinalizer(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {
+ {
+ MonitorLocker ml(slow_finalizers_monitor);
+ slow_finalizers_waiting++;
+ while (slow_finalizers_waiting < 10) {
+ ml.Wait();
+ }
+ ml.NotifyAll();
+ }
+
+ intptr_t* count = reinterpret_cast<intptr_t*>(peer);
+ AtomicOperations::IncrementBy(count, 1);
+}
+
+
+TEST_CASE(SlowFinalizer) {
+ slow_finalizers_monitor = new Monitor();
+
+ intptr_t count = 0;
+ for (intptr_t i = 0; i < 10; i++) {
+ Dart_EnterScope();
+ Dart_Handle str1 = Dart_NewStringFromCString("Live fast");
+ Dart_NewWeakPersistentHandle(str1, &count, 0, SlowFinalizer);
+ Dart_Handle str2 = Dart_NewStringFromCString("Die young");
+ Dart_NewWeakPersistentHandle(str2, &count, 0, SlowFinalizer);
+ Dart_ExitScope();
+
+ {
+ TransitionNativeToVM transition(thread);
+ Isolate::Current()->heap()->CollectAllGarbage();
+ }
+ }
+
+ {
+ TransitionNativeToVM transition(thread);
+ GCTestHelper::WaitForFinalizationTasks();
+ }
+
+ EXPECT_EQ(20, count);
+
+ delete slow_finalizers_monitor;
+}
+
+
static void CheckFloat32x4Data(Dart_Handle obj) {
void* raw_data = NULL;
intptr_t len;
@@ -2440,6 +2516,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(peer == 42);
}
}
@@ -2602,19 +2679,6 @@
}
-// Helper class to ensure new gen GC is triggered without any side effects.
-// The normal call to CollectGarbage(Heap::kNew) could potentially trigger
-// an old gen collection if there is a promotion failure and this could
-// perturb the test.
-class GCTestHelper : public AllStatic {
- public:
- static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) {
- bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks);
- Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks);
- }
-};
-
-
static Dart_Handle AsHandle(Dart_PersistentHandle weak) {
return Dart_HandleFromPersistent(weak);
}
@@ -2729,6 +2793,7 @@
TransitionNativeToVM transition(thread);
// Garbage collect new space again.
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+ GCTestHelper::WaitForFinalizationTasks();
}
{
@@ -2744,6 +2809,7 @@
TransitionNativeToVM transition(thread);
// Garbage collect old space again.
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ GCTestHelper::WaitForFinalizationTasks();
}
{
@@ -2788,6 +2854,7 @@
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
EXPECT(peer == 0);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(peer == 42);
}
}
@@ -2814,6 +2881,7 @@
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
EXPECT(peer == 0);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(peer == 0);
}
}
@@ -2874,6 +2942,7 @@
// Collect weakly referenced string, and promote strongly referenced string.
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
}
@@ -2884,6 +2953,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
}
}
@@ -2929,6 +2999,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+ GCTestHelper::WaitForFinalizationTasks();
EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
}
}
@@ -5915,6 +5986,11 @@
lib_uri = Dart_LibraryUrl(root_lib);
EXPECT_VALID(Dart_StringToCString(lib_uri, &uri_cstr));
EXPECT_STREQ("dart:core", uri_cstr); // Root library did change.
+
+ result = Dart_SetRootLibrary(Dart_Null());
+ EXPECT_VALID(result);
+ root_lib = Dart_RootLibrary();
+ EXPECT(Dart_IsNull(root_lib)); // Root library did change.
}
@@ -8707,6 +8783,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectAllGarbage();
+ GCTestHelper::WaitForFinalizationTasks();
}
EXPECT_EQ(80, peer8);
EXPECT_EQ(82, peer16);
diff --git a/runtime/vm/dart_api_state.cc b/runtime/vm/dart_api_state.cc
new file mode 100644
index 0000000..be30a2d
--- /dev/null
+++ b/runtime/vm/dart_api_state.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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/dart_api_state.h"
+
+#include "platform/assert.h"
+#include "platform/utils.h"
+#include "vm/heap.h"
+#include "vm/isolate.h"
+#include "vm/lockers.h"
+#include "vm/thread.h"
+#include "vm/timeline.h"
+
+namespace dart {
+
+BackgroundFinalizer::BackgroundFinalizer(Isolate* isolate,
+ FinalizationQueue* queue) :
+ isolate_(isolate),
+ queue_(queue) {
+ ASSERT(FLAG_background_finalization);
+ MonitorLocker ml(isolate->heap()->finalization_tasks_lock());
+ isolate->heap()->set_finalization_tasks(
+ isolate->heap()->finalization_tasks() + 1);
+ ml.Notify();
+}
+
+
+void BackgroundFinalizer::Run() {
+ bool result = Thread::EnterIsolateAsHelper(isolate_,
+ Thread::kFinalizerTask);
+ ASSERT(result);
+
+ {
+ Thread* thread = Thread::Current();
+ TIMELINE_FUNCTION_GC_DURATION(thread, "BackgroundFinalization");
+ TransitionVMToNative transition(thread);
+ for (intptr_t i = 0; i < queue_->length(); i++) {
+ FinalizablePersistentHandle* handle = (*queue_)[i];
+ FinalizablePersistentHandle::Finalize(isolate_, handle);
+ }
+ delete queue_;
+ }
+
+ // Exit isolate cleanly *before* notifying it, to avoid shutdown race.
+ Thread::ExitIsolateAsHelper();
+
+ {
+ Heap* heap = isolate_->heap();
+ MonitorLocker ml(heap->finalization_tasks_lock());
+ heap->set_finalization_tasks(heap->finalization_tasks() - 1);
+ ml.Notify();
+ }
+}
+
+} // namespace dart
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index b510377..f687fb2 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -15,8 +15,9 @@
#include "vm/handles.h"
#include "vm/object.h"
#include "vm/os.h"
-#include "vm/raw_object.h"
#include "vm/os_thread.h"
+#include "vm/raw_object.h"
+#include "vm/thread_pool.h"
#include "vm/visitor.h"
#include "vm/weak_table.h"
@@ -24,6 +25,25 @@
namespace dart {
+class FinalizablePersistentHandle;
+typedef MallocGrowableArray<FinalizablePersistentHandle*> FinalizationQueue;
+
+
+class BackgroundFinalizer : public ThreadPool::Task {
+ public:
+ BackgroundFinalizer(Isolate* isolate, FinalizationQueue* queue);
+ virtual ~BackgroundFinalizer() { }
+
+ void Run();
+
+ private:
+ Isolate* isolate_;
+ FinalizationQueue* queue_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundFinalizer);
+};
+
+
// Implementation of Zone support for very fast allocation of small chunks
// of memory. The chunks cannot be deallocated individually, but instead
// zones support deallocating all chunks in one fast operation when the
@@ -214,12 +234,12 @@
}
intptr_t external_size() const {
- return ExternalSizeBits::decode(external_data_);
+ return ExternalSizeInWordsBits::decode(external_data_) * kWordSize;
}
void SetExternalSize(intptr_t size, Isolate* isolate) {
ASSERT(size >= 0);
- set_external_size(Utils::RoundUp(size, kObjectAlignment));
+ set_external_size(size);
if (SpaceForExternal() == Heap::kNew) {
SetExternalNewSpaceBit();
}
@@ -227,9 +247,18 @@
}
// Called when the referent becomes unreachable.
- void UpdateUnreachable(Isolate* isolate) {
+ void UpdateUnreachable(Isolate* isolate, FinalizationQueue* queue) {
+ if (is_queued_for_finalization()) {
+ return;
+ }
EnsureFreeExternal(isolate);
- Finalize(isolate, this);
+ if (queue == NULL) {
+ Finalize(isolate, this);
+ } else {
+ MarkForFinalization();
+ queue->Add(this);
+ set_is_queued_for_finalization(true);
+ }
}
// Called when the referent has moved, potentially between generations.
@@ -252,20 +281,22 @@
private:
enum {
kExternalNewSpaceBit = 0,
- kExternalSizeBits = 1,
- kExternalSizeBitsSize = (kBitsPerWord - 1),
+ kQueuedForFinalizationBit = 1,
+ kExternalSizeBits = 2,
+ kExternalSizeBitsSize = (kBitsPerWord - 2),
};
// This part of external_data_ is the number of externally allocated bytes.
- // TODO(koda): Measure size in words instead.
- class ExternalSizeBits : public BitField<uword,
- intptr_t,
- kExternalSizeBits,
- kExternalSizeBitsSize> {};
+ class ExternalSizeInWordsBits : public BitField<uword,
+ intptr_t,
+ kExternalSizeBits,
+ kExternalSizeBitsSize> {};
// This bit of external_data_ is true if the referent was created in new
// space and UpdateRelocated has not yet detected any promotion.
class ExternalNewSpaceBit :
public BitField<uword, bool, kExternalNewSpaceBit, 1> {};
+ class QueuedForFinalizationBit :
+ public BitField<uword, bool, kQueuedForFinalizationBit, 1> {};
friend class FinalizablePersistentHandles;
@@ -299,6 +330,11 @@
callback_ = NULL;
}
+ void MarkForFinalization() {
+ raw_ = Object::null();
+ ASSERT(callback_ != NULL);
+ }
+
void set_raw(RawObject* raw) { raw_ = raw; }
void set_raw(const LocalHandle& ref) { raw_ = ref.raw(); }
void set_raw(const Object& object) { raw_ = object.raw(); }
@@ -310,8 +346,17 @@
}
void set_external_size(intptr_t size) {
- ASSERT(ExternalSizeBits::is_valid(size));
- external_data_ = ExternalSizeBits::update(size, external_data_);
+ intptr_t size_in_words = Utils::RoundUp(size, kObjectAlignment) / kWordSize;
+ ASSERT(ExternalSizeInWordsBits::is_valid(size_in_words));
+ external_data_ = ExternalSizeInWordsBits::update(size_in_words,
+ external_data_);
+ }
+
+ bool is_queued_for_finalization() const {
+ return QueuedForFinalizationBit::decode(external_data_);
+ }
+ void set_is_queued_for_finalization(bool value) {
+ external_data_ = QueuedForFinalizationBit::update(value, external_data_);
}
bool IsSetNewSpaceBit() const {
@@ -333,10 +378,13 @@
Heap::kNew : Heap::kOld;
}
+ friend class BackgroundFinalizer;
+
RawObject* raw_;
void* peer_;
uword external_data_;
Dart_WeakPersistentHandleFinalizer callback_;
+
DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods.
DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle);
};
@@ -501,9 +549,11 @@
: Handles<kFinalizablePersistentHandleSizeInWords,
kFinalizablePersistentHandlesPerChunk,
kOffsetOfRawPtrInFinalizablePersistentHandle>(),
- free_list_(NULL) { }
+ free_list_(NULL), mutex_(new Mutex()) { }
~FinalizablePersistentHandles() {
free_list_ = NULL;
+ delete mutex_;
+ mutex_ = NULL;
}
// Accessors.
@@ -530,25 +580,31 @@
// by calling FreeHandle.
FinalizablePersistentHandle* AllocateHandle() {
FinalizablePersistentHandle* handle;
- if (free_list_ != NULL) {
- handle = free_list_;
- free_list_ = handle->Next();
- handle->set_raw(Object::null());
- } else {
- handle = reinterpret_cast<FinalizablePersistentHandle*>(
- AllocateScopedHandle());
- handle->Clear();
+ {
+ MutexLocker ml(mutex_);
+ if (free_list_ != NULL) {
+ handle = free_list_;
+ free_list_ = handle->Next();
+ handle->set_raw(Object::null());
+ return handle;
+ }
}
+
+ handle = reinterpret_cast<FinalizablePersistentHandle*>(
+ AllocateScopedHandle());
+ handle->Clear();
return handle;
}
void FreeHandle(FinalizablePersistentHandle* handle) {
+ MutexLocker ml(mutex_);
handle->FreeHandle(free_list());
set_free_list(handle);
}
// Validate if passed in handle is a Persistent Handle.
bool IsValidHandle(Dart_WeakPersistentHandle object) const {
+ MutexLocker ml(mutex_);
return IsValidScopedHandle(reinterpret_cast<uword>(object));
}
@@ -559,6 +615,7 @@
private:
FinalizablePersistentHandle* free_list_;
+ Mutex* mutex_;
DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles);
};
@@ -761,6 +818,7 @@
ref->set_raw(object);
ref->set_peer(peer);
ref->set_callback(callback);
+ ref->set_is_queued_for_finalization(false);
// This may trigger GC, so it must be called last.
ref->SetExternalSize(external_size, isolate);
return ref;
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 367cdcc..a6e91c5 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -41,6 +41,8 @@
"Run optimizing compilation in background") \
R(background_compilation_stop_alot, false, bool, false, \
"Stress test system: stop background compiler often.") \
+P(background_finalization, bool, USING_MULTICORE, \
+ "Run weak handle finalizers in background") \
R(break_at_isolate_spawn, false, bool, false, \
"Insert a one-time breakpoint at the entrypoint for all spawned isolates") \
C(collect_code, false, true, bool, true, \
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0c8dbc0..4ab5652 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -120,7 +120,7 @@
ConstantInstr* FlowGraph::GetConstant(const Object& object) {
- ConstantInstr* constant = constant_instr_pool_.Lookup(object);
+ ConstantInstr* constant = constant_instr_pool_.LookupValue(object);
if (constant == NULL) {
// Otherwise, allocate and add it to the pool.
constant = new(zone()) ConstantInstr(
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index bba04b4..f93b1d1 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -1001,7 +1001,6 @@
private:
friend class PolymorphicInliner;
-
static bool Contains(const GrowableArray<intptr_t>& a, intptr_t deopt_id) {
for (intptr_t i = 0; i < a.length(); i++) {
if (a[i] == deopt_id) return true;
@@ -1470,7 +1469,8 @@
bool PolymorphicInliner::TryInliningPoly(intptr_t receiver_cid,
const Function& target) {
- if (TryInlineRecognizedMethod(receiver_cid, target)) {
+ if (owner_->inliner_->use_speculative_inlining() &&
+ TryInlineRecognizedMethod(receiver_cid, target)) {
owner_->inlined_ = true;
return true;
}
@@ -2460,6 +2460,33 @@
}
+static bool InlineGrowableArraySetter(FlowGraph* flow_graph,
+ intptr_t offset,
+ StoreBarrierType store_barrier_type,
+ Instruction* call,
+ TargetEntryInstr** entry,
+ Definition** last) {
+ Definition* array = call->ArgumentAt(0);
+ Definition* value = call->ArgumentAt(1);
+
+ *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(),
+ call->GetBlock()->try_index());
+ (*entry)->InheritDeoptTarget(Z, call);
+
+ // This is an internal method, no need to check argument types.
+ StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
+ offset,
+ new(Z) Value(array),
+ new(Z) Value(value),
+ store_barrier_type,
+ call->token_pos());
+ flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect);
+ *last = store;
+
+ return true;
+}
+
+
static intptr_t PrepareInlineByteArrayBaseOp(
FlowGraph* flow_graph,
Instruction* call,
@@ -2876,6 +2903,10 @@
intptr_t cid,
TargetEntryInstr** entry,
Definition** last) {
+ ASSERT((cid == kOneByteStringCid) ||
+ (cid == kTwoByteStringCid) ||
+ (cid == kExternalOneByteStringCid) ||
+ (cid == kExternalTwoByteStringCid));
Definition* str = call->ArgumentAt(0);
Definition* index = call->ArgumentAt(1);
@@ -2889,6 +2920,62 @@
}
+bool FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ FlowGraph* flow_graph,
+ ForwardInstructionIterator* iterator,
+ InstanceCallInstr* call) {
+ Function& target = Function::Handle(Z);
+ GrowableArray<intptr_t> class_ids;
+ call->ic_data()->GetCheckAt(0, &class_ids, &target);
+ const intptr_t receiver_cid = class_ids[0];
+
+ TargetEntryInstr* entry;
+ Definition* last;
+ if (!FlowGraphInliner::TryInlineRecognizedMethod(flow_graph,
+ receiver_cid,
+ target,
+ call,
+ call->ArgumentAt(0),
+ call->token_pos(),
+ *call->ic_data(),
+ &entry, &last)) {
+ return false;
+ }
+
+ // Insert receiver class check if needed.
+ if (MethodRecognizer::PolymorphicTarget(target) ||
+ flow_graph->InstanceCallNeedsClassCheck(call, target.kind())) {
+ Instruction* check = GetCheckClass(
+ flow_graph,
+ call->ArgumentAt(0),
+ ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()),
+ call->deopt_id(),
+ call->token_pos());
+ flow_graph->InsertBefore(call, check, call->env(), FlowGraph::kEffect);
+ }
+
+ // Remove the original push arguments.
+ for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+ PushArgumentInstr* push = call->PushArgumentAt(i);
+ push->ReplaceUsesWith(push->value()->definition());
+ push->RemoveFromGraph();
+ }
+ // Replace all uses of this definition with the result.
+ call->ReplaceUsesWith(last);
+ // Finally insert the sequence other definition in place of this one in the
+ // graph.
+ call->previous()->LinkTo(entry->next());
+ entry->UnuseAllInputs(); // Entry block is not in the graph.
+ last->LinkTo(call);
+ // Remove through the iterator.
+ ASSERT(iterator->Current() == call);
+ iterator->RemoveCurrentFromGraph();
+ call->set_previous(NULL);
+ call->set_next(NULL);
+ return true;
+}
+
+
bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
intptr_t receiver_cid,
const Function& target,
@@ -2898,11 +2985,6 @@
const ICData& ic_data,
TargetEntryInstr** entry,
Definition** last) {
- if (FLAG_precompiled_mode) {
- // The graphs generated below include deopts.
- return false;
- }
-
ICData& value_check = ICData::ZoneHandle(Z);
MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target);
switch (kind) {
@@ -3133,6 +3215,18 @@
return InlineDoubleOp(flow_graph, Token::kMUL, call, entry, last);
case MethodRecognizer::kDoubleDiv:
return InlineDoubleOp(flow_graph, Token::kDIV, call, entry, last);
+ case MethodRecognizer::kGrowableArraySetData:
+ ASSERT(receiver_cid == kGrowableObjectArrayCid);
+ ASSERT(ic_data.NumberOfChecks() == 1);
+ return InlineGrowableArraySetter(
+ flow_graph, GrowableObjectArray::data_offset(), kEmitStoreBarrier,
+ call, entry, last);
+ case MethodRecognizer::kGrowableArraySetLength:
+ ASSERT(receiver_cid == kGrowableObjectArrayCid);
+ ASSERT(ic_data.NumberOfChecks() == 1);
+ return InlineGrowableArraySetter(
+ flow_graph, GrowableObjectArray::length_offset(), kNoStoreBarrier,
+ call, entry, last);
default:
return false;
}
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index ade98b5..04bca93 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -13,7 +13,9 @@
class Definition;
class Field;
class FlowGraph;
+class ForwardInstructionIterator;
class Function;
+class InstanceCallInstr;
class Instruction;
class TargetEntryInstr;
@@ -42,6 +44,11 @@
bool trace_inlining() const { return trace_inlining_; }
+ static bool TryReplaceInstanceCallWithInline(
+ FlowGraph* flow_graph,
+ ForwardInstructionIterator* iterator,
+ InstanceCallInstr* call);
+
static bool TryInlineRecognizedMethod(FlowGraph* flow_graph,
intptr_t receiver_cid,
const Function& target,
@@ -52,6 +59,8 @@
TargetEntryInstr** entry,
Definition** last);
+ bool use_speculative_inlining() const { return use_speculative_inlining_; }
+
private:
friend class CallSiteInliner;
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 9b7eb8b..70a9dc5 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -910,7 +910,7 @@
// Attempt to find equivalent instruction that was already scheduled.
// If the instruction is still in the graph (it could have been
// un-scheduled by a rollback action) and it dominates the sink - use it.
- Instruction* emitted = map_.Lookup(instruction);
+ Instruction* emitted = map_.LookupValue(instruction);
if (emitted != NULL &&
!emitted->WasEliminated() &&
sink->IsDominatedBy(emitted)) {
diff --git a/runtime/vm/freelist.cc b/runtime/vm/freelist.cc
index b8df851..b90f93f 100644
--- a/runtime/vm/freelist.cc
+++ b/runtime/vm/freelist.cc
@@ -4,13 +4,12 @@
#include "vm/freelist.h"
-#include <map>
-
#include "vm/bit_set.h"
+#include "vm/hash_map.h"
#include "vm/lockers.h"
#include "vm/object.h"
-#include "vm/raw_object.h"
#include "vm/os_thread.h"
+#include "vm/raw_object.h"
namespace dart {
@@ -286,26 +285,53 @@
}
+class IntptrPair {
+ public:
+ IntptrPair() : first_(-1), second_(-1) {}
+ IntptrPair(intptr_t first, intptr_t second)
+ : first_(first), second_(second) {}
+
+ intptr_t first() const { return first_; }
+ intptr_t second() const { return second_; }
+ void set_second(intptr_t s) { second_ = s; }
+
+ bool operator==(const IntptrPair& other) {
+ return (first_ == other.first_) && (second_ == other.second_);
+ }
+
+ bool operator!=(const IntptrPair& other) {
+ return (first_ != other.first_) || (second_ != other.second_);
+ }
+
+ private:
+ intptr_t first_;
+ intptr_t second_;
+};
+
+
void FreeList::PrintLarge() const {
int large_sizes = 0;
int large_objects = 0;
intptr_t large_bytes = 0;
- std::map<intptr_t, intptr_t> sorted;
- std::map<intptr_t, intptr_t>::iterator it;
+ MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> > map;
FreeListElement* node;
for (node = free_lists_[kNumLists]; node != NULL; node = node->next()) {
- it = sorted.find(node->Size());
- if (it != sorted.end()) {
- it->second += 1;
- } else {
+ IntptrPair* pair = map.Lookup(node->Size());
+ if (pair == NULL) {
large_sizes += 1;
- sorted.insert(std::make_pair(node->Size(), 1));
+ map.Insert(IntptrPair(node->Size(), 1));
+ } else {
+ pair->set_second(pair->second() + 1);
}
large_objects += 1;
}
- for (it = sorted.begin(); it != sorted.end(); ++it) {
- intptr_t size = it->first;
- intptr_t list_length = it->second;
+
+ MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >::Iterator it =
+ map.GetIterator();
+ IntptrPair* pair;
+ while ((pair = it.Next()) != NULL) {
+ intptr_t size = pair->first();
+ intptr_t list_length = pair->second();
intptr_t list_bytes = list_length * size;
large_bytes += list_bytes;
OS::Print("large %3" Pd " [%8" Pd " bytes] : "
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 2ac946a..ae0e205 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -434,19 +434,21 @@
class MarkingWeakVisitor : public HandleVisitor {
public:
- MarkingWeakVisitor() : HandleVisitor(Thread::Current()) {
- }
+ MarkingWeakVisitor(Thread* thread, FinalizationQueue* queue) :
+ HandleVisitor(thread), queue_(queue) { }
void VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
RawObject* raw_obj = handle->raw();
if (IsUnreachable(raw_obj)) {
- handle->UpdateUnreachable(thread()->isolate());
+ handle->UpdateUnreachable(thread()->isolate(), queue_);
}
}
private:
+ FinalizationQueue* queue_;
+
DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor);
};
@@ -706,8 +708,19 @@
mark.DrainMarkingStack();
{
TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
- MarkingWeakVisitor mark_weak;
- IterateWeakRoots(isolate, &mark_weak);
+ if (FLAG_background_finalization) {
+ FinalizationQueue* queue = new FinalizationQueue();
+ MarkingWeakVisitor mark_weak(thread, queue);
+ IterateWeakRoots(isolate, &mark_weak);
+ if (queue->length() > 0) {
+ Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue));
+ } else {
+ delete queue;
+ }
+ } else {
+ MarkingWeakVisitor mark_weak(thread, NULL);
+ IterateWeakRoots(isolate, &mark_weak);
+ }
}
// All marking done; detach code, etc.
FinalizeResultsFrom(&mark);
@@ -743,8 +756,19 @@
// Phase 2: Weak processing on main thread.
{
TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
- MarkingWeakVisitor mark_weak;
- IterateWeakRoots(isolate, &mark_weak);
+ if (FLAG_background_finalization) {
+ FinalizationQueue* queue = new FinalizationQueue();
+ MarkingWeakVisitor mark_weak(thread, queue);
+ IterateWeakRoots(isolate, &mark_weak);
+ if (queue->length() > 0) {
+ Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue));
+ } else {
+ delete queue;
+ }
+ } else {
+ MarkingWeakVisitor mark_weak(thread, NULL);
+ IterateWeakRoots(isolate, &mark_weak);
+ }
}
barrier.Sync();
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index f2caa9e..372ff7f 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -5,28 +5,39 @@
#ifndef VM_HASH_MAP_H_
#define VM_HASH_MAP_H_
+#include "vm/growable_array.h" // For Malloc, EmptyBase
#include "vm/zone.h"
namespace dart {
-template <typename KeyValueTrait>
-class DirectChainedHashMap: public ValueObject {
+template<typename KeyValueTrait, typename B, typename Allocator = Zone>
+class BaseDirectChainedHashMap : public B {
public:
- DirectChainedHashMap() : array_size_(0),
- lists_size_(0),
- count_(0),
- array_(NULL),
- lists_(NULL),
- free_list_head_(kNil) {
+ explicit BaseDirectChainedHashMap(Allocator* allocator)
+ : array_size_(0),
+ lists_size_(0),
+ count_(0),
+ array_(NULL),
+ lists_(NULL),
+ free_list_head_(kNil),
+ allocator_(allocator) {
ResizeLists(kInitialSize);
Resize(kInitialSize);
}
- DirectChainedHashMap(const DirectChainedHashMap& other);
+ BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other);
+
+ ~BaseDirectChainedHashMap() {
+ allocator_->template Free<HashMapListElement>(array_, array_size_);
+ allocator_->template Free<HashMapListElement>(lists_, lists_size_);
+ }
void Insert(typename KeyValueTrait::Pair kv);
- typename KeyValueTrait::Value Lookup(typename KeyValueTrait::Key key) const;
+ typename KeyValueTrait::Value LookupValue(
+ typename KeyValueTrait::Key key) const;
+
+ typename KeyValueTrait::Pair* Lookup(typename KeyValueTrait::Key key) const;
bool IsEmpty() const { return count_ == 0; }
@@ -43,6 +54,29 @@
}
}
+ class Iterator {
+ public:
+ typename KeyValueTrait::Pair* Next();
+
+ void Reset() {
+ array_index_ = 0;
+ list_index_ = kNil;
+ }
+
+ private:
+ explicit Iterator(const BaseDirectChainedHashMap& map)
+ : map_(map), array_index_(0), list_index_(kNil) {}
+
+ const BaseDirectChainedHashMap& map_;
+ intptr_t array_index_;
+ intptr_t list_index_;
+
+ template<typename T, typename Bs, typename A>
+ friend class BaseDirectChainedHashMap;
+ };
+
+ Iterator GetIterator() const { return Iterator(*this); }
+
protected:
// A linked list of T values. Stored in arrays.
struct HashMapListElement {
@@ -72,12 +106,31 @@
// with a given hash. Colliding elements are stored in linked lists.
HashMapListElement* lists_; // The linked lists containing hash collisions.
intptr_t free_list_head_; // Unused elements in lists_ are on the free list.
+ Allocator* allocator_;
};
-template <typename KeyValueTrait>
-typename KeyValueTrait::Value
- DirectChainedHashMap<KeyValueTrait>::
+template<typename KeyValueTrait, typename B, typename Allocator>
+BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
+ BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other)
+ : B(),
+ array_size_(other.array_size_),
+ lists_size_(other.lists_size_),
+ count_(other.count_),
+ array_(other.allocator_->template Alloc<HashMapListElement>(
+ other.array_size_)),
+ lists_(other.allocator_->template Alloc<HashMapListElement>(
+ other.lists_size_)),
+ free_list_head_(other.free_list_head_),
+ allocator_(other.allocator_) {
+ memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
+ memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
+}
+
+
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Pair*
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
Lookup(typename KeyValueTrait::Key key) const {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -86,40 +139,69 @@
uword pos = Bound(hash);
if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
- return KeyValueTrait::ValueOf(array_[pos].kv);
+ return &array_[pos].kv;
}
intptr_t next = array_[pos].next;
while (next != kNil) {
if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
- return KeyValueTrait::ValueOf(lists_[next].kv);
+ return &lists_[next].kv;
}
next = lists_[next].next;
}
}
- return kNoValue;
+ return NULL;
}
-template <typename KeyValueTrait>
-DirectChainedHashMap<KeyValueTrait>::
- DirectChainedHashMap(const DirectChainedHashMap& other)
- : ValueObject(),
- array_size_(other.array_size_),
- lists_size_(other.lists_size_),
- count_(other.count_),
- array_(Thread::Current()->zone()->
- Alloc<HashMapListElement>(other.array_size_)),
- lists_(Thread::Current()->zone()->
- Alloc<HashMapListElement>(other.lists_size_)),
- free_list_head_(other.free_list_head_) {
- memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
- memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Value
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
+ LookupValue(typename KeyValueTrait::Key key) const {
+ const typename KeyValueTrait::Value kNoValue =
+ KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
+ typename KeyValueTrait::Pair* pair = Lookup(key);
+ return (pair == NULL) ? kNoValue : KeyValueTrait::ValueOf(*pair);
}
-template <typename KeyValueTrait>
-void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Pair*
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Iterator::Next() {
+ const typename KeyValueTrait::Pair kNoPair = typename KeyValueTrait::Pair();
+
+ if (array_index_ < map_.array_size_) {
+ // If we're not in the middle of a list, find the next array slot.
+ if (list_index_ == kNil) {
+ while ((map_.array_[array_index_].kv == kNoPair) &&
+ (array_index_ < map_.array_size_)) {
+ array_index_++;
+ }
+ if (array_index_ < map_.array_size_) {
+ // When we're done with the list, we'll continue with the next array
+ // slot.
+ const intptr_t old_array_index = array_index_;
+ array_index_++;
+ list_index_ = map_.array_[old_array_index].next;
+ return &map_.array_[old_array_index].kv;
+ } else {
+ return NULL;
+ }
+ }
+
+ // Otherwise, return the current lists_ entry, advancing list_index_.
+ intptr_t current = list_index_;
+ list_index_ = map_.lists_[current].next;
+ return &map_.lists_[current].kv;
+ }
+
+ return NULL;
+}
+
+
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Resize(
+ intptr_t new_size) {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -133,7 +215,7 @@
}
HashMapListElement* new_array =
- Thread::Current()->zone()->Alloc<HashMapListElement>(new_size);
+ allocator_->template Alloc<HashMapListElement>(new_size);
InitArray(new_array, new_size);
HashMapListElement* old_array = array_;
@@ -163,16 +245,17 @@
}
USE(old_count);
ASSERT(count_ == old_count);
+ allocator_->template Free<HashMapListElement>(old_array, old_size);
}
-template <typename T>
-void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::ResizeLists(
+ intptr_t new_size) {
ASSERT(new_size > lists_size_);
HashMapListElement* new_lists =
- Thread::Current()->zone()->
- Alloc<HashMapListElement>(new_size);
+ allocator_->template Alloc<HashMapListElement>(new_size);
InitArray(new_lists, new_size);
HashMapListElement* old_lists = lists_;
@@ -188,11 +271,12 @@
lists_[i].next = free_list_head_;
free_list_head_ = i;
}
+ allocator_->template Free<HashMapListElement>(old_lists, old_size);
}
-template <typename KeyValueTrait>
-void DirectChainedHashMap<KeyValueTrait>::
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
Insert(typename KeyValueTrait::Pair kv) {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -223,6 +307,24 @@
}
+template<typename KeyValueTrait>
+class DirectChainedHashMap
+ : public BaseDirectChainedHashMap<KeyValueTrait, ValueObject> {
+ public:
+ DirectChainedHashMap() : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
+ ASSERT_NOTNULL(Thread::Current()->zone())) {}
+};
+
+
+template<typename KeyValueTrait>
+class MallocDirectChainedHashMap
+ : public BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc> {
+ public:
+ MallocDirectChainedHashMap()
+ : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {}
+};
+
+
template<typename T>
class PointerKeyValueTrait {
public:
@@ -247,6 +349,20 @@
}
};
+
+template<typename T>
+class NumbersKeyValueTrait {
+ public:
+ typedef T Value;
+ typedef intptr_t Key;
+ typedef T Pair;
+
+ static intptr_t KeyOf(Pair kv) { return kv.first(); }
+ static T ValueOf(Pair kv) { return kv; }
+ static inline intptr_t Hashcode(Key key) { return key; }
+ static inline bool IsKeyEqual(Pair kv, Key key) { return kv.first() == key; }
+};
+
} // namespace dart
#endif // VM_HASH_MAP_H_
diff --git a/runtime/vm/hash_map_test.cc b/runtime/vm/hash_map_test.cc
index 522ff7c..7830b85 100644
--- a/runtime/vm/hash_map_test.cc
+++ b/runtime/vm/hash_map_test.cc
@@ -25,15 +25,94 @@
TestValue v2(1);
TestValue v3(0);
map.Insert(&v1);
- EXPECT(map.Lookup(&v1) == &v1);
+ EXPECT(map.LookupValue(&v1) == &v1);
map.Insert(&v2);
- EXPECT(map.Lookup(&v1) == &v1);
- EXPECT(map.Lookup(&v2) == &v2);
- EXPECT(map.Lookup(&v3) == &v1);
+ EXPECT(map.LookupValue(&v1) == &v1);
+ EXPECT(map.LookupValue(&v2) == &v2);
+ EXPECT(map.LookupValue(&v3) == &v1);
DirectChainedHashMap<PointerKeyValueTrait<TestValue> > map2(map);
- EXPECT(map2.Lookup(&v1) == &v1);
- EXPECT(map2.Lookup(&v2) == &v2);
- EXPECT(map2.Lookup(&v3) == &v1);
+ EXPECT(map2.LookupValue(&v1) == &v1);
+ EXPECT(map2.LookupValue(&v2) == &v2);
+ EXPECT(map2.LookupValue(&v3) == &v1);
+}
+
+
+TEST_CASE(MallocDirectChainedHashMap) {
+ MallocDirectChainedHashMap<PointerKeyValueTrait<TestValue> > map;
+ EXPECT(map.IsEmpty());
+ TestValue v1(0);
+ TestValue v2(1);
+ TestValue v3(0);
+ map.Insert(&v1);
+ EXPECT(map.LookupValue(&v1) == &v1);
+ map.Insert(&v2);
+ EXPECT(map.LookupValue(&v1) == &v1);
+ EXPECT(map.LookupValue(&v2) == &v2);
+ EXPECT(map.LookupValue(&v3) == &v1);
+ MallocDirectChainedHashMap<PointerKeyValueTrait<TestValue> > map2(map);
+ EXPECT(map2.LookupValue(&v1) == &v1);
+ EXPECT(map2.LookupValue(&v2) == &v2);
+ EXPECT(map2.LookupValue(&v3) == &v1);
+}
+
+
+class IntptrPair {
+ public:
+ IntptrPair() : first_(-1), second_(-1) {}
+ IntptrPair(intptr_t first, intptr_t second)
+ : first_(first), second_(second) {}
+
+ intptr_t first() const { return first_; }
+ intptr_t second() const { return second_; }
+
+ bool operator==(const IntptrPair& other) {
+ return (first_ == other.first_) && (second_ == other.second_);
+ }
+
+ bool operator!=(const IntptrPair& other) {
+ return (first_ != other.first_) || (second_ != other.second_);
+ }
+
+ private:
+ intptr_t first_;
+ intptr_t second_;
+};
+
+
+TEST_CASE(DirectChainedHashMapIterator) {
+ IntptrPair p1(1, 1);
+ IntptrPair p2(2, 2);
+ IntptrPair p3(3, 3);
+ IntptrPair p4(4, 4);
+ IntptrPair p5(5, 5);
+ DirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> > map;
+ EXPECT(map.IsEmpty());
+ DirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >::Iterator it =
+ map.GetIterator();
+ EXPECT(it.Next() == NULL);
+ it.Reset();
+
+ map.Insert(p1);
+ EXPECT(*it.Next() == p1);
+ it.Reset();
+
+ map.Insert(p2);
+ map.Insert(p3);
+ map.Insert(p4);
+ map.Insert(p5);
+ intptr_t count = 0;
+ intptr_t sum = 0;
+ while (true) {
+ IntptrPair* p = it.Next();
+ if (p == NULL) {
+ break;
+ }
+ count++;
+ sum += p->second();
+ }
+
+ EXPECT(count == 5);
+ EXPECT(sum == 15);
}
} // namespace dart
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index 8408f23..f1079b8 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -5,11 +5,6 @@
#ifndef VM_HASH_TABLE_H_
#define VM_HASH_TABLE_H_
-// Temporarily used when sorting the indices in EnumIndexHashTable.
-// TODO(koda): Remove these dependencies before using in production.
-#include <map>
-#include <vector>
-
#include "platform/assert.h"
#include "vm/object.h"
@@ -22,20 +17,16 @@
// - HashTable
// The next layer provides ordering and iteration functionality:
// - UnorderedHashTable
-// - EnumIndexHashTable
// - LinkedListHashTable (TODO(koda): Implement.)
-// The utility class HashTables handles growth and conversion (e.g., converting
-// a compact EnumIndexHashTable to an iteration-efficient LinkedListHashTable).
+// The utility class HashTables handles growth and conversion.
// The next layer fixes the payload size and provides a natural interface:
// - HashMap
// - HashSet
// Combining either of these with an iteration strategy, we get the templates
// intended for use outside this file:
// - UnorderedHashMap
-// - EnumIndexHashMap
// - LinkedListHashMap
// - UnorderedHashSet
-// - EnumIndexHashSet
// - LinkedListHashSet
// Each of these can be finally specialized with KeyTraits to support any set of
// lookup key types (e.g., look up a char* in a set of String objects), and
@@ -435,74 +426,6 @@
};
-// Table with insertion order, using one payload component for the enumeration
-// index, and one metadata element for the next enumeration index.
-template<typename KeyTraits, intptr_t kUserPayloadSize>
-class EnumIndexHashTable
- : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> {
- public:
- typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable;
- static const intptr_t kPayloadSize = kUserPayloadSize;
- static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex;
- EnumIndexHashTable(Object* key, Smi* value, Array* data)
- : BaseTable(key, value, data) {}
- EnumIndexHashTable(Zone* zone, RawArray* data)
- : BaseTable(zone, data) {}
- explicit EnumIndexHashTable(RawArray* data)
- : BaseTable(Thread::Current()->zone(), data) {}
- // Note: Does not check for concurrent modification.
- class Iterator {
- public:
- explicit Iterator(const EnumIndexHashTable* table) : index_(-1) {
- // TODO(koda): Use GrowableArray after adding stateful comparator support.
- std::map<intptr_t, intptr_t> enum_to_entry;
- for (intptr_t i = 0; i < table->NumEntries(); ++i) {
- if (table->IsOccupied(i)) {
- intptr_t enum_index =
- table->GetSmiValueAt(table->PayloadIndex(i, kPayloadSize));
- enum_to_entry[enum_index] = i;
- }
- }
- for (std::map<intptr_t, intptr_t>::iterator it = enum_to_entry.begin();
- it != enum_to_entry.end();
- ++it) {
- entries_.push_back(it->second);
- }
- }
- bool MoveNext() {
- if (index_ < (static_cast<intptr_t>(entries_.size() - 1))) {
- index_++;
- return true;
- }
- return false;
- }
- intptr_t Current() {
- return entries_[index_];
- }
-
- private:
- intptr_t index_;
- std::vector<intptr_t> entries_;
- };
-
- void Initialize() const {
- BaseTable::Initialize();
- BaseTable::SetSmiValueAt(kNextEnumIndex, 0);
- }
-
- void InsertKey(intptr_t entry, const Object& key) const {
- BaseTable::InsertKey(entry, key);
- BaseTable::SmiHandle() =
- Smi::New(BaseTable::GetSmiValueAt(kNextEnumIndex));
- BaseTable::UpdatePayload(entry, kPayloadSize, BaseTable::SmiHandle());
- // TODO(koda): Handle possible Smi overflow from repeated insert/delete.
- BaseTable::AdjustSmiValueAt(kNextEnumIndex, 1);
- }
-
- // No extra book-keeping needed for DeleteEntry.
-};
-
-
class HashTables : public AllStatic {
public:
// Allocates and initializes a table.
@@ -687,18 +610,6 @@
};
-template<typename KeyTraits>
-class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > {
- public:
- typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap;
- explicit EnumIndexHashMap(RawArray* data)
- : BaseMap(Thread::Current()->zone(), data) {}
- EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
- EnumIndexHashMap(Object* key, Smi* value, Array* data)
- : BaseMap(key, value, data) {}
-};
-
-
template<typename BaseIterTable>
class HashSet : public BaseIterTable {
public:
@@ -791,18 +702,6 @@
: BaseSet(key, value, data) {}
};
-
-template<typename KeyTraits>
-class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > {
- public:
- typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet;
- explicit EnumIndexHashSet(RawArray* data)
- : BaseSet(Thread::Current()->zone(), data) {}
- EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
- EnumIndexHashSet(Object* key, Smi* value, Array* data)
- : BaseSet(key, value, data) {}
-};
-
} // namespace dart
#endif // VM_HASH_TABLE_H_
diff --git a/runtime/vm/hash_table_test.cc b/runtime/vm/hash_table_test.cc
index 158af48..2d597b1 100644
--- a/runtime/vm/hash_table_test.cc
+++ b/runtime/vm/hash_table_test.cc
@@ -122,34 +122,6 @@
}
-TEST_CASE(EnumIndexHashMap) {
- typedef EnumIndexHashMap<TestTraits> Table;
- Table table(HashTables::New<Table>(5));
- table.UpdateOrInsert(String::Handle(String::New("a")),
- String::Handle(String::New("A")));
- EXPECT(table.ContainsKey("a"));
- table.UpdateValue("a", String::Handle(String::New("AAA")));
- String& a_value = String::Handle();
- a_value ^= table.GetOrNull("a");
- EXPECT(a_value.Equals("AAA"));
- Object& null_value = Object::Handle(table.GetOrNull("0"));
- EXPECT(null_value.IsNull());
-
- // Test on-demand allocation of a new key object using NewKey in traits.
- String& b_value = String::Handle();
- b_value ^=
- table.InsertNewOrGetValue("b", String::Handle(String::New("BBB")));
- EXPECT(b_value.Equals("BBB"));
- {
- // When the key is already present, there should be no allocation.
- NoSafepointScope no_safepoint;
- b_value ^= table.InsertNewOrGetValue("b", a_value);
- EXPECT(b_value.Equals("BBB"));
- }
- table.Release();
-}
-
-
std::string ToStdString(const String& str) {
EXPECT(str.IsOneByteString());
std::string result;
@@ -290,7 +262,6 @@
initial_capacity < 32;
++initial_capacity) {
TestSet<UnorderedHashSet<TestTraits> >(initial_capacity, false);
- TestSet<EnumIndexHashSet<TestTraits> >(initial_capacity, true);
}
}
@@ -300,7 +271,6 @@
initial_capacity < 32;
++initial_capacity) {
TestMap<UnorderedHashMap<TestTraits> >(initial_capacity, false);
- TestMap<EnumIndexHashMap<TestTraits> >(initial_capacity, true);
}
}
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 2c92b17..46fd761 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -35,6 +35,8 @@
old_space_(this, max_old_gen_words, max_external_words),
barrier_(new Monitor()),
barrier_done_(new Monitor()),
+ finalization_tasks_lock_(new Monitor()),
+ finalization_tasks_(0),
read_only_(false),
gc_new_space_in_progress_(false),
gc_old_space_in_progress_(false),
@@ -52,6 +54,7 @@
Heap::~Heap() {
delete barrier_;
delete barrier_done_;
+ delete finalization_tasks_lock_;
for (int sel = 0;
sel < kNumWeakSelectors;
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 6131bf3..d13150e 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -256,6 +256,10 @@
Monitor* barrier() const { return barrier_; }
Monitor* barrier_done() const { return barrier_done_; }
+ Monitor* finalization_tasks_lock() const { return finalization_tasks_lock_; }
+ intptr_t finalization_tasks() const { return finalization_tasks_; }
+ void set_finalization_tasks(intptr_t count) { finalization_tasks_ = count; }
+
bool ShouldPretenure(intptr_t class_id) const;
void SetupExternalPage(void* pointer, uword size, bool is_executable) {
@@ -353,6 +357,9 @@
Monitor* barrier_;
Monitor* barrier_done_;
+ Monitor* finalization_tasks_lock_;
+ intptr_t finalization_tasks_;
+
// GC stats collection.
GCStats stats_;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 85bae29..cc5e51f 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1762,6 +1762,48 @@
}
+Definition* CheckedSmiOpInstr::Canonicalize(FlowGraph* flow_graph) {
+ if ((left()->Type()->ToCid() == kSmiCid) &&
+ (right()->Type()->ToCid() == kSmiCid)) {
+ Definition* replacement = NULL;
+ // Operations that can't deoptimize are specialized here: These include
+ // bit-wise operators and comparisons. Other arithmetic operations can
+ // overflow or divide by 0 and can't be specialized unless we have extra
+ // range information.
+ switch (op_kind()) {
+ case Token::kBIT_AND:
+ case Token::kBIT_OR:
+ case Token::kBIT_XOR:
+ replacement =
+ new BinarySmiOpInstr(op_kind(),
+ new Value(left()->definition()),
+ new Value(right()->definition()),
+ Thread::kNoDeoptId);
+ default:
+ break;
+ }
+ if (Token::IsRelationalOperator(op_kind())) {
+ replacement = new RelationalOpInstr(token_pos(), op_kind(),
+ new Value(left()->definition()),
+ new Value(right()->definition()),
+ kSmiCid,
+ Thread::kNoDeoptId);
+ } else if (Token::IsEqualityOperator(op_kind())) {
+ replacement = new EqualityCompareInstr(token_pos(), op_kind(),
+ new Value(left()->definition()),
+ new Value(right()->definition()),
+ kSmiCid,
+ Thread::kNoDeoptId);
+ }
+ if (replacement != NULL) {
+ flow_graph->InsertBefore(this, replacement, env(), FlowGraph::kValue);
+ return replacement;
+ }
+ }
+ return this;
+}
+
+
Definition* BinaryIntegerOpInstr::Canonicalize(FlowGraph* flow_graph) {
// If both operands are constants evaluate this expression. Might
// occur due to load forwarding after constant propagation pass
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index d048c0e..2705634 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -6910,6 +6910,8 @@
virtual EffectSet Effects() const { return EffectSet::All(); }
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
PRINT_OPERANDS_TO_SUPPORT
DECLARE_INSTRUCTION(CheckedSmiOp)
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index d28bbb2..c1719d4 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -32,7 +32,6 @@
#define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M) \
M(IndirectGoto) \
M(LoadCodeUnits) \
- M(InstanceOf) \
M(LoadUntagged) \
M(AllocateUninitializedContext) \
M(BinaryInt32Op) \
@@ -56,8 +55,6 @@
M(BinaryMintOp) \
M(ShiftMintOp) \
M(UnaryMintOp) \
- M(StringToCharCode) \
- M(OneByteStringFromCharCode) \
M(InvokeMathCFunction) \
M(MergedMath) \
M(GuardFieldClass) \
@@ -179,6 +176,32 @@
DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
+EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(),
+ LocationSummary::kCall) {
+ SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
+ if (!type().IsVoidType() && type().IsInstantiated()) {
+ test_cache = SubtypeTestCache::New();
+ }
+
+ if (compiler->is_optimizing()) {
+ __ Push(locs()->in(0).reg()); // Value.
+ __ Push(locs()->in(1).reg()); // Instantiator type arguments.
+ }
+
+ __ PushConstant(type());
+ __ PushConstant(test_cache);
+ __ InstanceOf(negate_result() ? 1 : 0);
+ compiler->RecordSafepoint(locs());
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+ deopt_id(),
+ token_pos());
+
+ if (compiler->is_optimizing()) {
+ __ PopLocal(locs()->out(0).reg());
+ }
+}
+
+
DEFINE_MAKE_LOCATION_SUMMARY(AssertAssignable, 2,
Location::SameAsFirstInput(),
LocationSummary::kCall);
@@ -574,6 +597,27 @@
}
+EMIT_NATIVE_CODE(OneByteStringFromCharCode,
+ 1, Location::RequiresRegister(),
+ LocationSummary::kNoCall) {
+ ASSERT(compiler->is_optimizing());
+ const Register char_code = locs()->in(0).reg(); // Char code is a smi.
+ const Register result = locs()->out(0).reg();
+ __ OneByteStringFromCharCode(result, char_code);
+}
+
+
+EMIT_NATIVE_CODE(StringToCharCode,
+ 1, Location::RequiresRegister(),
+ LocationSummary::kNoCall) {
+ ASSERT(cid_ == kOneByteStringCid);
+ const Register str = locs()->in(0).reg();
+ const Register result = locs()->out(0).reg(); // Result char code is a smi.
+ __ StringToCharCode(result, str);
+}
+
+
+
EMIT_NATIVE_CODE(AllocateObject,
0, Location::RequiresRegister(),
LocationSummary::kCall) {
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5369226..bd26039 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1552,7 +1552,8 @@
void VisitHandle(uword addr) {
FinalizablePersistentHandle* handle =
reinterpret_cast<FinalizablePersistentHandle*>(addr);
- handle->UpdateUnreachable(thread()->isolate());
+ FinalizationQueue* queue = NULL; // Finalize in the foreground.
+ handle->UpdateUnreachable(thread()->isolate(), queue);
}
private:
@@ -1675,10 +1676,20 @@
if (heap_ != NULL) {
// Wait for any concurrent GC tasks to finish before shutting down.
// TODO(koda): Support faster sweeper shutdown (e.g., after current page).
- PageSpace* old_space = heap_->old_space();
- MonitorLocker ml(old_space->tasks_lock());
- while (old_space->tasks() > 0) {
- ml.Wait();
+ {
+ PageSpace* old_space = heap_->old_space();
+ MonitorLocker ml(old_space->tasks_lock());
+ while (old_space->tasks() > 0) {
+ ml.Wait();
+ }
+ }
+
+ // Wait for background finalization to finish before shutting down.
+ {
+ MonitorLocker ml(heap_->finalization_tasks_lock());
+ while (heap_->finalization_tasks() > 0) {
+ ml.Wait();
+ }
}
}
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index dd23e57..7ff3b0c 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -741,7 +741,8 @@
if (ic_data.NumberOfChecks() != 1) {
return false;
}
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
@@ -1635,50 +1636,6 @@
}
-bool JitOptimizer::TryReplaceInstanceCallWithInline(
- InstanceCallInstr* call) {
- Function& target = Function::Handle(Z);
- GrowableArray<intptr_t> class_ids;
- call->ic_data()->GetCheckAt(0, &class_ids, &target);
- const intptr_t receiver_cid = class_ids[0];
-
- TargetEntryInstr* entry;
- Definition* last;
- if (!FlowGraphInliner::TryInlineRecognizedMethod(flow_graph_,
- receiver_cid,
- target,
- call,
- call->ArgumentAt(0),
- call->token_pos(),
- *call->ic_data(),
- &entry, &last)) {
- return false;
- }
-
- // Insert receiver class check.
- AddReceiverCheck(call);
- // Remove the original push arguments.
- for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
- PushArgumentInstr* push = call->PushArgumentAt(i);
- push->ReplaceUsesWith(push->value()->definition());
- push->RemoveFromGraph();
- }
- // Replace all uses of this definition with the result.
- call->ReplaceUsesWith(last);
- // Finally insert the sequence other definition in place of this one in the
- // graph.
- call->previous()->LinkTo(entry->next());
- entry->UnuseAllInputs(); // Entry block is not in the graph.
- last->LinkTo(call);
- // Remove through the iterator.
- ASSERT(current_iterator()->Current() == call);
- current_iterator()->RemoveCurrentFromGraph();
- call->set_previous(NULL);
- call->set_next(NULL);
- return true;
-}
-
-
void JitOptimizer::ReplaceWithMathCFunction(
InstanceCallInstr* call,
MethodRecognizer::Kind recognized_kind) {
@@ -1734,49 +1691,15 @@
MethodRecognizer::Kind recognized_kind =
MethodRecognizer::RecognizeKind(target);
- if ((recognized_kind == MethodRecognizer::kGrowableArraySetData) &&
- (ic_data.NumberOfChecks() == 1) &&
- (class_ids[0] == kGrowableObjectArrayCid)) {
- // This is an internal method, no need to check argument types.
- Definition* array = call->ArgumentAt(0);
- Definition* value = call->ArgumentAt(1);
- StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
- GrowableObjectArray::data_offset(),
- new(Z) Value(array),
- new(Z) Value(value),
- kEmitStoreBarrier,
- call->token_pos());
- ReplaceCall(call, store);
- return true;
- }
-
- if ((recognized_kind == MethodRecognizer::kGrowableArraySetLength) &&
- (ic_data.NumberOfChecks() == 1) &&
- (class_ids[0] == kGrowableObjectArrayCid)) {
- // This is an internal method, no need to check argument types nor
- // range.
- Definition* array = call->ArgumentAt(0);
- Definition* value = call->ArgumentAt(1);
- StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
- GrowableObjectArray::length_offset(),
- new(Z) Value(array),
- new(Z) Value(value),
- kNoStoreBarrier,
- call->token_pos());
- ReplaceCall(call, store);
- return true;
- }
-
if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
(recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
(recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
- (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+ (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) ||
+ (recognized_kind == MethodRecognizer::kGrowableArraySetData) ||
+ (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) {
ASSERT(ic_data.NumberOfChecks() == 1);
- ASSERT((class_ids[0] == kOneByteStringCid) ||
- (class_ids[0] == kTwoByteStringCid) ||
- (class_ids[0] == kExternalOneByteStringCid) ||
- (class_ids[0] == kExternalTwoByteStringCid));
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
@@ -1785,7 +1708,8 @@
(class_ids[0] == kTwoByteStringCid) ||
(class_ids[0] == kExternalOneByteStringCid) ||
(class_ids[0] == kExternalTwoByteStringCid));
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
@@ -1873,7 +1797,8 @@
case MethodRecognizer::kDoubleSub:
case MethodRecognizer::kDoubleMul:
case MethodRecognizer::kDoubleDiv:
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
default:
// Unsupported method.
return false;
@@ -1882,7 +1807,8 @@
if (IsSupportedByteArrayViewCid(class_ids[0]) &&
(ic_data.NumberOfChecks() == 1)) {
- return TryReplaceInstanceCallWithInline(call);
+ return FlowGraphInliner::TryReplaceInstanceCallWithInline(
+ flow_graph_, current_iterator(), call);
}
if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
@@ -2041,14 +1967,6 @@
case MethodRecognizer::kFloat32x4NotEqual: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- // Replace call.
Float32x4ComparisonInstr* cmp =
new(Z) Float32x4ComparisonInstr(recognized_kind,
new(Z) Value(left),
@@ -2061,13 +1979,6 @@
case MethodRecognizer::kFloat32x4Max: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float32x4MinMaxInstr* minmax =
new(Z) Float32x4MinMaxInstr(
recognized_kind,
@@ -2080,13 +1991,6 @@
case MethodRecognizer::kFloat32x4Scale: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
// Left and right values are swapped when handed to the instruction,
// this is done so that the double value is loaded into the output
// register and can be destroyed.
@@ -2102,12 +2006,6 @@
case MethodRecognizer::kFloat32x4ReciprocalSqrt:
case MethodRecognizer::kFloat32x4Reciprocal: {
Definition* left = call->ArgumentAt(0);
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float32x4SqrtInstr* sqrt =
new(Z) Float32x4SqrtInstr(recognized_kind,
new(Z) Value(left),
@@ -2121,13 +2019,6 @@
case MethodRecognizer::kFloat32x4WithW: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float32x4WithInstr* with = new(Z) Float32x4WithInstr(recognized_kind,
new(Z) Value(left),
new(Z) Value(right),
@@ -2138,13 +2029,6 @@
case MethodRecognizer::kFloat32x4Absolute:
case MethodRecognizer::kFloat32x4Negate: {
Definition* left = call->ArgumentAt(0);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float32x4ZeroArgInstr* zeroArg =
new(Z) Float32x4ZeroArgInstr(
recognized_kind, new(Z) Value(left), call->deopt_id());
@@ -2155,13 +2039,6 @@
Definition* left = call->ArgumentAt(0);
Definition* lower = call->ArgumentAt(1);
Definition* upper = call->ArgumentAt(2);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float32x4ClampInstr* clamp = new(Z) Float32x4ClampInstr(
new(Z) Value(left),
new(Z) Value(lower),
@@ -2198,13 +2075,6 @@
case MethodRecognizer::kFloat64x2Sqrt:
case MethodRecognizer::kFloat64x2GetSignMask: {
Definition* left = call->ArgumentAt(0);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float64x2ZeroArgInstr* zeroArg =
new(Z) Float64x2ZeroArgInstr(
recognized_kind, new(Z) Value(left), call->deopt_id());
@@ -2218,13 +2088,6 @@
case MethodRecognizer::kFloat64x2Max: {
Definition* left = call->ArgumentAt(0);
Definition* right = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
Float64x2OneArgInstr* zeroArg =
new(Z) Float64x2OneArgInstr(recognized_kind,
new(Z) Value(left),
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index f1a0d87..f94e32a 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -822,8 +822,25 @@
}
intptr_t limit = offset + count;
for (intptr_t i = offset; i < limit; i++) {
- intptr_t code_unit = s.CharAt(i);
- buffer_.EscapeAndAddCodeUnit(code_unit);
+ uint16_t code_unit = s.CharAt(i);
+ if (Utf16::IsTrailSurrogate(code_unit)) {
+ buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
+ } else if (Utf16::IsLeadSurrogate(code_unit)) {
+ if (i + 1 == limit) {
+ buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
+ } else {
+ uint16_t next_code_unit = s.CharAt(i+1);
+ if (Utf16::IsTrailSurrogate(next_code_unit)) {
+ uint32_t decoded = Utf16::Decode(code_unit, next_code_unit);
+ buffer_.EscapeAndAddCodeUnit(decoded);
+ i++;
+ } else {
+ buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
+ }
+ }
+ } else {
+ buffer_.EscapeAndAddCodeUnit(code_unit);
+ }
}
// Return value indicates whether the string is truncated.
return (offset > 0) || (limit < length);
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index e8c4f5d..a0b27c2 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -219,8 +219,9 @@
"var unicode = '\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5\\u0163"
"\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E\\u00E5\\u0163"
"\\u00EE\\u1EDD\\u00F1';\n"
- "var surrogates = '\\u{1D11E}\\u{1D11E}\\u{1D11E}\\u{1D11E}"
- "\\u{1D11E}';\n"
+ "var surrogates = '\\u{1D11E}\\u{1D11E}\\u{1D11E}"
+ "\\u{1D11E}\\u{1D11E}';\n"
+ "var wrongEncoding = '\\u{1D11E}' + surrogates[0] + '\\u{1D11E}';"
"var nullInMiddle = 'This has\\u0000 four words.';";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -265,9 +266,7 @@
JSONObject jsobj(&js);
EXPECT(!jsobj.AddPropertyStr("unicode", obj));
}
- EXPECT_STREQ("{\"unicode\":\"\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5"
- "\\u0163\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E"
- "\\u00E5\\u0163\\u00EE\\u1EDD\\u00F1\"}", js.ToCString());
+ EXPECT_STREQ("{\"unicode\":\"Îñţérñåţîöñåļîžåţîờñ\"}", js.ToCString());
}
{
@@ -280,11 +279,24 @@
JSONObject jsobj(&js);
EXPECT(!jsobj.AddPropertyStr("surrogates", obj));
}
- EXPECT_STREQ("{\"surrogates\":\"\\uD834\\uDD1E\\uD834\\uDD1E\\uD834\\uDD1E"
- "\\uD834\\uDD1E\\uD834\\uDD1E\"}", js.ToCString());
+ EXPECT_STREQ("{\"surrogates\":\"𝄞𝄞𝄞𝄞𝄞\"}", js.ToCString());
}
{
+ result = Dart_GetField(lib, NewString("wrongEncoding"));
+ EXPECT_VALID(result);
+ obj ^= Api::UnwrapHandle(result);
+
+ JSONStream js;
+ {
+ JSONObject jsobj(&js);
+ EXPECT(!jsobj.AddPropertyStr("wrongEncoding", obj));
+ }
+ EXPECT_STREQ("{\"wrongEncoding\":\"𝄞\\uD834𝄞\"}", js.ToCString());
+ }
+
+
+ {
result = Dart_GetField(lib, NewString("nullInMiddle"));
EXPECT_VALID(result);
obj ^= Api::UnwrapHandle(result);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index be99b1d..0214cfb 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -21607,7 +21607,6 @@
}
}
};
-typedef EnumIndexHashMap<DefaultHashTraits> EnumIndexDefaultMap;
RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) {
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index fd26900..35df46b 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -1720,12 +1720,26 @@
it.GetNext();
entries++;
}
- // The root library might have no surviving members if it only exports main
- // from another library. It will still be referenced from the object store,
- // so retain it.
- bool retain = (entries > 0) ||
- lib.is_dart_scheme() ||
- (lib.raw() == root_lib.raw());
+ bool retain = false;
+ if (entries > 0) {
+ retain = true;
+ } else if (lib.is_dart_scheme()) {
+ // The core libraries are referenced from the object store.
+ retain = true;
+ } else if (lib.raw() == root_lib.raw()) {
+ // The root library might have no surviving members if it only exports
+ // main from another library. It will still be referenced from the object
+ // store, so retain it.
+ retain = true;
+ } else {
+ // A type for a top-level class may be referenced from an object pool as
+ // part of an error message.
+ const Class& top = Class::Handle(Z, lib.toplevel_class());
+ if (classes_to_retain_.Lookup(&top) != NULL) {
+ retain = true;
+ }
+ }
+
if (retain) {
lib.set_index(retained_libraries.Length());
retained_libraries.Add(lib);
@@ -1908,7 +1922,7 @@
RawStackmap* DedupStackmap(const Stackmap& stackmap) {
const Stackmap* canonical_stackmap =
- canonical_stackmaps_.Lookup(&stackmap);
+ canonical_stackmaps_.LookupValue(&stackmap);
if (canonical_stackmap == NULL) {
canonical_stackmaps_.Insert(
&Stackmap::ZoneHandle(zone_, stackmap.raw()));
@@ -1956,7 +1970,7 @@
RawArray* DedupStackmapList(const Array& stackmaps) {
const Array* canonical_stackmap_list =
- canonical_stackmap_lists_.Lookup(&stackmaps);
+ canonical_stackmap_lists_.LookupValue(&stackmaps);
if (canonical_stackmap_list == NULL) {
canonical_stackmap_lists_.Insert(
&Array::ZoneHandle(zone_, stackmaps.raw()));
@@ -2004,7 +2018,7 @@
RawInstructions* DedupOneInstructions(const Instructions& instructions) {
const Instructions* canonical_instructions =
- canonical_instructions_set_.Lookup(&instructions);
+ canonical_instructions_set_.LookupValue(&instructions);
if (canonical_instructions == NULL) {
canonical_instructions_set_.Insert(
&Instructions::ZoneHandle(zone_, instructions.raw()));
@@ -2710,8 +2724,11 @@
// The return value of setjmp is the deopt id of the check instruction
// that caused the bailout.
done = false;
+ if (!use_speculative_inlining) {
+ // Assert that we don't repeatedly retry speculation.
+ UNREACHABLE();
+ }
#if defined(DEBUG)
- ASSERT(use_speculative_inlining);
for (intptr_t i = 0; i < inlining_black_list.length(); ++i) {
ASSERT(inlining_black_list[i] != val);
}
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 32b4ec4..b6b2417 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -356,8 +356,8 @@
kTruncatedTraceBit = 5,
kClassAllocationSampleBit = 6,
kContinuationSampleBit = 7,
- kThreadTaskBit = 8, // 4 bits.
- kNextFreeBit = 12,
+ kThreadTaskBit = 8, // 5 bits.
+ kNextFreeBit = 13,
};
class HeadSampleBit : public BitField<uword, bool, kHeadSampleBit, 1> {};
class LeafFrameIsDart :
@@ -373,7 +373,7 @@
class ContinuationSampleBit
: public BitField<uword, bool, kContinuationSampleBit, 1> {};
class ThreadTaskBit
- : public BitField<uword, Thread::TaskKind, kThreadTaskBit, 4> {};
+ : public BitField<uword, Thread::TaskKind, kThreadTaskBit, 5> {};
int64_t timestamp_;
ThreadId tid_;
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index cc0f89d..6b3d839 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -542,7 +542,7 @@
ProfileFunction* Lookup(const Function& function) {
ASSERT(!function.IsNull());
- return function_hash_.Lookup(&function);
+ return function_hash_.LookupValue(&function);
}
ProfileFunction* GetUnknown() {
diff --git a/runtime/vm/redundancy_elimination.cc b/runtime/vm/redundancy_elimination.cc
index 93b3951..9a8c912 100644
--- a/runtime/vm/redundancy_elimination.cc
+++ b/runtime/vm/redundancy_elimination.cc
@@ -45,7 +45,7 @@
}
Instruction* Lookup(Instruction* other) const {
- return GetMapFor(other)->Lookup(other);
+ return GetMapFor(other)->LookupValue(other);
}
void Insert(Instruction* instr) {
@@ -707,7 +707,7 @@
}
intptr_t LookupAliasId(const Place& alias) {
- const Place* result = aliases_map_.Lookup(&alias);
+ const Place* result = aliases_map_.LookupValue(&alias);
return (result != NULL) ? result->id() : static_cast<intptr_t>(kNoAlias);
}
@@ -725,7 +725,7 @@
}
Place* LookupCanonical(Place* place) const {
- return places_map_->Lookup(place);
+ return places_map_->LookupValue(place);
}
void PrintSet(BitVector* set) {
@@ -851,14 +851,14 @@
}
const Place* CanonicalizeAlias(const Place& alias) {
- const Place* canonical = aliases_map_.Lookup(&alias);
+ const Place* canonical = aliases_map_.LookupValue(&alias);
if (canonical == NULL) {
canonical = Place::Wrap(zone_,
alias,
kAnyInstanceAnyIndexAlias + aliases_.length());
InsertAlias(canonical);
}
- ASSERT(aliases_map_.Lookup(&alias) == canonical);
+ ASSERT(aliases_map_.LookupValue(&alias) == canonical);
return canonical;
}
@@ -1234,7 +1234,7 @@
for (intptr_t j = 0; j < phi->InputCount(); j++) {
input_place.set_instance(phi->InputAt(j)->definition());
- Place* result = map->Lookup(&input_place);
+ Place* result = map->LookupValue(&input_place);
if (result == NULL) {
result = Place::Wrap(zone, input_place, places->length());
map->Insert(result);
@@ -1289,7 +1289,7 @@
continue;
}
- Place* result = map->Lookup(&place);
+ Place* result = map->LookupValue(&place);
if (result == NULL) {
result = Place::Wrap(zone, place, places->length());
map->Insert(result);
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 306a78a..ba36ac8 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -193,10 +193,13 @@
class ScavengerWeakVisitor : public HandleVisitor {
public:
- explicit ScavengerWeakVisitor(Scavenger* scavenger)
- : HandleVisitor(Thread::Current()),
- scavenger_(scavenger) {
- ASSERT(scavenger->heap_->isolate() == Thread::Current()->isolate());
+ ScavengerWeakVisitor(Thread* thread,
+ Scavenger* scavenger,
+ FinalizationQueue* finalization_queue) :
+ HandleVisitor(thread),
+ scavenger_(scavenger),
+ queue_(finalization_queue) {
+ ASSERT(scavenger->heap_->isolate() == thread->isolate());
}
void VisitHandle(uword addr) {
@@ -204,7 +207,7 @@
reinterpret_cast<FinalizablePersistentHandle*>(addr);
RawObject** p = handle->raw_addr();
if (scavenger_->IsUnreachable(p)) {
- handle->UpdateUnreachable(thread()->isolate());
+ handle->UpdateUnreachable(thread()->isolate(), queue_);
} else {
handle->UpdateRelocated(thread()->isolate());
}
@@ -212,6 +215,7 @@
private:
Scavenger* scavenger_;
+ FinalizationQueue* queue_;
DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor);
};
@@ -812,8 +816,19 @@
int64_t middle = OS::GetCurrentTimeMicros();
{
TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
- ScavengerWeakVisitor weak_visitor(this);
- IterateWeakRoots(isolate, &weak_visitor);
+ if (FLAG_background_finalization) {
+ FinalizationQueue* queue = new FinalizationQueue();
+ ScavengerWeakVisitor weak_visitor(thread, this, queue);
+ IterateWeakRoots(isolate, &weak_visitor);
+ if (queue->length() > 0) {
+ Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue));
+ } else {
+ delete queue;
+ }
+ } else {
+ ScavengerWeakVisitor weak_visitor(thread, this, NULL);
+ IterateWeakRoots(isolate, &weak_visitor);
+ }
}
ProcessWeakReferences();
page_space->ReleaseDataLock();
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 1938950..5a26b53 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -28,6 +28,7 @@
#include "vm/object_store.h"
#include "vm/os_thread.h"
#include "vm/stack_frame.h"
+#include "vm/symbols.h"
namespace dart {
@@ -1525,6 +1526,28 @@
}
{
+ BYTECODE(OneByteStringFromCharCode, A_X);
+ const intptr_t char_code = Smi::Value(RAW_CAST(Smi, FP[rD]));
+ ASSERT(char_code >= 0);
+ ASSERT(char_code <= 255);
+ RawString** strings = Symbols::PredefinedAddress();
+ const intptr_t index = char_code + Symbols::kNullCharCodeSymbolOffset;
+ FP[rA] = strings[index];
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(StringToCharCode, A_X);
+ RawOneByteString* str = RAW_CAST(OneByteString, FP[rD]);
+ if (str->ptr()->length_ == Smi::New(1)) {
+ FP[rA] = Smi::New(str->ptr()->data()[0]);
+ } else {
+ FP[rA] = Smi::New(-1);
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(AddTOS, A_B_C);
SMI_FASTPATH_TOS(intptr_t, SignedAddWithOverflow);
DISPATCH();
@@ -1854,6 +1877,73 @@
}
{
+ BYTECODE(InstanceOf, A); // Stack: instance, type args, type, cache
+ RawInstance* instance = static_cast<RawInstance*>(SP[-3]);
+ RawTypeArguments* instantiator_type_arguments =
+ static_cast<RawTypeArguments*>(SP[-2]);
+ RawAbstractType* type = static_cast<RawAbstractType*>(SP[-1]);
+ RawSubtypeTestCache* cache = static_cast<RawSubtypeTestCache*>(SP[0]);
+
+ if (cache != null_value) {
+ const intptr_t cid = SimulatorHelpers::GetClassId(instance);
+
+ RawTypeArguments* instance_type_arguments =
+ static_cast<RawTypeArguments*>(null_value);
+ RawObject* instance_cid_or_function;
+ if (cid == kClosureCid) {
+ RawClosure* closure = static_cast<RawClosure*>(instance);
+ instance_type_arguments = closure->ptr()->type_arguments_;
+ instance_cid_or_function = closure->ptr()->function_;
+ } else {
+ instance_cid_or_function = Smi::New(cid);
+
+ RawClass* instance_class =
+ thread->isolate()->class_table()->At(cid);
+ if (instance_class->ptr()->num_type_arguments_ < 0) {
+ goto InstanceOfCallRuntime;
+ } else if (instance_class->ptr()->num_type_arguments_ > 0) {
+ instance_type_arguments = reinterpret_cast<RawTypeArguments**>(
+ instance
+ ->ptr())[instance_class->ptr()
+ ->type_arguments_field_offset_in_words_];
+ }
+ }
+
+ for (RawObject** entries = cache->ptr()->cache_->ptr()->data();
+ entries[0] != null_value;
+ entries += SubtypeTestCache::kTestEntryLength) {
+ if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] ==
+ instance_cid_or_function) &&
+ (entries[SubtypeTestCache::kInstanceTypeArguments] ==
+ instance_type_arguments) &&
+ (entries[SubtypeTestCache::kInstantiatorTypeArguments] ==
+ instantiator_type_arguments)) {
+ SP[-3] = entries[SubtypeTestCache::kTestResult];
+ goto InstanceOfOk;
+ }
+ }
+ }
+
+ InstanceOfCallRuntime:
+ {
+ SP[1] = instance;
+ SP[2] = type;
+ SP[3] = instantiator_type_arguments;
+ SP[4] = cache;
+ Exit(thread, FP, SP + 5, pc);
+ NativeArguments native_args(thread, 4, SP + 1, SP - 3);
+ INVOKE_RUNTIME(DRT_Instanceof, native_args);
+ }
+
+ InstanceOfOk:
+ SP -= 3;
+ if (rA) { // Negate result.
+ SP[0] = (SP[0] == true_value) ? false_value : true_value;
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
RawObject** args = SP - 3;
if (args[0] != null_value) {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 7fa1573..8601b85 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -113,7 +113,7 @@
intptr_t SourceReport::GetScriptIndex(const Script& script) {
const String& url = String::Handle(zone(), script.url());
- ScriptTableEntry* pair = script_table_.Lookup(&url);
+ ScriptTableEntry* pair = script_table_.LookupValue(&url);
if (pair != NULL) {
return pair->index;
}
@@ -140,7 +140,7 @@
ASSERT(i == index);
const String& url2 = String::Handle(zone(), script->url());
ASSERT(url2.Equals(*url));
- ScriptTableEntry* pair = script_table_.Lookup(&url2);
+ ScriptTableEntry* pair = script_table_.LookupValue(&url2);
ASSERT(i == pair->index);
}
}
diff --git a/runtime/vm/store_buffer.cc b/runtime/vm/store_buffer.cc
index b257c0a..67f0fcb 100644
--- a/runtime/vm/store_buffer.cc
+++ b/runtime/vm/store_buffer.cc
@@ -104,7 +104,6 @@
// Sanity check: it makes no sense to schedule the GC in another isolate.
// (If Isolate ever gets multiple store buffers, we should avoid this
// coupling by passing in an explicit callback+parameter at construction.)
- ASSERT(thread->isolate()->mutator_thread() == thread);
ASSERT(thread->isolate()->store_buffer() == this);
thread->ScheduleInterrupts(Thread::kVMInterrupt);
}
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index ea5396a..1ce083a 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -145,6 +145,7 @@
kCompilerTask = 0x2,
kSweeperTask = 0x4,
kMarkerTask = 0x8,
+ kFinalizerTask = 0x10,
};
~Thread();
diff --git a/runtime/vm/unicode.h b/runtime/vm/unicode.h
index e06f1f9..7ea10e9 100644
--- a/runtime/vm/unicode.h
+++ b/runtime/vm/unicode.h
@@ -117,17 +117,17 @@
}
// Returns true if ch is a lead or trail surrogate.
- static bool IsSurrogate(int32_t ch) {
+ static bool IsSurrogate(uint32_t ch) {
return (ch & 0xFFFFF800) == 0xD800;
}
// Returns true if ch is a lead surrogate.
- static bool IsLeadSurrogate(int32_t ch) {
+ static bool IsLeadSurrogate(uint32_t ch) {
return (ch & 0xFFFFFC00) == 0xD800;
}
// Returns true if ch is a low surrogate.
- static bool IsTrailSurrogate(int32_t ch) {
+ static bool IsTrailSurrogate(uint32_t ch) {
return (ch & 0xFFFFFC00) == 0xDC00;
}
@@ -147,8 +147,8 @@
}
// Decodes a surrogate pair into a supplementary code point.
- static int32_t Decode(int32_t lead, int32_t trail) {
- return 0x10000 + ((lead & 0x3FF) << 10) + (trail & 0x3FF);
+ static int32_t Decode(uint16_t lead, uint16_t trail) {
+ return 0x10000 + ((lead & 0x000003FF) << 10) + (trail & 0x3FF);
}
// Encodes a single code point.
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 902eae7..36d9534 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -136,6 +136,7 @@
'dart_api_impl_test.cc',
'dart_api_message.cc',
'dart_api_message.h',
+ 'dart_api_state.cc',
'dart_api_state.h',
'dart_entry.cc',
'dart_entry.h',
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index d8ecef5..29d2765 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -176,6 +176,8 @@
friend class ApiZone;
template<typename T, typename B, typename Allocator>
friend class BaseGrowableArray;
+ template<typename T, typename B, typename Allocator>
+ friend class BaseDirectChainedHashMap;
DISALLOW_COPY_AND_ASSIGN(Zone);
};
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 6f5cf9d..7354ca2 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -1369,6 +1369,11 @@
}
if (!acceptsOptionalArguments) {
+ if (namedArguments != null && namedArguments.isNotEmpty) {
+ // Tried to invoke a function that takes a fixed number of arguments
+ // with named (optional) arguments.
+ return functionNoSuchMethod(function, arguments, namedArguments);
+ }
if (argumentCount == requiredParameterCount) {
return JS('var', r'#.apply(#, #)', jsFunction, function, arguments);
}
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 9d25927..d887e67 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -88,6 +88,24 @@
* entries with [fill]. After being created and filled, the list is
* no different from any other growable or fixed-length list
* created using [List].
+ *
+ * All entries in the returned list point to the same provided [fill] value.
+ * That all items in the list are the same object is
+ * observable when the given value is a mutable object.
+ *
+ * ```
+ * var shared = new List.filled(3, []);
+ * shared[0].add(499);
+ * print(shared); // => [[499], [499], [499]]
+ * ```
+ *
+ * You may use [List.generate] to create a new object for each position in
+ * in the list.
+ * ```
+ * var unique = new List.generate(3, (_) => []);
+ * unique[0].add(499);
+ * print(unique); // => [[499], [], []]
+ * ```
*/
external factory List.filled(int length, E fill, {bool growable: false});
diff --git a/sdk/lib/io/bytes_builder.dart b/sdk/lib/io/bytes_builder.dart
index 0c97748..2dca39d 100644
--- a/sdk/lib/io/bytes_builder.dart
+++ b/sdk/lib/io/bytes_builder.dart
@@ -160,7 +160,7 @@
if (bytes is Uint8List) {
typedBytes = bytes;
} else {
- bytes = new Uint8List.fromList(bytes);
+ typedBytes = new Uint8List.fromList(bytes);
}
_chunks.add(typedBytes);
_length += typedBytes.length;
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 4dbd24a..2740bdf 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -1663,6 +1663,7 @@
[ $compiler == dart2js && $runtime == chrome && $system == macos ]
Language/Expressions/Function_Invocation/async_invokation_t04: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/canvas-test_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Skip # Times out. Please triage this failure.
LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Please triage this failure
@@ -2300,6 +2301,7 @@
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Issue 26714
LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # Issue 26714
LayoutTests/fast/dom/importNode-unsupported-node-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/insert-span-into-long-text-bug-28245_t01: RuntimeError # Please triage this failure
@@ -3177,6 +3179,8 @@
WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
[ $compiler == dart2js && $runtime == ff && $system == windows ]
+LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError # Issue 22564
Language/Classes/Getters/type_object_t02: RuntimeError, Slow # Issue 25940
@@ -3196,7 +3200,6 @@
LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Skip # Times out always
LayoutTests/fast/canvas/webgl/texture-complete_t01: Skip # Times out sometimes
LayoutTests/fast/canvas/webgl/texture-npot_t01: Skip # Times out sometimes
-LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Issue 26714
[ $compiler == dart2js && $runtime == safari ]
Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
@@ -9514,6 +9517,21 @@
WebPlatformTest/webstorage/storage_builtins_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
+[ $compiler == dart2js && $runtime == ie11 && $builder_tag == win7]
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # fixed by co19 pull request whesse-patch-2
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
+
[ $compiler == dart2js && $cps_ir ]
Language/Types/Interface_Types/subtype_t09: Crash # Pending static: JSArray
LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
diff --git a/tests/compiler/dart2js/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
index 60563f8..fde84c3 100644
--- a/tests/compiler/dart2js/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
@@ -55,6 +55,8 @@
const ConstantData('"foo"', const { const {} : 'StringConstant("foo")' }),
const ConstantData('1 + 2', const { const {} : 'IntConstant(3)' }),
const ConstantData('-(1)', const { const {} : 'IntConstant(-1)' }),
+ const ConstantData('1 == 2', const { const {} : 'BoolConstant(false)' }),
+ const ConstantData('1 != 2', const { const {} : 'BoolConstant(true)' }),
const ConstantData('"foo".length', const { const {} : 'IntConstant(3)' }),
const ConstantData('identical(0, 1)',
const { const {} : 'BoolConstant(false)' }),
diff --git a/tests/compiler/dart2js/constant_expression_test.dart b/tests/compiler/dart2js/constant_expression_test.dart
index c24868f..f2b8f3b 100644
--- a/tests/compiler/dart2js/constant_expression_test.dart
+++ b/tests/compiler/dart2js/constant_expression_test.dart
@@ -51,6 +51,8 @@
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.BINARY),
const ConstantData('-(1)', ConstantExpressionKind.UNARY, text: '-1'),
const ConstantData('"foo".length', ConstantExpressionKind.STRING_LENGTH),
const ConstantData('identical(0, 1)', ConstantExpressionKind.IDENTICAL),
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index c413241..34e7efe 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -35,6 +35,7 @@
MessageKind.CANNOT_MIXIN_MALFORMED,
MessageKind.CANNOT_INSTANTIATE_ENUM,
MessageKind.CYCLIC_TYPEDEF_ONE,
+ MessageKind.DUPLICATE_DEFINITION,
MessageKind.EQUAL_MAP_ENTRY_KEY,
MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
MessageKind.FORMAL_DECLARED_CONST,
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index b72e479..5ee48ff 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -2702,8 +2702,7 @@
const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
getter: 'field(A#a)', setter: 'setter(B#a)',
operator: '+=', rhs: '42')),
- // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
- /*const Test.clazz(
+ const Test.clazz(
'''
class A {
var a;
@@ -2716,9 +2715,12 @@
m() => super.a += 42;
}
''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
- getter: 'field(B#a)', setter: 'field(A#a)',
- operator: '+=', rhs: '42')),*/
+ // TODO(johnniwinther): Change this to
+ // [VISIT_SUPER_FIELD_FIELD_COMPOUND] when dart2js supports shadow
+ // setters.
+ const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
+ element: 'field(B#a)',
+ operator: '+=', rhs: '42')),
const Test.clazz(
'''
class B {
@@ -4437,8 +4439,7 @@
const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_SET_IF_NULL,
getter: 'field(A#a)', setter: 'setter(B#a)',
rhs: '42')),
- // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
- /*const Test.clazz(
+ const Test.clazz(
'''
class A {
var a;
@@ -4451,9 +4452,12 @@
m() => super.a ??= 42;
}
''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_SET_IF_NULL,
- getter: 'field(B#a)', setter: 'field(A#a)',
- rhs: '42')),*/
+ // TODO(johnniwinther): Change this to
+ // [VISIT_SUPER_FIELD_FIELD_SET_IF_NULL] when dart2js supports shadow
+ // setters.
+ const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_SET_IF_NULL,
+ element: 'field(B#a)',
+ rhs: '42')),
const Test.clazz(
'''
class B {
diff --git a/tests/compiler/dart2js/serialization/analysis1_test.dart b/tests/compiler/dart2js/serialization/analysis1_test.dart
new file mode 100644
index 0000000..1b8532e
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/analysis1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.analysis1_test;
+
+import 'analysis_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['0', '${TESTS.length ~/ 2}']);
+}
diff --git a/tests/compiler/dart2js/serialization/analysis2_test.dart b/tests/compiler/dart2js/serialization/analysis2_test.dart
new file mode 100644
index 0000000..b13a6a3
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/analysis2_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.analysis2_test;
+
+import 'analysis_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['${TESTS.length ~/ 2}']);
+}
diff --git a/tests/compiler/dart2js/serialization/analysis_test.dart b/tests/compiler/dart2js/serialization/analysis_test_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/serialization/analysis_test.dart
rename to tests/compiler/dart2js/serialization/analysis_test_helper.dart
diff --git a/tests/compiler/dart2js/serialization/compilation1_test.dart b/tests/compiler/dart2js/serialization/compilation1_test.dart
new file mode 100644
index 0000000..3244d79
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.compilation1_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['0', '${TESTS.length ~/ 4}']);
+}
diff --git a/tests/compiler/dart2js/serialization/compilation2_test.dart b/tests/compiler/dart2js/serialization/compilation2_test.dart
new file mode 100644
index 0000000..6141cbb
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation2_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.compilation2_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['${TESTS.length ~/ 4}', '${2 * TESTS.length ~/ 4}']);
+}
diff --git a/tests/compiler/dart2js/serialization/compilation3_test.dart b/tests/compiler/dart2js/serialization/compilation3_test.dart
new file mode 100644
index 0000000..c168f22
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation3_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.compilation3_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['${2 * TESTS.length ~/ 4}', '${3 * TESTS.length ~/ 4}']);
+}
diff --git a/tests/compiler/dart2js/serialization/compilation4_test.dart b/tests/compiler/dart2js/serialization/compilation4_test.dart
new file mode 100644
index 0000000..7e2dc7c
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation4_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.compilation4_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['${3 * TESTS.length ~/ 4}']);
+}
diff --git a/tests/compiler/dart2js/serialization/compilation_test.dart b/tests/compiler/dart2js/serialization/compilation_test_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/serialization/compilation_test.dart
rename to tests/compiler/dart2js/serialization/compilation_test_helper.dart
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index e70b2ac..e5fab48 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -128,7 +128,7 @@
serializedData = new SerializedData(uri, file.readAsStringSync());
}
} else {
- SerializationResult result = await serialize(Uris.dart_core, uri);
+ SerializationResult result = await serialize(Uris.dart_core, dataUri: uri);
serializedData = result.serializedData;
}
if (arguments.saveSerializedData) {
@@ -146,11 +146,17 @@
SerializationResult(this.compiler, this.serializedData);
}
-Future<SerializationResult> serialize(Uri entryPoint, [Uri dataUri]) async {
+Future<SerializationResult> serialize(Uri entryPoint,
+ {Map<String, String> memorySourceFiles: const <String, String>{},
+ List<Uri> resolutionInputs: const <Uri>[],
+ Uri dataUri}) async {
if (dataUri == null) {
dataUri = Uri.parse('memory:${DEFAULT_DATA_FILE_NAME}');
}
- Compiler compiler = compilerFor(options: [Flags.analyzeAll]);
+ Compiler compiler = compilerFor(
+ options: [Flags.analyzeAll],
+ memorySourceFiles: memorySourceFiles,
+ resolutionInputs: resolutionInputs);
compiler.serialization.supportSerialization = true;
await compiler.run(entryPoint);
BufferedEventSink sink = new BufferedEventSink();
diff --git a/tests/compiler/dart2js/serialization/model1_test.dart b/tests/compiler/dart2js/serialization/model1_test.dart
new file mode 100644
index 0000000..9582274
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.model1_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['0', '${TESTS.length ~/ 2}']);
+}
diff --git a/tests/compiler/dart2js/serialization/model2_test.dart b/tests/compiler/dart2js/serialization/model2_test.dart
new file mode 100644
index 0000000..369e4a1
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model2_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.serialization.model2_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_data.dart';
+
+main() {
+ test.main(['${TESTS.length ~/ 2}']);
+}
diff --git a/tests/compiler/dart2js/serialization/model_test.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
similarity index 99%
rename from tests/compiler/dart2js/serialization/model_test.dart
rename to tests/compiler/dart2js/serialization/model_test_helper.dart
index 37b99df..2c6d861 100644
--- a/tests/compiler/dart2js/serialization/model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
library dart2js.serialization_model_test;
+
import 'dart:async';
import 'dart:io';
import 'package:async_helper/async_helper.dart';
diff --git a/tests/compiler/dart2js/serialization/reserialization_test.dart b/tests/compiler/dart2js/serialization/reserialization_test.dart
new file mode 100644
index 0000000..691bdab
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/reserialization_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for 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.reserialization_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/invariant.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:expect/expect.dart';
+import 'helper.dart';
+import 'test_helper.dart';
+import 'equivalence_test.dart';
+
+main(List<String> args) {
+ // Ensure that we can print out constant expressions.
+ DEBUG_MODE = true;
+
+ Arguments arguments = new Arguments.from(args);
+ Uri entryPoint;
+ if (arguments.filename != null) {
+ entryPoint = Uri.parse(arguments.filename);
+ } else {
+ entryPoint = Uri.parse('dart:core');
+ }
+ asyncTest(() async {
+ await testReserialization(entryPoint);
+ });
+}
+
+Future testReserialization(Uri entryPoint) async {
+ SerializationResult result1 = await serialize(entryPoint);
+ Compiler compiler1 = result1.compiler;
+ SerializedData serializedData1 = result1.serializedData;
+ Iterable<LibraryElement> libraries1 = compiler1.libraryLoader.libraries;
+
+ SerializationResult result2 = await serialize(entryPoint,
+ memorySourceFiles: serializedData1.toMemorySourceFiles(),
+ resolutionInputs: serializedData1.toUris());
+ Compiler compiler2 = result2.compiler;
+ SerializedData serializedData2 = result2.serializedData;
+ Iterable<LibraryElement> libraries2 = compiler2.libraryLoader.libraries;
+
+ SerializationResult result3 = await serialize(entryPoint,
+ memorySourceFiles: serializedData2.toMemorySourceFiles(),
+ resolutionInputs: serializedData2.toUris());
+ Compiler compiler3 = result3.compiler;
+ Iterable<LibraryElement> libraries3 = compiler3.libraryLoader.libraries;
+
+ for (LibraryElement library1 in libraries1) {
+ LibraryElement library2 = libraries2.firstWhere((LibraryElement library2) {
+ return library2.canonicalUri == library1.canonicalUri;
+ });
+ Expect.isNotNull(library2,
+ "No library found for ${library1.canonicalUri}.");
+ checkLibraryContent('library1', 'library2', 'library', library1, library2);
+
+ LibraryElement library3 = libraries3.firstWhere((LibraryElement library3) {
+ return library3.canonicalUri == library1.canonicalUri;
+ });
+ Expect.isNotNull(library3,
+ "No library found for ${library1.canonicalUri}.");
+ checkLibraryContent('library1', 'library3', 'library', library1, library3);
+ }
+
+ checkAllResolvedAsts(compiler1, compiler2);
+ checkAllResolvedAsts(compiler1, compiler3);
+
+ checkAllImpacts(compiler1, compiler2);
+ checkAllImpacts(compiler1, compiler3);
+}
diff --git a/tests/compiler/dart2js/serialization/resolved_ast_test.dart b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
index 4610076..d39f906 100644
--- a/tests/compiler/dart2js/serialization/resolved_ast_test.dart
+++ b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
@@ -55,39 +55,3 @@
checkAllResolvedAsts(compilerNormal, compilerDeserialized, verbose: true);
}
-
-void checkAllResolvedAsts(
- Compiler compiler1,
- Compiler compiler2,
- {bool verbose: false}) {
- checkLoadedLibraryMembers(
- compiler1,
- compiler2,
- (Element member1) {
- return member1 is ExecutableElement &&
- compiler1.resolution.hasResolvedAst(member1);
- },
- checkResolvedAsts,
- verbose: verbose);
-}
-
-
-/// Check equivalence of [impact1] and [impact2].
-void checkResolvedAsts(Compiler compiler1, Element member1,
- Compiler compiler2, Element member2,
- {bool verbose: false}) {
- if (!compiler2.serialization.isDeserialized(member2)) {
- return;
- }
- ResolvedAst resolvedAst1 = compiler1.resolution.getResolvedAst(member1);
- ResolvedAst resolvedAst2 = compiler2.serialization.getResolvedAst(member2);
-
- if (resolvedAst1 == null || resolvedAst2 == null) return;
-
- if (verbose) {
- print('Checking resolved asts for $member1 vs $member2');
- }
-
- testResolvedAstEquivalence(
- resolvedAst1, resolvedAst2, const CheckStrategy());
-}
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
index 87a580f..6dfa095 100644
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ b/tests/compiler/dart2js/serialization/test_data.dart
@@ -385,6 +385,75 @@
}
''',
}, expectedWarningCount: 1),
+
+ const Test('Unused noSuchMethod', const {
+ 'main.dart': '''
+import 'a.dart';
+
+main() {
+ new A().m();
+}
+''',
+ }, preserializedSourceFiles: const {
+ 'a.dart': '''
+class A {
+ noSuchMethod(_) => null;
+ m();
+}
+''',
+ }),
+
+ const Test('Malformed types', const {
+ 'main.dart': '''
+import 'a.dart';
+
+main() {
+ m();
+}
+''',
+ }, preserializedSourceFiles: const {
+ 'a.dart': '''
+Unresolved m() {}
+''',
+ }),
+
+ const Test('Function types for closures', const {
+ 'main.dart': '''
+import 'a.dart';
+
+typedef Func();
+
+main(args) {
+ (args.isEmpty ? new B() : new C()) is Func;
+}
+''',
+ }, preserializedSourceFiles: const {
+ 'a.dart': '''
+class B {
+ call(a) {}
+}
+class C {
+ call() {}
+}
+''',
+ }),
+
+ const Test('Double literal in constant constructor', const {
+ 'main.dart': '''
+import 'a.dart';
+
+main() {
+ const A(1.0);
+}
+''',
+ }, preserializedSourceFiles: const {
+ 'a.dart': '''
+class A {
+ final field1;
+ const A(a) : this.field1 = a + 1.0;
+}
+''',
+ }),
];
class Test {
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index a6dddf9..9d3115f 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -553,3 +553,39 @@
print(message);
}
}
+
+void checkAllResolvedAsts(
+ Compiler compiler1,
+ Compiler compiler2,
+ {bool verbose: false}) {
+ checkLoadedLibraryMembers(
+ compiler1,
+ compiler2,
+ (Element member1) {
+ return member1 is ExecutableElement &&
+ compiler1.resolution.hasResolvedAst(member1);
+ },
+ checkResolvedAsts,
+ verbose: verbose);
+}
+
+
+/// Check equivalence of [impact1] and [impact2].
+void checkResolvedAsts(Compiler compiler1, Element member1,
+ Compiler compiler2, Element member2,
+ {bool verbose: false}) {
+ if (!compiler2.serialization.isDeserialized(member2)) {
+ return;
+ }
+ ResolvedAst resolvedAst1 = compiler1.resolution.getResolvedAst(member1);
+ ResolvedAst resolvedAst2 = compiler2.serialization.getResolvedAst(member2);
+
+ if (resolvedAst1 == null || resolvedAst2 == null) return;
+
+ if (verbose) {
+ print('Checking resolved asts for $member1 vs $member2');
+ }
+
+ testResolvedAstEquivalence(
+ resolvedAst1, resolvedAst2, const CheckStrategy());
+}
diff --git a/tests/html/html.status b/tests/html/html.status
index 670665a..921c623 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -111,6 +111,7 @@
canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Skip # Times out. Please triage this failure.
transition_event_test/functional: Skip # Times out. Issue 22167
request_animation_frame_test: Skip # Times out. Issue 22167
+custom/*: Pass, Timeout # Issue 26789
[$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid ]
webgl_1_test: Pass, Fail # Issue 8219
diff --git a/tests/language/arg_param_trailing_comma_test.dart b/tests/language/arg_param_trailing_comma_test.dart
new file mode 100644
index 0000000..5c2c42a
--- /dev/null
+++ b/tests/language/arg_param_trailing_comma_test.dart
@@ -0,0 +1,401 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing params.
+
+// Convenience values.
+var c = new C();
+var x = 42;
+var y = 42;
+var z = 42;
+
+// Trailing comma in parameter litss.
+
+// Typedefs.
+typedef fx(x, ); /// none: ok
+typedef fy([y,]); /// none: continued
+typedef fxy(x, [y, ]); /// none: continued
+typedef fz({z,}); /// none: continued
+typedef fxz(x, {z, }); /// none: continued
+
+// As arguments type.
+argfx(void f(x, )) {} /// none: continued
+argfy(void f([y, ])) {} /// none: continued
+argfxy(void f(x, [y, ])) {} /// none: continued
+argfz(void f({z, })) {} /// none: continued
+argfxz(void f(x, {z, })) {} /// none: continued
+
+// Top level functions
+void topx(x,) {} /// none: continued
+void topy([y, ]) {} /// none: continued
+void topxy(x, [y, ]) {} /// none: continued
+void topz({z, }) {} /// none: continued
+void topxz(x, {z, }) {} /// none: continued
+
+void set topsetx(x, ) {} /// none: continued
+
+// After specific parameter formats.
+void afterDefaultValueY([int y = 42, ]) {} /// none: continued
+void afterDefaultValueZ({int z : 42, }) {} /// none: continued
+void afterFunsigX(void f(),) {} /// none: continued
+void afterFunsigY([void f(),]) {} /// none: continued
+void afterFunsigZ({void f(),}) {} /// none: continued
+void afterFunsigDefaultValueY([void f() = topy,]) {} /// none: continued
+void afterFunsigDefaultValueZ({void f() : topt,}) {} /// none: continued
+
+class C {
+ C();
+
+ // Constructors.
+ C.x(x, ); /// none: continued
+ C.y([y, ]); /// none: continued
+ C.xy(x, [y, ]); /// none: continued
+ C.z({z, }); /// none: continued
+ C.xz(x, {z, }); /// none: continued
+
+ // Static members
+ static void staticx(x,) {} /// none: continued
+ static void staticy([y, ]) {} /// none: continued
+ static void staticxy(x, [y, ]) {} /// none: continued
+ static void staticz({z, }) {} /// none: continued
+ static void staticxz(x, {z, }) {} /// none: continued
+
+ static void set staticsetx(x, ) {} /// none: continued
+
+ // Instance members
+ void instancex(x,) {} /// none: continued
+ void instancey([y, ]) {} /// none: continued
+ void instancexy(x, [y, ]) {} /// none: continued
+ void instancez({z, }) {} /// none: continued
+ void instancexz(x, {z, }) {} /// none: continued
+
+ void set instancesetx(x, ) {} /// none: continued
+
+ operator +(x, ) => this; /// none: continued
+ operator []=(x, y, ) {} /// none: continued
+}
+
+main(args, ) {
+ testCalls(); /// none: continued
+ // Make sure the Bad class is checked.
+ new Bad().method();
+}
+
+void testCalls() {
+ // Check that all functions can be called normally
+ topx(x); /// none: continued
+ topy(y); /// none: continued
+ topxy(x, y); /// none: continued
+ topz(); /// none: continued
+ topz(z: z); /// none: continued
+ topxz(x); /// none: continued
+ topxz(x, z: z); /// none: continued
+ topsetx = x; /// none: continued
+ afterDefaultValueY(); /// none: continued
+ afterDefaultValueY(y); /// none: continued
+ afterDefaultValueZ(); /// none: continued
+ afterDefaultValueZ(z: z); /// none: continued
+ new C.x(x); /// none: continued
+ new C.xy(x); /// none: continued
+ new C.xy(x, y); /// none: continued
+ new C.y(y); /// none: continued
+ new C.xz(x); /// none: continued
+ new C.xz(x, z: z); /// none: continued
+ new C.z(z: z); /// none: continued
+ C.staticx(x); /// none: continued
+ C.staticy(y); /// none: continued
+ C.staticxy(x); /// none: continued
+ C.staticxy(x, y); /// none: continued
+ C.staticz(); /// none: continued
+ C.staticz(z: z); /// none: continued
+ C.staticxz(x); /// none: continued
+ C.staticxz(x, z: z); /// none: continued
+ C.staticsetx = x; /// none: continued
+ c.instancex(x); /// none: continued
+ c.instancey(); /// none: continued
+ c.instancey(y); /// none: continued
+ c.instancexy(x); /// none: continued
+ c.instancexy(x, y); /// none: continued
+ c.instancez(); /// none: continued
+ c.instancez(z: z); /// none: continued
+ c.instancexz(x); /// none: continued
+ c.instancexz(x, z: z); /// none: continued
+ c.instancesetx = x; /// none: continued
+ c + x; /// none: continued
+ c[x] = y; /// none: continued
+
+ // Call with ekstra comma (not possible for setters and operators).
+ topx(x, ); /// none: continued
+ topy(y, ); /// none: continued
+ topxy(x, y, ); /// none: continued
+ topxy(x, ); /// none: continued
+ topz(z: z, ); /// none: continued
+ topxz(x, ); /// none: continued
+ topxz(x, z: z, ); /// none: continued
+ new C.x(x, ); /// none: continued
+ new C.xy(x, y, ); /// none: continued
+ new C.xy(x, ); /// none: continued
+ new C.y(y, ); /// none: continued
+ new C.xz(x, ); /// none: continued
+ new C.xz(x, z: z, ); /// none: continued
+ new C.z(z: z, ); /// none: continued
+ C.staticx(x, ); /// none: continued
+ C.staticy(y, ); /// none: continued
+ C.staticxy(x, y, ); /// none: continued
+ C.staticxy(x, ); /// none: continued
+ C.staticz(z: z, ); /// none: continued
+ C.staticxz(x, ); /// none: continued
+ C.staticxz(x, z: z, ); /// none: continued
+ c.instancex(x, ); /// none: continued
+ c.instancey(y, ); /// none: continued
+ c.instancexy(x, y, ); /// none: continued
+ c.instancexy(x, ); /// none: continued
+ c.instancez(z: z, ); /// none: continued
+ c.instancexz(x, ); /// none: continued
+ c.instancexz(x, z: z, ); /// none: continued
+
+ // Typedefs work as expected.
+ if (topx is! fx) throw "Bad type: $fx"; /// none: continued
+ if (topy is! fy) throw "Bad type: $fy"; /// none: continued
+ if (topxy is! fxy) throw "Bad type: $fxy"; /// none: continued
+ if (topz is! fz) throw "Bad type: $fz"; /// none: continued
+ if (topxz is! fxz) throw "Bad type: $fxz"; /// none: continued
+
+ // Parameter types work (checked mode only test).
+ argfx(topx); /// none: continued
+ argfy(topy); /// none: continued
+ argfxy(topxy); /// none: continued
+ argfz(topz); /// none: continued
+ argfxz(topxz); /// none: continued
+}
+
+
+// Invalid syntax. This was invalid syntax before the addition of trailing
+// commas too, and should stay that way.
+void topBadEmpty(,) {} /// 1: compile-time error
+void topBadStart(, a) {} /// 2: compile-time error
+void topBadEnd(a,,) {} /// 3: compile-time error
+void topBadMiddle(a,, b) {} /// 4: compile-time error
+void topBadPosEmpty([]) {} /// 5: compile-time error
+void topBadPosEmpty(,[]) {} /// 6: compile-time error
+void topBadPosEmpty([,]) {} /// 7: compile-time error
+void topBadPosEmpty([],) {} /// 8: compile-time error
+void topBadPosStart(,[a]) {} /// 9: compile-time error
+void topBadPosStart([, a]) {} /// 10: compile-time error
+void topBadPosEnd([a,,]) {} /// 11: compile-time error
+void topBadPosStart([a],) {} /// 12: compile-time error
+void topBadPosMiddle([a,, b]) {} /// 13: compile-time error
+void topBadNamEmpty({}) {} /// 14: compile-time error
+void topBadNamEmpty(,{}) {} /// 15: compile-time error
+void topBadNamEmpty({,}) {} /// 16: compile-time error
+void topBadNamEmpty({},) {} /// 17: compile-time error
+void topBadNamStart(,{a}) {} /// 18: compile-time error
+void topBadNamStart({, a}) {} /// 19: compile-time error
+void topBadNamEnd({a,,}) {} /// 20: compile-time error
+void topBadNamStart({a},) {} /// 21: compile-time error
+void topBadNamMiddle({a,, b}) {} /// 22: compile-time error
+void set topSetBadEmpty(,) {} /// 23: compile-time error
+void set topSetBadStart(, a) {} /// 24: compile-time error
+void set topSetBadEnd(a,,) {} /// 25: compile-time error
+void set topSetBadMiddle(a,, b) {} /// 26: compile-time error
+class Bad {
+ Bad.empty(,) {} /// 27: compile-time error
+ Bad.start(, a) {} /// 28: compile-time error
+ Bad.end(a,,) {} /// 29: compile-time error
+ Bad.middle(a,, b) {} /// 30: compile-time error
+ Bad.posEmpty([]) {} /// 31: compile-time error
+ Bad.posEmpty(,[]) {} /// 32: compile-time error
+ Bad.posEmpty([,]) {} /// 33: compile-time error
+ Bad.posEmpty([],) {} /// 34: compile-time error
+ Bad.posStart(,[a]) {} /// 35: compile-time error
+ Bad.posStart([, a]) {} /// 36: compile-time error
+ Bad.posEnd([a,,]) {} /// 37: compile-time error
+ Bad.posStart([a],) {} /// 38: compile-time error
+ Bad.PosMiddle([a,, b]) {} /// 39: compile-time error
+ Bad.namEmpty({}) {} /// 40: compile-time error
+ Bad.namEmpty(,{}) {} /// 41: compile-time error
+ Bad.namEmpty({,}) {} /// 42: compile-time error
+ Bad.namEmpty({},) {} /// 43: compile-time error
+ Bad.namStart(,{a}) {} /// 44: compile-time error
+ Bad.namStart({, a}) {} /// 45: compile-time error
+ Bad.namEnd({a,,}) {} /// 46: compile-time error
+ Bad.namStart({a},) {} /// 47: compile-time error
+ Bad.namMiddle({a,, b}) {} /// 48: compile-time error
+ static void staticBadEmpty(,) {} /// 49: compile-time error
+ static void staticBadStart(, a) {} /// 50: compile-time error
+ static void staticBadEnd(a,,) {} /// 51: compile-time error
+ static void staticBadMiddle(a,, b) {} /// 52: compile-time error
+ static void staticBadPosEmpty([]) {} /// 53: compile-time error
+ static void staticBadPosEmpty(,[]) {} /// 54: compile-time error
+ static void staticBadPosEmpty([,]) {} /// 55: compile-time error
+ static void staticBadPosEmpty([],) {} /// 56: compile-time error
+ static void staticBadPosStart(,[a]) {} /// 57: compile-time error
+ static void staticBadPosStart([, a]) {} /// 58: compile-time error
+ static void staticBadPosEnd([a,,]) {} /// 59: compile-time error
+ static void staticBadPosStart([a],) {} /// 60: compile-time error
+ static void staticBadPosMiddle([a,, b]) {} /// 61: compile-time error
+ static void staticBadNamEmpty({}) {} /// 62: compile-time error
+ static void staticBadNamEmpty(,{}) {} /// 63: compile-time error
+ static void staticBadNamEmpty({,}) {} /// 64: compile-time error
+ static void staticBadNamEmpty({},) {} /// 65: compile-time error
+ static void staticBadNamStart(,{a}) {} /// 66: compile-time error
+ static void staticBadNamStart({, a}) {} /// 67: compile-time error
+ static void staticBadNamEnd({a,,}) {} /// 68: compile-time error
+ static void staticBadNamStart({a},) {} /// 69: compile-time error
+ static void staticBadNamMiddle({a,, b}) {} /// 70: compile-time error
+ static void set staticSetBadEmpty(,) {} /// 71: compile-time error
+ static void set staticSetBadStart(, a) {} /// 72: compile-time error
+ static void set staticSetBadEnd(a,,) {} /// 73: compile-time error
+ static void set staticSetBadMiddle(a,, b) {} /// 74: compile-time error
+ void instanceBadEmpty(,) {} /// 75: compile-time error
+ void instanceBadStart(, a) {} /// 76: compile-time error
+ void instanceBadEnd(a,,) {} /// 77: compile-time error
+ void instanceBadMiddle(a,, b) {} /// 78: compile-time error
+ void instanceBadPosEmpty([]) {} /// 79: compile-time error
+ void instanceBadPosEmpty(,[]) {} /// 80: compile-time error
+ void instanceBadPosEmpty([,]) {} /// 81: compile-time error
+ void instanceBadPosEmpty([],) {} /// 82: compile-time error
+ void instanceBadPosStart(,[a]) {} /// 83: compile-time error
+ void instanceBadPosStart([, a]) {} /// 84: compile-time error
+ void instanceBadPosEnd([a,,]) {} /// 85: compile-time error
+ void instanceBadPosStart([a],) {} /// 86: compile-time error
+ void instanceBadPosMiddle([a,, b]) {} /// 87: compile-time error
+ void instanceBadNamEmpty({}) {} /// 88: compile-time error
+ void instanceBadNamEmpty(,{}) {} /// 89: compile-time error
+ void instanceBadNamEmpty({,}) {} /// 90: compile-time error
+ void instanceBadNamEmpty({},) {} /// 91: compile-time error
+ void instanceBadNamStart(,{a}) {} /// 92: compile-time error
+ void instanceBadNamStart({, a}) {} /// 93: compile-time error
+ void instanceBadNamEnd({a,,}) {} /// 94: compile-time error
+ void instanceBadNamStart({a},) {} /// 95: compile-time error
+ void instanceBadNamMiddle({a,, b}) {} /// 96: compile-time error
+ void set instanceSetBadEmpty(,) {} /// 97: compile-time error
+ void set instanceSetBadStart(, a) {} /// 98: compile-time error
+ void set instanceSetBadEnd(a,,) {} /// 99: compile-time error
+ void set instanceSetBadMiddle(a,, b) {} /// 100: compile-time error
+ void operator *(,); /// 101: compile-time error
+ void operator *(, a); /// 102: compile-time error
+ void operator *(a,,); /// 103: compile-time error
+ void operator []=(, a); /// 104: compile-time error
+ void operator []=(a,,); /// 105: compile-time error
+ void operator []=(a,, b); /// 106: compile-time error
+ void operator []=(a,); /// 107: compile-time error
+
+ method() {
+ // Local methods.
+ void localBadEmpty(,) {} /// 108: compile-time error
+ void localBadStart(, a) {} /// 109: compile-time error
+ void localBadEnd(a,,) {} /// 110: compile-time error
+ void localBadMiddle(a,, b) {} /// 111: compile-time error
+ void localBadPosEmpty([]) {} /// 112: compile-time error
+ void localBadPosEmpty(,[]) {} /// 113: compile-time error
+ void localBadPosEmpty([,]) {} /// 114: compile-time error
+ void localBadPosEmpty([],) {} /// 115: compile-time error
+ void localBadPosStart(,[a]) {} /// 116: compile-time error
+ void localBadPosStart([, a]) {} /// 117: compile-time error
+ void localBadPosEnd([a,,]) {} /// 118: compile-time error
+ void localBadPosStart([a],) {} /// 119: compile-time error
+ void localBadPosMiddle([a,, b]) {} /// 120: compile-time error
+ void localBadNamEmpty({}) {} /// 121: compile-time error
+ void localBadNamEmpty(,{}) {} /// 122: compile-time error
+ void localBadNamEmpty({,}) {} /// 123: compile-time error
+ void localBadNamEmpty({},) {} /// 124: compile-time error
+ void localBadNamStart(,{a}) {} /// 125: compile-time error
+ void localBadNamStart({, a}) {} /// 126: compile-time error
+ void localBadNamEnd({a,,}) {} /// 127: compile-time error
+ void localBadNamStart({a},) {} /// 128: compile-time error
+ void localBadNamMiddle({a,, b}) {} /// 129: compile-time error
+
+ // invalid calls.
+
+ topx(,); /// 130: compile-time error
+ topy(,); /// 131: compile-time error
+ topz(,); /// 132: compile-time error
+ topx(, x); /// 133: compile-time error
+ topz(, z:z); /// 134: compile-time error
+ topxy(x,, y); /// 135: compile-time error
+ topxz(x,, z:z); /// 136: compile-time error
+ topx(x,,); /// 137: compile-time error
+ topz(z:z,,); /// 138: compile-time error
+
+ new C.x(,); /// 139: compile-time error
+ new C.y(,); /// 140: compile-time error
+ new C.z(,); /// 141: compile-time error
+ new C.x(, x); /// 142: compile-time error
+ new C.z(, z:z); /// 143: compile-time error
+ new C.xy(x,, y); /// 144: compile-time error
+ new C.xz(x,, z:z); /// 145: compile-time error
+ new C.x(x,,); /// 146: compile-time error
+ new C.z(z:z,,); /// 147: compile-time error
+
+ C.staticx(,); /// 148: compile-time error
+ C.staticy(,); /// 149: compile-time error
+ C.staticz(,); /// 150: compile-time error
+ C.staticx(, x); /// 151: compile-time error
+ C.staticz(, z:z); /// 152: compile-time error
+ C.staticxy(x,, y); /// 153: compile-time error
+ C.staticxz(x,, z:z); /// 154: compile-time error
+ C.staticx(x,,); /// 155: compile-time error
+ C.staticz(z:z,,); /// 156: compile-time error
+
+ c.instancex(,); /// 157: compile-time error
+ c.instancey(,); /// 158: compile-time error
+ c.instancez(,); /// 159: compile-time error
+ c.instancex(, x); /// 160: compile-time error
+ c.instancez(, z:z); /// 161: compile-time error
+ c.instancexy(x,, y); /// 162: compile-time error
+ c.instancexz(x,, z:z); /// 163: compile-time error
+ c.instancex(x,,); /// 164: compile-time error
+ c.instancez(z:z,,); /// 165: compile-time error
+
+ c[x,] = y; /// 166: compile-time error
+ }
+
+ // As parameters:
+ void f(void topBadEmpty(,)) {} /// 167: compile-time error
+ void f(void topBadStart(, a)) {} /// 168: compile-time error
+ void f(void topBadEnd(a,,)) {} /// 169: compile-time error
+ void f(void topBadMiddle(a,, b)) {} /// 170: compile-time error
+ void f(void topBadPosEmpty([])) {} /// 171: compile-time error
+ void f(void topBadPosEmpty(,[])) {} /// 172: compile-time error
+ void f(void topBadPosEmpty([,])) {} /// 173: compile-time error
+ void f(void topBadPosEmpty([],)) {} /// 174: compile-time error
+ void f(void topBadPosStart(,[a])) {} /// 175: compile-time error
+ void f(void topBadPosStart([, a])) {} /// 176: compile-time error
+ void f(void topBadPosEnd([a,,])) {} /// 177: compile-time error
+ void f(void topBadPosStart([a],)) {} /// 178: compile-time error
+ void f(void topBadPosMiddle([a,, b])) {} /// 179: compile-time error
+ void f(void topBadNamEmpty({})) {} /// 180: compile-time error
+ void f(void topBadNamEmpty(,{})) {} /// 181: compile-time error
+ void f(void topBadNamEmpty({,})) {} /// 182: compile-time error
+ void f(void topBadNamEmpty({},)) {} /// 183: compile-time error
+ void f(void topBadNamStart(,{a})) {} /// 184: compile-time error
+ void f(void topBadNamStart({, a})) {} /// 185: compile-time error
+ void f(void topBadNamEnd({a,,})) {} /// 186: compile-time error
+ void f(void topBadNamStart({a},)) {} /// 187: compile-time error
+ void f(void topBadNamMiddle({a,, b})) {} /// 188: compile-time error
+}
+
+// As typedefs
+typedef void BadEmpty(,); /// 189: compile-time error
+typedef void BadStart(, a); /// 190: compile-time error
+typedef void BadEnd(a,,); /// 191: compile-time error
+typedef void BadMiddle(a,, b); /// 192: compile-time error
+typedef void BadPosEmpty([]); /// 193: compile-time error
+typedef void BadPosEmpty(,[]); /// 194: compile-time error
+typedef void BadPosEmpty([,]); /// 195: compile-time error
+typedef void BadPosEmpty([],); /// 196: compile-time error
+typedef void BadPosStart(,[a]); /// 197: compile-time error
+typedef void BadPosStart([, a]); /// 198: compile-time error
+typedef void BadPosEnd([a,,]); /// 199: compile-time error
+typedef void BadPosStart([a],); /// 200: compile-time error
+typedef void BadPosMiddle([a,, b]); /// 201: compile-time error
+typedef void BadNamEmpty({}); /// 202: compile-time error
+typedef void BadNamEmpty(,{}); /// 203: compile-time error
+typedef void BadNamEmpty({,}); /// 204: compile-time error
+typedef void BadNamEmpty({},); /// 205: compile-time error
+typedef void BadNamStart(,{a}); /// 206: compile-time error
+typedef void BadNamStart({, a}); /// 207: compile-time error
+typedef void BadNamEnd({a,,}); /// 208: compile-time error
+typedef void BadNamStart({a},); /// 209: compile-time error
+typedef void BadNamMiddle({a,, b}); /// 210: compile-time error
diff --git a/tests/language/initializing_formal_scope_test.dart b/tests/language/initializing_formal_scope_test.dart
new file mode 100644
index 0000000..dd85fad
--- /dev/null
+++ b/tests/language/initializing_formal_scope_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=--initializing-formal-access
+
+import "package:expect/expect.dart";
+
+// Duplicate definition checks for `this.x` will check the scopes associated
+// with the constructor, not all enclosing scopes; so this is not a conflict.
+var x;
+
+class A {
+ var x;
+ A(this.x) {
+ // In the body the field is in scope, not the initializing formal;
+ // so we can use the setter.
+ x += 1;
+ }
+}
+
+main() {
+ A a = new A(2);
+ Expect.equals(a.x, 3);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 77da565..e2bfc83 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,6 +5,8 @@
# This directory contains tests that are intended to show the
# current state of the language.
+arg_param_trailing_comma_test/none: Fail # Issue 26644
+
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) ]
tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
@@ -54,10 +56,10 @@
generic_methods_type_expression_test: CompiletimeError # Issue 25869
# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_capture_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_final_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_type_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
+initializing_formal_access_test: CompiletimeError # Issue 26656
+initializing_formal_capture_test: CompiletimeError # Issue 26656
+initializing_formal_final_test: CompiletimeError # Issue 26656
+initializing_formal_type_test: CompiletimeError # Issue 26656
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
@@ -109,10 +111,10 @@
generic_methods_type_expression_test: RuntimeError # Issue 25869
# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
-initializing_formal_capture_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
-initializing_formal_final_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
-initializing_formal_type_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
+initializing_formal_access_test: RuntimeError # Issue 26656
+initializing_formal_capture_test: RuntimeError # Issue 26656
+initializing_formal_final_test: RuntimeError # Issue 26656
+initializing_formal_type_test: RuntimeError # Issue 26656
config_import_test: Skip # Issue 26250
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 85801af..63ac9b5 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -513,8 +513,8 @@
generic_methods_type_expression_test: CompiletimeError # Issue 25868
# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_capture_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_final_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_promotion_test: StaticWarning # TODO(eernst): Create a suitable sdk issue.
-initializing_formal_type_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
+initializing_formal_access_test: CompiletimeError # Issue 26658
+initializing_formal_capture_test: CompiletimeError # Issue 26658
+initializing_formal_final_test: CompiletimeError # Issue 26658
+initializing_formal_promotion_test: StaticWarning # Issue 26658
+initializing_formal_type_test: CompiletimeError # Issue 26658
diff --git a/tests/standalone/io/bytes_builder_test.dart b/tests/standalone/io/bytes_builder_test.dart
new file mode 100644
index 0000000..7dd4909
--- /dev/null
+++ b/tests/standalone/io/bytes_builder_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
+main() {
+ for (var copying in [true, false]) {
+ var b;
+ testLength(n) {
+ Expect.equals(n, b.length);
+ if (n == 0) {
+ Expect.isTrue(b.isEmpty, "isEmpty: #${b.length}");
+ Expect.isFalse(b.isNotEmpty, "isNotEmpty: #${b.length}");
+ } else {
+ Expect.isTrue(b.isNotEmpty, "isNotEmpty: #${b.length}");
+ Expect.isFalse(b.isEmpty, "isEmpty: #${b.length}");
+ }
+ }
+
+ b = new BytesBuilder(copy: copying);
+ testLength(0);
+
+ b.addByte(0);
+ testLength(1);
+
+ b.add([1, 2, 3]);
+ testLength(4);
+
+ b.add(<int>[4, 5, 6]);
+ testLength(7);
+
+ b.add(new Uint8List.fromList([7, 8, 9]));
+ testLength(10);
+
+ b.add(new Uint16List.fromList([10, 11, 12]));
+ testLength(13);
+
+ var bytes = b.toBytes();
+ Expect.isTrue(bytes is Uint8List);
+ Expect.listEquals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], bytes);
+ testLength(13);
+
+ b.add("\x0d\x0e\x0f".codeUnits);
+ testLength(16);
+
+ bytes = b.takeBytes();
+ testLength(0);
+ Expect.isTrue(bytes is Uint8List);
+ Expect.listEquals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ bytes);
+
+ b.addByte(0);
+ testLength(1);
+
+ b.clear();
+ testLength(0);
+
+ b.addByte(0);
+ testLength(1);
+ }
+}
diff --git a/tests/standalone/io/socket_bind_test.dart b/tests/standalone/io/socket_bind_test.dart
index 084280d..f701f0c 100644
--- a/tests/standalone/io/socket_bind_test.dart
+++ b/tests/standalone/io/socket_bind_test.dart
@@ -66,22 +66,22 @@
bool addr2V6Only) async {
int freePort = await freeIPv4AndIPv6Port();
- asyncStart();
- return ServerSocket.bind(
- addr1, freePort, v6Only: addr1V6Only, shared: false).then((socket) {
+ var socket = await ServerSocket.bind(
+ addr1, freePort, v6Only: addr1V6Only, shared: false);
+
+ try {
Expect.isTrue(socket.port > 0);
- asyncStart();
- return ServerSocket.bind(
- addr2, freePort, v6Only: addr2V6Only, shared: false).then((socket2) {
+ var socket2 = await ServerSocket.bind(
+ addr2, freePort, v6Only: addr2V6Only, shared: false);
+ try {
Expect.equals(socket.port, socket2.port);
-
- return Future.wait([
- socket.close().whenComplete(asyncEnd),
- socket2.close().whenComplete(asyncEnd),
- ]);
- });
- });
+ } finally {
+ await socket2.close();
+ }
+ } finally {
+ await socket.close();
+ }
}
testListenCloseListenClose(String host) async {
@@ -120,16 +120,34 @@
return port;
}
+Future retry(Future fun(), {int maxCount: 10}) async {
+ for (int i = 0; i < maxCount; i++) {
+ try {
+ // If there is no exception this will simply return, otherwise we keep
+ // trying.
+ return await fun();
+ } catch (_) {}
+ print("Failed to execute test closure in attempt $i "
+ "(${maxCount - i} retries left).");
+ }
+ return await fun();
+}
+
main() async {
asyncStart();
- await testBindDifferentAddresses(InternetAddress.ANY_IP_V6,
- InternetAddress.ANY_IP_V4,
- true,
- false);
- await testBindDifferentAddresses(InternetAddress.ANY_IP_V4,
- InternetAddress.ANY_IP_V6,
- false,
- true);
+
+ await retry(() async {
+ await testBindDifferentAddresses(InternetAddress.ANY_IP_V6,
+ InternetAddress.ANY_IP_V4,
+ true,
+ false);
+ });
+ await retry(() async {
+ await testBindDifferentAddresses(InternetAddress.ANY_IP_V4,
+ InternetAddress.ANY_IP_V6,
+ false,
+ true);
+ });
for (var host in ['127.0.0.1', '::1']) {
testBindShared(host, false);
diff --git a/third_party/firefox_jsshell/README.google b/third_party/firefox_jsshell/README.google
index 08b90f8..7868748 100644
--- a/third_party/firefox_jsshell/README.google
+++ b/third_party/firefox_jsshell/README.google
@@ -1,8 +1,8 @@
Name: Firefox command line javascript shell.
Short Name: js-shell
-URL: http://ftp.mozilla.org/pub/mozilla.org/firefox/candidates/38-candidates/build2/
-Version: JavaScript-C38
-Date: May 05 2015
+URL: http://ftp.mozilla.org/pub/firefox/candidates/47.0-candidates/build2/
+Version: JavaScript-C47
+Date: June 3, 2016
License: MPL, http://www.mozilla.org/MPL
Description:
diff --git a/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1
index 8f8d719..1348fe9 100644
--- a/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1
+++ b/third_party/firefox_jsshell/linux/jsshell.tar.gz.sha1
@@ -1 +1 @@
-624241d790b53c24ea67997ed658f31f1ed9292d
\ No newline at end of file
+f44ede84757b76c86bc6dc8aee8f24699390623f
\ No newline at end of file
diff --git a/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1
index a5c645a..952f5cc 100644
--- a/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1
+++ b/third_party/firefox_jsshell/mac/jsshell.tar.gz.sha1
@@ -1 +1 @@
-16c59a086b713720df0154cd4ceaed2ee8cf0d33
\ No newline at end of file
+3d866ec4efe98698381671b25940b8ed1926ac4a
\ No newline at end of file
diff --git a/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1 b/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1
index d43fcd1..f8c7c1b 100644
--- a/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1
+++ b/third_party/firefox_jsshell/win/jsshell.tar.gz.sha1
@@ -1 +1 @@
-a7ed194f518813a9915f67026ef138dd96adfec1
\ No newline at end of file
+354b952f339d454fb89f2a8288f755d37eae6443
\ No newline at end of file
diff --git a/tools/VERSION b/tools/VERSION
index 67e5d05..954f2ea 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 18
PATCH 0
-PRERELEASE 2
+PRERELEASE 3
PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index fb3247f..220e6fc 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
vars.update({
"dartium_chromium_commit": "ef7d4ae18c646aea34c07a7ef62de7342c3b8c12",
- "dartium_webkit_commit": "bf1214d91e35290e9da29c9972640fc8c6825c81",
+ "dartium_webkit_commit": "e08c4cb1d7f1e16166f940d5dea59326c531d7b9",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index 76124f2..cacdd2a 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -4,10 +4,10 @@
library browser;
import "dart:async";
-import "dart:convert" show LineSplitter, UTF8, JSON;
+import "dart:convert" show UTF8, JSON;
import "dart:core";
import "dart:io";
-import "dart:math" show max, min;
+import "dart:math" show min;
import 'android.dart';
import 'http_server.dart';
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 8fa9bb7..c4be801 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -35,6 +35,11 @@
static Expectation SKIP_SLOW = byName('SkipSlow');
static Expectation SKIP_BY_DESIGN = byName('SkipByDesign');
+ // Can be returned by the test runner to say the result should be ignored,
+ // and assumed to meet the expectations, due to an infrastructure failure.
+ // Do not place in status files.
+ static Expectation IGNORE = byName('Ignore');
+
static Expectation byName(String name) {
_initialize();
name = name.toLowerCase();
@@ -77,6 +82,7 @@
build("SkipSlow", group: skip, isMetaExpectation: true);
build("Ok", isMetaExpectation: true);
build("Slow", isMetaExpectation: true);
+ build("Ignore");
}
}
@@ -94,6 +100,7 @@
bool canBeOutcomeOf(Expectation expectation) {
Expectation outcome = this;
+ if (outcome == IGNORE) return true;
while (outcome != null) {
if (outcome == expectation) {
return true;
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index b0e044c..ca3bfbe 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -31,6 +31,7 @@
new Path('third_party/pkg_tested'),
new Path('runtime/tests/vm'),
new Path('runtime/observatory/tests/service'),
+ new Path('runtime/observatory/tests/observatory_ui'),
new Path('samples'),
new Path('samples-dev'),
new Path('tests/benchmark_smoke'),
@@ -56,9 +57,6 @@
var firstConf = configurations[0];
var maxProcesses = firstConf['tasks'];
var progressIndicator = firstConf['progress'];
- // TODO(kustermann): Remove this option once the buildbots don't use it
- // anymore.
- var failureSummary = firstConf['failure-summary'];
BuildbotProgressIndicator.stepName = firstConf['step_name'];
var verbose = firstConf['verbose'];
var printTiming = firstConf['time'];
@@ -279,6 +277,7 @@
eventListener.add(new SummaryPrinter(jsonOnly: reportInJson));
} else {
eventListener.add(new ExitCodeSetter());
+ eventListener.add(new IgnoredTestMonitor());
}
// If any of the configurations need to access android devices we'll first
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 912ef75..7f44f3c 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -25,7 +25,8 @@
'lib',
'pkg',
'analyze_library',
- 'service'
+ 'service',
+ 'observatory_ui'
];
/**
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 3fdfbf3..b93294b 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -174,6 +174,31 @@
}
}
+class IgnoredTestMonitor extends EventListener {
+ static final int maxIgnored = 5;
+
+ int countIgnored = 0;
+
+ void done(TestCase test) {
+ if (test.lastCommandOutput.result(test) == Expectation.IGNORE) {
+ countIgnored++;
+ if (countIgnored > maxIgnored) {
+ print("/nMore than $maxIgnored tests were ignored due to flakes in");
+ print("the test infrastructure. Notify whesse@google.com.");
+ print("Output of the last ignored test was:");
+ print(_buildFailureOutput(test));
+ exit(1);
+ }
+ }
+ }
+
+ void allDone() {
+ if (countIgnored > 0) {
+ print("Ignored $countIgnored tests due to flaky infrastructure");
+ }
+ }
+}
+
class FlakyLogWriter extends EventListener {
void done(TestCase test) {
if (test.isFlaky && test.result != Expectation.PASS) {
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 3f755dd..132d0c6 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -355,9 +355,7 @@
final bool useBlobs;
AdbPrecompilationCommand._(this.precompiledRunnerFilename,
- this.precompiledTestDirectory,
- this.arguments,
- this.useBlobs)
+ this.precompiledTestDirectory, this.arguments, this.useBlobs)
: super._("adb_precompilation");
void _buildHashCode(HashCodeBuilder builder) {
@@ -376,7 +374,7 @@
precompiledTestDirectory == other.precompiledTestDirectory;
String toString() => 'Steps to push precompiled runner and precompiled code '
- 'to an attached device. Uses (and requires) adb.';
+ 'to an attached device. Uses (and requires) adb.';
}
class JSCommandlineCommand extends ProcessCommand {
@@ -466,8 +464,8 @@
String _destinationFile;
Map<String, Map> _dependencyOverrides;
- ModifyPubspecYamlCommand._(this._pubspecYamlFile,
- this._destinationFile, this._dependencyOverrides)
+ ModifyPubspecYamlCommand._(
+ this._pubspecYamlFile, this._destinationFile, this._dependencyOverrides)
: super._("modify_pubspec") {
assert(_pubspecYamlFile.endsWith("pubspec.yaml"));
assert(_destinationFile.endsWith("pubspec.yaml"));
@@ -667,9 +665,7 @@
}
AdbPrecompilationCommand getAdbPrecompiledCommand(String precompiledRunner,
- String testDirectory,
- List<String> arguments,
- bool useBlobs) {
+ String testDirectory, List<String> arguments, bool useBlobs) {
var command = new AdbPrecompilationCommand._(
precompiledRunner, testDirectory, arguments, useBlobs);
return _getUniqueCommand(command);
@@ -921,8 +917,9 @@
/**
* CommandOutput records the output of a completed command: the process's exit
* code, the standard output and standard error, whether the process timed out,
- * and the time the process took to run. It also contains a pointer to the
- * [TestCase] this is the output of.
+ * and the time the process took to run. It does not contain a pointer to the
+ * [TestCase] this is the output of, so some functions require the test case
+ * to be passed as an argument.
*/
abstract class CommandOutput {
Command get command;
@@ -974,7 +971,6 @@
*/
bool alreadyPrintedWarning = false;
- // TODO(kustermann): Remove testCase from this class.
CommandOutputImpl(
Command this.command,
int this.exitCode,
@@ -1040,7 +1036,7 @@
Expectation _negateOutcomeIfNegativeTest(
Expectation outcome, bool isNegative) {
if (!isNegative) return outcome;
-
+ if (outcome == Expectation.IGNORE) return outcome;
if (outcome.canBeOutcomeOf(Expectation.FAIL)) {
return Expectation.PASS;
}
@@ -1054,26 +1050,48 @@
// See: http://dartbug.com/15139.
static int WHITELISTED_CONTENTSHELL_EXITCODE = -1073740022;
static bool isWindows = io.Platform.operatingSystem == 'windows';
+ static bool _failedBecauseOfFlakyInfrastructure(List<int> stderrBytes) {
+ // If the browser test failed, it may have been because content shell
+ // and the virtual framebuffer X server didn't hook up, or it crashed with
+ // a core dump. Sometimes content shell crashes after it has set the stdout
+ // to PASS, so we have to do this check first.
+ // Content shell also fails with a broken pipe message: Issue 26739
+ var zygoteCrash =
+ new RegExp(r"ERROR:zygote_linux\.cc\(\d+\)] write: Broken pipe");
+ var stderr = decodeUtf8(stderrBytes);
+ // TODO(whesse): Issue: 7564
+ // This may not be happening anymore. Test by removing this suppression.
+ if (stderr.contains(MESSAGE_CANNOT_OPEN_DISPLAY) ||
+ stderr.contains(MESSAGE_FAILED_TO_RUN_COMMAND)) {
+ DebugLogger.warning(
+ "Warning: Failure because of missing XDisplay. Test ignored");
+ return true;
+ }
+ // Issue 26739
+ if (zygoteCrash.hasMatch(stderr)) {
+ DebugLogger.warning("Warning: Failure because of content_shell "
+ "zygote crash. Test ignored");
+ return true;
+ }
+ return false;
+ }
- bool _failedBecauseOfMissingXDisplay;
+ bool _infraFailure;
BrowserCommandOutputImpl(
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped)
: super(command, exitCode, timedOut, stdout, stderr, time,
- compilationSkipped, 0) {
- _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay();
- if (_failedBecauseOfMissingXDisplay) {
- DebugLogger.warning("Warning: Test failure because of missing XDisplay");
- // If we get the X server error, or DRT crashes with a core dump, retry
- // the test.
- }
- }
+ compilationSkipped, 0),
+ _infraFailure = _failedBecauseOfFlakyInfrastructure(stderr);
Expectation result(TestCase testCase) {
// Handle crashes and timeouts first
if (hasCrashed) return Expectation.CRASH;
if (hasTimedOut) return Expectation.TIMEOUT;
+ if (_infraFailure) {
+ return Expectation.IGNORE;
+ }
var outcome = _getOutcome();
if (testCase.hasRuntimeError) {
@@ -1091,8 +1109,8 @@
bool get successful => canRunDependendCommands;
bool get canRunDependendCommands {
- // We cannot rely on the exit code of content_shell as a method to determine
- // if we were successful or not.
+ // We cannot rely on the exit code of content_shell as a method to
+ // determine if we were successful or not.
return super.canRunDependendCommands && !didFail(null);
}
@@ -1101,34 +1119,12 @@
}
Expectation _getOutcome() {
- if (_failedBecauseOfMissingXDisplay) {
- return Expectation.FAIL;
- }
-
if (_browserTestFailure) {
return Expectation.RUNTIME_ERROR;
}
return Expectation.PASS;
}
- bool _didFailBecauseOfMissingXDisplay() {
- // Browser case:
- // If the browser test failed, it may have been because content shell
- // and the virtual framebuffer X server didn't hook up, or it crashed with
- // a core dump. Sometimes content shell crashes after it has set the stdout
- // to PASS, so we have to do this check first.
- var stderrLines = decodeUtf8(super.stderr).split("\n");
- for (String line in stderrLines) {
- // TODO(kustermann,ricow): Issue: 7564
- // This seems to happen quite frequently, we need to figure out why.
- if (line.contains(MESSAGE_CANNOT_OPEN_DISPLAY) ||
- line.contains(MESSAGE_FAILED_TO_RUN_COMMAND)) {
- return true;
- }
- }
- return false;
- }
-
bool get _rendererCrashed =>
decodeUtf8(super.stdout).contains("#CRASHED - rendere");
@@ -1334,13 +1330,6 @@
factory BrowserControllerTestOutcome(
Command command, BrowserTestOutput result) {
- void validate(String assertion, bool value) {
- if (!value) {
- throw "InvalidFormat sent from browser driving page: $assertion:\n\n"
- "${result.lastKnownMessage}";
- }
- }
-
String indent(String string, int numSpaces) {
var spaces = new List.filled(numSpaces, ' ').join('');
return string
@@ -1374,11 +1363,7 @@
stderr = "This test timed out. The delay until the test actually "
"started was: ${result.delayUntilTestStarted}.";
} else {
- // TODO(ricow/kustermann) as soon as we record the state periodically,
- // we will have more information and can remove this warning.
- stderr = "This test has not notified test.py that it started running. "
- "This could be a bug in test.py! "
- "Please contact ricow/whesse";
+ stderr = "This test has not notified test.py that it started running.";
}
}
@@ -1583,7 +1568,15 @@
Expectation result(TestCase testCase) {
// Handle general crash/timeout detection.
if (hasCrashed) return Expectation.CRASH;
- if (hasTimedOut) return Expectation.TIMEOUT;
+ if (hasTimedOut) {
+ bool isWindows = io.Platform.operatingSystem == 'windows';
+ bool isBrowserTestCase =
+ testCase.commands.any((command) => command is BrowserTestCommand);
+ // TODO(26060) Dart2js batch mode hangs on Windows under heavy load.
+ return (isWindows && isBrowserTestCase)
+ ? Expectation.IGNORE
+ : Expectation.TIMEOUT;
+ }
// Handle dart2js specific crash detection
if (exitCode == DART2JS_EXITCODE_CRASH ||
@@ -2533,8 +2526,8 @@
} else if (command is AdbPrecompilationCommand) {
assert(adbDevicePool != null);
return adbDevicePool.acquireDevice().then((AdbDevice device) {
- return _runAdbPrecompilationCommand(
- device, command, timeout).whenComplete(() {
+ return _runAdbPrecompilationCommand(device, command, timeout)
+ .whenComplete(() {
adbDevicePool.releaseDevice(device);
});
});
@@ -2565,35 +2558,36 @@
// All closures are of type "Future<AdbCommandResult> run()"
List<Function> steps = [];
- steps.add(() => device.runAdbShellCommand(
- ['rm', '-Rf', deviceTestDir]));
- steps.add(() => device.runAdbShellCommand(
- ['mkdir', '-p', deviceTestDir]));
+ steps.add(() => device.runAdbShellCommand(['rm', '-Rf', deviceTestDir]));
+ steps.add(() => device.runAdbShellCommand(['mkdir', '-p', deviceTestDir]));
// TODO: We should find a way for us to cache the runner binary and avoid
// pushhing it for every single test (this is bad for SSD cycle time, test
// timing).
steps.add(() => device.runAdbCommand(
- ['push', runner, '$devicedir/dart_precompiled_runtime']));
+ ['push', runner, '$devicedir/dart_precompiled_runtime']));
steps.add(() => device.runAdbShellCommand(
- ['chmod', '777', '$devicedir/dart_precompiled_runtime']));
+ ['chmod', '777', '$devicedir/dart_precompiled_runtime']));
for (var file in files) {
- steps.add(() => device.runAdbCommand(
- ['push', '$testdir/$file', '$deviceTestDir/$file']));
+ steps.add(() => device
+ .runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file']));
}
if (command.useBlobs) {
steps.add(() => device.runAdbShellCommand(
- ['$devicedir/dart_precompiled_runtime',
- '--run-app-snapshot=$deviceTestDir',
- '--use-blobs']..addAll(arguments),
- timeout: timeoutDuration));
+ [
+ '$devicedir/dart_precompiled_runtime',
+ '--run-app-snapshot=$deviceTestDir',
+ '--use-blobs'
+ ]..addAll(arguments),
+ timeout: timeoutDuration));
} else {
steps.add(() => device.runAdbShellCommand(
- ['$devicedir/dart_precompiled_runtime',
- '--run-app-snapshot=$deviceTestDir'
- ]..addAll(arguments),
- timeout: timeoutDuration));
+ [
+ '$devicedir/dart_precompiled_runtime',
+ '--run-app-snapshot=$deviceTestDir'
+ ]..addAll(arguments),
+ timeout: timeoutDuration));
}
var stopwatch = new Stopwatch()..start();
@@ -2623,9 +2617,8 @@
// immediately.
if (result.exitCode != 0) break;
}
- return createCommandOutput(
- command, result.exitCode, result.timedOut, UTF8.encode('$writer'),
- [], stopwatch.elapsed, false);
+ return createCommandOutput(command, result.exitCode, result.timedOut,
+ UTF8.encode('$writer'), [], stopwatch.elapsed, false);
}
BatchRunnerProcess _getBatchRunner(String identifier) {
@@ -2981,8 +2974,8 @@
executor = new ReplayingCommandExecutor(new Path(recordedInputFile));
} else {
executor = new CommandExecutorImpl(
- _globalConfiguration, maxProcesses,
- maxBrowserProcesses, adbDevicePool: adbDevicePool);
+ _globalConfiguration, maxProcesses, maxBrowserProcesses,
+ adbDevicePool: adbDevicePool);
}
// Run "runnable commands" using [executor] subject to
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index ce30a73..c73dc7c 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -2394,6 +2394,8 @@
static List<String> getExtraVmOptions(Map configuration) =>
getExtraOptions(configuration, 'vm_options');
+ static int shortNameCounter = 0; // Make unique short file names on Windows.
+
static String getShortName(String path) {
final PATH_REPLACEMENTS = const {
"pkg_polymer_e2e_test_bad_import_test": "polymer_bi",
@@ -2457,6 +2459,7 @@
}
path = path.replaceAll('/', '_');
final int WINDOWS_SHORTEN_PATH_LIMIT = 58;
+ final int WINDOWS_PATH_END_LENGTH = 30;
if (Platform.operatingSystem == 'windows' &&
path.length > WINDOWS_SHORTEN_PATH_LIMIT) {
for (var key in PATH_REPLACEMENTS.keys) {
@@ -2465,6 +2468,11 @@
break;
}
}
+ if (path.length > WINDOWS_SHORTEN_PATH_LIMIT) {
+ ++shortNameCounter;
+ var pathEnd = path.substring(path.length - WINDOWS_PATH_END_LENGTH);
+ path = "short${shortNameCounter}_$pathEnd";
+ }
}
return path;
}