Version 2.0.0-dev.15.0
Merge 220a91122a304cefcef98d0a4d75d54b78e90899 into dev
diff --git a/.packages b/.packages
index d559cca..1f0b101 100644
--- a/.packages
+++ b/.packages
@@ -45,6 +45,7 @@
http:third_party/pkg/http/lib
http_multi_server:third_party/pkg/http_multi_server/lib
http_parser:third_party/pkg/http_parser/lib
+http_retry:third_party/pkg/http_retry/lib
http_throttle:third_party/pkg/http_throttle/lib
intl:third_party/pkg/intl/lib
isolate:third_party/pkg/isolate/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9941193..4a385e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -122,59 +122,93 @@
}
```
-* Pub
+#### Pub
- * Git dependencies may now include a `path` parameter, indicating that the
- package exists in a subdirectory of the Git repository. For example:
+##### SDK Constraints
- ```yaml
- dependencies:
- foobar:
- git:
- url: git://github.com/dart-lang/multi_package_repo
- path: pkg/foobar
- ```
+There is now a default SDK constraint of `<2.0.0` for any package with no
+existing upper bound. This allows us to move more safely to 2.0.0. All new
+packages published on pub will now require an upper bound SDK constraint so
+future major releases of Dart don't destabilize the package ecosystem.
- * `pub get` and `pub upgrade` properly produce an error message and exit code
- when no network is present.
+All SDK constraint exclusive upper bounds are now treated as though they allow
+pre-release versions of that upper bound. For example, the SDK constraint
+`>=1.8.0 <2.0.0` now allows pre-release SDK versions such as `2.0.0-beta.3.0`.
+This allows early adopters to try out packages that don't explicitly declare
+support for the new version yet. You can disable this functionality by setting
+the `PUB_ALLOW_PRERELEASE_SDK` environment variable to `false`.
- * `pub serve` now waits for file watcher events to stabilize before scheduling
- new builds. This helps specifically with `safe-write` features in editors,
- as well as other situations such as `save all` which cause many fast edits.
+##### Other Features
- * Added the `--build-delay` argument to `pub serve` which sets the amount of
- time (in ms) to wait between file watcher events before scheduling a build.
- Defaults to 50.
+* Git dependencies may now include a `path` parameter, indicating that the
+ package exists in a subdirectory of the Git repository. For example:
- * Removed require.js module loading timeout for dartdevc, which resolves an
- issue where the initial load of an app might give a timeout error.
+ ```yaml
+ dependencies:
+ foobar:
+ git:
+ url: git://github.com/dart-lang/multi_package_repo
+ path: pkg/foobar
+ ```
- * There is now a default SDK constraint of `<2.0.0` for any package with
- no existing upper bound. This allows us to move more safely to 2.0.0.
+* Added an `--executables` option to `pub deps` command. This will list all
+ available executables that can be run with `pub run`.
- * All new packages published on pub will now require an upper bound SDK
- constraint so future major releases of Dart don't destabilize the package
- ecosystem.
+* Added a `PUB_MAX_WORKERS_PER_TASK` environment variable which can be set to
+ configure the number of dartdevc/analyzer workers that are used when compiling
+ with `--web-compiler=dartdevc`.
- * When on a pre-release SDK build, all upper bounds matching exactly the
- current SDK version but with no pre-release or build modifier will be
- upgraded to be <= the current SDK version. This allows early adopters to
- try out packages that don't explicitly declare support yet. You can disable
- this functionality by setting the PUB_ALLOW_PRERELEASE_SDK system
- environment variable to `false`.
+* Pub will now automatically retry HTTP requests that fail with a 502, 503, of
+ 504 error code ([issue 1556][pub#1556]).
- * Added `--executables` option to `pub deps` command. This will list all
- available executables that can be run with `pub run`.
+* Emit exit code 66 when a path dependency doesn't exist ([issue 1747][pub#1747]).
- * Fixed https://github.com/dart-lang/pub/issues/1684 so root package analysis
- options are not enforced for dependencies when compiling with dartdevc.
+[pub#1556]: https://github.com/dart-lang/pub/issues/1556
+[pub#1747]: https://github.com/dart-lang/pub/issues/1747
- * Fixed https://github.com/dart-lang/sdk/issues/30246 so you can include dart
- scripts from subdirectories with dartdevc.
+##### Bug Fixes
- * Added a PUB_MAX_WORKERS_PER_TASK system environment variable which can be
- set to configure the number of dartdevc/analyzer workers that are used
- when compiling with --web-compiler=dartdevc.
+* Added a `--build-delay` argument to `pub serve` which sets the amount of time
+ (in ms) to wait between file watcher events before scheduling a build.
+ Defaults to 50.
+
+* `pub get` and `pub upgrade` properly produce an error message and exit code
+ when no network is present.
+
+* `pub serve` now waits for file watcher events to stabilize before scheduling
+ new builds. This helps specifically with `safe-write` features in editors,
+ as well as other situations such as `save all` which cause many fast edits.
+
+* Removed the require.js module loading timeout for dartdevc, which resolves an
+ issue where the initial load of an app might give a timeout error.
+
+* Root package analysis options are no longer enforced for dependencies when
+ compiling with dartdevc ([issue 1684][pub#1684]).
+
+* Dart scripts can be included from subdirectories with dartdevc
+ ([issue 30246][]).
+
+* The `barback` infrastructure now supports `async` 2.0.0.
+
+* Print a more informative error message when the Flutter SDK isn't
+ available ([issue 1719][pub#1719]).
+
+* Don't crash when publishing a package that contains an empty submodule
+ ([issue 1679][pub#1679]).
+
+* Emit exit code 69 for TLS errors ([issue 1729][pub#1729]).
+
+* Fix `pub global run` for packages activated from a local path that also have
+ relative path dependencies ([issue 1751][pub#1751]).
+
+[pub#1684]: https://github.com/dart-lang/pub/issues/1684
+[pub#1719]: https://github.com/dart-lang/pub/issues/1719
+[pub#1679]: https://github.com/dart-lang/pub/issues/1679
+[pub#1729]: https://github.com/dart-lang/pub/issues/1729
+[pub#1751]: https://github.com/dart-lang/pub/issues/1751
+[issue 30246]: https://github.com/dart-lang/sdk/issues/30246
+
+#### Other Tools
* dartfmt
diff --git a/DEPS b/DEPS
index 642a59a..6f4f5f2 100644
--- a/DEPS
+++ b/DEPS
@@ -84,6 +84,7 @@
"html_tag" : "@0.13.2",
"http_multi_server_tag" : "@2.0.4",
"http_parser_tag" : "@3.1.1",
+ "http_retry_tag": "@0.1.0",
"http_tag" : "@0.11.3+14",
"http_throttle_tag" : "@1.0.1",
"idl_parser_rev": "@7fbe68cab90c38147dee4f48c30ad0d496c17915",
@@ -107,13 +108,13 @@
"ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
"pool_tag": "@1.3.3",
"protobuf_tag": "@0.5.4",
- "pub_rev": "@cde958f157d3662bf968bcbed05580d5c0355e89",
+ "pub_rev": "@667281eef93b4be648cceca400e954e000edba38",
"pub_semver_tag": "@1.3.2",
"quiver_tag": "@0.25.0",
"resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
"root_certificates_rev": "@a4c7c6f23a664a37bc1b6f15a819e3f2a292791a",
"scheduled_test_tag": "@0.12.11+1",
- "shelf_static_tag": "@0.2.5",
+ "shelf_static_rev": "@3558aa35a0d2f0f35868c3fd64b258e140db0122",
"shelf_packages_handler_tag": "@1.0.3",
"shelf_tag": "@0.7.1",
"shelf_web_socket_tag": "@0.2.2",
@@ -227,6 +228,9 @@
Var("http_multi_server_tag"),
Var("dart_root") + "/third_party/pkg/http_parser":
Var("github_mirror") + "http_parser.git" + Var("http_parser_tag"),
+ Var("dart_root") + "/third_party/pkg/http_retry":
+ Var("github_mirror") + "http_retry.git" +
+ Var("http_retry_tag"),
Var("dart_root") + "/third_party/pkg/http_throttle":
Var("github_mirror") + "http_throttle.git" +
Var("http_throttle_tag"),
@@ -289,7 +293,7 @@
Var("github_mirror") + "shelf_packages_handler.git"
+ Var("shelf_packages_handler_tag"),
Var("dart_root") + "/third_party/pkg/shelf_static":
- Var("github_mirror") + "shelf_static.git" + Var("shelf_static_tag"),
+ Var("github_mirror") + "shelf_static.git" + Var("shelf_static_rev"),
Var("dart_root") + "/third_party/pkg/shelf_web_socket":
Var("github_mirror") + "shelf_web_socket.git" +
Var("shelf_web_socket_tag"),
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 2df2b21..bd4e9c9 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -387,6 +387,7 @@
contextManager = new ContextManagerImpl(
resourceProvider,
+ fileContentOverlay,
sdkManager,
packageResolverProvider,
packageMapProvider,
@@ -442,7 +443,8 @@
'**/*.${AnalysisEngine.SUFFIX_HTML}',
'**/*.${AnalysisEngine.SUFFIX_HTM}',
'**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
- '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
+ '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
+ '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
];
for (String pattern in patterns) {
try {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 8892823..9fca4c5 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -21,6 +21,7 @@
import 'package:analyzer/source/sdk_ext.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -28,10 +29,12 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer/src/util/yaml.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgfile show parse;
@@ -432,6 +435,11 @@
final ResourceProvider resourceProvider;
/**
+ * The file content overlay.
+ */
+ final FileContentOverlay fileContentOverlay;
+
+ /**
* The manager used to access the SDK that should be associated with a
* particular context.
*/
@@ -522,6 +530,7 @@
ContextManagerImpl(
this.resourceProvider,
+ this.fileContentOverlay,
this.sdkManager,
this.packageResolverProvider,
this._packageMapProvider,
@@ -885,19 +894,54 @@
* options file at the given [path].
*/
void _analyzeAnalysisOptionsFile(AnalysisDriver driver, String path) {
- String content = driver.fsState.getFileForPath(path).content;
- List<AnalysisError> errors =
- GenerateOptionsErrorsTask.analyzeAnalysisOptions(
- resourceProvider.getFile(path).createSource(),
- content,
- driver.sourceFactory);
- AnalyzerConverter converter = new AnalyzerConverter();
- LineInfo lineInfo = _computeLineInfo(content);
+ List<protocol.AnalysisError> convertedErrors;
+ try {
+ String content = _readFile(path);
+ LineInfo lineInfo = _computeLineInfo(content);
+ List<AnalysisError> errors =
+ GenerateOptionsErrorsTask.analyzeAnalysisOptions(
+ resourceProvider.getFile(path).createSource(),
+ content,
+ driver.sourceFactory);
+ AnalyzerConverter converter = new AnalyzerConverter();
+ convertedErrors = converter.convertAnalysisErrors(errors,
+ lineInfo: lineInfo, options: driver.analysisOptions);
+ } catch (exception) {
+ // If the file cannot be analyzed, fall through to clear any previous
+ // errors.
+ }
callbacks.notificationManager.recordAnalysisErrors(
NotificationManager.serverId,
path,
- converter.convertAnalysisErrors(errors,
- lineInfo: lineInfo, options: driver.analysisOptions));
+ convertedErrors ?? <protocol.AnalysisError>[]);
+ }
+
+ /**
+ * Use the given analysis [driver] to analyze the content of the pubspec file
+ * at the given [path].
+ */
+ void _analyzePubspecFile(AnalysisDriver driver, String path) {
+ List<protocol.AnalysisError> convertedErrors;
+ try {
+ String content = _readFile(path);
+ YamlNode node = loadYamlNode(content);
+ if (node is YamlMap) {
+ PubspecValidator validator = new PubspecValidator(
+ resourceProvider, resourceProvider.getFile(path).createSource());
+ LineInfo lineInfo = _computeLineInfo(content);
+ List<AnalysisError> errors = validator.validate(node.nodes);
+ AnalyzerConverter converter = new AnalyzerConverter();
+ convertedErrors = converter.convertAnalysisErrors(errors,
+ lineInfo: lineInfo, options: driver.analysisOptions);
+ }
+ } catch (exception) {
+ // If the file cannot be analyzed, fall through to clear any previous
+ // errors.
+ }
+ callbacks.notificationManager.recordAnalysisErrors(
+ NotificationManager.serverId,
+ path,
+ convertedErrors ?? <protocol.AnalysisError>[]);
}
void _checkForAnalysisOptionsUpdate(
@@ -941,6 +985,20 @@
}
}
+ void _checkForPubspecUpdate(
+ String path, ContextInfo info, ChangeType changeType) {
+ if (_isPubspec(path)) {
+ AnalysisDriver driver = info.analysisDriver;
+ if (driver == null) {
+ // I suspect that this happens as a result of a race condition: server
+ // has determined that the file (at [path]) is in a context, but hasn't
+ // yet created a driver for that context.
+ return;
+ }
+ _analyzePubspecFile(driver, path);
+ }
+ }
+
/**
* Compute the set of files that are being flushed, this is defined as
* the set of sources in the removed context (context.sources), that are
@@ -1107,6 +1165,10 @@
if (optionsFile != null) {
_analyzeAnalysisOptionsFile(info.analysisDriver, optionsFile.path);
}
+ File pubspecFile = folder.getChildAssumingFile(PUBSPEC_NAME);
+ if (pubspecFile.exists) {
+ _analyzePubspecFile(info.analysisDriver, pubspecFile.path);
+ }
return info;
}
@@ -1425,6 +1487,7 @@
}
_checkForPackagespecUpdate(path, info, info.folder);
_checkForAnalysisOptionsUpdate(path, info, type);
+ _checkForPubspecUpdate(path, info, type);
}
/**
@@ -1515,6 +1578,15 @@
}
}
+ /**
+ * Read the contents of the file at the given [path], or throw an exception if
+ * the contents cannot be read.
+ */
+ String _readFile(String path) {
+ return fileContentOverlay[path] ??
+ resourceProvider.getFile(path).readAsStringSync();
+ }
+
Packages _readPackagespec(File specFile) {
try {
String contents = specFile.readAsStringSync();
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 4667311..2e80f58 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -48,6 +48,12 @@
: this.request = request,
this.entity = request.target.entity;
+ Token get droppedToken => request.target.droppedToken;
+
+ bool isEmptyBody(FunctionBody body) =>
+ body is EmptyFunctionBody ||
+ (body is BlockFunctionBody && body.beginToken.isSynthetic);
+
@override
visitArgumentList(ArgumentList node) {
if (request is DartCompletionRequestImpl) {
@@ -150,7 +156,7 @@
_addClassBodyKeywords();
int index = node.members.indexOf(entity);
ClassMember previous = index > 0 ? node.members[index - 1] : null;
- if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
+ if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
_addSuggestion(Keyword.ASYNC);
_addSuggestion2(ASYNC_STAR);
_addSuggestion2(SYNC_STAR);
@@ -202,7 +208,7 @@
if (entity == null || entity is Declaration) {
if (previousMember is FunctionDeclaration &&
previousMember.functionExpression is FunctionExpression &&
- previousMember.functionExpression.body is EmptyFunctionBody) {
+ isEmptyBody(previousMember.functionExpression.body)) {
_addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH);
_addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
_addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
@@ -335,6 +341,23 @@
}
@override
+ visitParenthesizedExpression(ParenthesizedExpression node) {
+ Expression expression = node.expression;
+ if (expression is Identifier || expression is PropertyAccess) {
+ if (entity == node.rightParenthesis) {
+ var next = expression.endToken.next;
+ if (next == entity || next == droppedToken) {
+ // Fasta parses `if (x i^)` as `if (x ^) where the `i` is in the token
+ // stream but not part of the ParenthesizedExpression.
+ _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+ return;
+ }
+ }
+ }
+ _addExpressionKeywords(node);
+ }
+
+ @override
visitIfStatement(IfStatement node) {
if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) {
// Actual: if (x i^)
@@ -390,7 +413,7 @@
@override
visitMethodDeclaration(MethodDeclaration node) {
if (entity == node.body) {
- if (node.body is EmptyFunctionBody) {
+ if (isEmptyBody(node.body)) {
_addClassBodyKeywords();
_addSuggestion(Keyword.ASYNC);
_addSuggestion2(ASYNC_STAR);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 22aa8ee..9c10cdb 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -19,6 +19,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
/**
* Checks if creating a method with the given [name] in [classElement] will
@@ -270,7 +271,9 @@
// Check local elements that might shadow the reference.
var localElements = await getLocalElements(match.element);
for (LocalElement localElement in localElements) {
- if (localElement.visibleRange.intersects(match.sourceRange)) {
+ SourceRange elementRange = localElement.visibleRange;
+ if (elementRange != null &&
+ elementRange.intersects(match.sourceRange)) {
return new _MatchShadowedByLocal(match, localElement);
}
}
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 431f5ed..af094d1 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -46,12 +46,12 @@
test_errorInPart() async {
String libPath = '$testFolder/main.dart';
String partPath = '$testFolder/main_part.dart';
- addFile(libPath, r'''
+ newFile(libPath, content: r'''
library main;
part 'main_part.dart';
class A {}
''');
- addFile(partPath, r'''
+ newFile(partPath, content: r'''
part of main;
class A {}
''');
@@ -77,7 +77,7 @@
test_fileWithoutContext() {
// Broken under the new driver.
String file = '/outside.dart';
- addFile(file, '''
+ newFile(file, content: '''
main() {
print(42);
}
@@ -124,7 +124,7 @@
Request request = _createGetErrorsRequest(testFile);
server.handleRequest(request);
// remove context, causes sending an "invalid file" error
- resourceProvider.deleteFolder(projectPath);
+ deleteFolder(projectPath);
// wait for an error response
Response response = await serverChannel.waitForResponse(request);
expect(response.error, isNotNull);
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 6df1179..85945fc 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -55,7 +55,7 @@
}
test_fileOutsideOfRoot() async {
- testFile = '/outside.dart';
+ testFile = resourceProvider.convertPath('/outside.dart');
addTestFile('''
main() {
var test = 0;
@@ -198,7 +198,7 @@
server.handleRequest(request);
// remove context, causes sending an "invalid file" error
{
- Folder projectFolder = resourceProvider.getResource(projectPath);
+ Folder projectFolder = getFolder(projectPath);
server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
}
// wait for an error response
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 4293c6c..4fc4eb1 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -43,11 +43,7 @@
List<AnalysisError> get testFileErrors => filesErrors[testFile];
void addOptionsFile(String contents) {
- addFile(optionsFilePath, contents);
- }
-
- void deleteFile(String filePath) {
- resourceProvider.deleteFile(filePath);
+ newFile(optionsFilePath, content: contents);
}
@override
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index c7a1196..8cfbfad 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -73,9 +73,7 @@
}
test_beforeAnalysis_excludeYamlFiles() async {
- File yamlFile = resourceProvider
- .getFolder(projectPath)
- .getChildAssumingFile('sample.yaml');
+ File yamlFile = getFolder(projectPath).getChildAssumingFile('sample.yaml');
yamlFile.writeAsStringSync('');
addTestFile('''
class A {}
@@ -117,7 +115,7 @@
// Making a change that *does* affect the set of reachable files should
// trigger the notification to be re-sent.
addTestFile('class A {}');
- addFile('/foo.dart', 'library foo;');
+ newFile('/foo.dart', content: 'library foo;');
await prepareAnalyzedFiles();
expect(analyzedFilesReceived, isTrue);
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 904a0e4..161eb85 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -45,6 +45,30 @@
];
}
+ test_analysisOptionsFile() async {
+ String analysisOptionsFile =
+ newFile('$projectPath/analysis_options.yaml', content: '''
+linter:
+ rules:
+ - invalid_lint_rule_name
+''').path;
+
+ Request request =
+ new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+ handleSuccessfulRequest(request);
+ await waitForTasksFinished();
+ await pumpEventQueue();
+ //
+ // Verify the error result.
+ //
+ List<AnalysisError> errors = filesErrors[analysisOptionsFile];
+ expect(errors, hasLength(1));
+ AnalysisError error = errors[0];
+ expect(error.location.file, '/project/analysis_options.yaml');
+ expect(error.severity, AnalysisErrorSeverity.WARNING);
+ expect(error.type, AnalysisErrorType.STATIC_WARNING);
+ }
+
test_importError() async {
createProject();
@@ -66,7 +90,7 @@
test_lintError() async {
var camelCaseTypesLintName = 'camel_case_types';
- addFile('$projectPath/.analysis_options', '''
+ newFile('$projectPath/.analysis_options', content: '''
linter:
rules:
- $camelCaseTypesLintName
@@ -81,7 +105,7 @@
await waitForTasksFinished();
List<Linter> lints;
AnalysisDriver testDriver = (server.contextManager as ContextManagerImpl)
- .getContextInfoFor(resourceProvider.getFolder(projectPath))
+ .getContextInfoFor(getFolder(projectPath))
.analysisDriver;
lints = testDriver.analysisOptions.lintRules;
// Registry should only contain single lint rule.
@@ -100,8 +124,7 @@
test_notInAnalysisRoot() async {
createProject();
- String otherFile = '/other.dart';
- addFile(otherFile, 'UnknownType V;');
+ String otherFile = newFile('/other.dart', content: 'UnknownType V;').path;
addTestFile('''
import '/other.dart';
main() {
@@ -128,6 +151,39 @@
expect(error.message, isNotNull);
}
+ test_pubspecFile() async {
+ String pubspecFile = newFile('$projectPath/pubspec.yaml', content: '''
+version: 1.3.2
+''').path;
+
+ Request setRootsRequest =
+ new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+ handleSuccessfulRequest(setRootsRequest);
+ await waitForTasksFinished();
+ await pumpEventQueue();
+ //
+ // Verify the error result.
+ //
+ List<AnalysisError> errors = filesErrors[pubspecFile];
+ expect(errors, hasLength(1));
+ AnalysisError error = errors[0];
+ expect(error.location.file, '/project/pubspec.yaml');
+ expect(error.severity, AnalysisErrorSeverity.WARNING);
+ expect(error.type, AnalysisErrorType.STATIC_WARNING);
+ //
+ // Fix the error and verify the new results.
+ //
+ modifyFile(pubspecFile, '''
+name: sample
+version: 1.3.2
+''');
+ await waitForTasksFinished();
+ await pumpEventQueue();
+
+ errors = filesErrors[pubspecFile];
+ expect(errors, hasLength(0));
+ }
+
test_StaticWarning() async {
createProject();
addTestFile('''
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index ceabbce..16df572 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -344,7 +344,7 @@
main() {
var part = 42;
}''');
- addFile('/project/bin/my_part.dart', 'part of lib;');
+ newFile('/project/bin/my_part.dart', content: 'part of lib;');
await prepareHighlights();
assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
@@ -934,7 +934,7 @@
}
void _addLibraryForTestPart() {
- addFile('$testFolder/my_lib.dart', '''
+ newFile('$testFolder/my_lib.dart', content: '''
library lib;
part 'test.dart';
''');
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
index df9b59d..56491fe 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
@@ -345,7 +345,7 @@
main() {
var part = 42;
}''');
- addFile('/project/bin/my_part.dart', 'part of lib;');
+ newFile('/project/bin/my_part.dart', content: 'part of lib;');
await prepareHighlights();
assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
@@ -1085,7 +1085,7 @@
}
void _addLibraryForTestPart() {
- addFile('$testFolder/my_lib.dart', '''
+ newFile('$testFolder/my_lib.dart', content: '''
library lib;
part 'test.dart';
''');
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index cc80eb9..7a6e597 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -271,7 +271,7 @@
}
test_method_withMethod_private_differentLib() async {
- addFile('$testFolder/lib.dart', r'''
+ newFile('$testFolder/lib.dart', content: r'''
import 'test.dart';
class B extends A {
void _m() {}
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index f57c6715..075acf7 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -229,7 +229,7 @@
}
test_annotationConstructor_importPrefix() async {
- addFile('$testFolder/my_annotation.dart', r'''
+ newFile('$testFolder/my_annotation.dart', content: r'''
library an;
class MyAnnotation {
const MyAnnotation();
@@ -304,7 +304,7 @@
}
test_annotationField_importPrefix() async {
- addFile('$testFolder/mayn.dart', r'''
+ newFile('$testFolder/mayn.dart', content: r'''
library an;
const myan = new Object();
''');
@@ -697,8 +697,8 @@
}
test_multiplyDefinedElement() async {
- addFile('$projectPath/bin/libA.dart', 'library A; int TEST = 1;');
- addFile('$projectPath/bin/libB.dart', 'library B; int TEST = 2;');
+ newFile('$projectPath/bin/libA.dart', content: 'library A; int TEST = 1;');
+ newFile('$projectPath/bin/libB.dart', content: 'library B; int TEST = 2;');
addTestFile('''
import 'libA.dart';
import 'libB.dart';
@@ -776,7 +776,7 @@
test_partOf() async {
var libCode = 'library lib; part "test.dart";';
- var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+ var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
addTestFile('part of lib;');
await prepareNavigation();
assertHasRegionString('lib');
@@ -808,7 +808,7 @@
test_string_export() async {
var libCode = 'library lib;';
- var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+ var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
addTestFile('export "lib.dart";');
await prepareNavigation();
assertHasRegionString('"lib.dart"');
@@ -823,7 +823,7 @@
test_string_import() async {
var libCode = 'library lib;';
- var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+ var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
addTestFile('import "lib.dart";');
await prepareNavigation();
assertHasRegionString('"lib.dart"');
@@ -844,7 +844,8 @@
test_string_part() async {
var unitCode = 'part of lib; f() {}';
- var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode);
+ var unitFile =
+ newFile('$projectPath/bin/test_unit.dart', content: unitCode).path;
addTestFile('''
library lib;
part "test_unit.dart";
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index 10abe23..86cac68 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -232,7 +232,7 @@
}
test_BAD_privateByPrivate_inDifferentLib() async {
- addFile('$testFolder/lib.dart', r'''
+ newFile('$testFolder/lib.dart', content: r'''
class A {
void _m() {}
}
diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart
index c78dd97..886b200 100644
--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/analysis/reanalyze_test.dart
@@ -46,8 +46,8 @@
test_reanalyze_with_overlay() async {
createProject();
- resourceProvider.newFolder(testFolder);
- resourceProvider.newFile(testFile, 'main() {}');
+ newFolder(testFolder);
+ newFile(testFile, content: 'main() {}');
// Update the content with an overlay that contains a syntax error.
server.updateContent('1', {testFile: new AddContentOverlay('main() {')});
await _resultsAvailable.future;
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 1de25bf..993fb07 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -57,49 +57,49 @@
test_fileNotInAnalysisRoot() async {
String path = '/other/file.dart';
- addFile(path, '');
+ newFile(path);
await _setPriorityFile(path);
_verifyPriorityFiles(path);
}
test_ignoredInAnalysisOptions() async {
String sampleFile = '$projectPath/samples/sample.dart';
- addFile('$projectPath/.analysis_options', r'''
+ newFile('$projectPath/.analysis_options', content: r'''
analyzer:
exclude:
- 'samples/**'
''');
- addFile(sampleFile, '');
+ newFile(sampleFile);
// attempt to set priority file
await _setPriorityFile(sampleFile);
_verifyPriorityFiles(sampleFile);
}
test_ignoredInAnalysisOptions_inChildContext() async {
- addFile('$projectPath/.packages', '');
- addFile('$projectPath/child/.packages', '');
+ newFile('$projectPath/.packages');
+ newFile('$projectPath/child/.packages');
String sampleFile = '$projectPath/child/samples/sample.dart';
- addFile('$projectPath/child/.analysis_options', r'''
+ newFile('$projectPath/child/.analysis_options', content: r'''
analyzer:
exclude:
- 'samples/**'
''');
- addFile(sampleFile, '');
+ newFile(sampleFile);
// attempt to set priority file
await _setPriorityFile(sampleFile);
_verifyPriorityFiles(sampleFile);
}
test_ignoredInAnalysisOptions_inRootContext() async {
- addFile('$projectPath/.packages', '');
- addFile('$projectPath/child/.packages', '');
+ newFile('$projectPath/.packages');
+ newFile('$projectPath/child/.packages');
String sampleFile = '$projectPath/child/samples/sample.dart';
- addFile('$projectPath/.analysis_options', r'''
+ newFile('$projectPath/.analysis_options', content: r'''
analyzer:
exclude:
- 'child/samples/**'
''');
- addFile(sampleFile, '');
+ newFile(sampleFile);
// attempt to set priority file
await _setPriorityFile(sampleFile);
_verifyPriorityFiles(sampleFile);
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index f2733f8..a4fc364 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -61,21 +61,18 @@
}
test_multiple_contexts() async {
- String fooPath = '/project1/foo.dart';
- resourceProvider.newFile(fooPath, '''
+ String fooPath = newFile('/project1/foo.dart', content: '''
library foo;
import '../project2/baz.dart';
-main() { f(); }''');
- String barPath = '/project2/bar.dart';
- resourceProvider.newFile(barPath, '''
+main() { f(); }''').path;
+ String barPath = newFile('/project2/bar.dart', content: '''
library bar;
import 'baz.dart';
-main() { f(); }''');
- String bazPath = '/project2/baz.dart';
- resourceProvider.newFile(bazPath, '''
+main() { f(); }''').path;
+ String bazPath = newFile('/project2/baz.dart', content: '''
library baz;
f(int i) {}
-''');
+''').path;
Request request =
new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], [])
.toRequest('0');
@@ -106,7 +103,7 @@
@failingTest
test_overlay_addPreviouslyImported() async {
// The list of errors doesn't include errors for '/project/target.dart'.
- Folder project = resourceProvider.newFolder('/project');
+ Folder project = newFolder('/project');
handleSuccessfulRequest(
new AnalysisSetAnalysisRootsParams([project.path], []).toRequest('0'));
@@ -130,8 +127,8 @@
test_overlayOnly() async {
String filePath = '/User/project1/test.dart';
- Folder folder1 = resourceProvider.newFolder('/User/project1');
- Folder folder2 = resourceProvider.newFolder('/User/project2');
+ Folder folder1 = newFolder('/User/project1');
+ Folder folder2 = newFolder('/User/project2');
Request request =
new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], [])
.toRequest('0');
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 2546cd8..1f797a9 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -14,11 +14,11 @@
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analyzer/context/context_root.dart' as analyzer;
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
@@ -47,10 +47,9 @@
/**
* An abstract base for all 'analysis' domain tests.
*/
-class AbstractAnalysisTest {
+class AbstractAnalysisTest extends Object with ResourceProviderMixin {
bool generateSummaryFiles = false;
MockServerChannel serverChannel;
- MemoryResourceProvider resourceProvider;
MockPackageMapProvider packageMapProvider;
TestPluginManager pluginManager;
AnalysisServer server;
@@ -89,12 +88,6 @@
handleSuccessfulRequest(request);
}
- String addFile(String path, String content) {
- path = resourceProvider.convertPath(path);
- resourceProvider.newFile(path, content);
- return path;
- }
-
void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
generalServices.add(service);
Request request = new AnalysisSetGeneralSubscriptionsParams(generalServices)
@@ -103,7 +96,7 @@
}
String addTestFile(String content) {
- addFile(testFile, content);
+ newFile(testFile, content: content);
this.testCode = content;
return testFile;
}
@@ -137,7 +130,7 @@
* Creates a project `/project`.
*/
void createProject({Map<String, String> packageRoots}) {
- resourceProvider.newFolder(projectPath);
+ newFolder(projectPath);
Request request = new AnalysisSetAnalysisRootsParams([projectPath], [],
packageRoots: packageRoots)
.toRequest('0');
@@ -149,7 +142,7 @@
* Fails if not found.
*/
int findFileOffset(String path, String search) {
- File file = resourceProvider.getResource(path) as File;
+ File file = getFile(path);
String code = file.createSource().contents.data;
int offset = code.indexOf(search);
expect(offset, isNot(-1), reason: '"$search" in\n$code');
@@ -177,8 +170,7 @@
}
String modifyTestFile(String content) {
- String path = resourceProvider.convertPath(testFile);
- resourceProvider.updateFile(path, content);
+ modifyFile(testFile, content);
this.testCode = content;
return testFile;
}
@@ -204,7 +196,6 @@
void setUp() {
serverChannel = new MockServerChannel();
- resourceProvider = new MemoryResourceProvider();
projectPath = resourceProvider.convertPath('/project');
testFolder = resourceProvider.convertPath('/project/bin');
testFile = resourceProvider.convertPath('/project/bin/test.dart');
@@ -225,7 +216,6 @@
server.done();
handler = null;
server = null;
- resourceProvider = null;
serverChannel = null;
}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 31c8a50..9ba47f2 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -10,10 +10,10 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_server.dart';
import 'package:analyzer/file_system/file_system.dart';
-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/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:plugin/manager.dart';
import 'package:test/test.dart';
@@ -29,10 +29,9 @@
}
@reflectiveTest
-class AnalysisServerTest {
+class AnalysisServerTest extends Object with ResourceProviderMixin {
MockServerChannel channel;
AnalysisServer server;
- MemoryResourceProvider resourceProvider;
MockPackageMapProvider packageMapProvider;
/**
@@ -42,10 +41,10 @@
Future do_not_test_no_duplicate_notifications() async {
// Subscribe to STATUS so we'll know when analysis is done.
server.serverServices = [ServerService.STATUS].toSet();
- resourceProvider.newFolder('/foo');
- resourceProvider.newFolder('/bar');
- resourceProvider.newFile('/foo/foo.dart', 'import "../bar/bar.dart";');
- File bar = resourceProvider.newFile('/bar/bar.dart', 'library bar;');
+ newFolder('/foo');
+ newFolder('/bar');
+ newFile('/foo/foo.dart', content: 'import "../bar/bar.dart";');
+ File bar = newFile('/bar/bar.dart', content: 'library bar;');
server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
Map<AnalysisService, Set<String>> subscriptions =
<AnalysisService, Set<String>>{};
@@ -92,7 +91,6 @@
void setUp() {
processRequiredPlugins();
channel = new MockServerChannel();
- resourceProvider = new MemoryResourceProvider();
// Create an SDK in the mock file system.
new MockSdk(resourceProvider: resourceProvider);
packageMapProvider = new MockPackageMapProvider();
@@ -116,9 +114,9 @@
Future test_serverStatusNotifications() {
server.serverServices.add(ServerService.STATUS);
- resourceProvider.newFolder('/pkg');
- resourceProvider.newFolder('/pkg/lib');
- resourceProvider.newFile('/pkg/lib/test.dart', 'class C {}');
+ newFolder('/pkg');
+ newFolder('/pkg/lib');
+ newFile('/pkg/lib/test.dart', content: 'class C {}');
server.setAnalysisRoots('0', ['/pkg'], [], {});
// Pump the event queue to make sure the server has finished any
// analysis.
@@ -144,8 +142,8 @@
test_setAnalysisSubscriptions_fileInIgnoredFolder_newOptions() async {
String path = '/project/samples/sample.dart';
- resourceProvider.newFile(path, '');
- resourceProvider.newFile('/project/analysis_options.yaml', r'''
+ newFile(path);
+ newFile('/project/analysis_options.yaml', content: r'''
analyzer:
exclude:
- 'samples/**'
@@ -163,8 +161,8 @@
test_setAnalysisSubscriptions_fileInIgnoredFolder_oldOptions() async {
String path = '/project/samples/sample.dart';
- resourceProvider.newFile(path, '');
- resourceProvider.newFile('/project/.analysis_options', r'''
+ newFile(path);
+ newFile('/project/.analysis_options', content: r'''
analyzer:
exclude:
- 'samples/**'
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index af60220..75833ab 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -74,12 +74,12 @@
super.setUp();
return new Future(() {
String content = spec.source;
- addFile(testFile, content);
+ newFile(testFile, content: content);
this.testCode = content;
completionOffset = spec.testLocation;
if (extraFiles != null) {
extraFiles.forEach((String fileName, String content) {
- addFile(fileName, content);
+ newFile(fileName, content: content);
});
}
}).then((_) => getSuggestions()).then((_) {
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 566c06c..7933584 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.context.directory.manager;
-
import 'dart:async';
import 'package:analysis_server/src/context_manager.dart';
@@ -12,7 +10,6 @@
import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/context/builder.dart';
@@ -25,6 +22,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/summary/summary_file_builder.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
@@ -90,16 +88,16 @@
//return super.test_embedder_added();
fail('NoSuchMethodError');
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'nope.dart']);
- String embedderPath = newFolder([projPath, 'embedder']);
- newFile([embedderPath, 'entry.dart']);
- String embedderSrcPath = newFolder([projPath, 'embedder', 'src']);
- newFile([embedderSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/nope.dart');
+ String embedderPath = '$projPath/embedder';
+ newFile('$embedderPath/entry.dart');
+ String embedderSrcPath = '$projPath/embedder/src';
+ newFile('$embedderSrcPath/part.dart');
// Setup _embedder.yaml.
- newFile([libPath, '_embedder.yaml'], r'''
+ newFile('$libPath/_embedder.yaml', content: r'''
embedded_libs:
"dart:foobar": "../embedder/entry.dart"
"dart:typed_data": "../embedder/src/part"
@@ -122,7 +120,7 @@
expect(sourceFactory.forUri('dart:typed_data'), isNull);
// Add .packages file that introduces a dependency with embedded libs.
- newFile([projPath, '.packages'], r'''
+ newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
await pumpEventQueue();
@@ -138,21 +136,21 @@
test_embedder_packagespec() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'nope.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/nope.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup _embedder.yaml.
- newFile([libPath, '_embedder.yaml'], r'''
+ newFile('$libPath/_embedder.yaml', content: r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
"dart:typed_data": "../sdk_ext/src/part"
''');
// Setup .packages file
- newFile([projPath, '.packages'], r'''
+ newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
// Setup context.
@@ -240,14 +238,14 @@
manager.setIgnorePatternsForContext(
rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']);
// Start creating files.
- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'ignoreme.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/ignoreme.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Pump event loop so new files are discovered and added to context.
await pumpEventQueue();
// Verify that ignored files were ignored.
@@ -368,21 +366,21 @@
test_sdk_ext_packagespec() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'nope.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/nope.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup sdk extension mapping.
- newFile([libPath, '_sdkext'], r'''
+ newFile('$libPath/_sdkext', content: r'''
{
"dart:foobar": "../sdk_ext/entry.dart"
}
''');
// Setup .packages file
- newFile([projPath, '.packages'], r'''
+ newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -429,13 +427,13 @@
}
void test_setRoots_addFolderWithNestedPackageSpec() {
- String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+ String examplePath = '$projPath/${ContextManagerTest.EXAMPLE_NAME}';
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([examplePath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
- newFile([examplePath, 'example.dart']);
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
+ newFile('$libPath/main.dart');
+ newFile('$examplePath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
+ newFile('$examplePath/example.dart');
packageMapProvider.packageMap['proj'] = <Folder>[
resourceProvider.getResource(libPath)
@@ -458,14 +456,15 @@
}
void test_setRoots_addFolderWithNestedPubspec() {
- String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+ String examplePath = '$projPath/${ContextManagerTest.EXAMPLE_NAME}';
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
- newFile([libPath, 'main.dart']);
- newFile([examplePath, ContextManagerImpl.PUBSPEC_NAME]);
- newFile([examplePath, 'example.dart']);
+ newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'proj:lib/');
+ newFile('$libPath/main.dart');
+ newFile('$examplePath/${ContextManagerImpl.PUBSPEC_NAME}');
+ newFile('$examplePath/example.dart');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -495,7 +494,7 @@
String packagespecPath = path.posix.join(projPath, '.packages');
resourceProvider.newFile(packagespecPath,
'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/');
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
File mainFile =
resourceProvider.newFile(path.posix.join(libPath, 'main.dart'), '');
Source source = mainFile.createSource();
@@ -546,17 +545,18 @@
}
void test_setRoots_addFolderWithPubspecAndLib() {
- String binPath = newFolder([projPath, ContextManagerTest.BIN_NAME]);
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- String srcPath = newFolder([libPath, ContextManagerTest.SRC_NAME]);
- String testPath = newFolder([projPath, ContextManagerTest.TEST_NAME]);
+ String binPath = '$projPath/${ContextManagerTest.BIN_NAME}';
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ String srcPath = '$libPath/${ContextManagerTest.SRC_NAME}';
+ String testPath = '$projPath/${ContextManagerTest.TEST_NAME}';
- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
- String appPath = newFile([binPath, 'app.dart']);
- newFile([libPath, 'main.dart']);
- newFile([srcPath, 'internal.dart']);
- String testFilePath = newFile([testPath, 'main_test.dart']);
+ newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'proj:lib/');
+ String appPath = newFile('$binPath/app.dart').path;
+ newFile('$libPath/main.dart');
+ newFile('$srcPath/internal.dart');
+ String testFilePath = newFile('$testPath/main_test.dart').path;
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
Iterable<Source> sources = callbacks.currentFileSources(projPath);
@@ -609,10 +609,12 @@
String projectBLib = '$root/sub/sub2/bbb/lib';
String subProjectB_file = '$projectB/bin/b.dart';
// create files
- newFile([projectA, ContextManagerImpl.PUBSPEC_NAME]);
- newFile([projectA, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
- newFile([projectB, ContextManagerImpl.PUBSPEC_NAME]);
- newFile([projectB, ContextManagerImpl.PACKAGE_SPEC_NAME], 'bar:lib/');
+ newFile('$projectA/${ContextManagerImpl.PUBSPEC_NAME}');
+ newFile('$projectA/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'foo:lib/');
+ newFile('$projectB/${ContextManagerImpl.PUBSPEC_NAME}');
+ newFile('$projectB/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'bar:lib/');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subProjectA_file, 'library a;');
resourceProvider.newFile(subProjectB_file, 'library b;');
@@ -640,8 +642,8 @@
void test_setRoots_addPackageRoot() {
String packagePathFoo = '/package1/foo';
String packageRootPath = '/package2/foo';
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
- 'foo:file:///package1/foo');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'foo:file:///package1/foo');
Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
@@ -893,8 +895,8 @@
void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
String packagePath = '/package/foo';
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
- 'foo:file:///package/foo');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'foo:file:///package/foo');
Folder packageFolder = resourceProvider.newFolder(packagePath);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(
@@ -939,7 +941,8 @@
void test_setRoots_packageResolver() {
String filePath = path.posix.join(projPath, 'lib', 'foo.dart');
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'foo:lib/');
resourceProvider.newFile(filePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -1077,8 +1080,8 @@
String packagePathFoo = '/package1/foo';
String packageRootPath = '/package2/foo';
Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
- 'foo:file:///package1/foo');
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'foo:file:///package1/foo');
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
manager.setRoots(includedPaths, excludedPaths,
@@ -1655,7 +1658,7 @@
}
}
-abstract class ContextManagerTest {
+abstract class ContextManagerTest extends Object with ResourceProviderMixin {
/**
* The name of the 'bin' directory.
*/
@@ -1685,8 +1688,6 @@
TestContextManagerCallbacks callbacks;
- MemoryResourceProvider resourceProvider;
-
MockPackageMapProvider packageMapProvider;
UriResolver packageResolver = null;
@@ -1737,11 +1738,6 @@
Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
- void deleteFile(List<String> pathComponents) {
- String filePath = path.posix.joinAll(pathComponents);
- resourceProvider.deleteFile(filePath);
- }
-
/**
* TODO(brianwilkerson) This doesn't add the strong mode processor when using
* the new analysis driver.
@@ -1749,24 +1745,6 @@
ErrorProcessor getProcessor(AnalysisError error) => errorProcessors
.firstWhere((ErrorProcessor p) => p.appliesTo(error), orElse: () => null);
- String newFile(List<String> pathComponents, [String content = '']) {
- String filePath = path.posix.joinAll(pathComponents);
- resourceProvider.newFile(filePath, content);
- return filePath;
- }
-
- String newFileFromBytes(List<String> pathComponents, List<int> bytes) {
- String filePath = path.posix.joinAll(pathComponents);
- resourceProvider.newFileWithBytes(filePath, bytes);
- return filePath;
- }
-
- String newFolder(List<String> pathComponents) {
- String folderPath = path.posix.joinAll(pathComponents);
- resourceProvider.newFolder(folderPath);
- return folderPath;
- }
-
void processRequiredPlugins() {
ExtensionManager manager = new ExtensionManager();
manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
@@ -1778,7 +1756,6 @@
void setUp() {
processRequiredPlugins();
- resourceProvider = new MemoryResourceProvider();
resourceProvider.newFolder(projPath);
packageMapProvider = new MockPackageMapProvider();
// Create an SDK in the mock file system.
@@ -1786,6 +1763,7 @@
DartSdkManager sdkManager = new DartSdkManager('/', true);
manager = new ContextManagerImpl(
resourceProvider,
+ new FileContentOverlay(),
sdkManager,
providePackageResolver,
packageMapProvider,
@@ -1833,9 +1811,13 @@
abstract class ContextManagerWithOptionsTest extends ContextManagerTest {
String get optionsFileName;
+ void deleteOptionsFile() {
+ deleteFile('$projPath/$optionsFileName');
+ }
+
test_analysis_options_file_delete() async {
// Setup analysis options
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
@@ -1858,7 +1840,7 @@
expect(analysisOptions.enableStrictCallChecks, isTrue);
// Remove options.
- deleteFile([projPath, optionsFileName]);
+ deleteOptionsFile();
await pumpEventQueue();
// Verify defaults restored.
@@ -1872,8 +1854,8 @@
// This fails because the ContextBuilder doesn't pick up the strongMode
// flag from the embedder.yaml file.
// Setup _embedder.yaml.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, '_embedder.yaml'], r'''
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/_embedder.yaml', content: r'''
analyzer:
strong-mode: true
errors:
@@ -1884,11 +1866,11 @@
''');
// Setup .packages file
- newFile([projPath, '.packages'], r'''
+ newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
// Setup analysis options
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
language:
enableStrictCallChecks: true
@@ -1910,7 +1892,7 @@
expect(lints, hasLength(2));
// Remove options.
- deleteFile([projPath, optionsFileName]);
+ deleteOptionsFile();
await pumpEventQueue();
// Verify defaults restored.
@@ -1923,17 +1905,17 @@
test_analysis_options_include() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup analysis options file which includes another options file.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
include: other_options.yaml
''');
- newFile([projPath, 'other_options.yaml'], r'''
+ newFile('$projPath/other_options.yaml', content: r'''
analyzer:
language:
enableStrictCallChecks: true
@@ -1955,15 +1937,15 @@
test_analysis_options_include_package() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup package
String booLibPosixPath = '/my/pkg/boo/lib';
- newFile([booLibPosixPath, 'other_options.yaml'], r'''
+ newFile('$booLibPosixPath/other_options.yaml', content: r'''
analyzer:
language:
enableStrictCallChecks: true
@@ -1974,9 +1956,9 @@
- camel_case_types
''');
// Setup analysis options file which includes another options file.
- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
- 'boo:$booLibPosixPath\n');
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+ content: 'boo:$booLibPosixPath\n');
+ newFile('$projPath/$optionsFileName', content: r'''
include: package:boo/other_options.yaml
''');
// Setup context.
@@ -1991,16 +1973,16 @@
test_analysis_options_parse_failure() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup analysis options file with ignore list.
- String optionsFilePath = newFile([projPath, optionsFileName], r'''
+ String optionsFilePath = newFile('$projPath/$optionsFileName', content: r'''
;
-''');
+''').path;
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -2012,7 +1994,7 @@
}
test_deleteRoot_hasAnalysisOptions() async {
- newFile([projPath, optionsFileName], '');
+ newFile('$projPath/$optionsFileName');
// Add the root.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -2029,14 +2011,14 @@
// This fails because the ContextBuilder doesn't pick up the strongMode
// flag from the embedder.yaml file.
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([projPath, 'test', 'test.dart']);
- newFile([sdkExtPath, 'entry.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$projPath/test', content: 'test.dart');
+ newFile('$sdkExtPath/entry.dart');
List<int> bytes = new SummaryBuilder([], null, true).build();
- newFileFromBytes([projPath, 'sdk.ds'], bytes);
+ newFileWithBytes('$projPath/sdk.ds', bytes);
// Setup _embedder.yaml.
- newFile([libPath, '_embedder.yaml'], r'''
+ newFile('$libPath/_embedder.yaml', content: r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
@@ -2050,11 +2032,11 @@
- avoid_as
''');
// Setup .packages file
- newFile([projPath, '.packages'], r'''
+ newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
// Setup analysis options
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
exclude:
- 'test/**'
@@ -2114,7 +2096,7 @@
test_error_filter_analysis_option() async {
// Create files.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
errors:
unused_local_variable: ignore
@@ -2129,7 +2111,7 @@
test_error_filter_analysis_option_multiple_filters() async {
// Create files.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
errors:
invalid_assignment: ignore
@@ -2147,7 +2129,7 @@
test_error_filter_analysis_option_synonyms() async {
// Create files.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
errors:
unused_local_variable: ignore
@@ -2163,7 +2145,7 @@
test_error_filter_analysis_option_unpsecified() async {
// Create files.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
# errors:
# unused_local_variable: ignore
@@ -2229,15 +2211,15 @@
test_path_filter_analysis_option() async {
// This fails because we're not analyzing the analysis options file.
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'nope.dart']);
- String sdkExtPath = newFolder([projPath, 'sdk_ext']);
- newFile([sdkExtPath, 'entry.dart']);
- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
- newFile([sdkExtSrcPath, 'part.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/nope.dart');
+ String sdkExtPath = '$projPath/sdk_ext';
+ newFile('$sdkExtPath/entry.dart');
+ String sdkExtSrcPath = '$projPath/sdk_ext/src';
+ newFile('$sdkExtSrcPath/part.dart');
// Setup analysis options file with ignore list.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
exclude:
- lib/nope.dart
@@ -2259,19 +2241,19 @@
test_path_filter_child_contexts_option() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'pubspec.yaml'], r'''
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/pubspec.yaml', content: r'''
name: foobar
''');
- String otherLibPath = newFolder([projPath, 'other_lib']);
- newFile([otherLibPath, 'entry.dart']);
- newFile([otherLibPath, 'pubspec.yaml'], r'''
+ String otherLibPath = '$projPath/other_lib';
+ newFile('$otherLibPath/entry.dart');
+ newFile('$otherLibPath/pubspec.yaml', content: r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores the 'other_lib'
// directory by name.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
exclude:
- 'other_lib'
@@ -2289,19 +2271,19 @@
test_path_filter_recursive_wildcard_child_contexts_option() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'pubspec.yaml'], r'''
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/pubspec.yaml', content: r'''
name: foobar
''');
- String otherLibPath = newFolder([projPath, 'other_lib']);
- newFile([otherLibPath, 'entry.dart']);
- newFile([otherLibPath, 'pubspec.yaml'], r'''
+ String otherLibPath = '$projPath/other_lib';
+ newFile('$otherLibPath/entry.dart');
+ newFile('$otherLibPath/pubspec.yaml', content: r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores 'other_lib'
// and all descendants.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
exclude:
- 'other_lib/**'
@@ -2320,19 +2302,19 @@
test_path_filter_wildcard_child_contexts_option() async {
// Create files.
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
- newFile([libPath, 'pubspec.yaml'], r'''
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
+ newFile('$libPath/pubspec.yaml', content: r'''
name: foobar
''');
- String otherLibPath = newFolder([projPath, 'other_lib']);
- newFile([otherLibPath, 'entry.dart']);
- newFile([otherLibPath, 'pubspec.yaml'], r'''
+ String otherLibPath = '$projPath/other_lib';
+ newFile('$otherLibPath/entry.dart');
+ newFile('$otherLibPath/pubspec.yaml', content: r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores 'other_lib'
// and all immediate children.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
exclude:
- 'other_lib/*'
@@ -2355,7 +2337,7 @@
// create files
resourceProvider.newFile(projectPubspec, 'name: project');
resourceProvider.newFile(examplePubspec, 'name: example');
- newFile([project, optionsFileName], r'''
+ newFile('$project/$optionsFileName', content: r'''
analyzer:
exclude:
- 'example'
@@ -2389,7 +2371,7 @@
// create files
resourceProvider.newFile(aPubspec, 'name: aaa');
resourceProvider.newFile(cPubspec, 'name: ccc');
- newFile([a, optionsFileName], r'''
+ newFile('$a/$optionsFileName', content: r'''
analyzer:
exclude:
- 'b**'
@@ -2416,12 +2398,12 @@
test_strong_mode_analysis_option() async {
// Create files.
- newFile([projPath, optionsFileName], r'''
+ newFile('$projPath/$optionsFileName', content: r'''
analyzer:
strong-mode: true
''');
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
- newFile([libPath, 'main.dart']);
+ String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+ newFile('$libPath/main.dart');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify that analysis options was parsed and strong-mode set.
@@ -2429,9 +2411,9 @@
}
test_watchEvents() async {
- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+ String libPath = newFolder('$projPath/${ContextManagerTest.LIB_NAME}').path;
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
- newFile([libPath, 'main.dart']);
+ newFile('$libPath/main.dart');
await new Future.delayed(new Duration(milliseconds: 1));
expect(callbacks.watchEvents, hasLength(1));
}
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 334e7f9..f79993c 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -9,10 +9,10 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
-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/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:plugin/manager.dart';
@@ -26,346 +26,271 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisDomainTest);
+ defineReflectiveTests(AnalysisDomainHandlerTest);
defineReflectiveTests(SetSubscriptionsTest);
});
-
- MockServerChannel serverChannel;
- MemoryResourceProvider resourceProvider;
- AnalysisServer server;
- AnalysisDomainHandler handler;
-
- void processRequiredPlugins() {
- ExtensionManager manager = new ExtensionManager();
- manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
- }
-
- setUp(() {
- serverChannel = new MockServerChannel();
- resourceProvider = new MemoryResourceProvider();
- processRequiredPlugins();
- // Create an SDK in the mock file system.
- new MockSdk(resourceProvider: resourceProvider);
- server = new AnalysisServer(
- serverChannel,
- resourceProvider,
- new MockPackageMapProvider(),
- new AnalysisServerOptions(),
- new DartSdkManager('/', false),
- InstrumentationService.NULL_SERVICE);
- handler = new AnalysisDomainHandler(server);
- });
-
- group('updateContent', testUpdateContent);
-
- group('AnalysisDomainHandler', () {
- // TODO(brianwilkerson) Re-enable these tests if we re-enable the
- // analysis.getReachableSources request.
-// group('getReachableSources', () {
-// test('valid sources', () async {
-// String fileA = '/project/a.dart';
-// String fileB = '/project/b.dart';
-// resourceProvider.newFile(fileA, 'import "b.dart";');
-// resourceProvider.newFile(fileB, '');
-//
-// server.setAnalysisRoots('0', ['/project/'], [], {});
-//
-// await server.onAnalysisComplete;
-//
-// var request =
-// new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
-// var response = handler.handleRequest(request);
-//
-// Map json = response.toJson()[Response.RESULT];
-//
-// // Sanity checks.
-// expect(json['sources'], hasLength(6));
-// expect(json['sources']['file:///project/a.dart'],
-// unorderedEquals(['dart:core', 'file:///project/b.dart']));
-// expect(json['sources']['file:///project/b.dart'], ['dart:core']);
-// });
-//
-// test('invalid source', () async {
-// resourceProvider.newFile('/project/a.dart', 'import "b.dart";');
-// server.setAnalysisRoots('0', ['/project/'], [], {});
-//
-// await server.onAnalysisComplete;
-//
-// var request =
-// new AnalysisGetReachableSourcesParams('/does/not/exist.dart')
-// .toRequest('0');
-// var response = handler.handleRequest(request);
-// expect(response.error, isNotNull);
-// expect(response.error.code,
-// RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
-// });
-// });
-
- group('setAnalysisRoots', () {
- Response testSetAnalysisRoots(
- List<String> included, List<String> excluded) {
- Request request = new AnalysisSetAnalysisRootsParams(included, excluded)
- .toRequest('0');
- return handler.handleRequest(request);
- }
-
- group('excluded', () {
- test('excluded folder', () async {
- String fileA = '/project/aaa/a.dart';
- String fileB = '/project/bbb/b.dart';
- resourceProvider.newFile(fileA, '// a');
- resourceProvider.newFile(fileB, '// b');
- var response = testSetAnalysisRoots(['/project'], ['/project/bbb']);
- expect(response, isResponseSuccess('0'));
- });
-
- test('not absolute', () async {
- var response = testSetAnalysisRoots([], ['foo/bar']);
- expect(
- response,
- isResponseFailure(
- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
- });
-
- test('not normalized', () async {
- var response = testSetAnalysisRoots([], ['/foo/../bar']);
- expect(
- response,
- isResponseFailure(
- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
- });
- });
-
- group('included', () {
- test('new folder', () async {
- String file = '/project/bin/test.dart';
- resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
- resourceProvider.newFile(file, 'main() {}');
- var response = testSetAnalysisRoots(['/project'], []);
- var serverRef = server;
- expect(response, isResponseSuccess('0'));
- // verify that unit is resolved eventually
- await server.onAnalysisComplete;
- var unit = await serverRef.getResolvedCompilationUnit(file);
- expect(unit, isNotNull);
- });
-
- test('nonexistent folder', () async {
- String fileB = '/project_b/b.dart';
- resourceProvider.newFile(fileB, '// b');
- var response = testSetAnalysisRoots(['/project_a', '/project_b'], []);
- var serverRef = server;
- expect(response, isResponseSuccess('0'));
- // Non-existence of /project_a should not prevent files in /project_b
- // from being analyzed.
- await server.onAnalysisComplete;
- var unit = await serverRef.getResolvedCompilationUnit(fileB);
- expect(unit, isNotNull);
- });
-
- test('not absolute', () async {
- var response = testSetAnalysisRoots(['foo/bar'], []);
- expect(
- response,
- isResponseFailure(
- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
- });
-
- test('not normalized', () async {
- var response = testSetAnalysisRoots(['/foo/../bar'], []);
- expect(
- response,
- isResponseFailure(
- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
- });
- });
- });
-
- group('setPriorityFiles', () {
- test('invalid', () {
- var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart'])
- .toRequest('0');
- var response = handler.handleRequest(request);
- expect(response, isResponseSuccess('0'));
- });
-
- test('valid', () {
- resourceProvider.newFolder('/p1');
- resourceProvider.newFile('/p1/a.dart', 'library a;');
- resourceProvider.newFolder('/p2');
- resourceProvider.newFile('/p2/b.dart', 'library b;');
- resourceProvider.newFile('/p2/c.dart', 'library c;');
-
- var setRootsRequest =
- new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], [])
- .toRequest('0');
- var setRootsResponse = handler.handleRequest(setRootsRequest);
- expect(setRootsResponse, isResponseSuccess('0'));
-
- void setPriorityFiles(List<String> fileList) {
- var request =
- new AnalysisSetPriorityFilesParams(fileList).toRequest('0');
- var response = handler.handleRequest(request);
- expect(response, isResponseSuccess('0'));
- // TODO(brianwilkerson) Enable the line below after getPriorityFiles
- // has been implemented.
- // expect(server.getPriorityFiles(), unorderedEquals(fileList));
- }
-
- setPriorityFiles(['/p1/a.dart', '/p2/b.dart']);
- setPriorityFiles(['/p2/b.dart', '/p2/c.dart']);
- setPriorityFiles([]);
- });
- });
-
- group('updateOptions', () {
- test('invalid', () {
- var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, {
- ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true}
- });
- var response = handler.handleRequest(request);
- // Invalid options should be silently ignored.
- expect(response, isResponseSuccess('0'));
- });
-
- test('null', () {
- // null is allowed as a synonym for {}.
- var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS,
- {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null});
- var response = handler.handleRequest(request);
- expect(response, isResponseSuccess('0'));
- });
- });
- });
}
-testUpdateContent() {
- test('bad type', () {
+@reflectiveTest
+class AnalysisDomainHandlerTest extends AbstractAnalysisTest {
+ Future outOfRangeTest(SourceEdit edit) async {
+ AnalysisTestHelper helper = new AnalysisTestHelper();
+ helper.createSingleFileProject('library A;');
+ await helper.onAnalysisComplete;
+ helper.sendContentChange(new AddContentOverlay('library B;'));
+ await helper.onAnalysisComplete;
+ ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]);
+ Request request =
+ new AnalysisUpdateContentParams({helper.testFile: contentChange})
+ .toRequest('0');
+ Response response = helper.handler.handleRequest(request);
+ expect(response,
+ isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE));
+ }
+
+ test_setAnalysisRoots_excludedFolder() async {
+ newFile('/project/aaa/a.dart', content: '// a');
+ newFile('/project/bbb/b.dart', content: '// b');
+ var response = testSetAnalysisRoots(['/project'], ['/project/bbb']);
+ expect(response, isResponseSuccess('0'));
+ }
+
+ test_setAnalysisRoots_included_newFolder() async {
+ newFile('/project/pubspec.yaml', content: 'name: project');
+ String file = newFile('/project/bin/test.dart', content: 'main() {}').path;
+ var response = testSetAnalysisRoots(['/project'], []);
+ var serverRef = server;
+ expect(response, isResponseSuccess('0'));
+ // verify that unit is resolved eventually
+ await server.onAnalysisComplete;
+ var unit = await serverRef.getResolvedCompilationUnit(file);
+ expect(unit, isNotNull);
+ }
+
+ test_setAnalysisRoots_included_nonexistentFolder() async {
+ String fileB = newFile('/project_b/b.dart', content: '// b').path;
+ var response = testSetAnalysisRoots(['/project_a', '/project_b'], []);
+ var serverRef = server;
+ expect(response, isResponseSuccess('0'));
+ // Non-existence of /project_a should not prevent files in /project_b
+ // from being analyzed.
+ await server.onAnalysisComplete;
+ var unit = await serverRef.getResolvedCompilationUnit(fileB);
+ expect(unit, isNotNull);
+ }
+
+ test_setAnalysisRoots_included_notAbsolute() async {
+ var response = testSetAnalysisRoots(['foo/bar'], []);
+ expect(response,
+ isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ }
+
+ test_setAnalysisRoots_included_notNormalized() async {
+ var response = testSetAnalysisRoots(['/foo/../bar'], []);
+ expect(response,
+ isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ }
+
+ test_setAnalysisRoots_notAbsolute() async {
+ var response = testSetAnalysisRoots([], ['foo/bar']);
+ expect(response,
+ isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ }
+
+ test_setAnalysisRoots_notNormalized() async {
+ var response = testSetAnalysisRoots([], ['/foo/../bar']);
+ expect(response,
+ isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+ }
+
+ test_setPriorityFiles_invalid() {
+ var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart'])
+ .toRequest('0');
+ var response = handler.handleRequest(request);
+ expect(response, isResponseSuccess('0'));
+ }
+
+ test_setPriorityFiles_valid() {
+ newFile('/p1/a.dart', content: 'library a;');
+ newFile('/p2/b.dart', content: 'library b;');
+ newFile('/p2/c.dart', content: 'library c;');
+
+ var setRootsRequest =
+ new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], []).toRequest('0');
+ var setRootsResponse = handler.handleRequest(setRootsRequest);
+ expect(setRootsResponse, isResponseSuccess('0'));
+
+ void setPriorityFiles(List<String> fileList) {
+ var request = new AnalysisSetPriorityFilesParams(fileList).toRequest('0');
+ var response = handler.handleRequest(request);
+ expect(response, isResponseSuccess('0'));
+ // TODO(brianwilkerson) Enable the line below after getPriorityFiles
+ // has been implemented.
+ // expect(server.getPriorityFiles(), unorderedEquals(fileList));
+ }
+
+ setPriorityFiles(['/p1/a.dart', '/p2/b.dart']);
+ setPriorityFiles(['/p2/b.dart', '/p2/c.dart']);
+ setPriorityFiles([]);
+ }
+
+ test_updateContent_badType() async {
AnalysisTestHelper helper = new AnalysisTestHelper();
helper.createSingleFileProject('// empty');
- return helper.onAnalysisComplete.then((_) {
- Request request = new Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, {
- ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: {
- helper.testFile: {
- 'type': 'foo',
- }
+ await helper.onAnalysisComplete;
+ Request request = new Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, {
+ ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: {
+ helper.testFile: {
+ 'type': 'foo',
}
- });
- Response response = helper.handler.handleRequest(request);
- expect(response, isResponseFailure('0'));
+ }
});
- });
+ Response response = helper.handler.handleRequest(request);
+ expect(response, isResponseFailure('0'));
+ }
- test('full content', () {
+ test_updateContent_changeOnDisk_duringOverride() async {
+ AnalysisTestHelper helper = new AnalysisTestHelper();
+ helper.createSingleFileProject('library A;');
+ await helper.onAnalysisComplete;
+ // update code
+ helper.sendContentChange(new AddContentOverlay('library B;'));
+ // There should be no errors
+ await helper.onAnalysisComplete;
+ expect(helper.getTestErrors(), hasLength(0));
+ // Change file on disk, adding a syntax error.
+ helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
+ // There should still be no errors (file should not have been reread).
+ await helper.onAnalysisComplete;
+ expect(helper.getTestErrors(), hasLength(0));
+ // Send a content change with a null content param--file should be
+ // reread from disk.
+ helper.sendContentChange(new RemoveContentOverlay());
+ // There should be errors now.
+ await helper.onAnalysisComplete;
+ expect(helper.getTestErrors(), hasLength(1));
+ }
+
+ test_updateContent_changeOnDisk_normal() async {
+ AnalysisTestHelper helper = new AnalysisTestHelper();
+ helper.createSingleFileProject('library A;');
+ await helper.onAnalysisComplete;
+ // There should be no errors
+ expect(helper.getTestErrors(), hasLength(0));
+ // Change file on disk, adding a syntax error.
+ helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
+ // There should be errors now.
+ await pumpEventQueue();
+ await helper.onAnalysisComplete;
+ expect(helper.getTestErrors(), hasLength(1));
+ }
+
+ test_updateContent_fullContent() async {
AnalysisTestHelper helper = new AnalysisTestHelper();
helper.createSingleFileProject('// empty');
- return helper.onAnalysisComplete.then((_) {
- // no errors initially
- List<AnalysisError> errors = helper.getTestErrors();
- expect(errors, isEmpty);
- // update code
- helper.sendContentChange(new AddContentOverlay('library lib'));
- // wait, there is an error
- return helper.onAnalysisComplete.then((_) {
- List<AnalysisError> errors = helper.getTestErrors();
- expect(errors, hasLength(1));
- });
- });
- });
+ await helper.onAnalysisComplete;
+ // no errors initially
+ List<AnalysisError> errors = helper.getTestErrors();
+ expect(errors, isEmpty);
+ // update code
+ helper.sendContentChange(new AddContentOverlay('library lib'));
+ // wait, there is an error
+ await helper.onAnalysisComplete;
+ errors = helper.getTestErrors();
+ expect(errors, hasLength(1));
+ }
- test('incremental', () {
+ test_updateContent_incremental() async {
AnalysisTestHelper helper = new AnalysisTestHelper();
String initialContent = 'library A;';
helper.createSingleFileProject(initialContent);
- return helper.onAnalysisComplete.then((_) {
- // no errors initially
- List<AnalysisError> errors = helper.getTestErrors();
- expect(errors, isEmpty);
- // Add the file to the cache
- helper.sendContentChange(new AddContentOverlay(initialContent));
- // update code
- helper.sendContentChange(new ChangeContentOverlay(
- [new SourceEdit('library '.length, 'A;'.length, 'lib')]));
- // wait, there is an error
- return helper.onAnalysisComplete.then((_) {
- List<AnalysisError> errors = helper.getTestErrors();
- expect(errors, hasLength(1));
- });
- });
- });
+ await helper.onAnalysisComplete;
+ // no errors initially
+ List<AnalysisError> errors = helper.getTestErrors();
+ expect(errors, isEmpty);
+ // Add the file to the cache
+ helper.sendContentChange(new AddContentOverlay(initialContent));
+ // update code
+ helper.sendContentChange(new ChangeContentOverlay(
+ [new SourceEdit('library '.length, 'A;'.length, 'lib')]));
+ // wait, there is an error
+ await helper.onAnalysisComplete;
+ errors = helper.getTestErrors();
+ expect(errors, hasLength(1));
+ }
- test('change on disk, normal', () {
- AnalysisTestHelper helper = new AnalysisTestHelper();
- helper.createSingleFileProject('library A;');
- return helper.onAnalysisComplete.then((_) {
- // There should be no errors
- expect(helper.getTestErrors(), hasLength(0));
- // Change file on disk, adding a syntax error.
- helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
- // There should be errors now.
- return pumpEventQueue().then((_) {
- return helper.onAnalysisComplete.then((_) {
- expect(helper.getTestErrors(), hasLength(1));
- });
- });
- });
- });
+ test_updateContent_outOfRange_beyondEnd() {
+ return outOfRangeTest(new SourceEdit(6, 6, 'foo'));
+ }
- test('change on disk, during override', () {
- AnalysisTestHelper helper = new AnalysisTestHelper();
- helper.createSingleFileProject('library A;');
- return helper.onAnalysisComplete.then((_) {
- // update code
- helper.sendContentChange(new AddContentOverlay('library B;'));
- // There should be no errors
- return helper.onAnalysisComplete.then((_) {
- expect(helper.getTestErrors(), hasLength(0));
- // Change file on disk, adding a syntax error.
- helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
- // There should still be no errors (file should not have been reread).
- return helper.onAnalysisComplete.then((_) {
- expect(helper.getTestErrors(), hasLength(0));
- // Send a content change with a null content param--file should be
- // reread from disk.
- helper.sendContentChange(new RemoveContentOverlay());
- // There should be errors now.
- return helper.onAnalysisComplete.then((_) {
- expect(helper.getTestErrors(), hasLength(1));
- });
- });
- });
- });
- });
+ test_updateContent_outOfRange_negativeLength() {
+ return outOfRangeTest(new SourceEdit(3, -1, 'foo'));
+ }
- group('out of range', () {
- Future outOfRangeTest(SourceEdit edit) {
- AnalysisTestHelper helper = new AnalysisTestHelper();
- helper.createSingleFileProject('library A;');
- return helper.onAnalysisComplete.then((_) {
- helper.sendContentChange(new AddContentOverlay('library B;'));
- return helper.onAnalysisComplete.then((_) {
- ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]);
- Request request =
- new AnalysisUpdateContentParams({helper.testFile: contentChange})
- .toRequest('0');
- Response response = helper.handler.handleRequest(request);
- expect(response,
- isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE));
- });
- });
- }
+ test_updateContent_outOfRange_negativeOffset() {
+ return outOfRangeTest(new SourceEdit(-1, 3, 'foo'));
+ }
- test('negative length', () {
- return outOfRangeTest(new SourceEdit(3, -1, 'foo'));
+ test_updateOptions_invalid() {
+ var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, {
+ ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true}
});
+ var response = handler.handleRequest(request);
+ // Invalid options should be silently ignored.
+ expect(response, isResponseSuccess('0'));
+ }
- test('negative offset', () {
- return outOfRangeTest(new SourceEdit(-1, 3, 'foo'));
- });
+ test_updateOptions_null() {
+ // null is allowed as a synonym for {}.
+ var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS,
+ {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null});
+ var response = handler.handleRequest(request);
+ expect(response, isResponseSuccess('0'));
+ }
- test('beyond end', () {
- return outOfRangeTest(new SourceEdit(6, 6, 'foo'));
- });
- });
+ Response testSetAnalysisRoots(List<String> included, List<String> excluded) {
+ Request request =
+ new AnalysisSetAnalysisRootsParams(included, excluded).toRequest('0');
+ return handler.handleRequest(request);
+ }
+
+ xtest_getReachableSources_invalidSource() async {
+ // TODO(brianwilkerson) Re-enable this test if we re-enable the
+ // analysis.getReachableSources request.
+ newFile('/project/a.dart', content: 'import "b.dart";');
+ server.setAnalysisRoots('0', ['/project/'], [], {});
+
+ await server.onAnalysisComplete;
+
+ var request = new AnalysisGetReachableSourcesParams('/does/not/exist.dart')
+ .toRequest('0');
+ var response = handler.handleRequest(request);
+ expect(response.error, isNotNull);
+ expect(response.error.code,
+ RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
+ }
+
+ xtest_getReachableSources_validSources() async {
+ // TODO(brianwilkerson) Re-enable this test if we re-enable the
+ // analysis.getReachableSources request.
+ String fileA = newFile('/project/a.dart', content: 'import "b.dart";').path;
+ newFile('/project/b.dart');
+
+ server.setAnalysisRoots('0', ['/project/'], [], {});
+
+ await server.onAnalysisComplete;
+
+ var request = new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
+ var response = handler.handleRequest(request);
+
+ Map json = response.toJson()[Response.RESULT];
+
+ // Sanity checks.
+ expect(json['sources'], hasLength(6));
+ expect(json['sources']['file:///project/a.dart'],
+ unorderedEquals(['dart:core', 'file:///project/b.dart']));
+ expect(json['sources']['file:///project/b.dart'], ['dart:core']);
+ }
}
@reflectiveTest
@@ -381,13 +306,11 @@
test_setRoots_packages() {
// prepare package
- String pkgFile = '/packages/pkgA/libA.dart';
- resourceProvider.newFile(pkgFile, '''
+ String pkgFile = newFile('/packages/pkgA/libA.dart', content: '''
library lib_a;
class A {}
-''');
- resourceProvider.newFile(
- '/project/.packages', 'pkgA:file:///packages/pkgA');
+''').path;
+ newFile('/project/.packages', content: 'pkgA:file:///packages/pkgA');
addTestFile('''
import 'package:pkgA/libA.dart';
main(A a) {
@@ -407,9 +330,8 @@
/**
* A helper to test 'analysis.*' requests.
*/
-class AnalysisTestHelper {
+class AnalysisTestHelper extends Object with ResourceProviderMixin {
MockServerChannel serverChannel;
- MemoryResourceProvider resourceProvider;
AnalysisServer server;
AnalysisDomainHandler handler;
@@ -425,7 +347,6 @@
AnalysisTestHelper() {
processRequiredPlugins();
serverChannel = new MockServerChannel();
- resourceProvider = new MemoryResourceProvider();
// Create an SDK in the mock file system.
new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
@@ -490,7 +411,7 @@
* Creates an empty project `/project`.
*/
void createEmptyProject() {
- resourceProvider.newFolder('/project');
+ newFolder('/project');
Request request =
new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0');
handleSuccessfulRequest(request);
@@ -502,8 +423,8 @@
*/
void createSingleFileProject(code) {
this.testCode = _getCodeString(code);
- resourceProvider.newFolder('/project');
- resourceProvider.newFile(testFile, testCode);
+ newFolder('/project');
+ newFile(testFile, content: testCode);
Request request =
new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0');
handleSuccessfulRequest(request);
@@ -601,11 +522,6 @@
handleSuccessfulRequest(request);
}
- String setFileContent(String path, String content) {
- resourceProvider.newFile(path, content);
- return path;
- }
-
/**
* Stops the associated server.
*/
@@ -663,13 +579,11 @@
}
test_afterAnalysis_packageFile_external() async {
- String pkgFile = '/packages/pkgA/lib/libA.dart';
- resourceProvider.newFile(pkgFile, '''
+ String pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
-''');
- resourceProvider.newFile(
- '/project/.packages', 'pkgA:file:///packages/pkgA/lib');
+''').path;
+ newFile('/project/.packages', content: 'pkgA:file:///packages/pkgA/lib');
//
addTestFile('''
import 'package:pkgA/libA.dart';
@@ -691,30 +605,23 @@
test_afterAnalysis_packageFile_inRoot() async {
String pkgA = '/pkgA';
String pkgB = '/pkgA';
- String pkgFileA = '$pkgA/lib/libA.dart';
- String pkgFileB = '$pkgA/lib/libB.dart';
- resourceProvider.newFile(pkgFileA, '''
+ String pkgFileA = newFile('$pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
-''');
- resourceProvider.newFile(pkgFileB, '''
+''').path;
+ newFile('$pkgA/lib/libB.dart', content: '''
import 'package:pkgA/libA.dart';
main() {
new A();
}
''');
packageMapProvider.packageMap = {
- 'pkgA': [
- resourceProvider.newFolder('$pkgA/lib'),
- resourceProvider.newFolder('$pkgB/lib')
- ]
+ 'pkgA': [newFolder('$pkgA/lib'), newFolder('$pkgB/lib')]
};
// add 'pkgA' and 'pkgB' as projects
- {
- resourceProvider.newFolder(projectPath);
- handleSuccessfulRequest(
- new AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0'));
- }
+ newFolder(projectPath);
+ handleSuccessfulRequest(
+ new AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0'));
// wait for analysis, no results initially
await waitForTasksFinished();
expect(filesHighlights[pkgFileA], isNull);
@@ -726,12 +633,11 @@
}
test_afterAnalysis_packageFile_notUsed() async {
- String pkgFile = '/packages/pkgA/lib/libA.dart';
- resourceProvider.newFile(pkgFile, '''
+ String pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
-''');
- resourceProvider.newFile('/project/.packages', 'pkgA:/packages/pkgA/lib');
+''').path;
+ newFile('/project/.packages', content: 'pkgA:/packages/pkgA/lib');
//
addTestFile('// no "pkgA" reference');
createProject();
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 5aad7e4..90b92b4 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -239,7 +239,7 @@
//
// We no longer support the analysis of non-dart files.
//
- testFile = '/project/web/test.html';
+ testFile = resourceProvider.convertPath('/project/web/test.html');
addTestFile('''
<html>^</html>
''');
@@ -251,7 +251,7 @@
}
test_import_uri_with_trailing() {
- addFile('/project/bin/testA.dart', 'library libA;');
+ newFile('/project/bin/testA.dart', content: 'library libA;');
addTestFile('''
import '/project/bin/t^.dart';
main() {}''');
@@ -499,7 +499,7 @@
}
test_inDartDoc_reference1() async {
- addFile('/testA.dart', '''
+ newFile('/testA.dart', content: '''
part of libA;
foo(bar) => 0;''');
addTestFile('''
@@ -528,7 +528,7 @@
}
test_inherited() {
- addFile('/libA.dart', 'class A {m() {}}');
+ newFile('/libA.dart', content: 'class A {m() {}}');
addTestFile('''
import '/libA.dart';
class B extends A {
@@ -606,7 +606,7 @@
}
test_local_override() {
- addFile('/libA.dart', 'class A {m() {}}');
+ newFile('/libA.dart', content: 'class A {m() {}}');
addTestFile('''
import '/libA.dart';
class B extends A {
@@ -649,7 +649,7 @@
}
test_overrides() {
- addFile('/libA.dart', 'class A {m() {}}');
+ newFile('/libA.dart', content: 'class A {m() {}}');
addTestFile('''
import '/libA.dart';
class B extends A {m() {^}}
@@ -663,7 +663,7 @@
}
test_partFile() {
- addFile('/project/bin/testA.dart', '''
+ newFile('/project/bin/testA.dart', content: '''
library libA;
part "$testFile";
import 'dart:html';
@@ -683,7 +683,7 @@
}
test_partFile2() {
- addFile('/testA.dart', '''
+ newFile('/testA.dart', content: '''
part of libA;
class A { }''');
addTestFile('''
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 913294f..c3ff619 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -26,9 +26,8 @@
}
test_getDiagnostics() async {
- String file = '/project/bin/test.dart';
- resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
- resourceProvider.newFile(file, 'main() {}');
+ newFile('/project/pubspec.yaml', content: 'name: project');
+ newFile('/project/bin/test.dart', content: 'main() {}');
server.setAnalysisRoots('0', ['/project/'], [], {});
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index b46daaa..8ccdb16 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -178,8 +178,7 @@
}
void test_mapUri_file() {
- String path = '/a/b.dart';
- resourceProvider.newFile(path, '');
+ String path = newFile('/a/b.dart').path;
// map the file
ExecutionMapUriResult result = _mapUri(file: path);
expect(result.file, isNull);
@@ -189,7 +188,7 @@
void test_mapUri_file_dartUriKind() {
String path = server.findSdk().mapDartUri('dart:async').fullName;
// hack - pretend that the SDK file exists in the project FS
- resourceProvider.newFile(path, '// hack');
+ newFile(path, content: '// hack');
// map file
ExecutionMapUriResult result = _mapUri(file: path);
expect(result.file, isNull);
@@ -198,7 +197,7 @@
void test_mapUri_uri() {
String path = '/a/b.dart';
- resourceProvider.newFile(path, '');
+ newFile(path);
// map the uri
ExecutionMapUriResult result = _mapUri(uri: 'file://$path');
expect(result.file, '/a/b.dart');
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 90732cd..684506f 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -111,20 +111,21 @@
test_suggestImportFromDifferentAnalysisRoot() async {
// Set up two projects.
- resourceProvider..newFolder("/project1")..newFolder("/project2");
+ newFolder("/project1");
+ newFolder("/project2");
handleSuccessfulRequest(
new AnalysisSetAnalysisRootsParams(["/project1", "/project2"], [])
.toRequest('0'),
handler: analysisHandler);
// Set up files.
- testFile = "/project1/main.dart";
- testCode = "main() { print(new Foo()); }";
+ testFile = resourceProvider.convertPath('/project1/main.dart');
+ testCode = 'main() { print(new Foo()); }';
_addOverlay(testFile, testCode);
// Add another file in the same project that imports the target file.
// This ensures it will be analyzed as an implicit Source.
- _addOverlay("/project1/another.dart", 'import "../project2/target.dart";');
- _addOverlay("/project2/target.dart", "class Foo() {}");
+ _addOverlay('/project1/another.dart', 'import "../project2/target.dart";');
+ _addOverlay('/project2/target.dart', 'class Foo() {}');
await waitForTasksFinished();
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index cf320de..351891f 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -84,8 +84,8 @@
}
Future test_OK_remove_unresolvedDirectives() {
- addFile('$testFolder/existing_part1.dart', 'part of lib;');
- addFile('$testFolder/existing_part2.dart', 'part of lib;');
+ newFile('$testFolder/existing_part1.dart', content: 'part of lib;');
+ newFile('$testFolder/existing_part2.dart', content: 'part of lib;');
addTestFile('''
library lib;
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index fd225c6..9fe5e02 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -271,8 +271,7 @@
test_analysis_onlyOneFile() async {
shouldWaitForFullAnalysis = false;
- String otherFile = '$testFolder/other.dart';
- addFile(otherFile, r'''
+ newFile('$testFolder/other.dart', content: r'''
foo(int myName) {}
''');
addTestFile('''
@@ -445,7 +444,7 @@
test_resetOnAnalysisSetChanged_watch_otherFile() async {
String otherFile = '$testFolder/other.dart';
- addFile(otherFile, '// other 1');
+ newFile(otherFile, content: '// other 1');
addTestFile('''
main() {
foo(1 + 2);
@@ -465,7 +464,7 @@
// The refactoring is reset, even though it's a different file. It is up to
// analyzer to track dependencies and provide resolved units fast when
// possible.
- addFile(otherFile, '// other 2');
+ newFile(otherFile, content: '// other 2');
await pumpEventQueue();
expect(test_resetCount, initialResetCount + 1);
}
@@ -980,7 +979,7 @@
test_analysis_onlyOneFile() async {
shouldWaitForFullAnalysis = false;
String otherFile = '$testFolder/other.dart';
- addFile(otherFile, r'''
+ newFile(otherFile, content: r'''
foo(int p) {}
''');
addTestFile('''
@@ -1048,8 +1047,7 @@
}
test_resetOnAnalysisSetChanged() async {
- String otherFile = '$testFolder/other.dart';
- addFile(otherFile, '// other 1');
+ newFile('$testFolder/other.dart', content: '// other 1');
addTestFile('''
main() {
int res = 1 + 2;
@@ -1217,7 +1215,7 @@
@failingTest
test_OK() {
fail('The move file refactoring is not supported under the new driver');
- resourceProvider.newFile('/project/bin/lib.dart', '');
+ newFile('/project/bin/lib.dart');
addTestFile('''
import 'dart:math';
import 'lib.dart';
@@ -1754,7 +1752,7 @@
}
test_library_partOfDirective() {
- addFile('$testFolder/my_lib.dart', '''
+ newFile('$testFolder/my_lib.dart', content: '''
library aaa.bbb.ccc;
part 'test.dart';
''');
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index abce2a0..d6b70c1 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -178,7 +178,7 @@
}
test_OK_genericFunctionType() async {
- addFile(projectPath + '/analysis_options.yaml', '''
+ newFile('$projectPath/analysis_options.yaml', content: '''
analyzer:
strong-mode: true
''');
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index c2d1547..19e5b52 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -164,17 +164,16 @@
test_class_extends_fileAndPackageUris() async {
// prepare packages
- String pkgFile = '/packages/pkgA/lib/libA.dart';
- resourceProvider.newFile(pkgFile, '''
+ newFile('/packages/pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
class B extends A {}
''');
- resourceProvider.newFile(
- '/packages/pkgA/.packages', 'pkgA:file:///packages/pkgA/lib');
+ newFile('/packages/pkgA/.packages',
+ content: 'pkgA:file:///packages/pkgA/lib');
// reference the package from a project
- resourceProvider.newFile(
- '$projectPath/.packages', 'pkgA:file:///packages/pkgA/lib');
+ newFile('$projectPath/.packages',
+ content: 'pkgA:file:///packages/pkgA/lib');
addTestFile('''
import 'package:pkgA/libA.dart';
class C extends A {}
@@ -696,7 +695,7 @@
}
test_member_method_private_differentLib() async {
- addFile('$testFolder/lib.dart', r'''
+ newFile('$testFolder/lib.dart', content: r'''
import 'test.dart';
class A {
void _m() {}
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index b578713..7f455ec 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -84,8 +84,8 @@
test_PrefixedIdentifier_field_inPart() async {
// SimpleIdentifier PrefixedIdentifier ExpressionStatement
- addFile('/project/bin/myLib.dart',
- 'library L; part "$testFile"; class A {static int s2;}');
+ newFile('/project/bin/myLib.dart',
+ content: 'library L; part "$testFile"; class A {static int s2;}');
addTestFile('part of L; foo() {A.^}');
await getSuggestionsWith({
'L.A': ['s2']
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 469bc3a..2e3f899 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -12,6 +12,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
@@ -45,6 +46,8 @@
*/
bool get isNullExpectedReturnTypeConsideredDynamic => true;
+ bool get usingFastaParser => analyzer.Parser.useFasta;
+
void addTestSource(String content) {
expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
completionOffset = content.indexOf('^');
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index d8a0b4b..da2dc8a 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -4,7 +4,6 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
-import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
@@ -321,7 +320,7 @@
// and reports a single function expression argument
// while analyzer adds the closing paren before the `a`
// and adds synthetic `;`s making `a` a statement.
- if (request.target.entity is BlockFunctionBody) {
+ if (usingFastaParser) {
assertSuggestKeywords([],
pseudoKeywords: ['async', 'async*', 'sync*'],
relevance: DART_RELEVANCE_HIGH);
@@ -363,9 +362,8 @@
addTestSource('main() {foo("bar", () as^ => null');
await computeSuggestions();
assertSuggestKeywords([],
- pseudoKeywords: request.target.entity is ExpressionFunctionBody
- ? ['async']
- : ['async', 'async*', 'sync*'],
+ pseudoKeywords:
+ usingFastaParser ? ['async'] : ['async', 'async*', 'sync*'],
relevance: DART_RELEVANCE_HIGH);
}
@@ -382,7 +380,7 @@
await computeSuggestions();
// Fasta interprets the argument as a function expression
// while analyzer adds synthetic `;`s making `a` a statement.
- if (request.target.entity is BlockFunctionBody) {
+ if (usingFastaParser) {
assertSuggestKeywords([],
pseudoKeywords: ['async', 'async*', 'sync*'],
relevance: DART_RELEVANCE_HIGH);
@@ -740,7 +738,7 @@
addTestSource('class A e^ implements foo');
await computeSuggestions();
assertSuggestKeywords(
- request.target.containingNode is ClassDeclaration
+ usingFastaParser
? [Keyword.EXTENDS]
: [Keyword.EXTENDS, Keyword.IMPLEMENTS],
relevance: DART_RELEVANCE_HIGH);
@@ -750,7 +748,7 @@
addTestSource('class A e^ implements foo { }');
await computeSuggestions();
assertSuggestKeywords(
- request.target.containingNode is ClassDeclaration
+ usingFastaParser
? [Keyword.EXTENDS]
: [Keyword.EXTENDS, Keyword.IMPLEMENTS],
relevance: DART_RELEVANCE_HIGH);
@@ -919,7 +917,7 @@
test_function_async() async {
addTestSource('main()^');
await computeSuggestions();
- assertSuggestKeywords(DECLARATION_KEYWORDS,
+ assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
pseudoKeywords: ['async', 'async*', 'sync*'],
relevance: DART_RELEVANCE_HIGH);
}
@@ -943,7 +941,7 @@
test_function_async4() async {
addTestSource('main()a^{}');
await computeSuggestions();
- assertSuggestKeywords(DECLARATION_KEYWORDS,
+ assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
pseudoKeywords: ['async', 'async*', 'sync*'],
relevance: DART_RELEVANCE_HIGH);
}
@@ -1475,8 +1473,14 @@
test_method_async4() async {
addTestSource('class A { foo() a^{}}');
await computeSuggestions();
- assertSuggestKeywords(CLASS_BODY_KEYWORDS,
- pseudoKeywords: ['async', 'async*', 'sync*']);
+ if (usingFastaParser) {
+ assertSuggestKeywords([],
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
+ } else {
+ assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+ pseudoKeywords: ['async', 'async*', 'sync*']);
+ }
}
test_method_async5() async {
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 678806c..1e93e6a 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -8,13 +8,13 @@
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:test/test.dart';
@@ -29,8 +29,7 @@
}
@reflectiveTest
-class SearchEngineImplTest {
- final MemoryResourceProvider provider = new MemoryResourceProvider();
+class SearchEngineImplTest extends Object with ResourceProviderMixin {
DartSdk sdk;
final ByteStore byteStore = new MemoryByteStore();
final FileContentOverlay contentOverlay = new FileContentOverlay();
@@ -41,36 +40,32 @@
AnalysisDriverScheduler scheduler;
void setUp() {
- sdk = new MockSdk(resourceProvider: provider);
+ sdk = new MockSdk(resourceProvider: resourceProvider);
logger = new PerformanceLog(logBuffer);
scheduler = new AnalysisDriverScheduler(logger);
scheduler.start();
}
test_membersOfSubtypes_hasMembers() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
- var c = _p('/test/c.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {
void a() {}
void b() {}
void c() {}
}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
class B extends A {
void a() {}
}
-''');
- provider.newFile(c, '''
+''').path;
+ var c = newFile('/test/c.dart', content: '''
import 'a.dart';
class C extends A {
void b() {}
}
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -89,20 +84,17 @@
}
test_membersOfSubtypes_noMembers() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {
void a() {}
void b() {}
void c() {}
}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
class B extends A {}
-''');
+''').path;
var driver = _newDriver();
@@ -119,22 +111,19 @@
}
test_membersOfSubtypes_noSubtypes() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {
void a() {}
void b() {}
void c() {}
}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
class B {
void a() {}
}
-''');
+''').path;
var driver = _newDriver();
@@ -151,10 +140,7 @@
}
test_membersOfSubtypes_private() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {
void a() {}
void _b() {}
@@ -163,8 +149,8 @@
class B extends A {
void _b() {}
}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
class C extends A {
void a() {}
@@ -173,7 +159,7 @@
class D extends B {
void _c() {}
}
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -191,14 +177,12 @@
}
test_searchAllSubtypes() async {
- var p = _p('/test.dart');
-
- provider.newFile(p, '''
+ var p = newFile('/test.dart', content: '''
class T {}
class A extends T {}
class B extends A {}
class C implements B {}
-''');
+''').path;
var driver = _newDriver();
driver.addFile(p);
@@ -215,18 +199,15 @@
}
test_searchAllSubtypes_acrossDrivers() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class T {}
class A extends T {}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
class B extends A {}
class C extends B {}
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -246,9 +227,6 @@
}
test_searchMemberDeclarations() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
var codeA = '''
class A {
int test; // 1
@@ -263,8 +241,8 @@
int test;
''';
- provider.newFile(a, codeA);
- provider.newFile(b, codeB);
+ var a = newFile('/test/a.dart', content: codeA).path;
+ var b = newFile('/test/b.dart', content: codeB).path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -295,23 +273,20 @@
}
test_searchMemberReferences() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {
int test;
}
foo(p) {
p.test;
}
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
bar(p) {
p.test = 1;
}
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -334,17 +309,14 @@
}
test_searchReferences() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class T {}
T a;
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
import 'a.dart';
T b;
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -365,17 +337,14 @@
}
test_searchTopLevelDeclarations() async {
- var a = _p('/test/a.dart');
- var b = _p('/test/b.dart');
-
- provider.newFile(a, '''
+ var a = newFile('/test/a.dart', content: '''
class A {}
int a;
-''');
- provider.newFile(b, '''
+''').path;
+ var b = newFile('/test/b.dart', content: '''
class B {}
get b => 42;
-''');
+''').path;
var driver1 = _newDriver();
var driver2 = _newDriver();
@@ -406,25 +375,23 @@
}
test_searchTopLevelDeclarations_dependentPackage() async {
- var a = _p('/a/lib/a.dart');
- provider.newFile(a, '''
+ var a = newFile('/a/lib/a.dart', content: '''
class A {}
''');
var driver1 = _newDriver();
- driver1.addFile(a);
+ driver1.addFile(a.path);
// The package:b uses the class A from the package:a,
// so it sees the declaration the element A.
- var b = _p('/b/lib/b.dart');
- provider.newFile(b, '''
+ var b = newFile('/b/lib/b.dart', content: '''
import 'package:a/a.dart';
class B extends A {}
''');
var driver2 = _newDriver(
- packageUriResolver: new PackageMapUriResolver(provider, {
- 'a': [provider.getFile(a).parent]
+ packageUriResolver: new PackageMapUriResolver(resourceProvider, {
+ 'a': [a.parent]
}));
- driver2.addFile(b);
+ driver2.addFile(b.path);
while (scheduler.isAnalyzing) {
await new Future.delayed(new Duration(milliseconds: 1));
@@ -451,23 +418,21 @@
AnalysisDriver _newDriver({UriResolver packageUriResolver}) {
var resolvers = <UriResolver>[
new DartUriResolver(sdk),
- new ResourceUriResolver(provider)
+ new ResourceUriResolver(resourceProvider)
];
if (packageUriResolver != null) {
resolvers.add(packageUriResolver);
}
- resolvers.add(new ResourceUriResolver(provider));
+ resolvers.add(new ResourceUriResolver(resourceProvider));
return new AnalysisDriver(
scheduler,
logger,
- provider,
+ resourceProvider,
byteStore,
contentOverlay,
null,
- new SourceFactory(resolvers, null, provider),
+ new SourceFactory(resolvers, null, resourceProvider),
new AnalysisOptionsImpl()..strongMode = true);
}
-
- String _p(String path) => provider.convertPath(path);
}
diff --git a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
index 38e71a9..db3d3f9 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/plugin/plugin_locator.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -14,17 +14,14 @@
}
@reflectiveTest
-class PluginLocatorTest {
- MemoryResourceProvider resourceProvider;
+class PluginLocatorTest extends Object with ResourceProviderMixin {
String packageRoot;
String pubspecPath;
String defaultDirPath;
PluginLocator locator;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
- packageRoot = resourceProvider.convertPath('/package');
- resourceProvider.newFolder(packageRoot);
+ packageRoot = newFolder('/package').path;
locator = new PluginLocator(resourceProvider);
}
@@ -66,25 +63,23 @@
}
void _createDefaultDir() {
- defaultDirPath = resourceProvider.pathContext.join(packageRoot,
- PluginLocator.toolsFolderName, PluginLocator.defaultPluginFolderName);
- resourceProvider.newFolder(defaultDirPath);
+ defaultDirPath = newFolder(
+ '/package/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}')
+ .path;
}
void _createPubspec(String content) {
- pubspecPath = resourceProvider.pathContext
- .join(packageRoot, PluginLocator.pubspecFileName);
- resourceProvider.newFile(pubspecPath, content);
+ pubspecPath =
+ newFile('/package/${PluginLocator.pubspecFileName}', content: content)
+ .path;
}
String _createPubspecWithKey() {
- String nonDefaultPath =
- resourceProvider.pathContext.join(packageRoot, 'pluginDir');
+ String nonDefaultPath = newFolder('/package/pluginDir').path;
_createPubspec('''
name: test_project
${PluginLocator.analyzerPluginKey}: $nonDefaultPath
''');
- resourceProvider.newFolder(nonDefaultPath);
return nonDefaultPath;
}
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index c9665cd..5d3e5b9a 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -9,9 +9,9 @@
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/channel/channel.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -105,7 +105,6 @@
@reflectiveTest
class DiscoveredPluginInfoTest {
- MemoryResourceProvider resourceProvider;
TestNotificationManager notificationManager;
String pluginPath = '/pluginDir';
String executionPath = '/pluginDir/bin/plugin.dart';
@@ -113,7 +112,6 @@
DiscoveredPluginInfo plugin;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
notificationManager = new TestNotificationManager();
plugin = new DiscoveredPluginInfo(pluginPath, executionPath, packagesPath,
notificationManager, InstrumentationService.NULL_SERVICE);
@@ -401,15 +399,13 @@
}
@reflectiveTest
-class PluginManagerTest {
- MemoryResourceProvider resourceProvider;
+class PluginManagerTest extends Object with ResourceProviderMixin {
String byteStorePath;
String sdkPath;
TestNotificationManager notificationManager;
PluginManager manager;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
byteStorePath = resourceProvider.convertPath('/byteStore');
sdkPath = resourceProvider.convertPath('/sdk');
notificationManager = new TestNotificationManager();
@@ -433,16 +429,13 @@
}
void test_pathsFor_withPackagesFile() {
- path.Context context = resourceProvider.pathContext;
//
// Build the minimal directory structure for a plugin package that includes
// a .packages file.
//
- String pluginDirPath = resourceProvider.convertPath('/plugin');
- String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart');
- resourceProvider.newFile(pluginFilePath, '');
- String packagesFilePath = context.join(pluginDirPath, '.packages');
- resourceProvider.newFile(packagesFilePath, '');
+ String pluginDirPath = newFolder('/plugin').path;
+ String pluginFilePath = newFile('/plugin/bin/plugin.dart').path;
+ String packagesFilePath = newFile('/plugin/.packages').path;
//
// Test path computation.
//
@@ -453,20 +446,17 @@
}
void test_pathsFor_withPubspec_inBazelWorkspace() {
- path.Context context = resourceProvider.pathContext;
//
// Build a Bazel workspace containing four packages, including the plugin.
//
- String rootPath = resourceProvider.convertPath('/workspaceRoot');
- resourceProvider.newFile(context.join(rootPath, 'WORKSPACE'), '');
- resourceProvider.newFolder(context.join(rootPath, 'bazel-bin'));
- resourceProvider.newFolder(context.join(rootPath, 'bazel-genfiles'));
+ newFile('/workspaceRoot/WORKSPACE');
+ newFolder('/workspaceRoot/bazel-bin');
+ newFolder('/workspaceRoot/bazel-genfiles');
String newPackage(String packageName, [List<String> dependencies]) {
String packageRoot =
- context.join(rootPath, 'third_party', 'dart', packageName);
- resourceProvider.newFile(
- context.join(packageRoot, 'lib', packageName + '.dart'), '');
+ newFolder('/workspaceRoot/third_party/dart/$packageName').path;
+ newFile('$packageRoot/lib/$packageName.dart');
StringBuffer buffer = new StringBuffer();
if (dependencies != null) {
buffer.writeln('dependencies:');
@@ -474,8 +464,7 @@
buffer.writeln(' $dependency: any');
}
}
- resourceProvider.newFile(
- context.join(packageRoot, 'pubspec.yaml'), buffer.toString());
+ newFile('$packageRoot/pubspec.yaml', content: buffer.toString());
return packageRoot;
}
@@ -483,15 +472,14 @@
newPackage('b', ['d']);
newPackage('c', ['d']);
newPackage('d');
- String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart');
- resourceProvider.newFile(pluginFilePath, '');
+ String pluginFilePath = newFile('$pluginDirPath/bin/plugin.dart').path;
//
// Test path computation.
//
List<String> paths = manager.pathsFor(pluginDirPath);
expect(paths, hasLength(2));
expect(paths[0], pluginFilePath);
- File packagesFile = resourceProvider.getFile(paths[1]);
+ File packagesFile = getFile(paths[1]);
expect(packagesFile.exists, isTrue);
String content = packagesFile.readAsStringSync();
List<String> lines = content.split('\n');
@@ -539,8 +527,7 @@
}
@reflectiveTest
-class PluginSessionTest {
- MemoryResourceProvider resourceProvider;
+class PluginSessionTest extends Object with ResourceProviderMixin {
TestNotificationManager notificationManager;
String pluginPath;
String executionPath;
@@ -550,7 +537,6 @@
PluginSession session;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
notificationManager = new TestNotificationManager();
pluginPath = resourceProvider.convertPath('/pluginDir');
executionPath = resourceProvider.convertPath('/pluginDir/bin/plugin.dart');
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 27f99f5..2707c57 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -17,6 +17,7 @@
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:path/path.dart' as path;
@@ -32,29 +33,22 @@
}
@reflectiveTest
-class PluginWatcherTest {
- MemoryResourceProvider resourceProvider;
+class PluginWatcherTest extends Object with ResourceProviderMixin {
TestPluginManager manager;
PluginWatcher watcher;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
manager = new TestPluginManager();
watcher = new PluginWatcher(resourceProvider, manager);
}
test_addedDriver() async {
- String pkg1Path = resourceProvider.convertPath('/pkg1');
- resourceProvider.newFile(
- resourceProvider.convertPath('/pkg1/lib/test1.dart'), '');
- resourceProvider.newFile(
- resourceProvider.convertPath('/pkg2/lib/pkg2.dart'), '');
- resourceProvider.newFile(
- resourceProvider.convertPath('/pkg2/pubspec.yaml'), 'name: pkg2');
- resourceProvider.newFile(
- resourceProvider.convertPath(
- '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart'),
- '');
+ String pkg1Path = newFolder('/pkg1').path;
+ newFile('/pkg1/lib/test1.dart');
+ newFile('/pkg2/lib/pkg2.dart');
+ newFile('/pkg2/pubspec.yaml', content: 'name: pkg2');
+ newFile(
+ '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart');
ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
TestDriver driver = new TestDriver(resourceProvider, contextRoot);
@@ -82,9 +76,8 @@
}
test_addedDriver_missingPackage() async {
- String pkg1Path = resourceProvider.convertPath('/pkg1');
- resourceProvider.newFile(
- resourceProvider.convertPath('/pkg1/lib/test1.dart'), '');
+ String pkg1Path = newFolder('/pkg1').path;
+ newFile('/pkg1/lib/test1.dart');
ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
TestDriver driver = new TestDriver(resourceProvider, contextRoot);
@@ -106,7 +99,7 @@
}
test_removedDriver() {
- String pkg1Path = resourceProvider.convertPath('/pkg1');
+ String pkg1Path = newFolder('/pkg1').path;
ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
TestDriver driver = new TestDriver(resourceProvider, contextRoot);
watcher.addedDriver(driver, contextRoot);
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart
index 19b72c9..2fe0471 100644
--- a/pkg/analysis_server/test/src/watch_manager_test.dart
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart
@@ -6,7 +6,7 @@
import 'package:analysis_server/src/watch_manager.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart';
@@ -72,67 +72,66 @@
}
@reflectiveTest
-class WatchManagerTest {
- MemoryResourceProvider provider;
+class WatchManagerTest extends Object with ResourceProviderMixin {
WatchListener listener;
WatchManager<Token> manager;
void setUp() {
- provider = new MemoryResourceProvider();
listener = new WatchListener();
- manager = new WatchManager<Token>(provider, listener.handleWatchEvent);
+ manager =
+ new WatchManager<Token>(resourceProvider, listener.handleWatchEvent);
}
Future test_addFolder_folderAndSubfolder() async {
- Folder topFolder = provider.getFolder('/a/b');
- Folder childFolder = provider.getFolder('/a/b/c/d');
+ Folder topFolder = getFolder('/a/b');
+ Folder childFolder = getFolder('/a/b/c/d');
Token topToken = new Token('topToken');
Token childToken = new Token('childToken');
manager.addFolder(topFolder, topToken);
manager.addFolder(childFolder, childToken);
- File newFile1 = provider.newFile('/a/b/c/lib.dart', '');
+ File newFile1 = newFile('/a/b/c/lib.dart');
await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]);
- File newFile2 = provider.newFile('/a/b/c/d/lib.dart', '');
+ File newFile2 = newFile('/a/b/c/d/lib.dart');
return _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]);
}
Future test_addFolder_singleFolder_multipleTokens() {
- Folder folder = provider.getFolder('/a/b');
+ Folder folder = getFolder('/a/b');
Token token1 = new Token('token1');
Token token2 = new Token('token2');
manager.addFolder(folder, token1);
manager.addFolder(folder, token2);
- File newFile = provider.newFile('/a/b/lib.dart', '');
- return _expectEvent(ChangeType.ADD, newFile.path, [token1, token2]);
+ File addedFile = newFile('/a/b/lib.dart');
+ return _expectEvent(ChangeType.ADD, addedFile.path, [token1, token2]);
}
Future test_addFolder_singleFolder_singleToken() async {
- Folder folder = provider.getFolder('/a/b');
+ Folder folder = getFolder('/a/b');
Token token = new Token('token');
manager.addFolder(folder, token);
- Folder newFolder = provider.newFolder('/a/b/c');
- await _expectEvent(ChangeType.ADD, newFolder.path, [token]);
+ Folder addedFolder = newFolder('/a/b/c');
+ await _expectEvent(ChangeType.ADD, addedFolder.path, [token]);
- File newFile = provider.newFile('/a/b/c/lib.dart', '');
- return _expectEvent(ChangeType.ADD, newFile.path, [token]);
+ File addedFile = newFile('/a/b/c/lib.dart');
+ return _expectEvent(ChangeType.ADD, addedFile.path, [token]);
}
Future test_addFolder_unrelatedFolders() async {
- Folder folder1 = provider.getFolder('/a/b');
- Folder folder2 = provider.getFolder('/c/d');
+ Folder folder1 = getFolder('/a/b');
+ Folder folder2 = getFolder('/c/d');
Token token1 = new Token('token1');
Token token2 = new Token('token2');
manager.addFolder(folder1, token1);
manager.addFolder(folder2, token2);
- File newFile1 = provider.newFile('/a/b/lib.dart', '');
+ File newFile1 = newFile('/a/b/lib.dart');
await _expectEvent(ChangeType.ADD, newFile1.path, [token1]);
- File newFile2 = provider.newFile('/c/d/lib.dart', '');
+ File newFile2 = newFile('/c/d/lib.dart');
return _expectEvent(ChangeType.ADD, newFile2.path, [token2]);
}
@@ -141,40 +140,40 @@
}
Future test_removeFolder_multipleTokens() {
- Folder folder = provider.getFolder('/a/b');
+ Folder folder = getFolder('/a/b');
Token token1 = new Token('token1');
Token token2 = new Token('token2');
manager.addFolder(folder, token1);
manager.addFolder(folder, token2);
manager.removeFolder(folder, token2);
- File newFile = provider.newFile('/a/b/lib.dart', '');
- return _expectEvent(ChangeType.ADD, newFile.path, [token1]);
+ File addedFile = newFile('/a/b/lib.dart');
+ return _expectEvent(ChangeType.ADD, addedFile.path, [token1]);
}
Future test_removeFolder_withChildren() async {
- Folder topFolder = provider.getFolder('/a/b');
- Folder childFolder = provider.getFolder('/a/b/c/d');
+ Folder topFolder = getFolder('/a/b');
+ Folder childFolder = getFolder('/a/b/c/d');
Token topToken = new Token('topToken');
Token childToken = new Token('childToken');
manager.addFolder(topFolder, topToken);
manager.addFolder(childFolder, childToken);
manager.removeFolder(topFolder, topToken);
- File newFile = provider.newFile('/a/b/c/d/lib.dart', '');
- await _expectEvent(ChangeType.ADD, newFile.path, [childToken]);
+ File addedFile = newFile('/a/b/c/d/lib.dart');
+ await _expectEvent(ChangeType.ADD, addedFile.path, [childToken]);
- provider.newFile('/a/b/lib.dart', '');
+ newFile('/a/b/lib.dart');
return _expectNoEvent();
}
Future test_removeFolder_withNoChildren() {
- Folder folder = provider.getFolder('/a/b');
+ Folder folder = getFolder('/a/b');
Token token = new Token('token');
manager.addFolder(folder, token);
manager.removeFolder(folder, token);
- provider.newFile('/a/b/lib.dart', '');
+ newFile('/a/b/lib.dart');
return _expectNoEvent();
}
@@ -197,11 +196,9 @@
}
@reflectiveTest
-class WatchNodeTest {
- MemoryResourceProvider provider = new MemoryResourceProvider();
-
+class WatchNodeTest extends Object with ResourceProviderMixin {
void test_creation_folder() {
- Folder folder = provider.getFolder('/a/b');
+ Folder folder = getFolder('/a/b');
WatchNode node = new WatchNode(folder);
expect(node, isNotNull);
expect(node.children, isEmpty);
@@ -223,9 +220,9 @@
void test_delete_nested_child() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
- WatchNode grandchildNode = new WatchNode(provider.getFolder('/a/b/c/d/e'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
+ WatchNode grandchildNode = new WatchNode(getFolder('/a/b/c/d/e'));
rootNode.insert(topNode);
rootNode.insert(childNode);
rootNode.insert(grandchildNode);
@@ -239,8 +236,8 @@
void test_delete_nested_noChild() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
rootNode.insert(topNode);
rootNode.insert(childNode);
@@ -252,8 +249,8 @@
void test_delete_top_child() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
rootNode.insert(topNode);
rootNode.insert(childNode);
@@ -264,7 +261,7 @@
void test_delete_top_noChild() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
rootNode.insert(topNode);
topNode.delete();
@@ -273,7 +270,7 @@
void test_findParent_childOfLeaf() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
rootNode.insert(topNode);
expect(rootNode.findParent('/a/b/c'), topNode);
@@ -281,8 +278,8 @@
void test_findParent_childOfNonLeaf() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
rootNode.insert(topNode);
rootNode.insert(childNode);
@@ -291,7 +288,7 @@
void test_findParent_noMatch() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
rootNode.insert(topNode);
expect(rootNode.findParent('/c/d'), rootNode);
@@ -299,9 +296,9 @@
void test_insert_intermediate_afterParentAndChild() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
- WatchNode intermediateNode = new WatchNode(provider.getFolder('/a/b/c'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
+ WatchNode intermediateNode = new WatchNode(getFolder('/a/b/c'));
rootNode.insert(topNode);
rootNode.insert(childNode);
@@ -316,8 +313,8 @@
void test_insert_nested_afterParent() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
rootNode.insert(topNode);
rootNode.insert(childNode);
@@ -328,8 +325,8 @@
void test_insert_nested_beforeParent() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
+ WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
rootNode.insert(childNode);
rootNode.insert(topNode);
@@ -340,7 +337,7 @@
void test_insert_top() {
WatchNode rootNode = new WatchNode(null);
- WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+ WatchNode topNode = new WatchNode(getFolder('/a/b'));
rootNode.insert(topNode);
expect(rootNode.children, equals([topNode]));
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 20bd277..b06f3f7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -551,6 +551,7 @@
for (ImportElement importElement in _libraryElement.imports) {
if (matchNodeElement(directive, importElement)) {
directive.element = importElement;
+ directive.prefix?.staticElement = importElement.prefix;
Source source = importElement.importedLibrary?.source;
if (source != null && !_isLibrarySource(source)) {
ErrorCode errorCode = importElement.isDeferred
@@ -1227,22 +1228,15 @@
kernel.VariableDeclaration variable = kernelType.function.variable;
FunctionElement element = declarationToElement[variable];
return element.type;
- } else if (kernelType is kernel.MemberInvocationDartType) {
- kernel.Member member = kernelType.member;
- if (member is kernel.Procedure &&
- member.kind == kernel.ProcedureKind.Method) {
- ExecutableElementImpl element =
- resynthesizer.getElementFromCanonicalName(member.canonicalName);
- return resynthesizer.instantiateFunctionType(
- context,
- element,
- member.function,
- member.function.functionType.withoutTypeParameters,
- kernelType.type);
- }
- return DynamicTypeImpl.instance;
} else if (kernelType is kernel.IndexAssignNullFunctionType) {
return null;
+ } else if (kernelType is kernel.TypeArgumentsDartType) {
+ List<kernel.DartType> kernelTypes = kernelType.types;
+ var types = new List<DartType>(kernelTypes.length);
+ for (var i = 0; i < kernelTypes.length; i++) {
+ types[i] = translateType(kernelTypes[i]);
+ }
+ return new TypeArgumentsDartType(types);
} else {
return resynthesizer.getType(context, kernelType);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 0f26c2c..8da11b2 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -8603,11 +8603,11 @@
@override
String get name {
- if (_kernel != null) {
- return _kernel.name;
- }
- if (_unlinkedImport != null) {
- if (_name == null) {
+ if (_name == null) {
+ if (_kernel != null) {
+ return _name = _kernel.name;
+ }
+ if (_unlinkedImport != null) {
LibraryElementImpl library = enclosingElement as LibraryElementImpl;
int prefixId = _unlinkedImport.prefixReference;
return _name = library._unlinkedDefiningUnit.references[prefixId].name;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index f5c683c..61f5a19 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -19,7 +19,6 @@
MemberKind,
optional,
Parser;
-import 'package:front_end/src/fasta/scanner/string_scanner.dart';
import 'package:front_end/src/fasta/scanner.dart' hide StringToken;
import 'package:front_end/src/scanner/token.dart'
show
@@ -2696,83 +2695,10 @@
}
@override
- Token injectGenericCommentTypeAssign(Token token) {
- // TODO(paulberry,scheglov,ahe): figure out how to share these generic
- // comment methods with BodyBuilder.
- return _injectGenericComment(
- token, TokenType.GENERIC_METHOD_TYPE_ASSIGN, 3);
- }
-
- @override
- Token injectGenericCommentTypeList(Token token) {
- return _injectGenericComment(token, TokenType.GENERIC_METHOD_TYPE_LIST, 2);
- }
-
- @override
- Token replaceTokenWithGenericCommentTypeAssign(
- Token tokenToStartReplacing, Token tokenWithComment) {
- Token injected = injectGenericCommentTypeAssign(tokenWithComment);
- if (!identical(injected, tokenWithComment)) {
- Token prev = tokenToStartReplacing.previous;
- prev.setNextWithoutSettingPrevious(injected);
- tokenToStartReplacing = injected;
- tokenToStartReplacing.previous = prev;
- }
- return tokenToStartReplacing;
- }
-
- @override
void discardTypeReplacedWithCommentTypeAssign() {
pop();
}
- /// Check if the given [token] has a comment token with the given [type],
- /// which should be either [TokenType.GENERIC_METHOD_TYPE_ASSIGN] or
- /// [TokenType.GENERIC_METHOD_TYPE_LIST]. If found, parse the comment
- /// into tokens and inject into the token stream before the [token].
- Token _injectGenericComment(Token token, TokenType type, int prefixLen) {
- if (parseGenericMethodComments) {
- CommentToken t = token.precedingComments;
- for (; t != null; t = t.next) {
- if (t.type == type) {
- String code = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
- Token tokens = _scanGenericMethodComment(code, t.offset + prefixLen);
- if (tokens != null) {
- // Remove the token from the comment stream.
- t.remove();
- // Insert the tokens into the stream.
- _injectTokenList(token, tokens);
- return tokens;
- }
- }
- }
- }
- return token;
- }
-
- void _injectTokenList(Token beforeToken, Token firstToken) {
- // Scanner creates a cyclic EOF token.
- Token lastToken = firstToken;
- while (lastToken.next.type != TokenType.EOF) {
- lastToken = lastToken.next;
- }
- // Inject these new tokens into the stream.
- Token previous = beforeToken.previous;
- lastToken.setNext(beforeToken);
- previous.setNext(firstToken);
- beforeToken = firstToken;
- }
-
- /// Scans the given [code], and returns the tokens, otherwise returns `null`.
- Token _scanGenericMethodComment(String code, int offset) {
- var scanner = new SubStringScanner(offset, code);
- Token firstToken = scanner.tokenize();
- if (scanner.hasErrors) {
- return null;
- }
- return firstToken;
- }
-
@override
void addCompileTimeError(Message message, int offset, int length) {
if (directives.isEmpty &&
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 02e3688..0976bb8 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -18,8 +18,10 @@
/// [errorReporter].
FastaErrorReporter(this.errorReporter);
- void reportByCode(String analyzerCode, int offset, int length,
- Map<String, dynamic> arguments) {
+ void reportByCode(
+ String analyzerCode, int offset, int length, Message message) {
+ Map<String, dynamic> arguments = message.arguments;
+
String stringOrTokenLexeme() {
var text = arguments['string'];
if (text == null) {
@@ -293,8 +295,8 @@
StrongModeCode.INVALID_CAST_NEW_EXPR, offset, length);
return;
case "INVALID_MODIFIER_ON_SETTER":
- errorReporter?.reportErrorForOffset(
- CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, offset, length);
+ _reportByCode(CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, message,
+ offset, length);
return;
case "INVALID_OPERATOR":
String text = stringOrTokenLexeme();
@@ -302,8 +304,8 @@
ParserErrorCode.INVALID_OPERATOR, offset, length, [text]);
return;
case "INVALID_OPERATOR_FOR_SUPER":
- errorReporter?.reportErrorForOffset(
- ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, offset, length);
+ _reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message,
+ offset, length);
return;
case "LIBRARY_DIRECTIVE_NOT_FIRST":
errorReporter?.reportErrorForOffset(
@@ -547,6 +549,19 @@
void reportMessage(Message message, int offset, int length) {
Code code = message.code;
- reportByCode(code.analyzerCode, offset, length, message.arguments);
+ reportByCode(code.analyzerCode, offset, length, message);
+ }
+
+ void _reportByCode(
+ ErrorCode errorCode, Message message, int offset, int length) {
+ if (errorReporter != null) {
+ errorReporter.reportError(new AnalysisError.forValues(
+ errorReporter.source,
+ offset,
+ length,
+ errorCode,
+ message.message,
+ null));
+ }
}
}
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index ccc7295..99dcdc7 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -11,7 +11,6 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/fasta/resolution_storer.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:front_end/src/base/syntactic_entity.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:kernel/kernel.dart' as kernel;
@@ -95,6 +94,7 @@
operatorType != TokenType.BAR_BAR) {
node.staticElement = _getReferenceFor(node.operator);
_getTypeFor(node.operator); // function type of the operator
+ _getTypeFor(node.operator); // type arguments
}
// Record the return type of the expression.
@@ -290,6 +290,7 @@
// We cannot use the detached FunctionType of `[]` or `[]=`.
_getTypeFor(node.leftBracket);
+ _getTypeFor(node.leftBracket); // type arguments
node.staticType = _getTypeFor(node.leftBracket);
@@ -303,13 +304,14 @@
DartType type = _getTypeFor(constructorName);
ConstructorElement element = _getReferenceFor(constructorName);
+ constructorName.staticElement = element;
+
node.staticElement = element;
node.staticType = type;
applyConstructorElement(type, element, constructorName);
ArgumentList argumentList = node.argumentList;
- _associateArgumentsWithParameters(element?.parameters, argumentList);
_applyResolutionToArguments(argumentList);
}
@@ -348,6 +350,7 @@
Element invokeElement = _getReferenceFor(node.methodName);
DartType invokeType = _getTypeFor(node.methodName);
+ DartType typeArgumentsDartType = _getTypeFor(argumentList);
DartType resultType = _getTypeFor(argumentList);
if (invokeElement is PropertyInducingElement) {
@@ -361,10 +364,11 @@
node.methodName.staticType = invokeType;
if (invokeType is FunctionType) {
- if (node.typeArguments != null) {
- _applyTypeArgumentsToList(invokeType, node.typeArguments.arguments);
+ if (node.typeArguments != null &&
+ typeArgumentsDartType is TypeArgumentsDartType) {
+ _applyTypeArgumentsToList(
+ typeArgumentsDartType, node.typeArguments.arguments);
}
- _associateArgumentsWithParameters(invokeType.parameters, argumentList);
}
_applyResolutionToArguments(argumentList);
@@ -415,6 +419,7 @@
SyntacticEntity entity = node.operator;
node.staticElement = _getReferenceFor(entity);
_getTypeFor(entity); // The function type of the operator.
+ _getTypeFor(entity); // The type arguments (empty).
node.staticType = _getTypeFor(entity);
}
}
@@ -436,7 +441,6 @@
constructorName?.staticElement = element;
ArgumentList argumentList = node.argumentList;
- _associateArgumentsWithParameters(element?.parameters, argumentList);
_applyResolutionToArguments(argumentList);
}
@@ -543,33 +547,6 @@
}
}
- /// Associate arguments of the [argumentList] with the [parameters].
- void _associateArgumentsWithParameters(
- List<ParameterElement> parameters, ArgumentList argumentList) {
- if (parameters != null) {
- List<Expression> arguments = argumentList.arguments;
- var correspondingParameters =
- new List<ParameterElement>(arguments.length);
- for (int i = 0; i < arguments.length; i++) {
- var argument = arguments[i];
- if (argument is NamedExpression) {
- for (var parameter in parameters) {
- SimpleIdentifier label = argument.name.label;
- if (parameter.parameterKind == ParameterKind.NAMED &&
- parameter.name == label.name) {
- label.staticElement = parameter;
- correspondingParameters[i] = parameter;
- break;
- }
- }
- } else {
- correspondingParameters[i] = parameters[i];
- }
- }
- argumentList.correspondingStaticParameters = correspondingParameters;
- }
- }
-
/// Return the [SyntacticEntity] with which the front-end associates
/// assignment to the given [leftHandSide].
SyntacticEntity _getAssignmentEntity(Expression leftHandSide) {
@@ -775,6 +752,24 @@
}
}
+/// A container with [typeArguments].
+class TypeArgumentsDartType implements ParameterizedType {
+ @override
+ final List<DartType> typeArguments;
+
+ TypeArgumentsDartType(this.typeArguments);
+
+ @override
+ bool get isUndefined => false;
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ String toString() {
+ return '<${typeArguments.join(', ')}>';
+ }
+}
+
/// Context for translating types.
abstract class TypeContext {
/// The enclosing [ClassElement], or `null` if not in a class.
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index d1d04a9..e059b8b 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -160,21 +160,6 @@
}
}
-/// Information about invocation of the [member] and its instantiated [type].
-class MemberInvocationDartType implements DartType {
- final Member member;
- final FunctionType type;
-
- MemberInvocationDartType(this.member, this.type);
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
- @override
- String toString() {
- return '($member, $type)';
- }
-}
-
/// A reference to the setter represented by the [member].
/// The [member] might be either a setter itself, or a field.
class MemberSetterNode implements TreeNode {
@@ -381,6 +366,7 @@
void indexAssignAfterReceiver(Expression write, DartType typeContext) {
_deferReference(write.fileOffset);
_recordType(const IndexAssignNullFunctionType(), write.fileOffset);
+ _recordType(new TypeArgumentsDartType(<DartType>[]), write.fileOffset);
_deferType(write.fileOffset);
}
@@ -438,6 +424,7 @@
_deferType(expression.fileOffset);
}
_deferType(expression.fileOffset);
+ _deferType(expression.fileOffset);
super.methodInvocationBeforeArgs(expression, isImplicitCall);
}
@@ -450,11 +437,11 @@
FunctionType calleeType,
Substitution substitution,
DartType inferredType) {
- _replaceType(
- inferredType,
- arguments.fileOffset != -1
- ? arguments.fileOffset
- : expression.fileOffset);
+ int resultOffset = arguments.fileOffset != -1
+ ? arguments.fileOffset
+ : expression.fileOffset;
+ _replaceType(inferredType, resultOffset);
+ _replaceType(new TypeArgumentsDartType(arguments.types), resultOffset);
if (!isImplicitCall) {
if (interfaceMember is ForwardingStub) {
interfaceMember = ForwardingStub.getInterfaceTarget(interfaceMember);
@@ -463,7 +450,7 @@
FunctionType invokeType = substitution == null
? calleeType
: substitution.substituteType(calleeType.withoutTypeParameters);
- _replaceType(new MemberInvocationDartType(interfaceMember, invokeType));
+ _replaceType(invokeType);
}
super.genericExpressionExit("methodInvocation", expression, inferredType);
}
@@ -471,11 +458,11 @@
@override
void methodInvocationExitCall(Expression expression, Arguments arguments,
bool isImplicitCall, DartType inferredType) {
- _replaceType(
- inferredType,
- arguments.fileOffset != -1
- ? arguments.fileOffset
- : expression.fileOffset);
+ int resultOffset = arguments.fileOffset != -1
+ ? arguments.fileOffset
+ : expression.fileOffset;
+ _replaceType(inferredType, resultOffset);
+ _replaceType(new TypeArgumentsDartType(arguments.types), resultOffset);
if (!isImplicitCall) {
throw new UnimplementedError(); // TODO(scheglov): handle this case
}
@@ -620,6 +607,7 @@
// type later.
_deferType(expression.fileOffset);
_deferType(expression.arguments.fileOffset);
+ _deferType(expression.arguments.fileOffset);
return super.staticInvocationEnter(
expression, prefixName, targetOffset, targetClass, typeContext);
}
@@ -632,10 +620,11 @@
DartType inferredType) {
_replaceType(inferredType);
_replaceReference(expression.target);
+ _replaceType(new TypeArgumentsDartType(expression.arguments.types));
FunctionType invokeType = substitution == null
? calleeType
: substitution.substituteType(calleeType.withoutTypeParameters);
- _replaceType(new MemberInvocationDartType(expression.target, invokeType));
+ _replaceType(invokeType);
super.genericExpressionExit("staticInvocation", expression, inferredType);
}
@@ -768,3 +757,17 @@
_types[slot] = type;
}
}
+
+/// A [DartType] wrapper around invocation type arguments.
+class TypeArgumentsDartType implements DartType {
+ final List<DartType> types;
+
+ TypeArgumentsDartType(this.types);
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ String toString() {
+ return '<${types.join(', ')}>';
+ }
+}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 1b8b79e..75a93ec 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -750,6 +750,11 @@
static const String ANALYSIS_OPTIONS_YAML_FILE = 'analysis_options.yaml';
/**
+ * The file name used for pubspec files.
+ */
+ static const String PUBSPEC_YAML_FILE = 'pubspec.yaml';
+
+ /**
* The unique instance of this class.
*/
static final AnalysisEngine instance = new AnalysisEngine._();
diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart
index a3a6ee3..0b13b05 100644
--- a/pkg/analyzer/lib/src/kernel/resynthesize.dart
+++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart
@@ -238,87 +238,13 @@
}
if (kernelType is kernel.FunctionType) {
- var typedef = kernelType.typedef;
- if (typedef != null) {
- GenericTypeAliasElementImpl typedefElement =
- getElementFromCanonicalName(typedef.canonicalName);
- GenericFunctionTypeElementImpl functionElement =
- typedefElement.function;
- return instantiateFunctionType(
- context, functionElement, typedef, typedef.type, kernelType);
- }
- var typeElement =
- new GenericFunctionTypeElementImpl.forKernel(context, kernelType);
- return typeElement.type;
+ return _getFunctionType(context, kernelType);
}
// TODO(scheglov) Support other kernel types.
throw new UnimplementedError('For ${kernelType.runtimeType}');
}
- /// Given the [executable] element that corresponds to the [kernelNode],
- /// and the [kernelType] that is the instantiated type of [kernelNode],
- /// return the instantiated type of the [executable].
- FunctionType instantiateFunctionType(
- ElementImpl context,
- FunctionTypedElement executable,
- kernel.TreeNode kernelNode,
- kernel.FunctionType kernelRawType,
- kernel.FunctionType kernelType) {
- // Prepare all kernel type parameters.
- var kernelTypeParameters = <kernel.TypeParameter>[];
- for (kernel.TreeNode node = kernelNode; node != null; node = node.parent) {
- if (node is kernel.Class) {
- kernelTypeParameters.addAll(node.typeParameters);
- } else if (node is kernel.FunctionNode) {
- kernelTypeParameters.addAll(node.typeParameters);
- } else if (node is kernel.Typedef) {
- kernelTypeParameters.addAll(node.typeParameters);
- }
- }
-
- // If no type parameters, the raw type of the element will do.
- FunctionTypeImpl rawType = executable.type;
- if (kernelTypeParameters.isEmpty) {
- return rawType;
- }
-
- // Compute type arguments for kernel type parameters.
- var kernelMap = kernel.unifyTypes(
- kernelRawType, kernelType, kernelTypeParameters.toSet());
-
- // Prepare Analyzer type parameters, in the same order as kernel ones.
- var astTypeParameters = <TypeParameterElement>[];
- for (Element element = executable;
- element != null;
- element = element.enclosingElement) {
- if (element is TypeParameterizedElement) {
- astTypeParameters.addAll(element.typeParameters);
- }
- }
-
- // Convert kernel type arguments into Analyzer types.
- int length = astTypeParameters.length;
- var usedTypeParameters = <TypeParameterElement>[];
- var usedTypeArguments = <DartType>[];
- for (var i = 0; i < length; i++) {
- var kernelParameter = kernelTypeParameters[i];
- var kernelArgument = kernelMap[kernelParameter];
- if (kernelArgument != null) {
- DartType astArgument = getType(context, kernelArgument);
- usedTypeParameters.add(astTypeParameters[i]);
- usedTypeArguments.add(astArgument);
- }
- }
-
- if (usedTypeParameters.isEmpty) {
- return rawType;
- }
-
- // Replace Analyzer type parameters with type arguments.
- return rawType.substitute4(usedTypeParameters, usedTypeArguments);
- }
-
void _buildTypeProvider() {
var coreLibrary = getLibrary('dart:core');
var asyncLibrary = getLibrary('dart:async');
@@ -330,6 +256,44 @@
asyncLibrary.createLoadLibraryFunction(_typeProvider);
}
+ /// Return the [FunctionType] that corresponds to the given [kernelType].
+ FunctionType _getFunctionType(
+ ElementImpl context, kernel.FunctionType kernelType) {
+ if (kernelType.typedef != null) {
+ return _getTypedefType(context, kernelType);
+ }
+
+ var element = new FunctionElementImpl('', -1);
+ context.encloseElement(element);
+
+ // Set type parameters.
+ {
+ List<kernel.TypeParameter> typeParameters = kernelType.typeParameters;
+ int count = typeParameters.length;
+ var astTypeParameters = new List<TypeParameterElement>(count);
+ for (int i = 0; i < count; i++) {
+ astTypeParameters[i] =
+ new TypeParameterElementImpl.forKernel(element, typeParameters[i]);
+ }
+ element.typeParameters = astTypeParameters;
+ }
+
+ // Set formal parameters.
+ var parameters = _getFunctionTypeParameters(kernelType);
+ var positionalParameters = parameters[0];
+ var namedParameters = parameters[1];
+ var astParameters = ParameterElementImpl.forKernelParameters(
+ element,
+ kernelType.requiredParameterCount,
+ positionalParameters,
+ namedParameters);
+ element.parameters = astParameters;
+
+ element.returnType = getType(element, kernelType.returnType);
+
+ return new FunctionTypeImpl(element);
+ }
+
InterfaceType _getInterfaceType(ElementImpl context,
kernel.CanonicalName className, List<kernel.DartType> kernelArguments) {
var libraryName = className.parent;
@@ -358,6 +322,52 @@
uri, () => _analysisContext.sourceFactory.forUri(uri));
}
+ /// Return the [FunctionType] for the given typedef based [kernelType].
+ FunctionType _getTypedefType(
+ ElementImpl context, kernel.FunctionType kernelType) {
+ kernel.Typedef typedef = kernelType.typedef;
+
+ GenericTypeAliasElementImpl typedefElement =
+ getElementFromCanonicalName(typedef.canonicalName);
+ GenericFunctionTypeElementImpl functionElement = typedefElement.function;
+
+ var kernelTypeParameters = typedef.typeParameters;
+
+ // If no type parameters, the raw type of the element will do.
+ FunctionTypeImpl rawType = functionElement.type;
+ if (kernelTypeParameters.isEmpty) {
+ return rawType;
+ }
+
+ // Compute type arguments for kernel type parameters.
+ var kernelMap = kernel.unifyTypes(
+ typedef.type, kernelType, kernelTypeParameters.toSet());
+
+ // Prepare Analyzer type parameters, in the same order as kernel ones.
+ var astTypeParameters = typedefElement.typeParameters;
+
+ // Convert kernel type arguments into Analyzer types.
+ int length = astTypeParameters.length;
+ var usedTypeParameters = <TypeParameterElement>[];
+ var usedTypeArguments = <DartType>[];
+ for (var i = 0; i < length; i++) {
+ var kernelParameter = kernelTypeParameters[i];
+ var kernelArgument = kernelMap[kernelParameter];
+ if (kernelArgument != null) {
+ DartType astArgument = getType(context, kernelArgument);
+ usedTypeParameters.add(astTypeParameters[i]);
+ usedTypeArguments.add(astArgument);
+ }
+ }
+
+ if (usedTypeParameters.isEmpty) {
+ return rawType;
+ }
+
+ // Replace Analyzer type parameters with type arguments.
+ return rawType.substitute4(usedTypeParameters, usedTypeArguments);
+ }
+
/// Return the [TypeParameterElement] for the given [kernelTypeParameter].
TypeParameterElement _getTypeParameter(
ElementImpl context, kernel.TypeParameter kernelTypeParameter) {
@@ -391,6 +401,28 @@
libraryElement.exportNamespace = new Namespace({});
return libraryElement;
}
+
+ /// Return the list with exactly two elements - positional and named
+ /// parameter lists.
+ static List<List<kernel.VariableDeclaration>> _getFunctionTypeParameters(
+ kernel.FunctionType type) {
+ int positionalCount = type.positionalParameters.length;
+ var positionalParameters =
+ new List<kernel.VariableDeclaration>(positionalCount);
+ for (int i = 0; i < positionalCount; i++) {
+ String name = i < type.positionalParameterNames.length
+ ? type.positionalParameterNames[i]
+ : 'arg_$i';
+ positionalParameters[i] = new kernel.VariableDeclaration(name,
+ type: type.positionalParameters[i]);
+ }
+
+ var namedParameters = type.namedParameters
+ .map((k) => new kernel.VariableDeclaration(k.name, type: k.type))
+ .toList(growable: false);
+
+ return [positionalParameters, namedParameters];
+ }
}
/**
@@ -1090,22 +1122,7 @@
@override
List<List<kernel.VariableDeclaration>> getFunctionTypeParameters(
kernel.FunctionType type) {
- int positionalCount = type.positionalParameters.length;
- var positionalParameters =
- new List<kernel.VariableDeclaration>(positionalCount);
- for (int i = 0; i < positionalCount; i++) {
- String name = i < type.positionalParameterNames.length
- ? type.positionalParameterNames[i]
- : 'arg_$i';
- positionalParameters[i] = new kernel.VariableDeclaration(name,
- type: type.positionalParameters[i]);
- }
-
- var namedParameters = type.namedParameters
- .map((k) => new kernel.VariableDeclaration(k.name, type: k.type))
- .toList(growable: false);
-
- return [positionalParameters, namedParameters];
+ return KernelResynthesizer._getFunctionTypeParameters(type);
}
@override
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
new file mode 100644
index 0000000..3753998
--- /dev/null
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:path/path.dart' as path;
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
+
+class PubspecValidator {
+ /**
+ * The name of the sub-field (under `flutter`) whose value is a list of assets
+ * available to Flutter apps at runtime.
+ */
+ static const String ASSETS_FIELD = 'assets';
+
+ /**
+ * The name of the field whose value is a map of dependencies.
+ */
+ static const String DEPENDENCIES_FIELD = 'dependencies';
+
+ /**
+ * The name of the field whose value is a map of development dependencies.
+ */
+ static const String DEV_DEPENDENCIES_FIELD = 'dev_dependencies';
+
+ /**
+ * The name of the field whose value is a specification of Flutter-specific
+ * configuration data.
+ */
+ static const String FLUTTER_FIELD = 'flutter';
+
+ /**
+ * The name of the field whose value is the name of the package.
+ */
+ static const String NAME_FIELD = 'name';
+
+ /**
+ * The resource provider used to access the file system.
+ */
+ final ResourceProvider provider;
+
+ /**
+ * The source representing the file being validated.
+ */
+ final Source source;
+
+ /**
+ * Initialize a newly create validator to validate the content of the given
+ * [source].
+ */
+ PubspecValidator(this.provider, this.source);
+
+ /**
+ * Validate the given [contents].
+ */
+ List<AnalysisError> validate(Map<dynamic, YamlNode> contents) {
+ RecordingErrorListener recorder = new RecordingErrorListener();
+ ErrorReporter reporter = new ErrorReporter(recorder, source);
+
+ _validateDependencies(reporter, contents);
+ _validateFlutter(reporter, contents);
+ _validateName(reporter, contents);
+
+ return recorder.errors;
+ }
+
+ /**
+ * Return a map whose keys are the names of declared dependencies and whose
+ * values are the specifications of those dependencies. The map is extracted
+ * from the given [contents] using the given [key].
+ */
+ Map<dynamic, YamlNode> _getDeclaredDependencies(
+ ErrorReporter reporter, Map<String, YamlNode> contents, String key) {
+ YamlNode field = contents[key];
+ if (field == null) {
+ return <String, YamlNode>{};
+ } else if (field is YamlMap) {
+ return field.nodes;
+ }
+ _reportErrorForNode(
+ reporter, field, PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP, [key]);
+ return <String, YamlNode>{};
+ }
+
+ /**
+ * Report an error for the given node.
+ */
+ void _reportErrorForNode(
+ ErrorReporter reporter, YamlNode node, ErrorCode errorCode,
+ [List<Object> arguments]) {
+ SourceSpan span = node.span;
+ reporter.reportErrorForOffset(
+ errorCode, span.start.offset, span.length, arguments);
+ }
+
+ /**
+ * Validate the value of the required `name` field.
+ */
+ void _validateDependencies(
+ ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+ Map<dynamic, YamlNode> declaredDependencies =
+ _getDeclaredDependencies(reporter, contents, DEPENDENCIES_FIELD);
+ Map<dynamic, YamlNode> declaredDevDependencies =
+ _getDeclaredDependencies(reporter, contents, DEV_DEPENDENCIES_FIELD);
+
+ for (YamlNode packageName in declaredDevDependencies.keys) {
+ if (declaredDependencies.containsKey(packageName)) {
+ _reportErrorForNode(reporter, packageName,
+ PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY, [packageName.value]);
+ }
+ }
+ }
+
+ /**
+ * Validate the value of the optional `flutter` field.
+ */
+ void _validateFlutter(
+ ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+ YamlNode flutterField = contents[FLUTTER_FIELD];
+ if (flutterField is YamlMap) {
+ YamlNode assetsField = flutterField.nodes[ASSETS_FIELD];
+ if (assetsField is YamlList) {
+ path.Context context = provider.pathContext;
+ String packageRoot = context.dirname(source.fullName);
+ for (YamlNode entryValue in assetsField.nodes) {
+ if (entryValue is YamlScalar) {
+ Object entry = entryValue.value;
+ if (entry is String) {
+ String normalizedEntry = context.joinAll(path.posix.split(entry));
+ String assetPath = context.join(packageRoot, normalizedEntry);
+ if (!provider.getFile(assetPath).exists) {
+ _reportErrorForNode(
+ reporter,
+ entryValue,
+ PubspecWarningCode.ASSET_DOES_NOT_EXIST,
+ [entryValue.value]);
+ }
+ } else {
+ _reportErrorForNode(
+ reporter, entryValue, PubspecWarningCode.ASSET_NOT_STRING);
+ }
+ } else {
+ _reportErrorForNode(
+ reporter, entryValue, PubspecWarningCode.ASSET_NOT_STRING);
+ }
+ }
+ } else if (assetsField != null) {
+ _reportErrorForNode(
+ reporter, assetsField, PubspecWarningCode.ASSET_FIELD_NOT_LIST);
+ } else {
+ // TODO(brianwilkerson) Should we report an error if `assets` is
+ // missing?
+ }
+ if (flutterField.length > 1) {
+ // TODO(brianwilkerson) Should we report an error if `flutter` contains
+ // keys other than `assets`?
+ }
+ } else if (flutterField != null) {
+ _reportErrorForNode(
+ reporter, flutterField, PubspecWarningCode.FLUTTER_FIELD_NOT_MAP);
+ }
+ }
+
+ /**
+ * Validate the value of the required `name` field.
+ */
+ void _validateName(ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+ YamlNode nameField = contents[NAME_FIELD];
+ if (nameField == null) {
+ reporter.reportErrorForOffset(PubspecWarningCode.MISSING_NAME, 0, 0);
+ } else if (nameField is! YamlScalar || nameField.value is! String) {
+ _reportErrorForNode(
+ reporter, nameField, PubspecWarningCode.NAME_NOT_STRING);
+ }
+ }
+}
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
new file mode 100644
index 0000000..6629300
--- /dev/null
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/error/error.dart';
+
+/**
+ * The error codes used for warnings in analysis options files. The convention
+ * for this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what is
+ * wrong and, when appropriate, how the problem can be corrected.
+ */
+class PubspecWarningCode extends ErrorCode {
+ /**
+ * A code indicating that a specified asset does not exist.
+ *
+ * Parameters:
+ * 0: the path to the asset as given in the file.
+ */
+ static const PubspecWarningCode ASSET_DOES_NOT_EXIST =
+ const PubspecWarningCode(
+ 'ASSET_DOES_NOT_EXIST',
+ "The asset {0} does not exist.",
+ "Try creating the file or fixing the path to the file.");
+
+ /**
+ * A code indicating that the value of the asset field is not a list.
+ */
+ static const PubspecWarningCode ASSET_FIELD_NOT_LIST = const PubspecWarningCode(
+ 'ASSET_FIELD_NOT_LIST',
+ "The value of the 'asset' field is expected to be a list of relative file paths.",
+ "Try converting the value to be a list of relative file paths.");
+
+ /**
+ * A code indicating that an element in the asset list is not a string.
+ */
+ static const PubspecWarningCode ASSET_NOT_STRING = const PubspecWarningCode(
+ 'ASSET_NOT_STRING',
+ "Assets are expected to be a file paths (strings).",
+ "Try converting the value to be a string.");
+
+ /**
+ * A code indicating that the value of a dependencies field is not a map.
+ */
+ static const PubspecWarningCode DEPENDENCIES_FIELD_NOT_MAP =
+ const PubspecWarningCode(
+ 'DEPENDENCIES_FIELD_NOT_MAP',
+ "The value of the '{0}' field is expected to be a map.",
+ "Try converting the value to be a map.");
+
+ /**
+ * A code indicating that the value of the flutter field is not a map.
+ */
+ static const PubspecWarningCode FLUTTER_FIELD_NOT_MAP =
+ const PubspecWarningCode(
+ 'FLUTTER_FIELD_NOT_MAP',
+ "The value of the 'flutter' field is expected to be a map.",
+ "Try converting the value to be a map.");
+
+ /**
+ * A code indicating that the name field is missing.
+ */
+ static const PubspecWarningCode MISSING_NAME = const PubspecWarningCode(
+ 'MISSING_NAME',
+ "The name field is required but missing.",
+ "Try adding a field named 'name'.");
+
+ /**
+ * A code indicating that the name field is not a string.
+ */
+ static const PubspecWarningCode NAME_NOT_STRING = const PubspecWarningCode(
+ 'NAME_NOT_STRING',
+ "The value of the name field is expected to be a string.",
+ "Try converting the value to be a string.");
+
+ /**
+ * A code indicating that a package listed as a dev dependency is also listed
+ * as a normal dependency.
+ *
+ * Parameters:
+ * 0: the name of the package in the dev_dependency list.
+ */
+ static const PubspecWarningCode UNNECESSARY_DEV_DEPENDENCY =
+ const PubspecWarningCode(
+ 'UNNECESSARY_DEV_DEPENDENCY',
+ "The dev dependency on {0} is unnecessary because there is also a "
+ "normal dependency on that package.",
+ "Try removing the dev dependency.");
+
+ /**
+ * Initialize a newly created warning code to have the given [name], [message]
+ * and [correction].
+ */
+ const PubspecWarningCode(String name, String message, [String correction])
+ : super(name, message, correction);
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
+
+ @override
+ ErrorType get type => ErrorType.STATIC_WARNING;
+}
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
new file mode 100644
index 0000000..a85b628
--- /dev/null
+++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+
+/**
+ * A mixin for test classes that adds a [ResourceProvider] and utility methods
+ * for manipulating the file system. The utility methods all take a posix style
+ * path and convert it as appropriate for the actual platform.
+ */
+class ResourceProviderMixin {
+ final MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+
+ void deleteFile(String path) {
+ String convertedPath = resourceProvider.convertPath(path);
+ resourceProvider.deleteFile(convertedPath);
+ }
+
+ void deleteFolder(String path) {
+ String convertedPath = resourceProvider.convertPath(path);
+ resourceProvider.deleteFolder(convertedPath);
+ }
+
+ File getFile(String path) {
+ String convertedPath = resourceProvider.convertPath(path);
+ return resourceProvider.getFile(convertedPath);
+ }
+
+ Folder getFolder(String path) {
+ String convertedPath = resourceProvider.convertPath(path);
+ return resourceProvider.getFolder(convertedPath);
+ }
+
+ void modifyFile(String path, String content) {
+ String convertedPath = resourceProvider.convertPath(path);
+ resourceProvider.modifyFile(convertedPath, content);
+ }
+
+ File newFile(String path, {String content = ''}) {
+ String convertedPath = resourceProvider.convertPath(path);
+ return resourceProvider.newFile(convertedPath, content);
+ }
+
+ File newFileWithBytes(String path, List<int> bytes) {
+ String convertedPath = resourceProvider.convertPath(path);
+ return resourceProvider.newFileWithBytes(convertedPath, bytes);
+ }
+
+ Folder newFolder(String path) {
+ String convertedPath = resourceProvider.convertPath(path);
+ return resourceProvider.newFolder(convertedPath);
+ }
+}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index dcd7eb6..5fcef73 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -89,13 +89,6 @@
@override
@failingTest
- test_async_used_as_identifier_in_suffix() async {
- // Bad state: Expected element reference for analyzer offset 46; got one for kernel offset 48
- await super.test_async_used_as_identifier_in_suffix();
- }
-
- @override
- @failingTest
test_async_used_as_identifier_in_switch_label() async {
// Bad state: No reference information for async at 31
await super.test_async_used_as_identifier_in_switch_label();
@@ -1716,48 +1709,6 @@
@override
@failingTest
- test_invalidModifierOnSetter_member_async() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_member_async();
- }
-
- @override
- @failingTest
- test_invalidModifierOnSetter_member_asyncStar() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_member_asyncStar();
- }
-
- @override
- @failingTest
- test_invalidModifierOnSetter_member_syncStar() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_member_syncStar();
- }
-
- @override
- @failingTest
- test_invalidModifierOnSetter_topLevel_async() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_topLevel_async();
- }
-
- @override
- @failingTest
- test_invalidModifierOnSetter_topLevel_asyncStar() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_topLevel_asyncStar();
- }
-
- @override
- @failingTest
- test_invalidModifierOnSetter_topLevel_syncStar() async {
- // AnalysisException: Element mismatch in /test.dart at /test.dart
- await super.test_invalidModifierOnSetter_topLevel_syncStar();
- }
-
- @override
- @failingTest
test_invalidReferenceToThis_factoryConstructor() async {
// Expected 1 errors of type CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, found 0
await super.test_invalidReferenceToThis_factoryConstructor();
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 7bbdb16..ef9fde2 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -164,13 +164,6 @@
@failingTest
@override
- test_importDeferredLibraryWithLoadFunction() async {
- // ad state: Expected element reference for analyzer offset 60; got one for kernel offset 65
- return super.test_importDeferredLibraryWithLoadFunction();
- }
-
- @failingTest
- @override
test_invalidAssignment_instanceVariable() async {
// Expected 1 errors of type HintCode.INVALID_ASSIGNMENT, found 0
return super.test_invalidAssignment_instanceVariable();
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 6b1c577..7532ea0 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -31,16 +31,17 @@
@override
@failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/31625')
- test_ambiguousImport_showCombinator() async {
- return super.test_ambiguousImport_showCombinator();
+ @potentialAnalyzerProblem
+ test_abstractSuperMemberReference_superHasNoSuchMethod() async {
+ // super.m() is not resolved by front-end
+ return super.test_abstractSuperMemberReference_superHasNoSuchMethod();
}
@override
@failingTest
- @potentialAnalyzerProblem
- test_assignmentToFinals_importWithPrefix() async {
- return super.test_assignmentToFinals_importWithPrefix();
+ @FastaProblem('https://github.com/dart-lang/sdk/issues/31625')
+ test_ambiguousImport_showCombinator() async {
+ return super.test_ambiguousImport_showCombinator();
}
@override
@@ -136,13 +137,6 @@
@override
@failingTest
- @potentialAnalyzerProblem
- test_constEval_propertyExtraction_fieldStatic_targetType() async {
- return super.test_constEval_propertyExtraction_fieldStatic_targetType();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
test_constructorDeclaration_scope_signature() async {
return super.test_constructorDeclaration_scope_signature();
@@ -199,7 +193,7 @@
@override
@failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/30838')
+ @potentialAnalyzerProblem
test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
return super
.test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments();
@@ -207,7 +201,7 @@
@override
@failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/30838')
+ @potentialAnalyzerProblem
test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
return super
.test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments();
@@ -236,13 +230,6 @@
@override
@failingTest
- @potentialAnalyzerProblem
- test_importPrefixes_withFirstLetterDifference() async {
- return super.test_importPrefixes_withFirstLetterDifference();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/31641')
test_invalidAnnotation_constantVariable_field() async {
return super.test_invalidAnnotation_constantVariable_field();
@@ -338,13 +325,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_sharedDeferredPrefix() async {
- return super.test_sharedDeferredPrefix();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_staticAccessToInstanceMember_annotation() async {
return super.test_staticAccessToInstanceMember_annotation();
}
@@ -352,20 +332,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_typeType_class_prefixed() async {
- return super.test_typeType_class_prefixed();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeType_functionTypeAlias_prefixed() async {
- return super.test_typeType_functionTypeAlias_prefixed();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_undefinedIdentifier_synthetic_whenExpression() async {
return super.test_undefinedIdentifier_synthetic_whenExpression();
}
@@ -390,11 +356,4 @@
test_undefinedMethod_functionExpression_directCall() async {
return super.test_undefinedMethod_functionExpression_directCall();
}
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_undefinedSetter_importWithPrefix() async {
- return super.test_undefinedSetter_importWithPrefix();
- }
}
diff --git a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
index 9f45d2e..85e8b1c 100644
--- a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/src/dart/error/hint_codes.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'non_hint_code_driver_test.dart';
@@ -18,6 +19,11 @@
/// them, or know that this is an analyzer problem.
const potentialAnalyzerProblem = const Object();
+/// Tests marked with this annotation fail because of a Fasta problem.
+class FastaProblem {
+ const FastaProblem(String issueUri);
+}
+
@reflectiveTest
class NonHintCodeTest_Kernel extends NonHintCodeTest_Driver {
@override
@@ -52,14 +58,6 @@
await super.test_duplicateImport_as();
}
- @failingTest
- @override
- @potentialAnalyzerProblem
- test_importDeferredLibraryWithLoadFunction() async {
- // Appears to be an issue with resolution of import prefixes.
- await super.test_importDeferredLibraryWithLoadFunction();
- }
-
@override
test_unnecessaryCast_generics() async {
// dartbug.com/18953
@@ -76,6 +74,15 @@
verify([source]);
}
+ @override
+ @failingTest
+ @FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
+ test_unusedImport_annotationOnDirective() async {
+ // TODO(scheglov) We don't yet parse annotations on import directives.
+ fail('This test fails in checked mode (indirectly)');
+// await super.test_unusedImport_annotationOnDirective();
+ }
+
@failingTest
@override
@potentialAnalyzerProblem
@@ -89,20 +96,4 @@
test_unusedImport_metadata() async {
await super.test_unusedImport_metadata();
}
-
- @failingTest
- @override
- @potentialAnalyzerProblem
- test_unusedImport_prefix_topLevelFunction() async {
- // Appears to be an issue with resolution of import prefixes.
- await super.test_unusedImport_prefix_topLevelFunction();
- }
-
- @failingTest
- @override
- @potentialAnalyzerProblem
- test_unusedImport_prefix_topLevelFunction2() async {
- // Appears to be an issue with resolution of import prefixes.
- await super.test_unusedImport_prefix_topLevelFunction2();
- }
}
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 9e4bdb6..eef6b16 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -55,14 +55,57 @@
@reflectiveTest
class ClassMemberParserTest_Fasta extends FastaParserTestCase
- with ClassMemberParserTestMixin {}
+ with ClassMemberParserTestMixin {
+ @override
+ void test_parseClassMember_method_generic_comment_noReturnType() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_generic_comment_parameterType() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_generic_comment_returnType() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_generic_comment_returnType_bound() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_generic_comment_returnType_complex() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_generic_comment_void() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseClassMember_method_static_generic_comment_returnType() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+}
/**
* Tests of the fasta parser based on [ComplexParserTestMixin].
*/
@reflectiveTest
class ComplexParserTest_Fasta extends FastaParserTestCase
- with ComplexParserTestMixin {}
+ with ComplexParserTestMixin {
+ @override
+ @failingTest
+ void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+ // Fasta does not support the generic comment syntax.
+ super
+ .test_assignableExpression_arguments_normal_chain_typeArgumentComments();
+ }
+}
/**
* Tests of the fasta parser based on [ErrorParserTest].
@@ -715,14 +758,6 @@
@override
@failingTest
- void test_invalidOperatorAfterSuper_assignableExpression() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, found 0
- super.test_invalidOperatorAfterSuper_assignableExpression();
- }
-
- @override
- @failingTest
void test_invalidOperatorAfterSuper_primaryExpression() {
// TODO(brianwilkerson) Does not recover.
// Expected: true
@@ -1698,6 +1733,81 @@
class ExpressionParserTest_Fasta extends FastaParserTestCase
with ExpressionParserTestMixin {
@override
+ void
+ test_parseAssignableExpression_expression_args_dot_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parseAssignableExpression_identifier_args_dot_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseCascadeSection_ia_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseCascadeSection_ii_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseCascadeSection_pa_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseCascadeSection_paa_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseCascadeSection_paapaa_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseConstExpression_listLiteral_typed_genericComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseConstExpression_mapLiteral_typed_genericComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseExpression_superMethodInvocation_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseFunctionExpression_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parseInstanceCreationExpression_qualifiedType_named_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parseInstanceCreationExpression_qualifiedType_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
@failingTest
void test_parseInstanceCreationExpression_type_named_typeArgumentComments() {
// TODO(brianwilkerson) Does not inject generic type arguments.
@@ -1706,6 +1816,33 @@
}
@override
+ void test_parseInstanceCreationExpression_type_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parsePrimaryExpression_listLiteral_typed_genericComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parsePrimaryExpression_mapLiteral_typed_genericComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
@failingTest
void test_parseUnaryExpression_decrement_super() {
// TODO(brianwilkerson) Does not recover.
@@ -1742,7 +1879,8 @@
/**
* Whether generic method comments should be enabled for the test.
*/
- bool enableGenericMethodComments = false;
+ bool get enableGenericMethodComments => false;
+ void set enableGenericMethodComments(bool enable) {}
@override
set enableLazyAssignmentOperators(bool value) {
@@ -2216,6 +2354,21 @@
}
@override
+ void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
@failingTest
void test_parseNormalFormalParameter_simple_const_noType() {
// TODO(brianwilkerson) Wrong errors:
@@ -2547,13 +2700,6 @@
@override
@failingTest
- void test_incompleteForEach() {
- // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
- super.test_incompleteForEach();
- }
-
- @override
- @failingTest
void test_incompleteLocalVariable_beforeIdentifier() {
// TODO(brianwilkerson) reportUnrecoverableErrorWithToken
super.test_incompleteLocalVariable_beforeIdentifier();
@@ -2707,6 +2853,42 @@
// Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
super.test_parseContinueStatement_noLabel();
}
+
+ @override
+ void test_parseFunctionDeclarationStatement_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void
+ test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseVariableDeclarationListAfterMetadata_const_typeComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseVariableDeclarationListAfterMetadata_dynamic_typeComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseVariableDeclarationListAfterMetadata_final_typeComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseVariableDeclarationListAfterMetadata_type_typeComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseVariableDeclarationListAfterMetadata_var_typeComment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
}
/**
@@ -2800,4 +2982,14 @@
super.test_parseCompilationUnitMember_abstractAsPrefix();
assertNoErrors();
}
+
+ @override
+ void test_parseFunctionDeclaration_functionWithTypeParameters_comment() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
+
+ @override
+ void test_parseFunctionDeclaration_getter_generic_comment_returnType() {
+ // Ignored: Fasta does not support the generic comment syntax.
+ }
}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index d0e036d..809fa22 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -834,6 +834,32 @@
expect(method.body, isNotNull);
}
+ void test_parseClassMember_method_generic_parameterType() {
+ createParser('m<T>(T p) => null;');
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ MethodDeclaration method = member;
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+ expect(method.returnType, isNull);
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+
+ FormalParameterList parameters = method.parameters;
+ expect(parameters, isNotNull);
+ expect(parameters.parameters, hasLength(1));
+ var parameter = parameters.parameters[0] as SimpleFormalParameter;
+ var parameterType = parameter.type as TypeName;
+ expect(parameterType.name.name, 'T');
+
+ expect(method.body, isNotNull);
+ }
+
void test_parseClassMember_method_generic_returnType() {
createParser('T m<T>() {}');
ClassMember member = parser.parseClassMember('C');
@@ -853,6 +879,79 @@
expect(method.body, isNotNull);
}
+ void test_parseClassMember_method_generic_returnType_bound() {
+ createParser('T m<T extends num>() {}');
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ MethodDeclaration method = member;
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+ expect((method.returnType as TypeName).name.name, 'T');
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ TypeParameter tp = method.typeParameters.typeParameters[0];
+ expect(tp.name.name, 'T');
+ expect(tp.extendsKeyword, isNotNull);
+ expect((tp.bound as TypeName).name.name, 'num');
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
+ void test_parseClassMember_method_generic_returnType_complex() {
+ createParser('Map<int, T> m<T>() => null;');
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ MethodDeclaration method = member;
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+
+ {
+ var returnType = method.returnType as TypeName;
+ expect(returnType, isNotNull);
+ expect(returnType.name.name, 'Map');
+
+ List<TypeAnnotation> typeArguments = returnType.typeArguments.arguments;
+ expect(typeArguments, hasLength(2));
+ expect((typeArguments[0] as TypeName).name.name, 'int');
+ expect((typeArguments[1] as TypeName).name.name, 'T');
+ }
+
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
+ void test_parseClassMember_method_generic_returnType_static() {
+ createParser('static T m<T>() {}');
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertNoErrors();
+ expect(member, new isInstanceOf<MethodDeclaration>());
+ MethodDeclaration method = member;
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNotNull);
+ expect(method.propertyKeyword, isNull);
+ expect(method.returnType, isNotNull);
+ expect((method.returnType as TypeName).name.name, 'T');
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
void test_parseClassMember_method_generic_void() {
createParser('void m<T>() {}');
ClassMember member = parser.parseClassMember('C');
@@ -4659,6 +4758,21 @@
]);
}
+ void test_switchCase_missingColon() {
+ SwitchStatement statement = parseStatement('switch (a) {case 1 return 0;}');
+ expect(statement, isNotNull);
+ listener
+ .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 6)]);
+ }
+
+ void test_switchDefault_missingColon() {
+ SwitchStatement statement =
+ parseStatement('switch (a) {default return 0;}');
+ expect(statement, isNotNull);
+ listener
+ .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 6)]);
+ }
+
void test_switchHasCaseAfterDefaultCase() {
SwitchStatement statement =
parseStatement('switch (a) {default: return 0; case 1: return 1;}');
@@ -4697,21 +4811,6 @@
]);
}
- void test_switchCase_missingColon() {
- SwitchStatement statement = parseStatement('switch (a) {case 1 return 0;}');
- expect(statement, isNotNull);
- listener
- .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 6)]);
- }
-
- void test_switchDefault_missingColon() {
- SwitchStatement statement =
- parseStatement('switch (a) {default return 0;}');
- expect(statement, isNotNull);
- listener
- .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 6)]);
- }
-
void test_switchMissingBlock() {
SwitchStatement statement =
parseStatement('switch (a) return;', expectedEndOffset: 11);
@@ -10502,7 +10601,8 @@
ForStatement statement = parseStatement('for (String item i) {}');
listener.assertErrors([
expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)
+ expectedError(
+ ParserErrorCode.EXPECTED_TOKEN, usingFastaParser ? 18 : 17, 1)
]);
expect(statement, new isInstanceOf<ForStatement>());
expect(statement.toSource(), 'for (String item; i;) {}');
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index 8947061..9439e01 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -221,27 +221,6 @@
@override
@failingTest
- test_futureOrNull_no_return() async {
- // Bad state: Found 2 argument types for 1 type arguments
- await super.test_futureOrNull_no_return();
- }
-
- @override
- @failingTest
- test_futureOrNull_no_return_value() async {
- // Bad state: Found 2 argument types for 1 type arguments
- await super.test_futureOrNull_no_return_value();
- }
-
- @override
- @failingTest
- test_futureOrNull_return_null() async {
- // Bad state: Found 2 argument types for 1 type arguments
- await super.test_futureOrNull_return_null();
- }
-
- @override
- @failingTest
test_generic_partial() async {
// AnalysisException: Element mismatch in /test.dart at class A<T>
await super.test_generic_partial();
@@ -298,27 +277,6 @@
@override
@failingTest
- test_inference_simplePolymorphicRecursion_function() async {
- // Expected: 'T'
- await super.test_inference_simplePolymorphicRecursion_function();
- }
-
- @override
- @failingTest
- test_inference_simplePolymorphicRecursion_interface() async {
- // Expected: 'T'
- await super.test_inference_simplePolymorphicRecursion_interface();
- }
-
- @override
- @failingTest
- test_inference_simplePolymorphicRecursion_simple() async {
- // RangeError (index): Invalid value: Valid value range is empty: 0
- await super.test_inference_simplePolymorphicRecursion_simple();
- }
-
- @override
- @failingTest
test_inferGenericInstantiation2() async {
// Expected 1 errors of type StrongModeCode.STRONG_MODE_COULD_NOT_INFER, found 0;
// 1 errors of type StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, found 0
@@ -434,13 +392,6 @@
@override
@failingTest
- test_genericMethod_max_doubleDouble_prefixed() async {
- // Bad state: Expected element reference for analyzer offset 49; got one for kernel offset 54
- await super.test_genericMethod_max_doubleDouble_prefixed();
- }
-
- @override
- @failingTest
test_genericMethod_nestedCapture() async {
// Bad state: Found 2 argument types for 1 type arguments
await super.test_genericMethod_nestedCapture();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
index 7dd81a7..e1a6eee 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
@@ -25,18 +25,6 @@
@override
@failingTest
- @potentialAnalyzerProblem
- test_annotation_constructor_withNestedConstructorInvocation() async {
- // This test is failing because analyzer and kernel disagree about how to
- // resolve annotations and constructors. Kernel is consistent between
- // annotations that invoke a constructor and other constructor invocations,
- // while analyzer treats them differently. They also differ in terms of the
- // resolution of the constructor name's element.
- await super.test_annotation_constructor_withNestedConstructorInvocation();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/31605')
test_constructor_redirected_generic() async {
await super.test_constructor_redirected_generic();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 09dbb38..7331a7d 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -186,12 +186,19 @@
var atD = AstFinder.getTopLevelFunction(result.unit, 'f').metadata[0];
InstanceCreationExpression constC = atD.arguments.arguments[0];
- expect(atD.name.staticElement, elementD);
- expect(atD.element, constructorD);
+ if (previewDart2) {
+ expect(atD.name.staticElement, constructorD);
+ expect(atD.element, constructorD);
+ } else {
+ expect(atD.name.staticElement, elementD);
+ expect(atD.element, constructorD);
+ }
expect(constC.staticElement, constructorC);
expect(constC.staticType, elementC.type);
+
expect(constC.constructorName.staticElement, constructorC);
+ expect(constC.constructorName.type.type, elementC.type);
}
test_annotation_kind_reference() async {
@@ -1355,14 +1362,10 @@
expect(initializer.constructorName, isNull);
List<Expression> arguments = initializer.argumentList.arguments;
-
- Expression aArgument = arguments[0];
- ParameterElement aElement = unnamedConstructor.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- Expression bArgument = arguments[1];
- ParameterElement bElement = unnamedConstructor.parameters[1];
- expect(bArgument.staticParameterElement, same(bElement));
+ _assertArgumentToParameter(
+ arguments[0], unnamedConstructor.parameters[0]);
+ _assertArgumentToParameter(
+ arguments[1], unnamedConstructor.parameters[1]);
}
{
@@ -1378,15 +1381,8 @@
expect(constructorName.staticType, isNull);
List<Expression> arguments = initializer.argumentList.arguments;
-
- Expression aArgument = arguments[0];
- ParameterElement aElement = namedConstructor.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = namedConstructor.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
+ _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
+ _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
}
}
@@ -1833,19 +1829,9 @@
expect(creation.constructorName.name, isNull);
- Expression aArgument = arguments[0];
- ParameterElement aElement = constructorElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = constructorElement.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
-
- NamedExpression cArgument = arguments[2];
- ParameterElement cElement = constructorElement.parameters[2];
- expect(cArgument.name.label.staticElement, same(cElement));
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], constructorElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], constructorElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], constructorElement.parameters[2]);
}
test_instanceCreation_noTypeArguments() async {
@@ -1884,7 +1870,7 @@
expect(value.constructorName.name, isNull);
Expression argument = value.argumentList.arguments[0];
- expect(argument.staticParameterElement, defaultConstructor.parameters[0]);
+ _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
}
{
@@ -1906,7 +1892,7 @@
expect(constructorName.staticType, isNull);
Expression argument = value.argumentList.arguments[0];
- expect(argument.staticParameterElement, namedConstructor.parameters[0]);
+ _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
}
}
@@ -1960,7 +1946,7 @@
expect(value.constructorName.name, isNull);
Expression argument = value.argumentList.arguments[0];
- expect(argument.staticParameterElement, defaultConstructor.parameters[0]);
+ _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
}
{
@@ -1995,7 +1981,7 @@
expect(constructorName.staticType, isNull);
Expression argument = value.argumentList.arguments[0];
- expect(argument.staticParameterElement, namedConstructor.parameters[0]);
+ _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
}
}
@@ -2284,19 +2270,9 @@
MethodInvocation invocation = statement.expression;
List<Expression> arguments = invocation.argumentList.arguments;
- Expression aArgument = arguments[0];
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
-
- NamedExpression cArgument = arguments[2];
- ParameterElement cElement = fElement.parameters[2];
- expect(cArgument.name.label.staticElement, same(cElement));
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
}
}
@@ -2394,18 +2370,9 @@
expect(invocation.staticInvokeType.toString(), fTypeString);
List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression aArgument = arguments[0];
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- Expression bArgument = arguments[1];
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgument.staticParameterElement, same(bElement));
-
- Expression cArgument = arguments[2];
- ParameterElement cElement = fElement.parameters[2];
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
}
}
@@ -2902,21 +2869,11 @@
BlockFunctionBody body = functionDeclaration.functionExpression.body;
ExpressionStatement statement = body.block.statements[0];
MethodInvocation invocation = statement.expression;
+
List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression aArgument = arguments[0];
- ParameterElement aElement = methodElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = methodElement.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
-
- NamedExpression cArgument = arguments[2];
- ParameterElement cElement = methodElement.parameters[2];
- expect(cArgument.name.label.staticElement, same(cElement));
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], methodElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], methodElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], methodElement.parameters[2]);
}
test_methodInvocation_instanceMethod_forwardingStub() async {
@@ -2973,13 +2930,13 @@
expect(invocation.staticType.toString(), 'void');
expect(invocation.staticInvokeType.toString(), invokeTypeStr);
if (previewDart2) {
- expect(invocation.staticInvokeType.element, same(mElement));
expect(invocation.methodName.staticElement, same(mElement));
expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+ } else {
+ expect(invocation.staticInvokeType.element, same(mElement));
}
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, mElement.parameters[0]);
+ _assertArgumentToParameter(arguments[0], mElement.parameters[0]);
}
}
@@ -3009,23 +2966,23 @@
expect(invocation.staticType.toString(), 'Map<int, double>');
expect(invocation.staticInvokeType.toString(), invokeTypeStr);
if (previewDart2) {
- expect(invocation.staticInvokeType.element, same(mElement));
expect(invocation.methodName.staticElement, same(mElement));
expect(invocation.methodName.staticType.toString(), invokeTypeStr);
}
- Expression aArgument = arguments[0];
- ParameterMember aArgumentParameter = aArgument.staticParameterElement;
- ParameterElement aElement = mElement.parameters[0];
- expect(aArgumentParameter.type, typeProvider.intType);
- expect(aArgumentParameter.baseElement, same(aElement));
-
- Expression bArgument = arguments[1];
- ParameterMember bArgumentParameter = bArgument.staticParameterElement;
- ParameterElement bElement = mElement.parameters[1];
- expect(bArgumentParameter.type, typeProvider.doubleType);
if (previewDart2) {
- expect(bArgumentParameter.baseElement, same(bElement));
+ expect(arguments[0].staticParameterElement, isNull);
+ expect(arguments[1].staticParameterElement, isNull);
+ } else {
+ Expression aArgument = arguments[0];
+ ParameterMember aArgumentParameter = aArgument.staticParameterElement;
+ ParameterElement aElement = mElement.parameters[0];
+ expect(aArgumentParameter.type, typeProvider.intType);
+ expect(aArgumentParameter.baseElement, same(aElement));
+
+ Expression bArgument = arguments[1];
+ ParameterMember bArgumentParameter = bArgument.staticParameterElement;
+ expect(bArgumentParameter.type, typeProvider.doubleType);
}
}
}
@@ -3047,19 +3004,9 @@
MethodInvocation invocation = statement.expression;
List<Expression> arguments = invocation.argumentList.arguments;
- Expression aArgument = arguments[0];
- ParameterElement aElement = fooElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = fooElement.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
-
- NamedExpression cArgument = arguments[2];
- ParameterElement cElement = fooElement.parameters[2];
- expect(cArgument.name.label.staticElement, same(cElement));
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], fooElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fooElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fooElement.parameters[2]);
}
test_methodInvocation_notFunction_field_dynamic() async {
@@ -3086,13 +3033,15 @@
ExpressionStatement statement = fooStatements[0];
MethodInvocation invocation = statement.expression;
expect(invocation.methodName.staticElement, same(fElement.getter));
- expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ if (previewDart2) {
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ } else {
+ expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ }
expect(invocation.staticType, DynamicTypeImpl.instance);
List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, isNull);
+ expect(arguments[0].staticParameterElement, isNull);
}
test_methodInvocation_notFunction_getter_dynamic() async {
@@ -3118,7 +3067,11 @@
ExpressionStatement statement = fooStatements[0];
MethodInvocation invocation = statement.expression;
expect(invocation.methodName.staticElement, same(fElement));
- expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ if (previewDart2) {
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ } else {
+ expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ }
expect(invocation.staticType, DynamicTypeImpl.instance);
List<Expression> arguments = invocation.argumentList.arguments;
@@ -3177,9 +3130,8 @@
expect(invocation.staticType, typeProvider.stringType);
List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, isNotNull);
+ _assertArgumentToParameter(
+ arguments[0], (fElement.type as FunctionType).parameters[0]);
}
test_methodInvocation_notFunction_topLevelVariable_dynamic() async {
@@ -3241,12 +3193,14 @@
var invokeTypeStr = '(int) → void';
expect(invocation.staticType.toString(), 'void');
expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- expect(invocation.staticInvokeType.element, same(mElement));
+ if (!previewDart2) {
+ expect(invocation.staticInvokeType.element, same(mElement));
+ }
expect(invocation.methodName.staticElement, same(mElement));
expect(invocation.methodName.staticType.toString(), invokeTypeStr);
Expression argument = arguments[0];
- expect(argument.staticParameterElement, mElement.parameters[0]);
+ _assertArgumentToParameter(argument, mElement.parameters[0]);
}
{
@@ -3263,12 +3217,14 @@
var invokeTypeStr = '(int) → void';
expect(invocation.staticType.toString(), 'void');
expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- expect(invocation.staticInvokeType.element, same(mElement));
+ if (!previewDart2) {
+ expect(invocation.staticInvokeType.element, same(mElement));
+ }
expect(invocation.methodName.staticElement, same(mElement));
expect(invocation.methodName.staticType.toString(), invokeTypeStr);
Expression argument = arguments[0];
- expect(argument.staticParameterElement, mElement.parameters[0]);
+ _assertArgumentToParameter(argument, mElement.parameters[0]);
}
}
@@ -3322,13 +3278,8 @@
expect(invocation.staticType, same(doubleType));
expect(invocation.staticInvokeType.toString(), fTypeString);
- Expression aArgument = arguments[0];
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- Expression bArgument = arguments[1];
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgument.staticParameterElement, same(bElement));
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
}
test_methodInvocation_topLevelFunction_generic() async {
@@ -3378,21 +3329,10 @@
expect(invocation.staticType, VoidTypeImpl.instance);
expect(invocation.staticInvokeType.toString(), fTypeString);
- Expression aArgument = arguments[0];
- ParameterMember aArgumentParameter = aArgument.staticParameterElement;
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgumentParameter.type, typeProvider.boolType);
- if (previewDart2) {
- expect(aArgumentParameter.baseElement, same(aElement));
- }
-
- Expression bArgument = arguments[1];
- ParameterMember bArgumentParameter = bArgument.staticParameterElement;
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgumentParameter.type, typeProvider.stringType);
- if (previewDart2) {
- expect(bArgumentParameter.baseElement, same(bElement));
- }
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+ parameterMemberType: typeProvider.boolType);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+ parameterMemberType: typeProvider.stringType);
}
// f(1, 2.3);
@@ -3409,21 +3349,10 @@
expect(invocation.staticType, VoidTypeImpl.instance);
expect(invocation.staticInvokeType.toString(), fTypeString);
- Expression aArgument = arguments[0];
- ParameterMember aArgumentParameter = aArgument.staticParameterElement;
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgumentParameter.type, typeProvider.intType);
- if (previewDart2) {
- expect(aArgumentParameter.baseElement, same(aElement));
- }
-
- Expression bArgument = arguments[1];
- ParameterMember bArgumentParameter = bArgument.staticParameterElement;
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgumentParameter.type, typeProvider.doubleType);
- if (previewDart2) {
- expect(bArgumentParameter.baseElement, same(bElement));
- }
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+ parameterMemberType: typeProvider.intType);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+ parameterMemberType: typeProvider.doubleType);
}
}
@@ -4852,19 +4781,9 @@
MethodInvocation invocation = statement.expression;
List<Expression> arguments = invocation.argumentList.arguments;
- Expression aArgument = arguments[0];
- ParameterElement aElement = fElement.parameters[0];
- expect(aArgument.staticParameterElement, same(aElement));
-
- NamedExpression bArgument = arguments[1];
- ParameterElement bElement = fElement.parameters[1];
- expect(bArgument.name.label.staticElement, same(bElement));
- expect(bArgument.staticParameterElement, same(bElement));
-
- NamedExpression cArgument = arguments[2];
- ParameterElement cElement = fElement.parameters[2];
- expect(cArgument.name.label.staticElement, same(cElement));
- expect(cArgument.staticParameterElement, same(cElement));
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
}
test_top_functionTypeAlias() async {
@@ -5141,6 +5060,39 @@
}
}
+ /// Assert that the [argument] is associated with the [expectedParameter],
+ /// if [previewDart2] is `null`. If the [argument] is a [NamedExpression],
+ /// the name must be resolved to the parameter in both cases.
+ void _assertArgumentToParameter(
+ Expression argument, ParameterElement expectedParameter,
+ {DartType parameterMemberType}) {
+ ParameterElement actualParameter = argument.staticParameterElement;
+ if (previewDart2) {
+ expect(actualParameter, isNull);
+ } else {
+ ParameterElement baseActualParameter;
+ if (actualParameter is ParameterMember) {
+ if (parameterMemberType != null) {
+ expect(actualParameter.type, parameterMemberType);
+ }
+ baseActualParameter = actualParameter.baseElement;
+ // Unwrap ParameterMember one more time.
+ // By some reason we wrap in twice.
+ if (baseActualParameter is ParameterMember) {
+ ParameterMember member = baseActualParameter;
+ baseActualParameter = member.baseElement;
+ }
+ } else {
+ baseActualParameter = actualParameter;
+ }
+ expect(baseActualParameter, same(expectedParameter));
+ // TODO(scheglov) Make this work for previewDart2 too.
+ if (argument is NamedExpression) {
+ expect(argument.name.label.staticElement, same(expectedParameter));
+ }
+ }
+ }
+
void _assertDefaultParameter(
DefaultFormalParameter node, ParameterElement element,
{String name, int offset, ParameterKind kind, DartType type}) {
@@ -5150,6 +5102,12 @@
name: name, offset: offset, kind: kind, type: type);
}
+ /// Assert that the [type] is a function type `() -> dynamic`.
+ void _assertDynamicFunctionType(FunctionType type) {
+ expect(type.parameters, isEmpty);
+ expect(type.returnType, DynamicTypeImpl.instance);
+ }
+
void _assertParameterElement(ParameterElement element,
{String name, int offset, ParameterKind kind, DartType type}) {
expect(element, isNotNull);
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
new file mode 100644
index 0000000..f8078ad
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
+import 'partial_code_support.dart';
+
+main() {
+ new AnnotationTest().buildAll();
+}
+
+class AnnotationTest extends PartialCodeTest {
+ buildAll() {
+ List<TestDescriptor> descriptors = <TestDescriptor>[
+ new TestDescriptor(
+ 'ampersand', '@', [ParserErrorCode.MISSING_IDENTIFIER], '@_s_',
+ allFailing: true),
+ new TestDescriptor(
+ 'leftParen', '@a(', [ParserErrorCode.EXPECTED_TOKEN], '@a()',
+ allFailing: true),
+ ];
+ buildTests('annotation_topLevel', descriptors,
+ PartialCodeTest.declarationSuffixes);
+ buildTests('annotation_classMember', descriptors,
+ PartialCodeTest.classMemberSuffixes,
+ head: 'class C { ', tail: ' }');
+ buildTests(
+ 'annotation_local', descriptors, PartialCodeTest.statementSuffixes,
+ head: 'f() { ', tail: ' }');
+ }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
index 102cb02..e714b32 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
@@ -4,6 +4,7 @@
import 'package:test/test.dart';
+import 'annotation_test.dart' as annotation;
import 'assert_statement_test.dart' as assert_statement;
import 'break_statement_test.dart' as break_statement;
import 'class_declaration_test.dart' as class_declaration;
@@ -23,11 +24,13 @@
import 'return_statement_test.dart' as return_statement;
import 'switch_statement_test.dart' as switch_statement;
import 'top_level_variable_test.dart' as top_level_variable;
+import 'try_statement_test.dart' as try_statement;
import 'while_statement_test.dart' as while_statement;
import 'yield_statement_test.dart' as yield_statement;
main() {
group('partial_code', () {
+ annotation.main();
assert_statement.main();
break_statement.main();
class_declaration.main();
@@ -47,6 +50,7 @@
return_statement.main();
switch_statement.main();
top_level_variable.main();
+ try_statement.main();
while_statement.main();
yield_statement.main();
});
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
new file mode 100644
index 0000000..a6c927d
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
+import 'partial_code_support.dart';
+
+main() {
+ new TryStatementTest().buildAll();
+}
+
+class TryStatementTest extends PartialCodeTest {
+ buildAll() {
+ buildTests(
+ 'try_statement',
+ [
+ //
+ // No clauses.
+ //
+ new TestDescriptor(
+ 'keyword',
+ 'try',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_CATCH_OR_FINALLY
+ ],
+ "try {} finally {}",
+ allFailing: true),
+ new TestDescriptor('noCatchOrFinally', 'try {}',
+ [ParserErrorCode.MISSING_CATCH_OR_FINALLY], "try {} finally {}",
+ allFailing: true),
+ //
+ // Single on clause.
+ //
+ new TestDescriptor(
+ 'on',
+ 'try {} on',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} on _s_ {}",
+ allFailing: true),
+ new TestDescriptor('on_identifier', 'try {} on A',
+ [ParserErrorCode.EXPECTED_TOKEN], "try {} on A {}",
+ failing: ['block']),
+ //
+ // Single catch clause.
+ //
+ new TestDescriptor(
+ 'catch',
+ 'try {} catch',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'catch_leftParen',
+ 'try {} catch (',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'catch_identifier',
+ 'try {} catch (e',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "try {} catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'catch_identifierComma',
+ 'try {} catch (e, ',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} catch (e, _s_) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'catch_identifierCommaIdentifier',
+ 'try {} catch (e, s',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "try {} catch (e, s) {}",
+ allFailing: true),
+ new TestDescriptor('catch_rightParen', 'try {} catch (e, s)',
+ [ParserErrorCode.EXPECTED_TOKEN], "try {} catch (e, s) {}",
+ failing: ['block']),
+ //
+ // Single catch clause after an on clause.
+ //
+ new TestDescriptor(
+ 'on_catch',
+ 'try {} on A catch',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} on A catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'on_catch_leftParen',
+ 'try {} on A catch (',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} on A catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'on_catch_identifier',
+ 'try {} on A catch (e',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "try {} on A catch (e) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'on_catch_identifierComma',
+ 'try {} on A catch (e, ',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "try {} on A catch (e, _s_) {}",
+ allFailing: true),
+ new TestDescriptor(
+ 'on_catch_identifierCommaIdentifier',
+ 'try {} on A catch (e, s',
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "try {} on A catch (e, s) {}",
+ allFailing: true),
+ new TestDescriptor('on_catch_rightParen', 'try {} on A catch (e, s)',
+ [ParserErrorCode.EXPECTED_TOKEN], "try {} on A catch (e, s) {}",
+ failing: ['block']),
+ //
+ // Only a finally clause.
+ //
+ new TestDescriptor('finally_noCatch_noBlock', 'try {} finally',
+ [ParserErrorCode.EXPECTED_TOKEN], "try {} finally {}",
+ failing: ['block']),
+ //
+ // A catch and finally clause.
+ //
+ new TestDescriptor(
+ 'finally_catch_noBlock',
+ 'try {} catch (e) {} finally',
+ [ParserErrorCode.EXPECTED_TOKEN],
+ "try {} catch (e) {} finally {}",
+ failing: ['block']),
+ ],
+ PartialCodeTest.statementSuffixes,
+ head: 'f() { ',
+ tail: ' }');
+ }
+}
diff --git a/pkg/analyzer/test/src/fasta/resolution_applier_test.dart b/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
index 6c720dd..bdd7051 100644
--- a/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
+++ b/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
@@ -74,6 +74,7 @@
], <DartType>[
typeProvider.stringType,
new FunctionTypeImpl(new FunctionElementImpl('+', -1)),
+ new TypeArgumentsDartType([]),
typeProvider.intType,
typeProvider.stringType,
]);
@@ -91,8 +92,10 @@
], <DartType>[
typeProvider.objectType,
typeProvider.objectType,
+ new TypeArgumentsDartType([]),
typeProvider.objectType,
typeProvider.objectType,
+ new TypeArgumentsDartType([]),
typeProvider.objectType
]);
}
@@ -257,6 +260,7 @@
], <DartType>[
typeProvider.stringType,
typeProvider.intType,
+ new TypeArgumentsDartType([]),
typeProvider.intType,
typeProvider.stringType,
typeProvider.stringType
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
new file mode 100644
index 0000000..c2e11d0
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -0,0 +1,240 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/yaml.dart';
+
+import '../../generated/test_support.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PubspecValidatorTest);
+ });
+}
+
+@reflectiveTest
+class PubspecValidatorTest extends Object with ResourceProviderMixin {
+ PubspecValidator validator;
+
+ /**
+ * Assert that when the validator is used on the given [content] the
+ * [expectedErrorCodes] are produced.
+ */
+ void assertErrors(String content, List<ErrorCode> expectedErrorCodes) {
+ YamlNode node = loadYamlNode(content);
+ if (node is! YamlMap) {
+ // The file is empty.
+ node = new YamlMap();
+ }
+ List<AnalysisError> errors = validator.validate((node as YamlMap).nodes);
+ GatheringErrorListener listener = new GatheringErrorListener();
+ listener.addAll(errors);
+ listener.assertErrorsWithCodes(expectedErrorCodes);
+ }
+
+ /**
+ * Assert that when the validator is used on the given [content] no errors are
+ * produced.
+ */
+ void assertNoErrors(String content) {
+ assertErrors(content, []);
+ }
+
+ void setUp() {
+ File pubspecFile = getFile('/sample/pubspec.yaml');
+ Source source = pubspecFile.createSource();
+ validator = new PubspecValidator(resourceProvider, source);
+ }
+
+ test_assetDoesNotExist_error() {
+ assertErrors('''
+name: sample
+flutter:
+ assets:
+ - assets/my_icon.png
+''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
+ }
+
+ test_assetDoesNotExist_noError() {
+ newFile('/sample/assets/my_icon.png');
+ assertNoErrors('''
+name: sample
+flutter:
+ assets:
+ - assets/my_icon.png
+''');
+ }
+
+ test_assetFieldNotList_error_empty() {
+ assertErrors('''
+name: sample
+flutter:
+ assets:
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+ }
+
+ test_assetFieldNotList_error_string() {
+ assertErrors('''
+name: sample
+flutter:
+ assets: assets/my_icon.png
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+ }
+
+ test_assetFieldNotList_noError() {
+ newFile('/sample/assets/my_icon.png');
+ assertNoErrors('''
+name: sample
+flutter:
+ assets:
+ - assets/my_icon.png
+''');
+ }
+
+ test_assetNotString_error_int() {
+ assertErrors('''
+name: sample
+flutter:
+ assets:
+ - 23
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+ }
+
+ test_assetNotString_error_map() {
+ assertErrors('''
+name: sample
+flutter:
+ assets:
+ - my_icon:
+ default: assets/my_icon.png
+ large: assets/large/my_icon.png
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+ }
+
+ test_assetNotString_noError() {
+ newFile('/sample/assets/my_icon.png');
+ assertNoErrors('''
+name: sample
+flutter:
+ assets:
+ - assets/my_icon.png
+''');
+ }
+
+ test_dependenciesFieldNotMap_dev_error_bool() {
+ assertErrors('''
+name: sample
+dev_dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+ }
+
+ test_dependenciesFieldNotMap_dev_error_empty() {
+ assertErrors('''
+name: sample
+dev_dependencies:
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+ }
+
+ test_dependenciesFieldNotMap_dev_noError() {
+ assertNoErrors('''
+name: sample
+dev_dependencies:
+ a: any
+''');
+ }
+
+ test_dependenciesFieldNotMap_error_bool() {
+ assertErrors('''
+name: sample
+dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+ }
+
+ test_dependenciesFieldNotMap_error_empty() {
+ assertErrors('''
+name: sample
+dependencies:
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+ }
+
+ test_dependenciesFieldNotMap_noError() {
+ assertNoErrors('''
+name: sample
+dependencies:
+ a: any
+''');
+ }
+
+ test_flutterFieldNotMap_error_bool() {
+ assertErrors('''
+name: sample
+flutter: true
+''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+ }
+
+ test_flutterFieldNotMap_error_empty() {
+ assertErrors('''
+name: sample
+flutter:
+''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+ }
+
+ test_flutterFieldNotMap_noError() {
+ newFile('/sample/assets/my_icon.png');
+ assertNoErrors('''
+name: sample
+flutter:
+ assets:
+ - assets/my_icon.png
+''');
+ }
+
+ test_missingName_error() {
+ assertErrors('', [PubspecWarningCode.MISSING_NAME]);
+ }
+
+ test_missingName_noError() {
+ assertNoErrors('''
+name: sample
+''');
+ }
+
+ test_nameNotString_error_int() {
+ assertErrors('''
+name: 42
+''', [PubspecWarningCode.NAME_NOT_STRING]);
+ }
+
+ test_nameNotString_noError() {
+ assertNoErrors('''
+name: sample
+''');
+ }
+
+ test_unnecessaryDevDependency_error() {
+ assertErrors('''
+name: sample
+dependencies:
+ a: any
+dev_dependencies:
+ a: any
+''', [PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY]);
+ }
+
+ test_unnecessaryDevDependency_noError() {
+ assertNoErrors('''
+name: sample
+dependencies:
+ a: any
+dev_dependencies:
+ b: any
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/pubspec/test_all.dart b/pkg/analyzer/test/src/pubspec/test_all.dart
new file mode 100644
index 0000000..a7e7ebe
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'pubspec_validator_test.dart' as pubspec_validator;
+
+main() {
+ defineReflectiveSuite(() {
+ pubspec_validator.main();
+ }, name: 'pubspec');
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 8db1a7e..14ef322d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9525,31 +9525,19 @@
test_typedef_type_parameters_bound_recursive() async {
shouldCompareLibraryElements = false;
var library = await checkLibrary('typedef void F<T extends F>();');
- if (isSharedFrontEnd) {
- // Typedefs cannot reference themselves.
- checkElementText(library, r'''
-typedef F<T extends dynamic> = void Function();
-''');
- } else {
- checkElementText(library, r'''
+ // Typedefs cannot reference themselves.
+ checkElementText(library, r'''
typedef F<T extends () → void> = void Function();
''');
- }
}
test_typedef_type_parameters_bound_recursive2() async {
shouldCompareLibraryElements = false;
var library = await checkLibrary('typedef void F<T extends List<F>>();');
- if (isSharedFrontEnd) {
- // Typedefs cannot reference themselves.
- checkElementText(library, r'''
-typedef F<T extends List<dynamic>> = void Function();
-''');
- } else {
- checkElementText(library, r'''
+ // Typedefs cannot reference themselves.
+ checkElementText(library, r'''
typedef F<T extends List<() → void>> = void Function();
''');
- }
}
test_typedef_type_parameters_f_bound_complex() async {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
index 9e05d71..40060b1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
@@ -383,7 +383,7 @@
}
@failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/31213')
+ @FastaProblem('https://github.com/dart-lang/sdk/issues/31711')
test_typedef_generic_asFieldType() async {
await super.test_typedef_generic_asFieldType();
}
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index d6d0d19..369c7b9 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -9,6 +9,7 @@
import 'dart/test_all.dart' as dart;
import 'fasta/test_all.dart' as fasta;
import 'lint/test_all.dart' as lint;
+import 'pubspec/test_all.dart' as pubspec;
import 'source/test_all.dart' as source;
import 'summary/test_all.dart' as summary;
import 'task/test_all.dart' as task;
@@ -22,6 +23,7 @@
dart.main();
fasta.main();
lint.main();
+ pubspec.main();
source.main();
summary.main();
task.main();
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 4313841..b0dac1f 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -88,6 +88,17 @@
final AstNode containingNode;
/**
+ * The "dropped" identifier or keyword which the completed text will replace,
+ * or `null` if none.
+ *
+ * For the purposes of code completion, a "dropped" token is an identifier
+ * or keyword that is part of the token stream, but that the parser has
+ * skipped and not reported in to the parser listeners, meaning that it is
+ * not part of the AST.
+ */
+ Token droppedToken;
+
+ /**
* The entity which the completed text will replace (or which will be
* displaced once the completed text is inserted). This may be an AstNode or
* a Token, or it may be null if the cursor is after all tokens in the file.
@@ -235,7 +246,9 @@
Object entity, this.isCommentText)
: this.containingNode = containingNode,
this.entity = entity,
- this.argIndex = _computeArgIndex(containingNode, entity);
+ this.argIndex = _computeArgIndex(containingNode, entity),
+ this.droppedToken =
+ _computeDroppedToken(containingNode, entity, offset);
/**
* Return `true` if the [containingNode] is a cascade
@@ -263,7 +276,8 @@
bool isKeywordOrIdentifier(Token token) =>
token.type.isKeyword || token.type == TokenType.IDENTIFIER;
- Token token = entity is AstNode ? (entity as AstNode).beginToken : entity;
+ Token token = droppedToken ??
+ (entity is AstNode ? (entity as AstNode).beginToken : entity);
if (token != null && requestOffset < token.offset) {
token = token.previous;
}
@@ -388,6 +402,52 @@
return null;
}
+ static Token _computeDroppedToken(
+ AstNode containingNode, Object entity, int offset) {
+ // Find the last token of the member before the entity.
+ var previousMember;
+ for (var member in containingNode.childEntities) {
+ if (entity == member) {
+ break;
+ }
+ if (member is! Comment && member is! CommentToken) {
+ previousMember = member;
+ }
+ }
+ Token token;
+ if (previousMember is AstNode) {
+ token = previousMember.endToken;
+ } else if (previousMember is Token) {
+ token = previousMember;
+ }
+ if (token == null) {
+ return null;
+ }
+
+ // Find the first token of the entity (which may be the entity itself).
+ Token endSearch;
+ if (entity is AstNode) {
+ endSearch = entity.beginToken;
+ } else if (entity is Token) {
+ endSearch = entity;
+ }
+ if (endSearch == null) {
+ return null;
+ }
+
+ // Find a dropped token that overlaps the offset.
+ token = token.next;
+ while (token != endSearch && !token.isEof) {
+ if (token.isKeywordOrIdentifier &&
+ token.offset <= offset &&
+ offset <= token.end) {
+ return token;
+ }
+ token = token.next;
+ }
+ return null;
+ }
+
/**
* Determine if the offset is contained in a preceding comment token
* and return that token, otherwise return `null`.
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index a555373..40c3fcd 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:test/test.dart';
@@ -25,6 +26,8 @@
int completionOffset;
CompletionTarget target;
+ bool get usingFastaParser => analyzer.Parser.useFasta;
+
Future<Null> addTestSource(String content) async {
expect(completionOffset, isNull, reason: 'Call addTestSource exactly once');
completionOffset = content.indexOf('^');
@@ -39,12 +42,16 @@
}
Future<Null> assertTarget(entityText, nodeText,
- {int argIndex: null, bool isFunctionalArgument: false}) async {
+ {int argIndex: null,
+ bool isFunctionalArgument: false,
+ String droppedToken}) async {
void assertCommon() {
expect(target.entity.toString(), entityText, reason: 'entity');
expect(target.containingNode.toString(), nodeText,
reason: 'containingNode');
expect(target.argIndex, argIndex, reason: 'argIndex');
+ expect(target.droppedToken?.toString(), droppedToken ?? isNull,
+ reason: 'droppedToken');
}
// Assert with parsed unit
@@ -403,6 +410,16 @@
'// normal comment ', 'class C2 {zoo(z) {} String name;}');
}
+ test_IfStatement_droppedToken() async {
+ // Comment ClassDeclaration CompilationUnit
+ await addTestSource('main() { if (v i^) }');
+ if (usingFastaParser) {
+ await assertTarget(')', '(v)', droppedToken: 'i');
+ } else {
+ await assertTarget('i;', 'if (v) i;');
+ }
+ }
+
test_MethodDeclaration_inLineComment2() async {
// Comment ClassDeclaration CompilationUnit
await addTestSource('''
@@ -555,13 +572,13 @@
test_SwitchStatement_c() async {
// Token('c') SwitchStatement
await addTestSource('main() { switch(x) {c^} }');
- await assertTarget('}', 'switch (x) {}');
+ await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
}
test_SwitchStatement_c2() async {
// Token('c') SwitchStatement
await addTestSource('main() { switch(x) { c^ } }');
- await assertTarget('}', 'switch (x) {}');
+ await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
}
test_SwitchStatement_empty() async {
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index c9319e4..7cbc7e7 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -37,6 +37,7 @@
/// using the kernel representation.
/// See [CompilerOptions.useKernel] for details.
static const String useKernel = '--use-kernel';
+ static const String strongMode = '--strong';
static const String platformBinaries = '--platform-binaries=.+';
static const String minify = '--minify';
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 8a189c9..115def6 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -8,6 +8,7 @@
import '../common_elements.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
+import '../deferred_load.dart' show OutputUnit;
import '../util/util.dart' show Hashing;
enum ConstantValueKind {
@@ -24,6 +25,7 @@
INTERCEPTOR,
SYNTHETIC,
DEFERRED,
+ DEFERRED_GLOBAL,
NON_CONSTANT,
}
@@ -45,6 +47,8 @@
covariant InterceptorConstantValue constant, covariant A arg);
R visitSynthetic(covariant SyntheticConstantValue constant, covariant A arg);
R visitDeferred(covariant DeferredConstantValue constant, covariant A arg);
+ R visitDeferredGlobal(
+ covariant DeferredGlobalConstantValue constant, covariant A arg);
R visitNonConstant(covariant NonConstantValue constant, covariant A arg);
}
@@ -94,8 +98,8 @@
/// expression from the value so the unparse of these is best effort.
///
/// For the synthetic constants, [DeferredConstantValue],
- /// [SyntheticConstantValue], [InterceptorConstantValue] the unparse is
- /// descriptive only.
+ /// [DeferredGlobalConstantValue], [SyntheticConstantValue],
+ /// [InterceptorConstantValue] the unparse is descriptive only.
String toDartText();
/// Returns a structured representation of this constant suited for debugging.
@@ -752,7 +756,8 @@
}
/// A reference to a constant in another output unit.
-/// Used for referring to deferred constants.
+///
+/// Used for referring to deferred constants when evaluating constant values.
class DeferredConstantValue extends ConstantValue {
DeferredConstantValue(this.referenced, this.import);
@@ -784,6 +789,50 @@
}
}
+/// A reference to a constant in another output unit.
+///
+/// Used for referring to deferred constants that appear as initializers of
+/// final (non-const) global fields.
+///
+// TODO(sigmund): this should eventually not be a constant value. In particular,
+// [DeferredConstantValue] is introduced by the constant evaluator when it first
+// sees constants used in the program. [DeferredGlobalConstantValue] are
+// introduced later by the SSA builder and should be represented
+// with a dedicated JEntity instead. We currently model them as a regular
+// constant to take advantage of the machinery we already have in place to
+// generate deferred constants in the emitter.
+class DeferredGlobalConstantValue extends ConstantValue {
+ DeferredGlobalConstantValue(this.referenced, this.unit);
+
+ final ConstantValue referenced;
+ final OutputUnit unit;
+
+ bool get isReference => true;
+
+ bool operator ==(other) {
+ return other is DeferredGlobalConstantValue &&
+ referenced == other.referenced &&
+ unit == other.unit;
+ }
+
+ get hashCode => (referenced.hashCode * 17 + unit.hashCode) & 0x3fffffff;
+
+ List<ConstantValue> getDependencies() => <ConstantValue>[referenced];
+
+ accept(ConstantValueVisitor visitor, arg) =>
+ visitor.visitDeferredGlobal(this, arg);
+
+ DartType getType(CommonElements types) => referenced.getType(types);
+
+ ConstantValueKind get kind => ConstantValueKind.DEFERRED_GLOBAL;
+
+ String toDartText() => 'deferred_global(${referenced.toDartText()})';
+
+ String toStructuredText() {
+ return 'DeferredGlobalConstant(${referenced.toStructuredText()})';
+ }
+}
+
/// A constant value resulting from a non constant or erroneous constant
/// expression.
// TODO(johnniwinther): Expand this to contain the error kind.
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 2fa6522..b016904 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -399,6 +399,7 @@
new OptionHandler(Flags.useContentSecurityPolicy, passThrough),
new OptionHandler(Flags.enableExperimentalMirrors, passThrough),
new OptionHandler(Flags.enableAssertMessage, passThrough),
+ new OptionHandler(Flags.strongMode, passThrough),
// TODO(floitsch): remove conditional directives flag.
// We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index cbe47ff..8ba05a1 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -11,7 +11,11 @@
import 'common_elements.dart' show ElementEnvironment;
import 'compiler.dart' show Compiler;
import 'constants/values.dart'
- show ConstantValue, ConstructedConstantValue, DeferredConstantValue;
+ show
+ ConstantValue,
+ ConstructedConstantValue,
+ DeferredConstantValue,
+ DeferredGlobalConstantValue;
import 'elements/types.dart';
import 'elements/elements.dart'
show AstElement, ClassElement, Element, MethodElement, LocalFunctionElement;
@@ -69,6 +73,8 @@
return name.compareTo(other.name);
}
+ Set<ImportEntity> get importsForTesting => _imports;
+
String toString() => "OutputUnit($name, $_imports)";
}
@@ -496,6 +502,8 @@
for (ImportEntity import in allDeferredImports) {
String result = computeImportDeferName(import, compiler);
assert(result != null);
+ // Note: tools that process the json file to build multi-part initial load
+ // bundles depend on the fact that makeUnique appends only digits.
_importDeferName[import] = makeUnique(result, usedImportNames);
}
@@ -544,7 +552,7 @@
///
/// The deferred loading algorithm maps elements and constants to an output
/// unit. Each output unit is identified by a subset of deferred imports (an
- /// [ImportSet]), and they will contain the elements that are inheretly used
+ /// [ImportSet]), and they will contain the elements that are inherently used
/// by all those deferred imports. An element is used by a deferred import if
/// it is either loaded by that import or transitively accessed by an element
/// that the import loads. An empty set represents the main output unit,
@@ -1091,13 +1099,6 @@
if (!isProgramSplit) return mainOutputUnit;
entity = entity is Element ? entity.implementation : entity;
OutputUnit unit = _entityToUnit[entity];
- // TODO(redemption): ensure any entity that is requested is in the map.
- // Currently closure methods are not handled correctly. The old pipeline
- // finds the appropriate output unit because the synthetic $call methods
- // transitively have the member-context as an enclosing element, and those
- // methods are found. The new pipeline doesn't expose that connection. We
- // should handle this in the emitter or while translating OutputUnitData to
- // the J-model.
if (unit != null) return unit;
if (entity is Element) {
Element element = entity;
@@ -1171,11 +1172,11 @@
return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
}
- /// Registers that a constant is used in a deferred library.
+ /// Registers that a constant is used in the same deferred output unit as
+ /// [field].
void registerConstantDeferredUse(
- DeferredConstantValue constant, ImportEntity import) {
+ DeferredGlobalConstantValue constant, OutputUnit unit) {
if (!isProgramSplit) return;
- var unit = _importSets.singleton(import).unit;
assert(
_constantToUnit[constant] == null || _constantToUnit[constant] == unit);
_constantToUnit[constant] = unit;
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 93747d9..bc3d0c0 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -10,7 +10,7 @@
import 'package:dart2js_info/info.dart';
import '../compiler_new.dart';
-import 'closure.dart';
+import 'common/names.dart';
import 'common/tasks.dart' show CompilerTask;
import 'common.dart';
import 'common_elements.dart';
@@ -50,7 +50,8 @@
compiler.dumpInfoTask._constantToNode.forEach((constant, node) {
// TODO(sigmund): add dependencies on other constants
var size = compiler.dumpInfoTask._nodeToSize[node];
- var code = jsAst.prettyPrint(node, compiler.options);
+ var code = jsAst.prettyPrint(node,
+ enableMinification: compiler.options.enableMinification);
var info = new ConstantInfo(
size: size, code: code, outputUnit: _unitInfoForConstant(constant));
_constantToInfo[constant] = info;
@@ -219,18 +220,17 @@
return classInfo;
}
- ClosureInfo visitClosureClass(ClosureClassElement element) {
+ ClosureInfo visitClosureClass(ClassEntity element) {
ClosureInfo closureInfo = new ClosureInfo(
name: element.name,
outputUnit: _unitInfoForEntity(element),
size: compiler.dumpInfoTask.sizeOf(element));
_entityToInfo[element] = closureInfo;
- ClosureRepresentationInfo closureRepresentation =
- compiler.backendStrategy.closureDataLookup.getClosureInfo(element.node);
- assert(closureRepresentation.closureClassEntity == element);
+ FunctionEntity callMethod = closedWorld.elementEnvironment
+ .lookupClassMember(element, Identifiers.call);
- FunctionInfo functionInfo = visitFunction(closureRepresentation.callMethod);
+ FunctionInfo functionInfo = visitFunction(callMethod);
if (functionInfo == null) return null;
closureInfo.function = functionInfo;
functionInfo.parent = closureInfo;
@@ -544,7 +544,8 @@
// Concatenate rendered ASTs.
StringBuffer sb = new StringBuffer();
for (jsAst.Node ast in code) {
- sb.writeln(jsAst.prettyPrint(ast, compiler.options));
+ sb.writeln(jsAst.prettyPrint(ast,
+ enableMinification: compiler.options.enableMinification));
}
return sb.toString();
}
@@ -615,6 +616,7 @@
result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap();
stopwatch.stop();
+
result.program = new ProgramInfo(
entrypoint: infoCollector
._entityToInfo[closedWorld.elementEnvironment.mainFunction],
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index ad1ca0d..c282f29 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -948,6 +948,7 @@
abstract class ImportElement extends Element implements ImportEntity {
Uri get uri;
LibraryElement get importedLibrary;
+ LibraryElement get enclosingLibrary => library;
bool get isDeferred;
PrefixElement get prefix;
String get name;
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 1e6207e..8d68752 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -38,6 +38,9 @@
///
/// The [name] property corresponds to the prefix name, if any.
abstract class ImportEntity extends Entity {
+ /// The library where this import occurs (where the import is declared).
+ LibraryEntity get enclosingLibrary;
+
/// Whether the import is a deferred import.
bool get isDeferred;
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 8ed5033..9d137e9 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -1002,6 +1002,9 @@
Import get node => super.node;
@override
+ LibraryElement get enclosingLibrary => library;
+
+ @override
LibraryElement get importedLibrary => libraryDependency;
@override
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 336e319..116eb19 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -99,11 +99,11 @@
///
/// Will never return the a given filename more than once, even if called with
/// the same element.
- String filenameFromElement(MemberElement element) {
+ String filenameFromElement(MemberEntity element) {
// The toString method of elements include characters that are unsuitable
// for URIs and file systems.
List<String> parts = <String>[];
- parts.add(element.library?.libraryName);
+ parts.add(element.library.canonicalUri.pathSegments.last);
parts.add(element.enclosingClass?.name);
if (element.isGetter) {
parts.add('get-${element.name}');
@@ -115,19 +115,10 @@
} else {
parts.add(element.name);
}
- } else if (element.isOperator) {
+ } else {
parts.add(Elements
.operatorNameToIdentifier(element.name)
.replaceAll(r'$', '-'));
- } else {
- parts.add(element.name);
- }
- if (element != element) {
- if (element.name.isEmpty) {
- parts.add('anon${element.sourcePosition.begin}');
- } else {
- parts.add(element.name);
- }
}
String filename = parts.where((x) => x != null && x != '').join('.');
if (usedFilenames.add(filename)) return filename;
@@ -149,7 +140,7 @@
final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
int usedIds = 0;
final OutputSink output;
- final MemberElement element;
+ final MemberEntity element;
TypeInformation returnValue;
_GraphGenerator(this.global, this.element, this.output) {
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index 421ed12..da70b55 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -109,6 +109,40 @@
return _buildTreeNode(node);
}
+ /// Creates the source information for a [base] and end of [member]. If [base]
+ /// is not provided, the offset of [member] is used as the start position.
+ ///
+ /// This is used function declarations and return expressions which both point
+ /// to the end of the member as the closing position.
+ SourceInformation _buildFunctionEnd(MemberEntity member, [ir.TreeNode base]) {
+ MemberDefinition definition = _elementMap.getMemberDefinition(member);
+ ir.Node node = definition.node;
+ switch (definition.kind) {
+ case MemberKind.regular:
+ if (node is ir.Procedure) {
+ return _buildFunction(base ?? node, node.function);
+ }
+ break;
+ case MemberKind.constructor:
+ case MemberKind.constructorBody:
+ if (node is ir.Procedure) {
+ return _buildFunction(base ?? node, node.function);
+ } else if (node is ir.Constructor) {
+ return _buildFunction(base ?? node, node.function);
+ }
+ break;
+ case MemberKind.closureCall:
+ if (node is ir.FunctionDeclaration) {
+ return _buildFunction(base ?? node, node.function);
+ } else if (node is ir.FunctionExpression) {
+ return _buildFunction(base ?? node, node.function);
+ }
+ break;
+ default:
+ }
+ return _buildTreeNode(base ?? node);
+ }
+
/// Creates the source information for exiting a function definition defined
/// by the root [node] and its [functionNode].
///
@@ -207,8 +241,10 @@
}
/// Creates source information based on the location of [node].
- SourceInformation _buildTreeNode(ir.TreeNode node) {
- return new PositionSourceInformation(_getSourceLocation(node));
+ SourceInformation _buildTreeNode(ir.TreeNode node,
+ [SourceLocation closingPosition]) {
+ return new PositionSourceInformation(
+ _getSourceLocation(node), closingPosition);
}
@override
@@ -352,7 +388,7 @@
@override
SourceInformation buildReturn(ir.Node node) {
- return _buildTreeNode(node);
+ return _buildFunctionEnd(_member, node);
}
@override
@@ -370,34 +406,7 @@
@override
SourceInformation buildDeclaration(MemberEntity member) {
- MemberDefinition definition = _elementMap.getMemberDefinition(member);
- switch (definition.kind) {
- case MemberKind.regular:
- ir.Node node = definition.node;
- if (node is ir.Procedure) {
- return _buildFunction(node, node.function);
- }
- break;
- case MemberKind.constructor:
- case MemberKind.constructorBody:
- ir.Node node = definition.node;
- if (node is ir.Procedure) {
- return _buildFunction(node, node.function);
- } else if (node is ir.Constructor) {
- return _buildFunction(node, node.function);
- }
- break;
- case MemberKind.closureCall:
- ir.Node node = definition.node;
- if (node is ir.FunctionDeclaration) {
- return _buildFunction(node, node.function);
- } else if (node is ir.FunctionExpression) {
- return _buildFunction(node, node.function);
- }
- break;
- default:
- }
- return _buildTreeNode(definition.node);
+ return _buildFunctionEnd(member);
}
@override
diff --git a/pkg/compiler/lib/src/io/multi_information.dart b/pkg/compiler/lib/src/io/multi_information.dart
index 9f8d909..84c3421 100644
--- a/pkg/compiler/lib/src/io/multi_information.dart
+++ b/pkg/compiler/lib/src/io/multi_information.dart
@@ -310,7 +310,7 @@
SourceLocation get endPosition => infos.first?.endPosition;
@override
- SourceLocation get closingPosition => infos.first?.closingPosition;
+ SourceLocation get innerPosition => infos.first?.innerPosition;
@override
SourceLocation get startPosition => infos.first?.startPosition;
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 4363274..4e1fd6c 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -25,9 +25,9 @@
final SourceLocation startPosition;
@override
- final SourceLocation closingPosition;
+ final SourceLocation innerPosition;
- PositionSourceInformation(this.startPosition, [this.closingPosition]);
+ PositionSourceInformation(this.startPosition, [this.innerPosition]);
@override
List<SourceLocation> get sourceLocations {
@@ -35,8 +35,8 @@
if (startPosition != null) {
list.add(startPosition);
}
- if (closingPosition != null) {
- list.add(closingPosition);
+ if (innerPosition != null) {
+ list.add(innerPosition);
}
return list;
}
@@ -44,7 +44,7 @@
@override
SourceSpan get sourceSpan {
SourceLocation location =
- startPosition != null ? startPosition : closingPosition;
+ startPosition != null ? startPosition : innerPosition;
Uri uri = location.sourceUri;
int offset = location.offset;
return new SourceSpan(uri, offset, offset);
@@ -52,14 +52,14 @@
int get hashCode {
return 0x7FFFFFFF &
- (startPosition.hashCode * 17 + closingPosition.hashCode * 19);
+ (startPosition.hashCode * 17 + innerPosition.hashCode * 19);
}
bool operator ==(other) {
if (identical(this, other)) return true;
if (other is! PositionSourceInformation) return false;
return startPosition == other.startPosition &&
- closingPosition == other.closingPosition;
+ innerPosition == other.innerPosition;
}
/// Create a textual representation of the source information using [uriText]
@@ -72,9 +72,9 @@
sb.write('[${startPosition.line},'
'${startPosition.column}]');
}
- if (closingPosition != null) {
- sb.write('-[${closingPosition.line},'
- '${closingPosition.column}]');
+ if (innerPosition != null) {
+ sb.write('-[${innerPosition.line},'
+ '${innerPosition.column}]');
}
return sb.toString();
}
@@ -83,7 +83,7 @@
if (startPosition != null) {
return _computeText(startPosition.sourceUri.pathSegments.last);
} else {
- return _computeText(closingPosition.sourceUri.pathSegments.last);
+ return _computeText(innerPosition.sourceUri.pathSegments.last);
}
}
@@ -91,7 +91,7 @@
if (startPosition != null) {
return _computeText('${startPosition.sourceUri}');
} else {
- return _computeText('${closingPosition.sourceUri}');
+ return _computeText('${innerPosition.sourceUri}');
}
}
}
@@ -194,7 +194,17 @@
SourceInformation buildListLiteral(Node node) => buildBegin(node);
@override
- SourceInformation buildReturn(Node node) => buildBegin(node);
+ SourceInformation buildReturn(Node node) {
+ SourceFile sourceFile = computeSourceFile(resolvedAst);
+ SourceLocation startPosition = new OffsetSourceLocation(
+ sourceFile, node.getBeginToken().charOffset, name);
+ SourceLocation endPosition;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ endPosition = new OffsetSourceLocation(
+ sourceFile, resolvedAst.node.getEndToken().charOffset, name);
+ }
+ return new PositionSourceInformation(startPosition, endPosition);
+ }
@override
SourceInformation buildImplicitReturn(MemberElement element) {
@@ -446,8 +456,7 @@
case SourcePositionKind.START:
return sourceInformation.startPosition;
case SourcePositionKind.INNER:
- return sourceInformation.closingPosition ??
- sourceInformation.startPosition;
+ return sourceInformation.innerPosition ?? sourceInformation.startPosition;
}
}
@@ -603,6 +612,55 @@
PositionTraceListener(this.sourceMapper, this.reader);
+ /// Registers source information for [node] on the [offset] in the JavaScript
+ /// code using [kind] to determine what information to use.
+ ///
+ /// For most nodes the start position of the source information is used.
+ /// For instance a return expression points to the the start position of the
+ /// source information, typically the start of the return statement that
+ /// created the JavaScript return node:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// @return "foo"; return "foo";
+ /// ^
+ /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+ /// code position.)
+ ///
+ ///
+ /// For [StepKind.CALL] the `CallPosition.getSemanticPositionForCall` method
+ /// is called to determine whether the start or the inner position should be
+ /// used. For instance if the receiver of the JavaScript call is a "simple"
+ /// expression then the start position of the source information is used:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// t1.@foo$0() local.foo()
+ /// ^
+ ///
+ /// If the receiver of the JavaScript call is "complex" then the inner
+ /// position of the source information is used:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// get$bar().@foo() bar.foo()
+ /// ^
+ ///
+ /// For [StepKind.FUN_EXIT] the inner position of the source information
+ /// is used. For a JavaScript function without a return statement this maps
+ /// the end brace to the end brace of the corresponding Dart function. For a
+ /// JavaScript function exited through a return statement this maps the end of
+ /// the return statement to the end brace of the Dart function:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// foo: function() { foo() {
+ /// @} }
+ /// ^
+ /// foo: function() { foo() {
+ /// return 0;@ return 0;
+ /// } }
+ /// ^
@override
void onStep(js.Node node, Offset offset, StepKind kind) {
int codeLocation = offset.value;
@@ -663,13 +721,69 @@
/// The position of a [js.Call] node.
class CallPosition {
+ /// The call node for which the positions have been computed.
final js.Node node;
+
+ /// The position for [node] used as the offset in the JavaScript code.
+ ///
+ /// This is either `CodePositionKind.START` for code like
+ ///
+ /// t1.foo$0()
+ /// ^
+ /// where the left-most offset of the receiver should be used, or
+ /// `CodePositionKind.CLOSING` for code like
+ ///
+ /// get$bar().foo$0()
+ /// ^
+ ///
+ /// where the name of the called method should be used (here the method
+ /// 'foo$0').
final CodePositionKind codePositionKind;
+
+ /// The position from the [SourceInformation] used in the mapped Dart code.
+ ///
+ /// This is either `SourcePositionKind.START` for code like
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// t1.@foo$0() local.foo()
+ /// ^
+ ///
+ /// where the JavaScript receiver is a "simple" expression, or
+ /// `SourcePositionKind.CLOSING` for code like
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// get$bar().@foo() bar.foo()
+ /// ^
+ ///
+ /// where the JavaScript receiver is a "complex" expression.
+ ///
+ /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+ /// code position.)
final SourcePositionKind sourcePositionKind;
CallPosition(this.node, this.codePositionKind, this.sourcePositionKind);
- /// Computes the [CallPosition] for [node].
+ /// Computes the [CallPosition] for the call [node].
+ ///
+ /// For instance if the receiver of the JavaScript call is a "simple"
+ /// expression then the start position of the source information is used:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// t1.@foo$0() local.foo()
+ /// ^
+ ///
+ /// If the receiver of the JavaScript call is "complex" then the inner
+ /// position of the source information is used:
+ ///
+ /// JavaScript: Dart:
+ ///
+ /// get$bar().@foo() bar.foo()
+ /// ^
+ /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+ /// code position.)
static CallPosition getSemanticPositionForCall(js.Call node) {
if (node.target is js.PropertyAccess) {
js.PropertyAccess access = node.target;
@@ -728,6 +842,13 @@
}
}
+/// An offset of a JavaScript node within the output code.
+///
+/// This object holds three different values for the offset corresponding to
+/// three different ways browsers can compute the offset of a JavaScript node.
+///
+/// Currently [subexpressionOffset] is used since it corresponds the most to the
+/// offset used by most browsers.
class Offset {
/// The offset of the enclosing statement relative to the beginning of the
/// file.
@@ -1153,6 +1274,9 @@
visit(node.value);
notifyStep(
node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.RETURN);
+ Offset exitOffset = getOffsetForNode(
+ node, getSyntaxOffset(node, kind: CodePositionKind.CLOSING));
+ notifyStep(node, exitOffset, StepKind.FUN_EXIT);
statementOffset = null;
leftToRightOffset = null;
}
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index ac33b01..34a80d7 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -28,8 +28,10 @@
/// The source location associated with the start of the JS node.
SourceLocation get startPosition => null;
- /// The source location associated with the closing of the JS node.
- SourceLocation get closingPosition => null;
+ /// The source location associated with an inner of the JS node.
+ ///
+ /// The inner position is for instance `foo()` in `o.foo()`.
+ SourceLocation get innerPosition => null;
/// The source location associated with the end of the JS node.
SourceLocation get endPosition => null;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 97c6069..9a819e8 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -15,12 +15,13 @@
export 'package:js_ast/js_ast.dart';
export 'js_debug.dart';
-String prettyPrint(Node node, CompilerOptions compilerOptions,
- {bool allowVariableMinification: true,
+String prettyPrint(Node node,
+ {bool enableMinification: false,
+ bool allowVariableMinification: true,
Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) {
// TODO(johnniwinther): Do we need all the options here?
JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
- shouldCompressOutput: compilerOptions.enableMinification,
+ shouldCompressOutput: enableMinification,
minifyLocalVariables: allowVariableMinification,
renamerForNames: renamerForNames);
SimpleJavaScriptPrintingContext context =
@@ -130,7 +131,7 @@
/// for example by the lazy emitter or when generating code generators.
class UnparsedNode extends DeferredString implements AstContainer {
final Node tree;
- final CompilerOptions _compilerOptions;
+ final bool _enableMinification;
final bool _protectForEval;
LiteralString _cachedLiteral;
@@ -141,11 +142,11 @@
/// When its string [value] is requested, the node pretty-prints the given
/// [ast] and, if [protectForEval] is true, wraps the resulting string in
/// parenthesis. The result is also escaped.
- UnparsedNode(this.tree, this._compilerOptions, this._protectForEval);
+ UnparsedNode(this.tree, this._enableMinification, this._protectForEval);
LiteralString get _literal {
if (_cachedLiteral == null) {
- String text = prettyPrint(tree, _compilerOptions);
+ String text = prettyPrint(tree, enableMinification: _enableMinification);
if (_protectForEval) {
if (tree is Fun) text = '($text)';
if (tree is LiteralExpression) {
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 35913d3..b2b61c8 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -871,7 +871,8 @@
String getGeneratedCode(MemberEntity element) {
assert(!(element is MemberElement && !element.isDeclaration),
failedAt(element));
- return jsAst.prettyPrint(generatedCode[element], compiler.options);
+ return jsAst.prettyPrint(generatedCode[element],
+ enableMinification: compiler.options.enableMinification);
}
/// Generates the output and returns the total size of the generated code.
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 605b8f8..d52f2f0 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -370,4 +370,10 @@
jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
return constantReferenceGenerator(constant.referenced);
}
+
+ @override
+ jsAst.Expression visitDeferredGlobal(DeferredGlobalConstantValue constant,
+ [_]) {
+ return constantReferenceGenerator(constant.referenced);
+ }
}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 902fb2c..51e274e 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1995,6 +1995,11 @@
void visitDeferred(DeferredConstantValue constant, [_]) {
addRoot('Deferred');
}
+
+ @override
+ void visitDeferredGlobal(DeferredGlobalConstantValue constant, [_]) {
+ addRoot('Deferred');
+ }
}
/**
@@ -2116,6 +2121,12 @@
return _combine(hash, _visit(constant.referenced));
}
+ @override
+ int visitDeferredGlobal(DeferredGlobalConstantValue constant, [_]) {
+ int hash = constant.unit.hashCode;
+ return _combine(hash, _visit(constant.referenced));
+ }
+
int _hashString(int hash, String s) {
int length = s.length;
hash = _combine(hash, length);
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 89ee3d0..79057a1 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -137,9 +137,6 @@
/// is a function type.
jsAst.Template get templateForIsFunctionType;
- /// Returns the JavaScript template that creates at runtime a new function
- /// type object.
- jsAst.Template get templateForCreateFunctionType;
jsAst.Name get getFunctionThatReturnsNullName;
/// Returns a [jsAst.Expression] representing the given [type]. Type variables
@@ -801,13 +798,6 @@
return _representationGenerator.templateForIsFunctionType;
}
- /// Returns the JavaScript template that creates at runtime a new function
- /// type object.
- @override
- jsAst.Template get templateForCreateFunctionType {
- return _representationGenerator.templateForCreateFunctionType;
- }
-
@override
jsAst.Expression getTypeRepresentation(
Emitter emitter, DartType type, OnVariableCallback onVariable,
@@ -1055,15 +1045,6 @@
return jsAst.js.expressionTemplateFor("'${namer.functionTypeTag}' in #");
}
- /// Returns the JavaScript template that creates at runtime a new function
- /// type object.
- jsAst.Template get templateForCreateFunctionType {
- // The value of the functionTypeTag can be anything. We use "dynaFunc" for
- // easier debugging.
- return jsAst.js
- .expressionTemplateFor('{ ${namer.functionTypeTag}: "dynafunc" }');
- }
-
jsAst.Expression visitFunctionType(FunctionType type, Emitter emitter) {
List<jsAst.Property> properties = <jsAst.Property>[];
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index a3774ff..7f65831 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -261,8 +261,8 @@
jsAst.Statement tearOffGetter;
if (!options.useContentSecurityPolicy) {
- jsAst.Expression tearOffAccessText =
- new jsAst.UnparsedNode(tearOffAccessExpression, options, false);
+ jsAst.Expression tearOffAccessText = new jsAst.UnparsedNode(
+ tearOffAccessExpression, options.enableMinification, false);
tearOffGetter = js.statement('''
function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) {
return isIntercepted
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index 48721d5..0b8e6a7 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -233,6 +233,13 @@
// TODO(sra): What kind of Entity is `prefix`?
return compareElements(a.import, b.import);
}
+
+ int visitDeferredGlobal(
+ DeferredGlobalConstantValue a, DeferredGlobalConstantValue b) {
+ int r = compareValues(a.referenced, b.referenced);
+ if (r != 0) return r;
+ return a.unit.compareTo(b.unit);
+ }
}
class _KindVisitor implements ConstantValueVisitor<int, Null> {
@@ -251,6 +258,7 @@
static const int INTERCEPTOR = 11;
static const int SYNTHETIC = 12;
static const int DEFERRED = 13;
+ static const int DEFERRED_GLOBAL = 14;
static const int NONCONSTANT = 13;
static int kind(ConstantValue constant) =>
@@ -270,6 +278,7 @@
int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
+ int visitDeferredGlobal(DeferredGlobalConstantValue a, _) => DEFERRED_GLOBAL;
}
/// Visitor for distinguishing types by kind.
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index d5b051b..c96a17c 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -342,9 +342,6 @@
case JsBuiltin.rawRuntimeType:
return jsAst.js.expressionTemplateFor("#.constructor");
- case JsBuiltin.createFunctionTypeRti:
- return backend.rtiEncoder.templateForCreateFunctionType;
-
case JsBuiltin.isSubtype:
// TODO(floitsch): move this closer to where is-check properties are
// built.
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 3f76e8b..d21e5e7 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -372,8 +372,9 @@
_MetadataEntry _addGlobalMetadata(jsAst.Node node, OutputUnit outputUnit) {
String nameToKey(jsAst.Name name) => "${name.key}";
- String printed =
- jsAst.prettyPrint(node, _options, renamerForNames: nameToKey);
+ String printed = jsAst.prettyPrint(node,
+ enableMinification: _options.enableMinification,
+ renamerForNames: nameToKey);
_metadataMap[outputUnit] ??= new Map<String, _BoundMetadataEntry>();
return _metadataMap[outputUnit].putIfAbsent(printed, () {
return new _BoundMetadataEntry(node);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 6d0d91e..4a14cc2 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -698,9 +698,7 @@
_rtiSubstitutions,
_jsInteropAnalysis);
- void visitMember(ClassEntity declarer, MemberEntity member) {
- if (cls != declarer) return;
-
+ void visitMember(MemberEntity member) {
if (member.isInstanceMember && !member.isAbstract && !member.isField) {
// TODO(herhut): Remove once _buildMethod can no longer return null.
Method method = _buildMethod(member);
@@ -747,11 +745,10 @@
// MixinApplications run through the members of their mixin. Here, we are
// only interested in direct members.
if (!onlyForRti && !_elementEnvironment.isMixinApplication(cls)) {
- _elementEnvironment.forEachClassMember(cls, visitMember);
- _elementEnvironment.forEachConstructorBody(
- cls,
- (ConstructorBodyEntity constructorBody) =>
- visitMember(cls, constructorBody));
+ List<MemberEntity> members = <MemberEntity>[];
+ _elementEnvironment.forEachLocalClassMember(cls, members.add);
+ _elementEnvironment.forEachConstructorBody(cls, members.add);
+ _sorter.sortMembers(members).forEach(visitMember);
}
bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
List<Field> instanceFields = onlyForRti
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index f4ff829..f1b2ad4 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -132,9 +132,6 @@
case JsBuiltin.rawRuntimeType:
return js.js.expressionTemplateFor("#.constructor");
- case JsBuiltin.createFunctionTypeRti:
- return _backend.rtiEncoder.templateForCreateFunctionType;
-
case JsBuiltin.isSubtype:
// TODO(floitsch): move this closer to where is-check properties are
// built.
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 5a95832..7f82042 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -168,7 +168,7 @@
} else {
failedAt(member, "Unexpected closure node ${node}");
}
- KernelClosureClass closureClass = _produceSyntheticElements(
+ KernelClosureClassInfo closureClassInfo = _produceSyntheticElements(
closedWorldBuilder,
member,
functionNode,
@@ -177,8 +177,8 @@
localFunctionsNeedingRti,
classesNeedingRti);
// Add also for the call method.
- _scopeMap[closureClass.callMethod] = closureClass;
- callMethods.add(closureClass.callMethod);
+ _scopeMap[closureClassInfo.callMethod] = closureClassInfo;
+ callMethods.add(closureClassInfo.callMethod);
}
});
return callMethods;
@@ -190,7 +190,7 @@
/// the closure accesses a variable that gets accessed at some point), then
/// boxForCapturedVariables stores the local context for those variables.
/// If no variables are captured, this parameter is null.
- KernelClosureClass _produceSyntheticElements(
+ KernelClosureClassInfo _produceSyntheticElements(
JsClosedWorldBuilder closedWorldBuilder,
MemberEntity member,
ir.FunctionNode node,
@@ -201,28 +201,24 @@
_updateScopeBasedOnRtiNeed(
info, node.parent, localFunctionsNeedingRti, classesNeedingRti, member);
KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
- KernelClosureClass closureClass = closedWorldBuilder.buildClosureClass(
- member,
- node,
- member.library,
- boxedVariables,
- info,
- node.location,
- localsMap);
+ KernelClosureClassInfo closureClassInfo =
+ closedWorldBuilder.buildClosureClass(member, node, member.library,
+ boxedVariables, info, node.location, localsMap);
// We want the original declaration where that function is used to point
// to the correct closure class.
- _memberClosureRepresentationMap[closureClass.callMethod] = closureClass;
- _globalLocalsMap.setLocalsMap(closureClass.callMethod, localsMap);
+ _memberClosureRepresentationMap[closureClassInfo.callMethod] =
+ closureClassInfo;
+ _globalLocalsMap.setLocalsMap(closureClassInfo.callMethod, localsMap);
if (node.parent is ir.Member) {
assert(_elementMap.getMember(node.parent) == member);
- _memberClosureRepresentationMap[member] = closureClass;
+ _memberClosureRepresentationMap[member] = closureClassInfo;
} else {
assert(node.parent is ir.FunctionExpression ||
node.parent is ir.FunctionDeclaration);
- _localClosureRepresentationMap[node.parent] = closureClass;
+ _localClosureRepresentationMap[node.parent] = closureClassInfo;
}
- return closureClass;
+ return closureClassInfo;
}
@override
@@ -478,7 +474,7 @@
}
// TODO(johnniwinther): Add unittest for the computed [ClosureClass].
-class KernelClosureClass extends JsScopeInfo
+class KernelClosureClassInfo extends JsScopeInfo
implements ClosureRepresentationInfo {
JFunction callMethod;
final Local closureEntity;
@@ -487,7 +483,7 @@
final Map<Local, JField> localToFieldMap = new Map<Local, JField>();
- KernelClosureClass.fromScopeInfo(
+ KernelClosureClassInfo.fromScopeInfo(
this.closureClassEntity,
ir.FunctionNode closureSourceNode,
Map<Local, JRecordField> boxedVariables,
@@ -550,8 +546,8 @@
class JClosureField extends JField implements PrivatelyNamedJSEntity {
final Local _declaredEntity;
- JClosureField(String name, KernelClosureClass containingClass, bool isConst,
- bool isAssignable, this._declaredEntity)
+ JClosureField(String name, KernelClosureClassInfo containingClass,
+ bool isConst, bool isAssignable, this._declaredEntity)
: super(
containingClass.closureClassEntity.library,
containingClass.closureClassEntity,
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 4229b83..e9b84a1 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -9,7 +9,7 @@
import '../elements/names.dart';
import '../elements/types.dart';
import '../kernel/indexed.dart';
-import 'closure.dart' show KernelClosureClass;
+import 'closure.dart' show KernelClosureClassInfo;
/// Map from 'frontend' to 'backend' elements.
///
@@ -522,11 +522,11 @@
}
class JClosureCallMethod extends JMethod {
- JClosureCallMethod(KernelClosureClass containingClass,
+ JClosureCallMethod(KernelClosureClassInfo closureClassInfo,
ParameterStructure parameterStructure, AsyncMarker asyncMarker)
: super(
- containingClass.closureClassEntity.library,
- containingClass.closureClassEntity,
+ closureClassInfo.closureClassEntity.library,
+ closureClassInfo.closureClassEntity,
Names.call,
parameterStructure,
asyncMarker,
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 4d56126..0ee5d63 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -159,6 +159,7 @@
SelectorConstraintsStrategy selectorConstraintsStrategy) {
return new KernelCodegenWorldBuilder(
elementMap,
+ _globalLocalsMap,
closedWorld.elementEnvironment,
nativeBasicData,
closedWorld,
@@ -474,7 +475,7 @@
/// Construct a closure class and set up the necessary class inference
/// hierarchy.
- KernelClosureClass buildClosureClass(
+ KernelClosureClassInfo buildClosureClass(
MemberEntity member,
ir.FunctionNode originalClosureFunctionNode,
JLibrary enclosingLibrary,
@@ -484,7 +485,7 @@
KernelToLocalsMap localsMap) {
ClassEntity superclass = _commonElements.closureClass;
- KernelClosureClass cls = _elementMap.constructClosureClass(
+ KernelClosureClassInfo closureClassInfo = _elementMap.constructClosureClass(
member,
originalClosureFunctionNode,
enclosingLibrary,
@@ -497,13 +498,13 @@
// Tell the hierarchy that this is the super class. then we can use
// .getSupertypes(class)
ClassHierarchyNode parentNode = _classHierarchyNodes[superclass];
- ClassHierarchyNode node = new ClassHierarchyNode(
- parentNode, cls.closureClassEntity, parentNode.hierarchyDepth + 1);
- _classHierarchyNodes[cls.closureClassEntity] = node;
- _classSets[cls.closureClassEntity] = new ClassSet(node);
+ ClassHierarchyNode node = new ClassHierarchyNode(parentNode,
+ closureClassInfo.closureClassEntity, parentNode.hierarchyDepth + 1);
+ _classHierarchyNodes[closureClassInfo.closureClassEntity] = node;
+ _classSets[closureClassInfo.closureClassEntity] = new ClassSet(node);
node.isDirectlyInstantiated = true;
- return cls;
+ return closureClassInfo;
}
}
@@ -622,10 +623,13 @@
}
ConstantValue visitDeferred(DeferredConstantValue constant, _) {
+ throw new UnsupportedError("DeferredConstantValue with --use-kernel");
+ }
+
+ ConstantValue visitDeferredGlobal(DeferredGlobalConstantValue constant, _) {
var referenced = constant.referenced.accept(this, null);
if (referenced == constant.referenced) return constant;
- // TODO(sigmund): do we need a JImport entity?
- return new DeferredConstantValue(referenced, constant.import);
+ return new DeferredGlobalConstantValue(referenced, constant.unit);
}
DartType _handleType(DartType type) {
diff --git a/pkg/compiler/lib/src/kernel/deferred_load.dart b/pkg/compiler/lib/src/kernel/deferred_load.dart
index ea96d26..f9d46c3 100644
--- a/pkg/compiler/lib/src/kernel/deferred_load.dart
+++ b/pkg/compiler/lib/src/kernel/deferred_load.dart
@@ -22,15 +22,42 @@
@override
Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library) {
- if (element is! MemberEntity) return const <ImportEntity>[];
+ ir.NamedNode node;
+ String nodeName;
+ ir.Library enclosingLibrary;
+ if (element is ClassEntity) {
+ ClassDefinition definition = _elementMap.getClassDefinition(element);
+ if (definition.kind != ClassKind.regular) {
+ // You can't import closures.
+ return const <ImportEntity>[];
+ }
+ ir.Class _node = definition.node;
+ nodeName = _node.name;
+ enclosingLibrary = _node.enclosingLibrary;
+ node = _node;
+ } else if (element is MemberEntity) {
+ ir.Member _node = _elementMap.getMemberDefinition(element).node;
+ nodeName = _node.name.name;
+ enclosingLibrary = _node.enclosingLibrary;
+ node = _node;
+ } else if (element is Local ||
+ element is LibraryEntity ||
+ element is TypeVariableEntity) {
+ return const <ImportEntity>[];
+ } else if (element is TypedefEntity) {
+ throw new UnimplementedError("KernelDeferredLoadTask.importsTo typedef");
+ } else {
+ throw new UnsupportedError(
+ "KernelDeferredLoadTask.importsTo unexpected entity type: "
+ "${element.runtimeType}");
+ }
List<ImportEntity> imports = [];
ir.Library source = _elementMap.getLibraryNode(library);
- ir.Member member = _elementMap.getMemberDefinition(element).node;
for (ir.LibraryDependency dependency in source.dependencies) {
if (dependency.isExport) continue;
- if (!_isVisible(dependency.combinators, member.name.name)) continue;
- if (member.enclosingLibrary == dependency.targetLibrary ||
- additionalExports(dependency.targetLibrary).contains(member)) {
+ if (!_isVisible(dependency.combinators, nodeName)) continue;
+ if (enclosingLibrary == dependency.targetLibrary ||
+ additionalExports(dependency.targetLibrary).contains(node)) {
imports.add(_elementMap.getImport(dependency));
}
}
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 9360a77..2d256cc 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -180,6 +180,9 @@
/// Returns the definition information for [member].
MemberDefinition getMemberDefinition(covariant MemberEntity member);
+ /// Returns the definition information for [cls].
+ ClassDefinition getClassDefinition(covariant ClassEntity cls);
+
/// Return the [ImportEntity] corresponding to [node].
ImportEntity getImport(ir.LibraryDependency node);
}
@@ -276,7 +279,7 @@
enum ClassKind {
regular,
closure,
- // TODO(efortuna, johnniwinther): Container is not a class, but is
+ // TODO(efortuna, johnniwinther): Record is not a class, but is
// masquerading as one currently for consistency with the old element model.
record,
}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 2d6dc79..92e71cd 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -71,6 +71,7 @@
}
abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
+ final CompilerOptions options;
final DiagnosticReporter reporter;
CommonElements _commonElements;
ElementEnvironment _elementEnvironment;
@@ -92,7 +93,7 @@
final EntityDataMap<IndexedTypedef, TypedefData> _typedefs =
new EntityDataMap<IndexedTypedef, TypedefData>();
- KernelToElementMapBase(this.reporter, Environment environment) {
+ KernelToElementMapBase(this.options, this.reporter, Environment environment) {
_elementEnvironment = new KernelElementEnvironment(this);
_commonElements = new CommonElements(_elementEnvironment);
_constantEnvironment = new KernelConstantEnvironment(this, environment);
@@ -438,8 +439,7 @@
namedParameterTypes.add(getDartType(variable.type));
}
List<FunctionTypeVariable> typeVariables;
- if (node.typeParameters.isNotEmpty &&
- DartTypeConverter.enableFunctionTypeVariables) {
+ if (node.typeParameters.isNotEmpty && options.strongMode) {
List<DartType> typeParameters = <DartType>[];
for (ir.TypeParameter typeParameter in node.typeParameters) {
typeParameters
@@ -703,6 +703,9 @@
'KernelToElementMapBase._forEachConstructorBody');
}
+ void _forEachNestedClosure(
+ MemberEntity member, void f(FunctionEntity closure));
+
void _forEachLocalClassMember(IndexedClass cls, void f(MemberEntity member)) {
assert(checkFamily(cls));
ClassEnv env = _classes.getEnv(cls);
@@ -790,7 +793,7 @@
}
/// Mixin that implements the abstract methods in [KernelToElementMapBase].
-abstract class ElementCreatorMixin {
+abstract class ElementCreatorMixin implements KernelToElementMapBase {
ProgramEnv get _env;
EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> get _libraries;
EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> get _classes;
@@ -1012,11 +1015,8 @@
int typeParameters = node.typeParameters.length;
List<String> namedParameters =
node.namedParameters.map((p) => p.name).toList()..sort();
- return new ParameterStructure(
- requiredParameters,
- positionalParameters,
- namedParameters,
- DartTypeConverter.enableFunctionTypeVariables ? typeParameters : 0);
+ return new ParameterStructure(requiredParameters, positionalParameters,
+ namedParameters, options.strongMode ? typeParameters : 0);
}
IndexedLibrary createLibrary(String name, Uri canonicalUri);
@@ -1142,11 +1142,10 @@
KElementCreatorMixin {
native.BehaviorBuilder _nativeBehaviorBuilder;
FrontendStrategy _frontendStrategy;
- CompilerOptions _options;
KernelToElementMapForImpactImpl(DiagnosticReporter reporter,
- Environment environment, this._frontendStrategy, this._options)
- : super(reporter, environment);
+ Environment environment, this._frontendStrategy, CompilerOptions options)
+ : super(options, reporter, environment);
@override
bool checkFamily(Entity entity) {
@@ -1158,6 +1157,13 @@
}
@override
+ void _forEachNestedClosure(
+ MemberEntity member, void f(FunctionEntity closure)) {
+ throw new UnsupportedError(
+ "KernelToElementMapForImpactImpl._forEachNestedClosure");
+ }
+
+ @override
NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
/// Adds libraries in [program] to the set of libraries.
@@ -1171,7 +1177,7 @@
@override
native.BehaviorBuilder get nativeBehaviorBuilder =>
_nativeBehaviorBuilder ??= new KernelBehaviorBuilder(elementEnvironment,
- commonElements, nativeBasicData, reporter, _options);
+ commonElements, nativeBasicData, reporter, options);
ResolutionImpact computeWorldImpact(KMember member) {
return buildKernelImpact(
@@ -1180,7 +1186,7 @@
ScopeModel computeScopeModel(KMember member) {
ir.Member node = _members.getData(member).definition.node;
- return KernelClosureAnalysis.computeScopeModel(member, node, _options);
+ return KernelClosureAnalysis.computeScopeModel(member, node, options);
}
/// Returns the kernel [ir.Procedure] node for the [method].
@@ -1255,6 +1261,11 @@
MemberDefinition getMemberDefinition(MemberEntity member) {
return _getMemberDefinition(member);
}
+
+ @override
+ ClassDefinition getClassDefinition(ClassEntity cls) {
+ return _getClassDefinition(cls);
+ }
}
class KernelElementEnvironment extends ElementEnvironment {
@@ -1423,8 +1434,7 @@
@override
void forEachNestedClosure(
MemberEntity member, void f(FunctionEntity closure)) {
- throw new UnimplementedError(
- 'KernelElementEnvironment.forEachNestedClosure');
+ elementMap._forEachNestedClosure(member, f);
}
@override
@@ -1534,8 +1544,6 @@
/// Visitor that converts kernel dart types into [DartType].
class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
- static bool enableFunctionTypeVariables = false;
-
final KernelToElementMapBase elementMap;
final Map<ir.TypeParameter, DartType> currentFunctionTypeParameters =
<ir.TypeParameter, DartType>{};
@@ -1588,7 +1596,7 @@
int index = 0;
List<FunctionTypeVariable> typeVariables;
for (ir.TypeParameter typeParameter in node.typeParameters) {
- if (enableFunctionTypeVariables) {
+ if (elementMap.options.strongMode) {
// TODO(johnniwinther): Support recursive type variable bounds, like
// `void Function<T extends Foo<T>>(T t)` when #31531 is fixed.
DartType bound = typeParameter.bound.accept(this);
@@ -2046,11 +2054,15 @@
ElementCreatorMixin
implements
KernelToWorldBuilder {
+ /// Map from members to the call methods created for their nested closures.
+ Map<MemberEntity, List<FunctionEntity>> _nestedClosureMap =
+ <MemberEntity, List<FunctionEntity>>{};
+
NativeBasicData nativeBasicData;
JsKernelToElementMap(DiagnosticReporter reporter, Environment environment,
KernelToElementMapForImpactImpl _elementMap)
- : super(reporter, environment) {
+ : super(_elementMap.options, reporter, environment) {
_env = _elementMap._env;
for (int libraryIndex = 0;
libraryIndex < _elementMap._libraries.length;
@@ -2122,6 +2134,13 @@
}
}
+ @override
+ void _forEachNestedClosure(
+ MemberEntity member, void f(FunctionEntity closure)) {
+ assert(checkFamily(member));
+ _nestedClosureMap[member]?.forEach(f);
+ }
+
InterfaceType getMemberThisType(MemberEntity member) {
return _members.getData(member).getMemberThisType(this);
}
@@ -2321,7 +2340,7 @@
Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
recordFieldsVisibleInScope.containsKey(local);
- KernelClosureClass constructClosureClass(
+ KernelClosureClassInfo constructClosureClass(
MemberEntity member,
ir.FunctionNode node,
JLibrary enclosingLibrary,
@@ -2369,20 +2388,24 @@
closureEntity = new JLocal('', localsMap.currentMember);
}
- KernelClosureClass cls = new KernelClosureClass.fromScopeInfo(
- classEntity,
- node,
- <Local, JRecordField>{},
- info,
- localsMap,
- closureEntity,
- info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
- this);
- _buildClosureClassFields(cls, member, memberThisType, info, localsMap,
- recordFieldsVisibleInScope, memberMap);
+ KernelClosureClassInfo closureClassInfo =
+ new KernelClosureClassInfo.fromScopeInfo(
+ classEntity,
+ node,
+ <Local, JRecordField>{},
+ info,
+ localsMap,
+ closureEntity,
+ info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
+ this);
+ _buildClosureClassFields(closureClassInfo, member, memberThisType, info,
+ localsMap, recordFieldsVisibleInScope, memberMap);
FunctionEntity callMethod = new JClosureCallMethod(
- cls, _getParameterStructure(node), getAsyncMarker(node));
+ closureClassInfo, _getParameterStructure(node), getAsyncMarker(node));
+ _nestedClosureMap
+ .putIfAbsent(member, () => <FunctionEntity>[])
+ .add(callMethod);
_members.register<IndexedFunction, FunctionData>(
callMethod,
new ClosureFunctionData(
@@ -2392,12 +2415,12 @@
getFunctionType(node),
node,
typeVariableAccess));
- memberMap[callMethod.name] = cls.callMethod = callMethod;
- return cls;
+ memberMap[callMethod.name] = closureClassInfo.callMethod = callMethod;
+ return closureClassInfo;
}
void _buildClosureClassFields(
- KernelClosureClass cls,
+ KernelClosureClassInfo closureClassInfo,
MemberEntity member,
InterfaceType memberThisType,
KernelScopeInfo info,
@@ -2420,7 +2443,7 @@
if (_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
bool constructedField = _constructClosureFieldForRecord(
capturedLocal,
- cls,
+ closureClassInfo,
memberThisType,
memberMap,
variable,
@@ -2434,8 +2457,8 @@
// Add a field for the captured 'this'.
if (info.thisUsedAsFreeVariable) {
_constructClosureField(
- cls.thisLocal,
- cls,
+ closureClassInfo.thisLocal,
+ closureClassInfo,
memberThisType,
memberMap,
getClassDefinition(member.enclosingClass).node,
@@ -2453,7 +2476,7 @@
if (!_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
_constructClosureField(
capturedLocal,
- cls,
+ closureClassInfo,
memberThisType,
memberMap,
variable,
@@ -2465,7 +2488,7 @@
} else if (variable is TypeParameterTypeWithContext) {
_constructClosureField(
localsMap.getLocalTypeVariable(variable.type, this),
- cls,
+ closureClassInfo,
memberThisType,
memberMap,
variable.type.parameter,
@@ -2488,7 +2511,7 @@
/// in the closure class.
bool _constructClosureFieldForRecord(
Local capturedLocal,
- KernelClosureClass cls,
+ KernelClosureClassInfo closureClassInfo,
InterfaceType memberThisType,
Map<String, MemberEntity> memberMap,
ir.TreeNode sourceNode,
@@ -2498,32 +2521,32 @@
// Don't construct a new field if the box that holds this local already has
// a field in the closure class.
- if (cls.localToFieldMap.containsKey(recordField.box)) {
- cls.boxedVariables[capturedLocal] = recordField;
+ if (closureClassInfo.localToFieldMap.containsKey(recordField.box)) {
+ closureClassInfo.boxedVariables[capturedLocal] = recordField;
return false;
}
FieldEntity closureField = new JClosureField(
- '_box_$fieldNumber', cls, true, false, recordField.box);
+ '_box_$fieldNumber', closureClassInfo, true, false, recordField.box);
_members.register<IndexedField, FieldData>(
closureField,
new ClosureFieldData(
new ClosureMemberDefinition(
- cls.localToFieldMap[capturedLocal],
+ closureClassInfo.localToFieldMap[capturedLocal],
computeSourceSpanFromTreeNode(sourceNode),
MemberKind.closureField,
sourceNode),
memberThisType));
memberMap[closureField.name] = closureField;
- cls.localToFieldMap[recordField.box] = closureField;
- cls.boxedVariables[capturedLocal] = recordField;
+ closureClassInfo.localToFieldMap[recordField.box] = closureField;
+ closureClassInfo.boxedVariables[capturedLocal] = recordField;
return true;
}
_constructClosureField(
Local capturedLocal,
- KernelClosureClass cls,
+ KernelClosureClassInfo closureClassInfo,
InterfaceType memberThisType,
Map<String, MemberEntity> memberMap,
ir.TreeNode sourceNode,
@@ -2532,7 +2555,7 @@
int fieldNumber) {
FieldEntity closureField = new JClosureField(
_getClosureVariableName(capturedLocal.name, fieldNumber),
- cls,
+ closureClassInfo,
isConst,
isAssignable,
capturedLocal);
@@ -2541,13 +2564,13 @@
closureField,
new ClosureFieldData(
new ClosureMemberDefinition(
- cls.localToFieldMap[capturedLocal],
+ closureClassInfo.localToFieldMap[capturedLocal],
computeSourceSpanFromTreeNode(sourceNode),
MemberKind.closureField,
sourceNode),
memberThisType));
memberMap[closureField.name] = closureField;
- cls.localToFieldMap[capturedLocal] = closureField;
+ closureClassInfo.localToFieldMap[capturedLocal] = closureField;
}
// Returns a non-unique name for the given closure element.
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index aa25d5e..9117831 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -20,13 +20,14 @@
import '../js_backend/namer.dart';
import '../js_emitter/code_emitter_task.dart';
import '../native/native.dart' as native;
+import '../options.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
import 'element_map.dart';
-import 'element_map_impl.dart';
import 'kernel_debug.dart';
abstract class KernelToElementMapBaseMixin implements KernelToElementMap {
+ CompilerOptions get options;
DiagnosticReporter get reporter;
ElementEnvironment get elementEnvironment;
LibraryEntity getLibrary(ir.Library node);
@@ -44,12 +45,8 @@
CallStructure getCallStructure(ir.Arguments arguments) {
int argumentCount = arguments.positional.length + arguments.named.length;
List<String> namedArguments = arguments.named.map((e) => e.name).toList();
- return new CallStructure(
- argumentCount,
- namedArguments,
- DartTypeConverter.enableFunctionTypeVariables
- ? arguments.types.length
- : 0);
+ return new CallStructure(argumentCount, namedArguments,
+ options.strongMode ? arguments.types.length : 0);
}
@override
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 3083498..a4a9011 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -173,7 +173,10 @@
dependencies.forEach((ir.LibraryDependency node) {
if (node.isExport) return;
imports[node] = new KImport(
- node.isDeferred, node.name, node.targetLibrary.importUri);
+ node.isDeferred,
+ node.name,
+ node.targetLibrary.importUri,
+ elementMap.getLibrary(node.enclosingLibrary));
});
}
}
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index fd9ec25..6f14b6e 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -25,8 +25,9 @@
final bool isDeferred;
final String name;
final Uri uri;
+ final LibraryEntity enclosingLibrary;
- KImport(this.isDeferred, this.name, this.uri);
+ KImport(this.isDeferred, this.name, this.uri, this.enclosingLibrary);
String toString() =>
'${kElementPrefix}import($name:${isDeferred ? ' deferred' : ''})';
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index d6ea085..cd97a06 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -99,6 +99,10 @@
reporter: elementMap.reporter,
objectType: elementMap.commonElements.objectType);
+ // TODO(sigmund): delete once Issue #31118 is fixed.
+ @override
+ bool get reportMultiInheritanceIssue => false;
+
InterfaceType getThisType(ClassEntity cls) {
return elementMap._getThisType(cls);
}
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index b4d108f..b0e0610 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -863,7 +863,8 @@
} else {
initializedCompilerState = fe.initializeCompiler(
initializedCompilerState,
- new Dart2jsTarget(new TargetFlags()),
+ new Dart2jsTarget(
+ new TargetFlags(strongMode: _elementMap.options.strongMode)),
platformBinaries.resolve("dart2js_platform.dill"),
_packageConfig);
program = await fe.compile(
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 466e63a..73650f6 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -213,11 +213,16 @@
/// sources to kernel, and then continue compilation from the kernel
/// representation.
///
- /// When this flag is on, the compiler also acccepts reading .dill files from
+ /// When this flag is on, the compiler also accepts reading .dill files from
/// disk. The compiler reads the sources differently depending on the
/// extension format.
final bool useKernel;
+ /// Enables strong mode in dart2js.
+ ///
+ /// This is work-in-progress and will only be supported for [useKernel].
+ final bool strongMode;
+
/// When obfuscating for minification, whether to use the frequency of a name
/// as an heuristic to pick shorter names.
final bool useFrequencyNamer;
@@ -325,6 +330,7 @@
resolveOnly: _hasOption(options, Flags.resolveOnly),
sourceMapUri: _extractUriOption(options, '--source-map='),
strips: _extractCsvOption(options, '--force-strip='),
+ strongMode: _hasOption(options, Flags.strongMode),
testMode: _hasOption(options, Flags.testMode),
trustJSInteropTypeAnnotations:
_hasOption(options, Flags.trustJSInteropTypeAnnotations),
@@ -390,6 +396,7 @@
bool resolveOnly: false,
Uri sourceMapUri: null,
List<String> strips: const [],
+ bool strongMode: false,
bool testMode: false,
bool trustJSInteropTypeAnnotations: false,
bool trustPrimitives: false,
@@ -470,6 +477,7 @@
resolveOnly: resolveOnly,
sourceMapUri: sourceMapUri,
strips: strips,
+ strongMode: strongMode,
testMode: testMode,
trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
trustPrimitives: trustPrimitives,
@@ -522,6 +530,7 @@
this.compileOnly: false,
this.sourceMapUri: null,
this.strips: const [],
+ this.strongMode: false,
this.testMode: false,
this.trustJSInteropTypeAnnotations: false,
this.trustPrimitives: false,
@@ -582,6 +591,7 @@
compileOnly,
sourceMapUri,
strips,
+ strongMode,
testMode,
trustJSInteropTypeAnnotations,
trustPrimitives,
@@ -649,6 +659,7 @@
compileOnly: compileOnly ?? options.compileOnly,
sourceMapUri: sourceMapUri ?? options.sourceMapUri,
strips: strips ?? options.strips,
+ strongMode: strongMode ?? options.strongMode,
testMode: testMode ?? options.testMode,
trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations ??
options.trustJSInteropTypeAnnotations,
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index b01dbf3..a134269 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -228,6 +228,9 @@
}
}
+ // TODO(sigmund): delete once Issue #31118 is fixed.
+ bool get reportMultiInheritanceIssue => true;
+
void _addAtDepth(InterfaceType type, int depth) {
LinkEntry<InterfaceType> prev = null;
LinkEntry<InterfaceType> link = map[depth];
@@ -236,11 +239,13 @@
if (existingType == type) return;
if (existingType.element == type.element) {
if (reporter != null) {
- reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, {
- 'thisType': getThisType(cls),
- 'firstType': existingType,
- 'secondType': type
- });
+ if (reportMultiInheritanceIssue) {
+ reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, {
+ 'thisType': getThisType(cls),
+ 'firstType': existingType,
+ 'secondType': type
+ });
+ }
} else {
assert(false, failedAt(cls, 'Invalid ordered typeset for $cls'));
}
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index b47e1c6..1c4b55c 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -533,13 +533,20 @@
void forEachLocalClassMember(
covariant ClassElement cls, void f(MemberElement member)) {
cls.ensureResolved(_resolution);
- cls.forEachLocalMember((_member) {
+
+ void handleMember(_member) {
MemberElement member = _member;
if (member.isSynthesized) return;
if (member.isMalformed) return;
if (member.isConstructor) return;
+ if (!member.isDeclaration) return;
f(member);
- });
+ }
+
+ cls.forEachLocalMember(handleMember);
+ if (cls.isPatched) {
+ cls.implementation.forEachLocalMember(handleMember);
+ }
}
@override
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index bb7a800..9fef23a 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -1032,6 +1032,20 @@
}
@override
+ bool visitDeferredGlobal(DeferredGlobalConstantValue value1,
+ covariant DeferredGlobalConstantValue value2) {
+ return strategy.testSets(
+ value1,
+ value2,
+ 'imports',
+ value1.unit.importsForTesting,
+ value2.unit.importsForTesting,
+ strategy.elementEquivalence) &&
+ strategy.testConstantValues(
+ value1, value2, 'referenced', value1.referenced, value2.referenced);
+ }
+
+ @override
bool visitNonConstant(
NonConstantValue value1, covariant NonConstantValue value2) {
return true;
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 773980d..34549ec 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -2330,6 +2330,8 @@
}
}
+ LibraryElement get enclosingLibrary => library;
+
@override
bool get isDeferred {
_ensurePrefixResolved();
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 559e4fb..0c2ea28 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -15,6 +15,7 @@
import '../constants/constant_system.dart';
import '../constants/expressions.dart';
import '../constants/values.dart';
+import '../deferred_load.dart' show OutputUnit;
import '../diagnostics/messages.dart' show Message, MessageTemplate;
import '../dump_info.dart' show InfoReporter;
import '../elements/elements.dart';
@@ -2184,8 +2185,10 @@
ImportElement deferredImport =
deferredLoadTask.deferredImportElement(node, elements);
if (deferredImport != null) {
+ OutputUnit unit =
+ compiler.backend.outputUnitData.outputUnitForMember(field);
instruction = graph.addDeferredConstant(
- value, deferredImport, sourceInformation, compiler, closedWorld);
+ value, unit, sourceInformation, compiler, closedWorld);
} else {
instruction = graph.addConstant(value, closedWorld,
sourceInformation: sourceInformation);
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 803a408..0f0724b 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -2530,8 +2530,18 @@
ConstantValue value = _elementMap.getFieldConstantValue(field);
if (value != null) {
if (!field.isAssignable) {
- stack.add(graph.addConstant(value, closedWorld,
- sourceInformation: sourceInformation));
+ var unit = compiler.backend.outputUnitData.outputUnitForEntity(field);
+ // TODO(sigmund): this is not equivalent to what the old FE does: if
+ // there is no prefix the old FE wouldn't treat this in any special
+ // way. Also, if the prefix points to a constant in the main output
+ // unit, the old FE would still generate a deferred wrapper here.
+ if (!unit.isMainOutput) {
+ stack.add(graph.addDeferredConstant(
+ value, unit, sourceInformation, compiler, closedWorld));
+ } else {
+ stack.add(graph.addConstant(value, closedWorld,
+ sourceInformation: sourceInformation));
+ }
} else {
push(new HStatic(field, _typeInferenceMap.getInferredTypeOf(field),
sourceInformation));
@@ -4790,7 +4800,7 @@
// Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
static const INLINING_NODES_OUTSIDE_LOOP = 15;
static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
- static const INLINING_NODES_INSIDE_LOOP = 42;
+ static const INLINING_NODES_INSIDE_LOOP = 34;
static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
static bool canBeInlined(KernelToElementMapForBuilding elementMap,
@@ -4838,6 +4848,7 @@
return true;
}
+ @override
defaultNode(ir.Node node) {
if (tooDifficult) return;
if (!registerNode()) return;
@@ -4848,6 +4859,7 @@
node.visitChildren(this);
}
+ @override
visitReturnStatement(ir.ReturnStatement node) {
if (!registerNode()) return;
if (seenReturn) {
@@ -4858,6 +4870,7 @@
seenReturn = true;
}
+ @override
visitThrow(ir.Throw node) {
if (!registerNode()) return;
if (seenReturn) {
@@ -4876,42 +4889,51 @@
// isn't in the AST based inline weeder.
}
+ @override
visitForStatement(ir.ForStatement node) {
_handleLoop();
}
+ @override
visitForInStatement(ir.ForInStatement node) {
_handleLoop();
}
+ @override
visitWhileStatement(ir.WhileStatement node) {
_handleLoop();
}
+ @override
visitDoStatement(ir.DoStatement node) {
_handleLoop();
}
+ @override
visitTryCatch(ir.TryCatch node) {
if (tooDifficult) return;
tooDifficultReason = 'try';
}
+ @override
visitTryFinally(ir.TryFinally node) {
if (tooDifficult) return;
tooDifficultReason = 'try';
}
+ @override
visitFunctionExpression(ir.FunctionExpression node) {
if (!registerNode()) return;
tooDifficultReason = 'closure';
}
+ @override
visitFunctionDeclaration(ir.FunctionDeclaration node) {
if (!registerNode()) return;
tooDifficultReason = 'closure';
}
+ @override
visitFunctionNode(ir.FunctionNode node) {
if (node.asyncMarker != ir.AsyncMarker.Sync) {
tooDifficultReason = 'async/await';
@@ -4919,6 +4941,36 @@
}
node.visitChildren(this);
}
+
+ @override
+ visitConditionalExpression(ir.ConditionalExpression node) {
+ // Heuristic: In "parameter ? A : B" there is a high probability that
+ // parameter is a constant. Assuming the parameter is constant, we can
+ // compute a count that is bounded by the largest arm rather than the sum of
+ // both arms.
+ ir.Expression condition = node.condition;
+ condition.accept(this);
+ if (tooDifficult) return;
+ int commonPrefixCount = nodeCount;
+
+ node.then.accept(this);
+ if (tooDifficult) return;
+ int thenCount = nodeCount - commonPrefixCount;
+
+ nodeCount = commonPrefixCount;
+ node.otherwise.accept(this);
+ if (tooDifficult) return;
+ int elseCount = nodeCount - commonPrefixCount;
+
+ nodeCount = commonPrefixCount + thenCount + elseCount;
+ if (condition is ir.VariableGet &&
+ condition.variable.parent is ir.FunctionNode) {
+ nodeCount =
+ commonPrefixCount + (thenCount > elseCount ? thenCount : elseCount);
+ }
+ // This is last so that [tooDifficult] is always updated.
+ if (!registerNode()) return;
+ }
}
/// Class in charge of building try, catch and/or finally blocks. This handles
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index a373b52..2b98deb 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -8,6 +8,7 @@
import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
import '../constants/values.dart';
+import '../deferred_load.dart' show OutputUnit;
import '../elements/entities.dart';
import '../elements/jumps.dart';
import '../elements/types.dart';
@@ -273,15 +274,12 @@
HConstant addDeferredConstant(
ConstantValue constant,
- ImportEntity import,
+ OutputUnit unit,
SourceInformation sourceInformation,
Compiler compiler,
ClosedWorld closedWorld) {
- // TODO(sigurdm,johnniwinther): These deferred constants should be created
- // by the constant evaluator.
- ConstantValue wrapper = new DeferredConstantValue(constant, import);
- compiler.backend.outputUnitData
- .registerConstantDeferredUse(wrapper, import);
+ ConstantValue wrapper = new DeferredGlobalConstantValue(constant, unit);
+ compiler.backend.outputUnitData.registerConstantDeferredUse(wrapper, unit);
return addConstant(wrapper, closedWorld,
sourceInformation: sourceInformation);
}
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index e13b834..d796db4 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -684,6 +684,8 @@
NumConstantValue constantNum;
if (constant is DeferredConstantValue) {
constantNum = constant.referenced;
+ } else if (constant is DeferredGlobalConstantValue) {
+ constantNum = constant.referenced;
} else {
constantNum = constant;
}
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 382a3e6..0bd4b32 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -35,6 +35,12 @@
}
@override
+ TypeMask visitDeferredGlobal(
+ DeferredGlobalConstantValue constant, ClosedWorld closedWorld) {
+ return constant.referenced.accept(this, closedWorld);
+ }
+
+ @override
TypeMask visitDouble(DoubleConstantValue constant, ClosedWorld closedWorld) {
// We have to recognize double constants that are 'is int'.
if (closedWorld.constantSystem.isInt(constant)) {
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 2649f62..7335b12 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -667,10 +667,12 @@
}
class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl {
- KernelToWorldBuilder _elementMap;
+ final KernelToWorldBuilder _elementMap;
+ final GlobalLocalsMap _globalLocalsMap;
KernelCodegenWorldBuilder(
this._elementMap,
+ this._globalLocalsMap,
ElementEnvironment elementEnvironment,
NativeBasicData nativeBasicData,
ClosedWorld world,
@@ -697,8 +699,7 @@
@override
void forEachParameterAsLocal(
FunctionEntity function, void f(Local parameter)) {
- throw new UnimplementedError(
- 'KernelCodegenWorldBuilder.forEachParameterAsLocal');
+ forEachOrderedParameter(_globalLocalsMap, _elementMap, function, f);
}
@override
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index a8501fb..c08d246 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -296,17 +296,28 @@
Map<ClassEntity, _ClassUsage> get classUsageForTesting => _processedClasses;
/// Map of registered usage of static members of live classes.
- final Map<Entity, _MemberUsage> _staticMemberUsage = <Entity, _MemberUsage>{};
-
- Map<Entity, _MemberUsage> get staticMemberUsageForTesting =>
- _staticMemberUsage;
-
- /// Map of registered usage of instance members of live classes.
- final Map<MemberEntity, _MemberUsage> _instanceMemberUsage =
+ final Map<MemberEntity, _MemberUsage> _memberUsage =
<MemberEntity, _MemberUsage>{};
- Map<MemberEntity, _MemberUsage> get instanceMemberUsageForTesting =>
- _instanceMemberUsage;
+ Map<MemberEntity, _MemberUsage> get staticMemberUsageForTesting {
+ Map<MemberEntity, _MemberUsage> map = <MemberEntity, _MemberUsage>{};
+ _memberUsage.forEach((MemberEntity member, _MemberUsage usage) {
+ if (!member.isInstanceMember) {
+ map[member] = usage;
+ }
+ });
+ return map;
+ }
+
+ Map<MemberEntity, _MemberUsage> get instanceMemberUsageForTesting {
+ Map<MemberEntity, _MemberUsage> map = <MemberEntity, _MemberUsage>{};
+ _memberUsage.forEach((MemberEntity member, _MemberUsage usage) {
+ if (member.isInstanceMember) {
+ map[member] = usage;
+ }
+ });
+ return map;
+ }
/// Map containing instance members of live classes that are not yet live
/// themselves.
@@ -616,7 +627,7 @@
MemberEntity element = staticUse.element;
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
- _MemberUsage usage = _staticMemberUsage.putIfAbsent(element, () {
+ _MemberUsage usage = _memberUsage.putIfAbsent(element, () {
_MemberUsage usage = new _MemberUsage(element);
useSet.addAll(usage.appliedUse);
return usage;
@@ -749,7 +760,7 @@
// its metadata parsed and analyzed.
// Note: this assumes that there are no non-native fields on native
// classes, which may not be the case when a native class is subclassed.
- _instanceMemberUsage.putIfAbsent(member, () {
+ _memberUsage.putIfAbsent(member, () {
bool isNative = _nativeBasicData.isNativeClass(cls);
_MemberUsage usage = new _MemberUsage(member, isNative: isNative);
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
@@ -816,12 +827,7 @@
@override
bool isMemberUsed(MemberEntity member) {
- if (member.isInstanceMember) {
- _MemberUsage usage = _instanceMemberUsage[member];
- if (usage != null && usage.hasUse) return true;
- }
- _MemberUsage usage = _staticMemberUsage[member];
- return usage != null && usage.hasUse;
+ return _memberUsage[member]?.hasUse ?? false;
}
Map<ClassEntity, Set<ClassEntity>> populateHierarchyNodes() {
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 8c3965d..a5b2922 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -24,6 +24,7 @@
import '../js_backend/native_data.dart' show NativeBasicData, NativeDataBuilder;
import '../js_backend/no_such_method_registry.dart';
import '../js_backend/runtime_types.dart';
+import '../js_model/locals.dart';
import '../kernel/element_map_impl.dart';
import '../native/enqueue.dart' show NativeResolutionEnqueuer;
import '../options.dart';
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index ef74950..a91d346 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -867,6 +867,7 @@
}
ClassSet classSet = getClassSet(base);
+ assert(classSet != null, failedAt(base, "No class set for $base."));
ClassHierarchyNode node = classSet.node;
if (query == ClassQuery.EXACT) {
return node.isExplicitlyInstantiated && !hasConcreteMatch(base, selector);
diff --git a/pkg/compiler/testing_dart.json b/pkg/compiler/testing_dart.json
index 82bbdb7..736a55f 100644
--- a/pkg/compiler/testing_dart.json
+++ b/pkg/compiler/testing_dart.json
@@ -14,83 +14,45 @@
],
"exclude": [
- "^tests/compiler/dart2js/analyze_api_test\\.dart",
- "^tests/compiler/dart2js/analyze_test_test\\.dart",
- "^tests/compiler/dart2js/bad_output_io_test\\.dart",
- "^tests/compiler/dart2js/boolified_operator_test\\.dart",
"^tests/compiler/dart2js/codegen_helper\\.dart",
"^tests/compiler/dart2js/constant_expression_evaluate_test\\.dart",
"^tests/compiler/dart2js/constant_expression_test\\.dart",
- "^tests/compiler/dart2js/dart2js_batch2_test\\.dart",
- "^tests/compiler/dart2js/dart2js_batch_test\\.dart",
- "^tests/compiler/dart2js/dart2js_resolver_test\\.dart",
- "^tests/compiler/dart2js/data/dart2js_batch2_run\\.dart",
"^tests/compiler/dart2js/data/mirrors_helper\\.dart",
"^tests/compiler/dart2js/data/one_line_dart_program\\.dart",
- "^tests/compiler/dart2js/deferred_custom_element_test\\.dart",
- "^tests/compiler/dart2js/deferred_dont_inline_deferred_constants_test\\.dart",
- "^tests/compiler/dart2js/deferred_dont_inline_deferred_globals_test\\.dart",
- "^tests/compiler/dart2js/deferred_follow_constant_dependencies_test\\.dart",
- "^tests/compiler/dart2js/deferred_follow_implicit_super_regression_test\\.dart",
- "^tests/compiler/dart2js/deferred_inline_restrictions_test\\.dart",
- "^tests/compiler/dart2js/deferred_load_graph_segmentation2_test\\.dart",
- "^tests/compiler/dart2js/deferred_load_graph_segmentation_test\\.dart",
- "^tests/compiler/dart2js/deferred_mirrors_test\\.dart",
- "^tests/compiler/dart2js/deferred_not_in_main_test\\.dart",
- "^tests/compiler/dart2js/embedded_category_api_boundary_test\\.dart",
- "^tests/compiler/dart2js/exit_code_test\\.dart",
- "^tests/compiler/dart2js/expect_annotations2_test\\.dart",
- "^tests/compiler/dart2js/flatten_test\\.dart",
- "^tests/compiler/dart2js/gvn_dynamic_field_get_test\\.dart",
- "^tests/compiler/dart2js/import_mirrors_test\\.dart",
- "^tests/compiler/dart2js/import_test\\.dart",
+ "^tests/compiler/dart2js/deferred/inline_restrictions_test\\.dart",
+ "^tests/compiler/dart2js/deferred/load_graph_segmentation2_test\\.dart",
+ "^tests/compiler/dart2js/deferred/load_graph_segmentation_test\\.dart",
+ "^tests/compiler/dart2js/mirrors/deferred_mirrors_test\\.dart",
+ "^tests/compiler/dart2js/deferred/not_in_main_test\\.dart",
"^tests/compiler/dart2js/in_user_code_test\\.dart",
- "^tests/compiler/dart2js/interop_anonymous_unreachable_test\\.dart",
- "^tests/compiler/dart2js/js_constant_test\\.dart",
- "^tests/compiler/dart2js/js_parser_statements_test\\.dart",
- "^tests/compiler/dart2js/js_spec_optimization_test\\.dart",
"^tests/compiler/dart2js/jsinterop/world_test\\.dart",
"^tests/compiler/dart2js/kernel/class_hierarchy_test\\.dart",
"^tests/compiler/dart2js/kernel/closed_world_test\\.dart",
"^tests/compiler/dart2js/kernel/visitor_test\\.dart",
- "^tests/compiler/dart2js/least_upper_bound_test\\.dart",
- "^tests/compiler/dart2js/library_resolution_test\\.dart",
- "^tests/compiler/dart2js/list_tracer2_test\\.dart",
- "^tests/compiler/dart2js/list_tracer3_test\\.dart",
- "^tests/compiler/dart2js/members_test\\.dart",
"^tests/compiler/dart2js/memory_compiler\\.dart",
- "^tests/compiler/dart2js/message_kind_helper\\.dart",
- "^tests/compiler/dart2js/metadata_test\\.dart",
- "^tests/compiler/dart2js/minimal_resolution_test\\.dart",
- "^tests/compiler/dart2js/mirrors_used_test\\.dart",
+ "^tests/compiler/dart2js/old_frontend/message_kind_helper\\.dart",
+ "^tests/compiler/dart2js/old_frontend/metadata_test\\.dart",
+ "^tests/compiler/dart2js/mirrors/mirrors_used_test\\.dart",
"^tests/compiler/dart2js/mixin_typevariable_test\\.dart",
- "^tests/compiler/dart2js/mock_compiler\\.dart",
- "^tests/compiler/dart2js/modulo_remainder_test\\.dart",
"^tests/compiler/dart2js/needs_no_such_method_test\\.dart",
"^tests/compiler/dart2js/no_such_method_enabled_test\\.dart",
"^tests/compiler/dart2js/output_collector\\.dart",
- "^tests/compiler/dart2js/override_inheritance_test\\.dart",
- "^tests/compiler/dart2js/package_root_test\\.dart",
- "^tests/compiler/dart2js/partial_parser_test\\.dart",
- "^tests/compiler/dart2js/patch_test\\.dart",
+ "^tests/compiler/dart2js/old_frontend/patch_test\\.dart",
"^tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main_package\\.dart",
"^tests/compiler/dart2js/quarantined/http_test\\.dart",
- "^tests/compiler/dart2js/reexport_handled_test\\.dart",
- "^tests/compiler/dart2js/resolution_test\\.dart",
- "^tests/compiler/dart2js/resolver_test\\.dart",
+ "^tests/compiler/dart2js/old_frontend/reexport_handled_test\\.dart",
+ "^tests/compiler/dart2js/old_frontend/resolution_test\\.dart",
"^tests/compiler/dart2js/serialization/analysis_test_helper\\.dart",
"^tests/compiler/dart2js/serialization/compilation_test_helper\\.dart",
"^tests/compiler/dart2js/serialization/duplicate_library_test\\.dart",
"^tests/compiler/dart2js/serialization/equivalence_test\\.dart",
"^tests/compiler/dart2js/serialization/model_test_helper\\.dart",
"^tests/compiler/dart2js/serialization/test_helper\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_closure_test\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_const_closure2_test\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_const_closure_default_test\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_const_closure_test\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_global_field_closure_test\\.dart",
- "^tests/compiler/dart2js/simple_inferrer_test\\.dart",
- "^tests/compiler/dart2js/size_test\\.dart",
+ "^tests/compiler/dart2js/inference/simple_inferrer_closure_test\\.dart",
+ "^tests/compiler/dart2js/inference/simple_inferrer_const_closure2_test\\.dart",
+ "^tests/compiler/dart2js/inference/simple_inferrer_const_closure_test\\.dart",
+ "^tests/compiler/dart2js/inference/simple_inferrer_global_field_closure_test\\.dart",
+ "^tests/compiler/dart2js/inference/simple_inferrer_test\\.dart",
"^tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper\\.dart",
"^tests/compiler/dart2js/sourcemaps/diff_view\\.dart",
"^tests/compiler/dart2js/sourcemaps/html_parts\\.dart",
@@ -105,15 +67,9 @@
"^tests/compiler/dart2js/sourcemaps/stacktrace_test\\.dart",
"^tests/compiler/dart2js/subtype_test\\.dart",
"^tests/compiler/dart2js/subtypeset_test\\.dart",
- "^tests/compiler/dart2js/tdiv_test\\.dart",
"^tests/compiler/dart2js/token_naming_test\\.dart",
- "^tests/compiler/dart2js/trust_type_annotations_test\\.dart",
- "^tests/compiler/dart2js/type_checker_test\\.dart",
- "^tests/compiler/dart2js/type_equals_test\\.dart",
- "^tests/compiler/dart2js/type_inference8_test\\.dart",
- "^tests/compiler/dart2js/type_mask2_test\\.dart",
- "^tests/compiler/dart2js/type_mask_test\\.dart",
- "^tests/compiler/dart2js/type_order_test\\.dart",
+ "^tests/compiler/dart2js/inference/type_inference8_test\\.dart",
+ "^tests/compiler/dart2js/inference/type_mask2_test\\.dart",
"^tests/compiler/dart2js/type_representation_test\\.dart",
"^tests/compiler/dart2js/type_substitution_test\\.dart",
"^tests/compiler/dart2js/type_variable_occurrence_test\\.dart",
diff --git a/pkg/dart_internal/lib/extract_type_arguments.dart b/pkg/dart_internal/lib/extract_type_arguments.dart
index 7c93e5f..218d075 100644
--- a/pkg/dart_internal/lib/extract_type_arguments.dart
+++ b/pkg/dart_internal/lib/extract_type_arguments.dart
@@ -9,6 +9,7 @@
//
// Only this exact special file is allowed to import "dart:_internal" without
// causing a compile error.
+// ignore: import_internal_library
import 'dart:_internal' as internal;
/// Given an [Iterable], invokes [extract], passing the [iterable]'s type
diff --git a/pkg/dev_compiler/bin/dartdevk.dart b/pkg/dev_compiler/bin/dartdevk.dart
index 7a212de..b0d6aec 100755
--- a/pkg/dev_compiler/bin/dartdevk.dart
+++ b/pkg/dev_compiler/bin/dartdevk.dart
@@ -9,14 +9,18 @@
import 'dart:convert';
import 'dart:io';
+import 'package:bazel_worker/bazel_worker.dart';
import 'package:dev_compiler/src/kernel/command.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
Future main(List<String> args) async {
- if (args.isNotEmpty && args.last == "--batch") {
- await runBatch(args.sublist(0, args.length - 1));
+ var parsedArgs = _preprocessArgs(args);
+ if (parsedArgs.isBatch) {
+ await runBatch(parsedArgs.args);
+ } else if (parsedArgs.isWorker) {
+ await new _CompilerWorker(parsedArgs.args).run();
} else {
- var result = await compile(args);
+ var result = await compile(parsedArgs.args);
var succeeded = result.result;
exitCode = succeeded ? 0 : 1;
}
@@ -60,3 +64,80 @@
var time = watch.elapsedMilliseconds;
print('>>> BATCH END (${tests - failed})/$tests ${time}ms');
}
+
+/// Runs the compiler worker loop.
+class _CompilerWorker extends AsyncWorkerLoop {
+ /// The original args supplied to the executable.
+ final List<String> _startupArgs;
+
+ _CompilerWorker(this._startupArgs) : super();
+
+ /// Performs each individual work request.
+ Future<WorkResponse> performRequest(WorkRequest request) async {
+ var args = _startupArgs.toList()..addAll(request.arguments);
+
+ var output = new StringBuffer();
+ var result = await runZoned(() => compile(args), zoneSpecification:
+ new ZoneSpecification(print: (self, parent, zone, message) {
+ output.writeln(message.toString());
+ }));
+ return new WorkResponse()
+ ..exitCode = result.result ? 0 : 1
+ ..output = output.toString();
+ }
+}
+
+/// Preprocess arguments to determine whether DDK is used in batch mode or as a
+/// persistent worker.
+///
+/// When used in batch mode, we expect a `--batch` parameter last.
+///
+/// When used as a persistent bazel worker, the `--persistent_worker` might be
+/// present, and an argument of the form `@path/to/file` might be provided. The
+/// latter needs to be replaced by reading all the contents of the
+/// file and expanding them into the resulting argument list.
+_ParsedArgs _preprocessArgs(List<String> args) {
+ if (args.isEmpty) return new _ParsedArgs(false, false, args);
+
+ String lastArg = args.last;
+ if (lastArg == '--batch') {
+ return new _ParsedArgs(true, false, args.sublist(0, args.length - 1));
+ }
+
+ var newArgs = [];
+ bool isWorker = false;
+ var len = args.length;
+ for (int i = 0; i < len; i++) {
+ var arg = args[i];
+ if (i == len - 1 && arg.startsWith('@')) {
+ newArgs.addAll(_readLines(arg.substring(1)));
+ } else if (arg == '--persistent_worker') {
+ isWorker = true;
+ } else {
+ newArgs.add(arg);
+ }
+ }
+ return new _ParsedArgs(false, isWorker, newArgs);
+}
+
+/// Return all lines in a file found at [path].
+Iterable<String> _readLines(String path) {
+ try {
+ return new File(path)
+ .readAsStringSync()
+ .replaceAll('\r\n', '\n')
+ .replaceAll('\r', '\n')
+ .split('\n')
+ .where((String line) => line.isNotEmpty);
+ } on FileSystemException catch (e) {
+ throw new Exception('Failed to read $path: $e');
+ }
+}
+
+class _ParsedArgs {
+ final bool isBatch;
+ final bool isWorker;
+ final List<String> args;
+
+ _ParsedArgs(this.isBatch, this.isWorker, this.args);
+}
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index b50616f..857af1f 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -100,7 +100,9 @@
try {
sdkRequest = await HttpRequest.request(sdkUrl,
- responseType: "arraybuffer", mimeType: "application/octet-stream");
+ responseType: "arraybuffer",
+ mimeType: "application/octet-stream",
+ withCredentials: true);
} catch (error) {
onError('Dart sdk summaries failed to load: $error. url: $sdkUrl');
return null;
diff --git a/pkg/front_end/lib/src/api_prototype/summary_generator.dart b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
index 6557156..8bd633a 100644
--- a/pkg/front_end/lib/src/api_prototype/summary_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
@@ -35,9 +35,14 @@
/// are also listed in the build unit sources, otherwise an error results. (It
/// is not permitted to refer to a part file declared in another build unit).
///
+/// If [truncate] is true, the resulting summary doesn't include any references
+/// to libraries loaded from the input summaries, and only contains code that
+/// was compiled from sources.
+///
/// The return value is a list of bytes to write to the summary file.
-Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options) async {
+Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options,
+ {bool truncate: false}) async {
return (await generateKernel(new ProcessedOptions(options, true, sources),
- buildSummary: true, buildProgram: false))
+ buildSummary: true, buildProgram: false, truncateSummary: truncate))
?.summary;
}
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index fc92b87..a7adc1f 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -30,7 +30,7 @@
CompilerOptions options = new CompilerOptions()
..target = target
- ..strongMode = false
+ ..strongMode = target.strongMode
..linkedDependencies = [sdkUri]
..packagesFileUri = packagesFileUri;
diff --git a/pkg/front_end/lib/src/api_unstable/summary_worker.dart b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
new file mode 100644
index 0000000..33c09af
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// API needed by `utils/front_end/summary_worker.dart`, a tool used to compute
+/// summaries in build systems like bazel, pub-build, and package-build.
+
+import 'dart:async' show Future;
+
+import 'package:front_end/src/api_prototype/file_system.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/kernel_generator_impl.dart';
+import 'package:kernel/target/targets.dart' show Target;
+
+import '../api_prototype/compiler_options.dart';
+import 'compiler_state.dart';
+
+export 'compiler_state.dart';
+
+export '../api_prototype/physical_file_system.dart' show PhysicalFileSystem;
+export '../fasta/fasta_codes.dart' show LocatedMessage;
+export '../fasta/severity.dart' show Severity;
+
+Future<InitializedCompilerState> initializeCompiler(
+ InitializedCompilerState oldState,
+ Uri sdkSummary,
+ Uri packagesFile,
+ List<Uri> inputSummaries,
+ Target target,
+ FileSystem fileSystem) async {
+ // TODO(sigmund): use incremental compiler when it supports our use case.
+ // Note: it is common for the summary worker to invoke the compiler with the
+ // same input summary URIs, but with different contents, so we'd need to be
+ // able to track shas or modification time-stamps to be able to invalidate the
+ // old state appropriately.
+ CompilerOptions options = new CompilerOptions()
+ ..sdkSummary = sdkSummary
+ ..packagesFileUri = packagesFile
+ ..inputSummaries = inputSummaries
+ ..target = target
+ ..fileSystem = fileSystem
+ ..chaseDependencies = true;
+
+ ProcessedOptions processedOpts = new ProcessedOptions(options, true, []);
+
+ return new InitializedCompilerState(options, processedOpts);
+}
+
+Future<List<int>> compile(InitializedCompilerState compilerState,
+ List<Uri> inputs, ProblemHandler problemHandler) async {
+ CompilerOptions options = compilerState.options;
+ options..onProblem = problemHandler;
+
+ ProcessedOptions processedOpts = compilerState.processedOpts;
+ processedOpts.inputs.clear();
+ processedOpts.inputs.addAll(inputs);
+
+ var result = await generateKernel(processedOpts,
+ buildSummary: true, buildProgram: false);
+ return result?.summary;
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index dea20dc..7a77519 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -175,8 +175,10 @@
int finishTypeVariables(ClassBuilder object) => 0;
void becomeCoreLibrary(dynamicType) {
- addBuilder("dynamic",
- new DynamicTypeBuilder<T, dynamic>(dynamicType, this, -1), -1);
+ if (scope.local["dynamic"] == null) {
+ addBuilder("dynamic",
+ new DynamicTypeBuilder<T, dynamic>(dynamicType, this, -1), -1);
+ }
}
void forEach(void f(String name, Builder builder)) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 0268c43..dad91b9 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -2066,7 +2066,7 @@
messageTemplate:
r"""The integer literal #lexeme can't be represented in 64 bits.""",
tipTemplate:
- r"""Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
+ r"""Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
withArguments: _withArgumentsIntegerLiteralIsOutOfRange);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2083,7 +2083,7 @@
message:
"""The integer literal $lexeme can't be represented in 64 bits.""",
tip:
- """Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
+ """Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
arguments: {'token': token});
}
@@ -4174,7 +4174,7 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageSuperAsExpression = const MessageCode(
"SuperAsExpression",
- message: r"""Super calls can't be used as expressions.""",
+ message: r"""Can't use 'super' as an expression.""",
tip:
r"""To delegate a constructor to a super constructor, put the super call as an initializer.""");
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index e210ad2..0a3c742 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -6,7 +6,8 @@
import 'dart:async' show Future;
-import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
+import 'package:kernel/kernel.dart'
+ show Library, Program, Source, loadProgramFromBytes;
import '../api_prototype/incremental_kernel_generator.dart'
show DeltaProgram, IncrementalKernelGenerator;
@@ -76,6 +77,7 @@
@override
Future<FastaDelta> computeDelta({Uri entryPoint}) async {
ticker.reset();
+ entryPoint ??= context.options.inputs.single;
return context.runInContext<Future<FastaDelta>>((CompilerContext c) async {
if (platform == null) {
UriTranslator uriTranslator = await c.options.getUriTranslator();
@@ -98,21 +100,37 @@
List<LibraryBuilder> reusedLibraries =
computeReusedLibraries(invalidatedUris);
- ticker.logMs("Decided to reuse ${reusedLibraries.length} libraries");
+ if (userCode != null) {
+ ticker.logMs("Decided to reuse ${reusedLibraries.length}"
+ " of ${userCode.loader.builders.length} libraries");
+ }
userCode = new KernelTarget(
c.fileSystem, false, platform, platform.uriTranslator,
uriToSource: c.uriToSource);
for (LibraryBuilder library in reusedLibraries) {
userCode.loader.builders[library.uri] = library;
+ if (library.uri.scheme == "dart" && library.uri.path == "core") {
+ userCode.loader.coreLibrary = library;
+ }
}
userCode.read(entryPoint);
await userCode.buildOutlines();
- return new FastaDelta(
- await userCode.buildProgram(verify: c.options.verify));
+ // This is not the full program. It is the program including all
+ // libraries loaded from .dill files.
+ Program programWithDill =
+ await userCode.buildProgram(verify: c.options.verify);
+
+ // This is the incremental program.
+ Program program = new Program(
+ nameRoot: programWithDill.root,
+ libraries: new List<Library>.from(userCode.loader.libraries),
+ uriToSource: new Map<Uri, Source>.from(userCode.uriToSource));
+
+ return new FastaDelta(program);
});
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 7f5ddbf..40d70e2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -13,6 +13,7 @@
show
messageInvalidInitializer,
messageLoadLibraryTakesNoArguments,
+ messageSuperAsExpression,
templateIntegerLiteralIsOutOfRange;
import '../messages.dart' show Message;
@@ -352,8 +353,8 @@
if (!isSuper) {
return new ShadowThisExpression();
} else {
- return helper.deprecated_buildCompileTimeError(
- "Can't use `super` as an expression.", offsetForToken(token));
+ return helper.buildCompileTimeError(
+ messageSuperAsExpression, offsetForToken(token));
}
}
@@ -406,6 +407,8 @@
doInvocation(int offset, Arguments arguments) {
if (isInitializer) {
return buildConstructorInitializer(offset, new Name(""), arguments);
+ } else if (isSuper) {
+ return helper.buildCompileTimeError(messageSuperAsExpression, offset);
} else {
return helper.buildMethodInvocation(
new ShadowThisExpression(), callName, arguments, offset,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
index eeb4bad..263fef7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
@@ -66,7 +66,8 @@
builtType.typedefReference = target.reference;
if (typeVariables != null) {
for (KernelTypeVariableBuilder tv in typeVariables) {
- tv.parameter.bound = tv?.bound?.build(library);
+ // Follow bound in order to find all cycles
+ tv.bound?.build(library);
target.typeParameters.add(tv.parameter..parent = target);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 24a0534..431bd48 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -231,17 +231,18 @@
loader.resolveTypes();
List<SourceClassBuilder> myClasses = collectMyClasses();
loader.checkSemantics(myClasses);
+ loader.finishTypeVariables(objectClassBuilder);
loader.buildProgram();
installDefaultSupertypes();
installDefaultConstructors(myClasses);
loader.resolveConstructors();
- loader.finishTypeVariables(objectClassBuilder);
program =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
if (metadataCollector != null) {
program.addMetadataRepository(metadataCollector.repository);
}
loader.computeHierarchy(program);
+ computeCoreTypes();
loader.checkOverrides(myClasses);
if (!loader.target.disableTypeInference) {
loader.prepareTopLevelInference(myClasses);
@@ -513,6 +514,41 @@
isSyntheticDefault: true);
}
+ void computeCoreTypes() {
+ List<Library> libraries = <Library>[];
+ for (String platformLibrary in const [
+ "dart:_internal",
+ "dart:async",
+ "dart:core",
+ "dart:mirrors"
+ ]) {
+ Uri uri = Uri.parse(platformLibrary);
+ LibraryBuilder library = loader.builders[uri];
+ if (library == null) {
+ // TODO(ahe): This is working around a bug in kernel_driver_test or
+ // kernel_driver.
+ bool found = false;
+ for (Library target in dillTarget.loader.libraries) {
+ if (target.importUri == uri) {
+ libraries.add(target);
+ found = true;
+ break;
+ }
+ }
+ if (!found && uri.path != "mirrors") {
+ // dart:mirrors is optional.
+ throw "Can't find $uri";
+ }
+ } else {
+ libraries.add(library.target);
+ }
+ }
+ Program plaformLibraries = new Program();
+ // Add libraries directly to prevent that their parents are changed.
+ plaformLibraries.libraries.addAll(libraries);
+ loader.computeCoreTypes(plaformLibraries);
+ }
+
void finishAllConstructors(List<SourceClassBuilder> builders) {
Class objectClass = this.objectClass;
for (SourceClassBuilder builder in builders) {
diff --git a/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart b/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
index 28904d0..381c598 100644
--- a/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
@@ -6,8 +6,6 @@
import '../../scanner/token.dart' show Token;
-import '../fasta_codes.dart' show Message;
-
import 'assert.dart' show Assert;
import 'listener.dart' show Listener;
@@ -38,16 +36,6 @@
}
}
- @override
- Token parseRecoverExpression(Token token, Message message) {
- Token begin = token;
- // TODO(brianwilkerson): Remove the invocation of `syntheticPreviousToken`
- // when `parseRecoverExpression` accepts the last consumed token.
- token = skipExpression(syntheticPreviousToken(token));
- listener.handleRecoverExpression(begin, message);
- return token;
- }
-
// This method is overridden for two reasons:
// 1. Avoid generating events for arguments.
// 2. Avoid calling skip expression for each argument (which doesn't work).
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index ff2104f..27989e2 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1200,11 +1200,6 @@
}
@override
- void handleRecoverExpression(Token token, Message message) {
- listener?.handleRecoverExpression(token, message);
- }
-
- @override
void handleRecoverableError(
Message message, Token startToken, Token endToken) {
listener?.handleRecoverableError(message, startToken, endToken);
@@ -1291,16 +1286,6 @@
}
@override
- Token injectGenericCommentTypeAssign(Token token) {
- return listener?.injectGenericCommentTypeAssign(token);
- }
-
- @override
- Token injectGenericCommentTypeList(Token token) {
- return listener?.injectGenericCommentTypeList(token);
- }
-
- @override
void logEvent(String name) {
listener?.logEvent(name);
}
@@ -1314,13 +1299,6 @@
List<ParserError> get recoverableErrors => listener?.recoverableErrors;
@override
- Token replaceTokenWithGenericCommentTypeAssign(
- Token tokenToStartReplacing, Token tokenWithComment) {
- return listener?.replaceTokenWithGenericCommentTypeAssign(
- tokenToStartReplacing, tokenWithComment);
- }
-
- @override
set suppressParseErrors(bool value) {
listener?.suppressParseErrors = value;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 8a9cf34..60f90dd 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -208,13 +208,6 @@
void beginExpressionStatement(Token token) {}
- /// Called by [ClassMemberParser] after skipping an expression as error
- /// recovery. For a stack-based listener, the suggested action is to push
- /// `null` or a synthetic erroneous expression.
- void handleRecoverExpression(Token token, Message message) {
- logEvent("RecoverExpression");
- }
-
/// Called by [Parser] after parsing an extraneous expression as error
/// recovery. For a stack-based listener, the suggested action is to discard
/// an expression from the stack.
@@ -1215,28 +1208,6 @@
logEvent("Script");
}
- /// Matches a generic comment type substitution and injects it into the token
- /// stream before the given [token].
- Token injectGenericCommentTypeAssign(Token token) {
- return token;
- }
-
- /// Matches a generic comment type variables or type arguments and injects
- /// them into the token stream before the given [token].
- Token injectGenericCommentTypeList(Token token) {
- return token;
- }
-
- /// If the [tokenWithComment] has a type substitution comment /*=T*/, then
- /// the comment should be scanned into new tokens, and these tokens inserted
- /// instead of tokens from the [tokenToStartReplacing] to the
- /// [tokenWithComment]. Returns the first newly inserted token, or the
- /// original [tokenWithComment].
- Token replaceTokenWithGenericCommentTypeAssign(
- Token tokenToStartReplacing, Token tokenWithComment) {
- return tokenToStartReplacing;
- }
-
/// A type has been just parsed, and the parser noticed that the next token
/// has a type substitution comment /*=T*. So, the type that has been just
/// parsed should be discarded, and a new type should be parsed instead.
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index c8920ee..b371988 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -478,11 +478,7 @@
} else if (identical(value, 'static')) {
token = parseStaticRecovery(token);
} else if (identical(value, 'typedef')) {
- // TODO(brianwilkerson): Move this into a `parseTypedefRecovery` method
- // that can be more sophisticated about skipping the rest of the typedef
- // declaration.
- parser.reportRecoverableError(token.next, fasta.messageTypedefInClass);
- token = token.next;
+ token = parseTypedefRecovery(token);
} else if (identical(value, 'var')) {
token = parseVarRecovery(token);
} else if (token.next.isModifier) {
@@ -637,6 +633,16 @@
return next;
}
+ Token parseTypedefRecovery(Token token) {
+ token = token.next;
+ assert(optional('typedef', token));
+ parser.reportRecoverableError(token, fasta.messageTypedefInClass);
+ // TODO(brianwilkerson): If the declaration appears to be a valid typedef
+ // then skip the entire declaration so that we generate a single error
+ // (above) rather than many unhelpful errors.
+ return token;
+ }
+
Token parseVarRecovery(Token token) {
token = token.next;
if (token.next.isIdentifier && optional('(', token.next.next)) {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 3548042..08cfbc2 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -604,14 +604,13 @@
} else {
// Recovery
listener.endImport(importKeyword, null);
- return parseImportRecovery(uri, token);
+ return parseImportRecovery(uri);
}
}
/// Recover given out-of-order clauses in an import directive where [token] is
- /// the import keyword and [recoveryStart] is the token on which main parsing
- /// stopped.
- Token parseImportRecovery(Token token, Token recoveryStart) {
+ /// the import keyword.
+ Token parseImportRecovery(Token token) {
final primaryListener = listener;
final recoveryListener = new ImportRecoveryListener(primaryListener);
@@ -739,10 +738,10 @@
Token equalitySign;
if (optional('==', token)) {
equalitySign = token;
- token = parseLiteralStringOrRecoverExpression(token).next;
+ token = ensureLiteralString(token).next;
}
expect(')', token);
- token = parseLiteralStringOrRecoverExpression(token);
+ token = ensureLiteralString(token);
listener.endConditionalUri(ifKeyword, leftParen, equalitySign);
return token;
}
@@ -889,7 +888,7 @@
Token partKeyword = token.next;
assert(optional('part', partKeyword));
listener.beginPart(partKeyword);
- token = parseLiteralStringOrRecoverExpression(partKeyword);
+ token = ensureLiteralString(partKeyword);
token = ensureSemicolon(token);
listener.endPart(partKeyword, token);
return token;
@@ -911,7 +910,7 @@
token = parseQualified(ofKeyword, IdentifierContext.partName,
IdentifierContext.partNameContinuation);
} else {
- token = parseLiteralStringOrRecoverExpression(ofKeyword);
+ token = ensureLiteralString(ofKeyword);
}
token = ensureSemicolon(token);
listener.endPartOf(partKeyword, ofKeyword, token, hasName);
@@ -924,12 +923,6 @@
/// ;
/// ```
Token parseMetadataStar(Token token) {
- // TODO(brianwilkerson): Either remove the invocation of `previous` by
- // making `injectGenericCommentTypeAssign` accept and return the last
- // consumed token, or remove the invocation of
- // `injectGenericCommentTypeAssign` by invoking it outside this method where
- // invoking it is necessary.
- token = listener.injectGenericCommentTypeAssign(token.next).previous;
listener.beginMetadataStar(token.next);
int count = 0;
while (optional('@', token.next)) {
@@ -1042,10 +1035,19 @@
}
Token skipFormalParameters(Token token, MemberKind kind) {
+ Token lastConsumed = token;
token = token.next;
- assert(optional('(', token));
// TODO(ahe): Shouldn't this be `beginFormalParameters`?
listener.beginOptionalFormalParameters(token);
+ if (!optional('(', token)) {
+ if (optional(';', token)) {
+ reportRecoverableError(token, fasta.messageExpectedOpenParens);
+ listener.endFormalParameters(0, token, token, kind);
+ return lastConsumed;
+ }
+ listener.endFormalParameters(0, token, token, kind);
+ return reportUnexpectedToken(token);
+ }
Token closeBrace = closeBraceTokenFor(token);
listener.endFormalParameters(0, token, closeBrace, kind);
return closeBrace;
@@ -1450,7 +1452,7 @@
// Recovery
token = parseClassHeaderRecovery(start, begin, classKeyword);
}
- token = parseClassBody(token, start.next);
+ token = parseClassBody(token);
listener.endClassDeclaration(begin, token);
return token;
}
@@ -2030,20 +2032,11 @@
// analyze the tokens following the const keyword.
assert(optional("const", token.next));
beforeBegin = token;
- token = listener.injectGenericCommentTypeAssign(token.next.next);
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeAssign` returns the last consumed token.
- begin = beforeToken = token.previous;
- // TODO(brianwilkerson): Figure out how to remove the invocation of
- // `previous`.
- beforeBegin = begin.previous;
- assert(begin.next == token);
+ begin = beforeToken = token.next;
+ token = beforeToken.next;
} else {
- // Modify [begin] in case generic type are injected from a comment.
- begin = token = listener.injectGenericCommentTypeAssign(token.next);
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeAssign` returns the last consumed token.
- beforeToken = beforeBegin = begin.previous;
+ beforeToken = beforeBegin = token;
+ token = begin = token.next;
}
if (optional("void", token)) {
@@ -2140,18 +2133,6 @@
listener.handleType(begin, token.next);
}
- {
- Token newBegin = listener.replaceTokenWithGenericCommentTypeAssign(
- begin, token.next);
- if (!identical(newBegin, begin)) {
- listener.discardTypeReplacedWithCommentTypeAssign();
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `replaceTokenWithGenericCommentTypeAssign` returns the last
- // consumed token.
- return parseType(newBegin.previous);
- }
- }
-
for (int i = 0; i < functionTypes; i++) {
Token next = token.next;
assert(optional('Function', next));
@@ -2408,9 +2389,7 @@
return parseNamedFunctionRest(beforeName, begin, formals, true);
case TypeContinuation.VariablesDeclarationOrExpression:
- if (looksLikeType &&
- token.isIdentifier &&
- isOneOf4(token.next, '=', ';', ',', 'in')) {
+ if (looksLikeType && token.isIdentifier) {
// TODO(ahe): Generate type events and call
// parseVariablesDeclarationNoSemicolonRest instead.
return parseVariablesDeclarationNoSemicolon(beforeBegin);
@@ -2512,11 +2491,6 @@
reportRecoverableError(nameToken, fasta.messagePrivateNamedParameter);
}
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` returns the last consumed token.
- beforeToken = listener.injectGenericCommentTypeList(token).previous;
- token = beforeToken.next;
-
Token inlineFunctionTypeStart;
if (optional("<", token)) {
Token closer = closeBraceTokenFor(token);
@@ -2640,9 +2614,6 @@
/// TODO(ahe): Clean this up.
Token parseStuffOpt(Token token, Function beginStuff, Function stuffParser,
Function endStuff, Function handleNoStuff) {
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` returns the last consumed token.
- token = listener.injectGenericCommentTypeList(token.next).previous;
Token next = token.next;
if (optional('<', next)) {
BeginToken begin = next;
@@ -2961,16 +2932,11 @@
} else if (isGetter) {
hasName = true;
}
- token = listener.injectGenericCommentTypeAssign(token);
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeAssign` returns the last consumed token.
- previous = token.previous;
identifiers = identifiers.prepend(previous);
if (!isGeneralizedFunctionType(token)) {
// Read a potential return type.
if (isValidTypeReference(token)) {
- Token type = token;
// type ...
if (optional('.', token.next)) {
// type '.' ...
@@ -2994,22 +2960,6 @@
}
}
}
- // If the next token after a type has a type substitution comment
- // /*=T*/, then the previous type tokens and the reference to them
- // from the link should be replaced.
- {
- Token newType = listener.replaceTokenWithGenericCommentTypeAssign(
- type, token.next);
- if (!identical(newType, type)) {
- identifiers = identifiers.tail;
- token = newType;
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `replaceTokenWithGenericCommentTypeAssign` returns the last
- // consumed token.
- previous = token.previous;
- continue;
- }
- }
} else if (token.type.isBuiltIn) {
// Handle the edge case where a built-in keyword is being used
// as the identifier, as in "abstract<T>() => 0;"
@@ -3314,23 +3264,6 @@
return token;
}
- Token parseLiteralStringOrRecoverExpression(Token token) {
- // TODO(brianwilkerson) Replace invocations of this method with invocations
- // of `ensureParseLiteralString`.
- Token next = token.next;
- if (identical(next.kind, STRING_TOKEN)) {
- return parseLiteralString(token);
- } else if (next is ErrorToken) {
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `reportErrorToken` returns the last consumed token.
- return reportErrorToken(next, false).previous;
- } else {
- reportRecoverableErrorWithToken(next, fasta.templateExpectedString);
- return parseRecoverExpression(
- token, fasta.templateExpectedString.withArguments(next));
- }
- }
-
Token expectSemicolon(Token token) {
return expect(';', token);
}
@@ -3438,12 +3371,7 @@
/// '{' classMember* '}'
/// ;
/// ```
- ///
- /// The [beforeBody] token is required to be a token that appears somewhere
- /// before the [token] in the token stream.
- Token parseClassBody(Token token, Token beforeBody) {
- // TODO(brianwilkerson): Remove the parameter `beforeBody` because it is not
- // being used.
+ Token parseClassBody(Token token) {
Token previousToken = token;
Token begin = token = token.next;
listener.beginClassBody(token);
@@ -4376,10 +4304,6 @@
return token;
}
- Token parseRecoverExpression(Token token, Message message) {
- return parseExpression(token);
- }
-
int expressionDepth = 0;
Token parseExpression(Token token) {
if (expressionDepth++ > 500) {
@@ -4618,11 +4542,7 @@
next = token.next;
} else if (optional('(', next)) {
if (typeArguments == null) {
- next = listener.injectGenericCommentTypeList(next);
if (isValidMethodTypeArguments(next)) {
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` (invoked above) returns the last
- // consumed token.
token = parseTypeArgumentsOpt(token);
next = token.next;
} else {
@@ -4641,9 +4561,6 @@
}
Token parsePrimary(Token token, IdentifierContext context) {
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` returns the last consumed token.
- token = listener.injectGenericCommentTypeList(token.next).previous;
final kind = token.next.kind;
if (kind == IDENTIFIER_TOKEN) {
return parseSendOrFunctionLiteral(token, context);
@@ -5026,11 +4943,8 @@
/// ;
/// ```
Token parseConstExpression(Token token) {
- Token constKeyword = token.next;
+ Token constKeyword = token = token.next;
assert(optional('const', constKeyword));
- // TODO(brianwilkerson) Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` returns the last consumed token.
- token = listener.injectGenericCommentTypeList(constKeyword.next).previous;
Token next = token.next;
final String value = next.stringValue;
if ((identical(value, '[')) || (identical(value, '[]'))) {
@@ -5209,10 +5123,7 @@
}
Token parseSend(Token token, IdentifierContext context) {
- Token beginToken = ensureIdentifier(token, context);
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `injectGenericCommentTypeList` returns the last consumed token.
- token = listener.injectGenericCommentTypeList(beginToken.next).previous;
+ Token beginToken = token = ensureIdentifier(token, context);
if (isValidMethodTypeArguments(token.next)) {
token = parseTypeArgumentsOpt(token);
} else {
@@ -5380,20 +5291,6 @@
Token parseVariablesDeclarationMaybeSemicolon(
Token token, bool endWithSemicolon) {
token = parseMetadataStar(token);
-
- // If the next token has a type substitution comment /*=T*/, then
- // the current 'var' token should be repealed and replaced.
- // TODO(brianwilkerson): Shouldn't this also work when the current token is
- // something other than `var`, such as in `Object /*=T*/ v;`?
- if (optional('var', token.next)) {
- // TODO(brianwilkerson): Remove the invocation of `previous` when
- // `replaceTokenWithGenericCommentTypeAssign` returns the last consumed
- // token.
- token = listener
- .replaceTokenWithGenericCommentTypeAssign(token.next, token.next.next)
- .previous;
- }
-
token = parseModifiers(token, MemberKind.Local, isVarAllowed: true);
return parseVariablesDeclarationMaybeSemicolonRest(token, endWithSemicolon);
}
@@ -5462,6 +5359,7 @@
/// ;
/// ```
Token parseForStatement(Token awaitToken, Token token) {
+ // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
Token forKeyword = token.next;
assert(awaitToken == null || optional('await', awaitToken));
listener.beginForStatement(forKeyword);
@@ -5518,6 +5416,7 @@
/// ;
/// ```
Token parseForRest(Token forToken, Token leftParenthesis, Token token) {
+ // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
Token leftSeparator = ensureSemicolon(token);
if (optional(';', leftSeparator.next)) {
token = parseEmptyStatement(leftSeparator);
@@ -5559,6 +5458,7 @@
/// ```
Token parseForInRest(
Token awaitToken, Token forKeyword, Token leftParenthesis, Token token) {
+ // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
Token inKeyword = token.next;
assert(optional('in', inKeyword) || optional(':', inKeyword));
listener.beginForInExpression(inKeyword.next);
@@ -6047,7 +5947,7 @@
Token next = token.next;
if (optional(';', next)) {
// Report and skip extra semicolons that appear between members.
- // TODO(brianwilkerson) Provide a more specific error message.
+ // TODO(brianwilkerson): Provide a more specific error message.
reportRecoverableError(
next, fasta.templateExpectedClassMember.withArguments(next));
listener.handleInvalidMember(next);
diff --git a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
index e6a502d..6166889 100644
--- a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
+++ b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
@@ -26,26 +26,12 @@
RecoveryListener(this._primaryListener);
@override
- Token injectGenericCommentTypeAssign(Token token) =>
- _primaryListener.injectGenericCommentTypeAssign(token);
-
- @override
- Token injectGenericCommentTypeList(Token token) =>
- _primaryListener.injectGenericCommentTypeList(token);
-
- @override
Token handleUnrecoverableError(Token token, Message message) =>
_primaryListener.handleUnrecoverableError(token, message);
@override
Token newSyntheticToken(Token next) =>
_primaryListener.newSyntheticToken(next);
-
- @override
- Token replaceTokenWithGenericCommentTypeAssign(
- Token tokenToStartReplacing, Token tokenWithComment) =>
- _primaryListener.replaceTokenWithGenericCommentTypeAssign(
- tokenToStartReplacing, tokenWithComment);
}
class ClassHeaderRecoveryListener extends RecoveryListener {
diff --git a/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart b/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
index 33969af..98dc6fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
@@ -15,5 +15,5 @@
class TopLevelParser extends ClassMemberParser {
TopLevelParser(Listener listener) : super(listener);
- Token parseClassBody(Token token, Token beforeBody) => skipClassBody(token);
+ Token parseClassBody(Token token) => skipClassBody(token);
}
diff --git a/pkg/front_end/lib/src/fasta/source/diet_parser.dart b/pkg/front_end/lib/src/fasta/source/diet_parser.dart
index d3002d8..9f1bc91 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_parser.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_parser.dart
@@ -6,37 +6,13 @@
import '../../scanner/token.dart' show Token;
-import '../fasta_codes.dart' show messageExpectedOpenParens;
-
-import '../parser.dart'
- show ClassMemberParser, Listener, MemberKind, closeBraceTokenFor, optional;
+import '../parser.dart' show ClassMemberParser, Listener, MemberKind;
// TODO(ahe): Move this to parser package.
class DietParser extends ClassMemberParser {
DietParser(Listener listener) : super(listener);
Token parseFormalParameters(Token token, MemberKind kind) {
- return skipFormals(token, kind);
- }
-
- // TODO(brianwilkerson): Move this method to Parser, and, if possible, merge
- // it with skipFormalParameters.
- Token skipFormals(Token token, MemberKind kind) {
- token = token.next;
- listener.beginOptionalFormalParameters(token);
- if (!optional('(', token)) {
- if (optional(';', token)) {
- reportRecoverableError(token, messageExpectedOpenParens);
- listener.endFormalParameters(0, token, token, kind);
- // TODO(brianwilkerson): Until this method accepts the last consumed
- // token, this returns the wrong token (it should be the token before
- // `token`).
- return token;
- }
- return reportUnexpectedToken(token);
- }
- Token closeBrace = closeBraceTokenFor(token);
- listener.endFormalParameters(0, token, closeBrace, kind);
- return closeBrace;
+ return skipFormalParameters(token, kind);
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index b59d33a..1bfbc7c 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -191,13 +191,6 @@
}
@override
- void handleRecoverExpression(Token token, Message message) {
- debugEvent("RecoverExpression");
- push(NullValue.Expression);
- push(token.charOffset);
- }
-
- @override
void endPart(Token partKeyword, Token semicolon) {
debugEvent("Part");
int charOffset = popCharOffset();
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 5c71111..ac4e347 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -536,6 +536,9 @@
void computeHierarchy(Program program) {
hierarchy = new IncrementalClassHierarchy();
ticker.logMs("Computed class hierarchy");
+ }
+
+ void computeCoreTypes(Program program) {
coreTypes = new CoreTypes(program);
ticker.logMs("Computed core types");
}
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index 6bb8712..7586246 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -305,11 +305,6 @@
}
@override
- void handleRecoverExpression(Token token, Message message) {
- debugEvent("RecoverExpression");
- }
-
- @override
void handleDirectivesOnly() {
pop(); // Discard the metadata.
}
diff --git a/pkg/front_end/lib/src/fasta/util/link.dart b/pkg/front_end/lib/src/fasta/util/link.dart
index 87d6b2a..80e21ff 100644
--- a/pkg/front_end/lib/src/fasta/util/link.dart
+++ b/pkg/front_end/lib/src/fasta/util/link.dart
@@ -127,6 +127,7 @@
// Unsupported Iterable<T> methods.
//
bool any(bool f(T e)) => _unsupported('any');
+ Iterable<T> cast<T>() => _unsupported('cast');
T elementAt(int i) => _unsupported('elementAt');
Iterable<K> expand<K>(Iterable<K> f(T e)) => _unsupported('expand');
T firstWhere(bool f(T e), {T orElse()}) => _unsupported('firstWhere');
@@ -134,15 +135,18 @@
return _unsupported('fold');
}
+ Iterable<T> followedBy(Iterable<T> other) => _unsupported('followedBy');
T get last => _unsupported('get:last');
T lastWhere(bool f(T e), {T orElse()}) => _unsupported('lastWhere');
String join([separator = '']) => _unsupported('join');
T reduce(T combine(T a, T b)) => _unsupported('reduce');
- T singleWhere(bool f(T e)) => _unsupported('singleWhere');
+ Iterable<T> retype<T>() => _unsupported('retype');
+ T singleWhere(bool f(T e), {T orElse()}) => _unsupported('singleWhere');
Iterable<T> skipWhile(bool f(T e)) => _unsupported('skipWhile');
Iterable<T> take(int n) => _unsupported('take');
Iterable<T> takeWhile(bool f(T e)) => _unsupported('takeWhile');
Set<T> toSet() => _unsupported('toSet');
+ Iterable<T> whereType<T>() => _unsupported('whereType');
Iterable<T> where(bool f(T e)) => _unsupported('where');
_unsupported(String method) => throw new UnsupportedError(method);
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 97effa6..ed9816d 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -15,7 +15,6 @@
import 'fasta/compiler_context.dart' show CompilerContext;
import 'fasta/deprecated_problems.dart' show deprecated_InputError, reportCrash;
import 'fasta/dill/dill_target.dart' show DillTarget;
-import 'fasta/kernel/kernel_outline_shaker.dart';
import 'fasta/kernel/kernel_target.dart' show KernelTarget;
import 'fasta/kernel/utils.dart';
import 'fasta/kernel/verifier.dart';
@@ -27,19 +26,19 @@
Future<CompilerResult> generateKernel(ProcessedOptions options,
{bool buildSummary: false,
bool buildProgram: true,
- bool trimDependencies: false}) async {
+ bool truncateSummary: false}) async {
return await CompilerContext.runWithOptions(options, (_) async {
return await generateKernelInternal(
buildSummary: buildSummary,
buildProgram: buildProgram,
- trimDependencies: trimDependencies);
+ truncateSummary: truncateSummary);
});
}
Future<CompilerResult> generateKernelInternal(
{bool buildSummary: false,
bool buildProgram: true,
- bool trimDependencies: false}) async {
+ bool truncateSummary: false}) async {
var options = CompilerContext.current.options;
var fs = options.fileSystem;
if (!await options.validateOptions()) return null;
@@ -100,17 +99,6 @@
await kernelTarget.buildOutlines(nameRoot: nameRoot);
List<int> summary = null;
if (buildSummary) {
- if (trimDependencies) {
- // TODO(sigmund): see if it is worth supporting this. Note: trimming the
- // program is destructive, so if we are emitting summaries and the
- // program in a single API call, we would need to clone the program here
- // to avoid deleting pieces that are needed by kernelTarget.buildProgram
- // below.
- assert(!buildProgram);
- var excluded =
- dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
- trimProgram(summaryProgram, (uri) => !excluded.contains(uri));
- }
if (options.verify) {
for (var error in verifyProgram(summaryProgram)) {
options.report(error, Severity.error);
@@ -120,20 +108,23 @@
printProgramText(summaryProgram,
libraryFilter: kernelTarget.isSourceLibrary);
}
- if (kernelTarget.errors.isEmpty) {
- summary = serializeProgram(summaryProgram, excludeUriToSource: true);
- }
+
+ // Copy the program to exclude the uriToSource map from the summary.
+ //
+ // Note: we don't pass the library argument to the constructor to
+ // preserve the the libraries parent pointer (it should continue to point
+ // to the program within KernelTarget).
+ var trimmedSummaryProgram = new Program(nameRoot: summaryProgram.root)
+ ..libraries.addAll(truncateSummary
+ ? kernelTarget.loader.libraries
+ : summaryProgram.libraries);
+ summary = serializeProgram(trimmedSummaryProgram);
options.ticker.logMs("Generated outline");
}
Program program;
if (buildProgram && kernelTarget.errors.isEmpty) {
program = await kernelTarget.buildProgram(verify: options.verify);
- if (trimDependencies) {
- var excluded =
- dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
- trimProgram(program, (uri) => !excluded.contains(uri));
- }
if (options.debugDump) {
printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
}
diff --git a/pkg/front_end/lib/src/scanner/scanner.dart b/pkg/front_end/lib/src/scanner/scanner.dart
index bd01cfe..6091c28 100644
--- a/pkg/front_end/lib/src/scanner/scanner.dart
+++ b/pkg/front_end/lib/src/scanner/scanner.dart
@@ -557,7 +557,7 @@
_tail = _tail.setNext(eofToken);
if (_stackEnd >= 0) {
_hasUnmatchedGroups = true;
- // TODO(brianwilkerson) Fix the ungrouped tokens?
+ // TODO(brianwilkerson): Fix the ungrouped tokens?
}
}
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 67eae73..81ac570 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -56,10 +56,13 @@
///
/// Wraps [summaryFor] with some default testing options (see [setup]).
Future<List<int>> summarize(List<String> inputs, Map<String, dynamic> sources,
- {List<String> inputSummaries: const [], CompilerOptions options}) async {
+ {List<String> inputSummaries: const [],
+ CompilerOptions options,
+ bool truncate: false}) async {
options ??= new CompilerOptions();
await setup(options, sources, inputSummaries: inputSummaries);
- return await summaryFor(inputs.map(toTestUri).toList(), options);
+ return await summaryFor(inputs.map(toTestUri).toList(), options,
+ truncate: truncate);
}
/// Defines a default set of options for testing:
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 494ec4e..b6047e9 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1446,7 +1446,7 @@
template: "Expected identifier, but got 'super'."
SuperAsExpression:
- template: "Super calls can't be used as expressions."
+ template: "Can't use 'super' as an expression."
tip: "To delegate a constructor to a super constructor, put the super call as an initializer."
SwitchHasCaseAfterDefault:
@@ -1550,7 +1550,7 @@
IntegerLiteralIsOutOfRange:
template: "The integer literal #lexeme can't be represented in 64 bits."
- tip: "Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
+ tip: "Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
ColonInPlaceOfIn:
template: "For-in loops use 'in' rather than a colon."
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index caf5c1c..7b6e9cc 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -18,7 +18,6 @@
dev_dependencies:
analyzer: '>=0.30.0 <0.32.0'
args: '>=0.13.0 <2.0.0'
- bazel_worker: ^0.1.4
dart_style: '^1.0.7'
json_rpc_2: ^2.0.4
mockito: ^2.0.2
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
new file mode 100644
index 0000000..97f02fc
--- /dev/null
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+library fasta.test.incremental_dynamic_test;
+
+import 'package:async_helper/async_helper.dart' show asyncTest;
+
+import 'package:expect/expect.dart' show Expect;
+
+import "package:front_end/src/api_prototype/compiler_options.dart"
+ show CompilerOptions;
+
+import 'package:front_end/src/base/processed_options.dart'
+ show ProcessedOptions;
+
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+ show computePlatformBinariesLocation;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+ show FastaDelta, IncrementalCompiler;
+
+import 'package:front_end/src/fasta/severity.dart' show Severity;
+
+void problemHandler(LocatedMessage message, Severity severity, String formatted,
+ int line, int column) {
+ throw "Unexpected message: $formatted";
+}
+
+test({bool sdkFromSource}) async {
+ final CompilerOptions optionBuilder = new CompilerOptions()
+ ..packagesFileUri = Uri.base.resolve(".packages")
+ ..strongMode = false
+ ..onProblem = problemHandler;
+
+ if (sdkFromSource) {
+ optionBuilder.librariesSpecificationUri =
+ Uri.base.resolve("sdk/lib/libraries.json");
+ } else {
+ optionBuilder.sdkSummary =
+ computePlatformBinariesLocation().resolve("vm_platform.dill");
+ }
+
+ final Uri helloDart = Uri.base.resolve("pkg/front_end/testcases/hello.dart");
+
+ final ProcessedOptions options =
+ new ProcessedOptions(optionBuilder, false, [helloDart]);
+
+ IncrementalCompiler compiler =
+ new IncrementalCompiler(new CompilerContext(options));
+
+ FastaDelta delta = await compiler.computeDelta();
+
+ if (sdkFromSource) {
+ // Expect that the new program contains at least the following libraries:
+ // dart:core, dart:async, and hello.dart.
+ Expect.isTrue(delta.newProgram.libraries.length > 2,
+ "${delta.newProgram.libraries.length} <= 2");
+ } else {
+ // Expect that the new program contains exactly hello.dart.
+ Expect.isTrue(delta.newProgram.libraries.length == 1,
+ "${delta.newProgram.libraries.length} != 1");
+ }
+
+ compiler.invalidate(helloDart);
+
+ delta = await compiler.computeDelta(entryPoint: helloDart);
+ // Expect that the new program contains exactly hello.dart
+ Expect.isTrue(delta.newProgram.libraries.length == 1,
+ "${delta.newProgram.libraries.length} != 1");
+}
+
+void main() {
+ asyncTest(() async {
+ await test(sdkFromSource: true);
+ await test(sdkFromSource: false);
+ });
+}
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 052e616..36306a2 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -100,6 +100,22 @@
checkDSummary(summaryD);
});
+ test('dependencies not included in truncated summaries', () async {
+ // Note: by default this test is loading the SDK from summaries.
+ var summaryA = await summarize(['a.dart'], allSources, truncate: true);
+ var program = loadProgramFromBytes(summaryA);
+ expect(program.libraries.length, 1);
+ expect(program.libraries.single.importUri.path.endsWith('a.dart'), isTrue);
+
+ var sourcesWithA = new Map.from(allSources);
+ sourcesWithA['a.dill'] = summaryA;
+ var summaryB = await summarize(['b.dart'], sourcesWithA,
+ inputSummaries: ['a.dill'], truncate: true);
+ program = loadProgramFromBytes(summaryB);
+ expect(program.libraries.length, 1);
+ expect(program.libraries.single.importUri.path.endsWith('b.dart'), isTrue);
+ });
+
test('summarization by default is hermetic', () async {
var errors = [];
var options = new CompilerOptions()..onError = (e) => errors.add(e);
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 98b16fc..da87982 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -132,6 +132,7 @@
regress/issue_29983: Crash
regress/issue_29984: Crash
regress/issue_29985: Crash
+regress/issue_30838: Crash
regress/issue_31155: Crash # Issue 31155.
regress/issue_31157: Crash
regress/issue_31180: Crash
@@ -139,11 +140,13 @@
regress/issue_31186: Crash
regress/issue_31187: Crash
regress/issue_31198: Crash
+regress/issue_31213: Crash
reorder_super: Crash
runtime_checks/implicit_downcast_assert_initializer: Crash
runtime_checks/implicit_downcast_constructor_initializer: Crash
runtime_checks_new/for_in_call_kinds: Crash
statements: Crash
+super_call: Crash
super_rasta_copy: Crash
type_variable_as_super: Crash
uninitialized_fields: Crash
diff --git a/pkg/front_end/testcases/incremental.status b/pkg/front_end/testcases/incremental.status
index d5feffe..c572cda 100644
--- a/pkg/front_end/testcases/incremental.status
+++ b/pkg/front_end/testcases/incremental.status
@@ -3,3 +3,5 @@
# BSD-style license that can be found in the LICENSE.md file.
# Status file for the test suite ../test/fasta/incremental_test.dart.
+
+dartino/change_in_part.incremental: Crash # Parts aren't handled correctly
diff --git a/pkg/front_end/testcases/rasta/super.dart.strong.expect b/pkg/front_end/testcases/rasta/super.dart.strong.expect
index e4997f7..4de50f1 100644
--- a/pkg/front_end/testcases/rasta/super.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.strong.expect
@@ -51,8 +51,8 @@
self::use(super.{self::A::~}());
super.{self::A::unary-}();
self::use(super.{self::A::unary-}());
- (let final dynamic #t1 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:5: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n +super;\n ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:6: Error: Can't use `super` as an expression.\n +super;\n ^")));
- self::use((let final dynamic #t2 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:9: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n use(+super);\n ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:10: Error: Can't use `super` as an expression.\n use(+super);\n ^"))));
+ (let final dynamic #t1 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:5: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n +super;\n ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:6: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n +super;\n ^")));
+ self::use((let final dynamic #t2 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:9: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n use(+super);\n ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:10: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n use(+super);\n ^"))));
super.{self::A::==}(87);
self::use(super.{self::A::==}(87));
!super.{self::A::==}(87);
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart b/pkg/front_end/testcases/regress/issue_30838.dart
new file mode 100644
index 0000000..3125604
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {
+ bar()<String>("hello");
+}
+
+class A {
+ Foo<int> f;
+ void test() {
+ f<String>("hello");
+ }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect b/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect
new file mode 100644
index 0000000..bf351e8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+ field <T extends core::Object>(T) → core::int f = null;
+ default constructor •() → void
+ : super core::Object::•()
+ ;
+ method test() → void {
+ this.f<core::String>("hello");
+ }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+ return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+ return self::foo;
+static method test1() → void {
+ self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect
new file mode 100644
index 0000000..ea2077a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+ field <T extends core::Object>(T) → core::int f;
+ default constructor •() → void
+ ;
+ method test() → void
+ ;
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+ ;
+static method bar() → <T extends core::Object>(T) → core::int
+ ;
+static method test1() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect
new file mode 100644
index 0000000..a9dea91
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+ field <T extends core::Object>(T) → core::int f = null;
+ default constructor •() → void
+ : super core::Object::•()
+ ;
+ method test() → void {
+ this.{self::A::f}<core::String>("hello");
+ }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+ return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+ return self::foo;
+static method test1() → void {
+ self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
index 2761375..072b91b 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
@@ -9,7 +9,7 @@
}
class B extends self::A {
constructor •() → void
- : final dynamic #t1 = const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Super calls can't be used as expressions.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n B(): super().foo() {}\n ^")).foo() {}
+ : final dynamic #t1 = const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n B(): super().foo() {}\n ^")).foo() {}
}
static method bad() → dynamic {
new self::B::•();
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
index 6dde538..ad0da2f 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
@@ -9,7 +9,7 @@
}
class B extends self::A {
constructor •() → void
- : final dynamic #t1 = const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Super calls can't be used as expressions.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n B(): super().foo() {}\n ^")).foo() {}
+ : final dynamic #t1 = const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n B(): super().foo() {}\n ^")).foo() {}
}
static method bad() → dynamic {
new self::B::•();
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart b/pkg/front_end/testcases/regress/issue_31213.dart
new file mode 100644
index 0000000..f4b522a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
+
+dynamic producer<K>() {
+ return <A>(int v1) {
+ return <B>(A v2, K v3, B v4) => 0;
+ };
+}
+
+main() {
+ assert(producer<String>() is D<String>);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect
new file mode 100644
index 0000000..860b081
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+ return <A extends core::Object>(core::int v1) → dynamic {
+ return <B extends core::Object>(A v2, self::producer::K v3, B v4) → dynamic => 0;
+ };
+}
+static method main() → dynamic {
+ assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
new file mode 100644
index 0000000..ab22b45
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
new file mode 100644
index 0000000..c6e0d5f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+ return <A extends core::Object>(core::int v1) → <B extends core::Object>(A, self::producer::K, B) → core::int {
+ return <B extends core::Object>(A v2, self::producer::K v3, B v4) → core::int => 0;
+ };
+}
+static method main() → dynamic {
+ assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/super_call.dart b/pkg/front_end/testcases/super_call.dart
new file mode 100644
index 0000000..6d9d0a1
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+class A {
+ int call(int x) => x * 2;
+}
+
+class B extends A {
+ int call(int x) => x * 3;
+
+ int call_super() {
+ // Assumes that super() means super.call().
+ // In reality, it is illegal to use it this way.
+ return super(5);
+ }
+}
+
+main() {
+ assert(new B().call_super() == 10);
+}
diff --git a/pkg/front_end/testcases/super_call.dart.direct.expect b/pkg/front_end/testcases/super_call.dart.direct.expect
new file mode 100644
index 0000000..b526f3a0
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.direct.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ default constructor •() → void
+ : super core::Object::•()
+ ;
+ method call(core::int x) → core::int
+ return x.*(2);
+}
+class B extends self::A {
+ default constructor •() → void
+ : super self::A::•()
+ ;
+ method call(core::int x) → core::int
+ return x.*(3);
+ method call_super() → core::int {
+ return const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n return super(5);\n ^"));
+ }
+}
+static method main() → dynamic {
+ assert(new self::B::•().call_super().==(10));
+}
diff --git a/pkg/front_end/testcases/super_call.dart.outline.expect b/pkg/front_end/testcases/super_call.dart.outline.expect
new file mode 100644
index 0000000..a12055e
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ default constructor •() → void
+ ;
+ method call(core::int x) → core::int
+ ;
+}
+class B extends self::A {
+ default constructor •() → void
+ ;
+ method call(core::int x) → core::int
+ ;
+ method call_super() → core::int
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/super_call.dart.strong.expect b/pkg/front_end/testcases/super_call.dart.strong.expect
new file mode 100644
index 0000000..3c4e3e0
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.strong.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ default constructor •() → void
+ : super core::Object::•()
+ ;
+ method call(core::int x) → core::int
+ return x.{core::num::*}(2);
+}
+class B extends self::A {
+ default constructor •() → void
+ : super self::A::•()
+ ;
+ method call(core::int x) → core::int
+ return x.{core::num::*}(3);
+ method call_super() → core::int {
+ return const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n return super(5);\n ^")) as{TypeError} core::int;
+ }
+}
+static method main() → dynamic {
+ assert(new self::B::•().{self::B::call_super}().{core::num::==}(10));
+}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index db9b11f..d2304b1 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -10,6 +10,10 @@
import 'dart:io' show File, exitCode;
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+import 'package:kernel/target/targets.dart' show TargetFlags, targets;
+
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/fasta/deprecated_problems.dart'
@@ -38,6 +42,8 @@
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
compileEntryPoint(List<String> arguments) async {
+ targets["dart2js"] = (TargetFlags flags) => new Dart2jsTarget(flags);
+
// Timing results for each iteration
List<double> elapsedTimes = <double>[];
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index f93fabc..82edc93 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -487,6 +487,8 @@
visitNestedExpression(node.value, EXPRESSION,
newInForInit: false, newAtStatementBegin: false);
}
+ // Set the closing position to be before the optional semicolon.
+ currentNode.closingPosition = _charCount;
outSemicolonLn();
}
diff --git a/pkg/js_ast/test/printer_callback_test.dart b/pkg/js_ast/test/printer_callback_test.dart
index d142e83..6483d28 100644
--- a/pkg/js_ast/test/printer_callback_test.dart
+++ b/pkg/js_ast/test/printer_callback_test.dart
@@ -40,7 +40,7 @@
}""",
TestMode.DELIMITER: """
function(a, b) {
- return null;
+ return null@4;
@0}""",
TestMode.EXIT: """
function(a@1, b@2) {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 4e5135b..9300ef0 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1507,6 +1507,7 @@
this.isExternal = isExternal;
this.isConst = isConst;
this.isForwardingStub = isForwardingStub;
+ this.isForwardingSemiStub = isForwardingSemiStub;
this.transformerFlags = transformerFlags;
}
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 5b2ab4e..60b6e3c 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -340,7 +340,7 @@
TypeParameter freshTypeParameter(TypeParameter node) {
var fresh = new TypeParameter(node.name);
substitution[node] = new TypeParameterType(fresh);
- fresh.bound = node.bound != null ? visit(node.bound) : null;
+ fresh.bound = visit(node.bound);
return fresh;
}
}
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index cea0972..fbbfb81 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -145,6 +145,10 @@
void declareTypeParameters(List<TypeParameter> parameters) {
for (int i = 0; i < parameters.length; ++i) {
var parameter = parameters[i];
+ if (parameter.bound == null) {
+ problem(
+ currentParent, "Missing bound for type parameter '$parameter'.");
+ }
if (!typeParametersInScope.add(parameter)) {
problem(parameter, "Type parameter '$parameter' redeclared.");
}
@@ -577,7 +581,7 @@
problem(
currentParent,
"Type parameter '$parameter' referenced from"
- " static context, parent is '${parameter.parent}'.");
+ " static context, parent is: '${parameter.parent}'.");
}
}
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 7c7c243..32b80f9 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -104,7 +104,7 @@
negativeTest(
'Class type parameter in static method',
"Type parameter 'test_lib::TestClass::T' referenced from static context,"
- " parent is 'test_lib::TestClass'.", (TestHarness test) {
+ " parent is: 'test_lib::TestClass'.", (TestHarness test) {
return new Procedure(
new Name('bar'),
ProcedureKind.Method,
@@ -115,7 +115,7 @@
negativeTest(
'Class type parameter in static field',
"Type parameter 'test_lib::TestClass::T' referenced from static context,"
- " parent is 'test_lib::TestClass'.", (TestHarness test) {
+ " parent is: 'test_lib::TestClass'.", (TestHarness test) {
return new Field(new Name('field'),
initializer:
new TypeLiteral(new TypeParameterType(test.classTypeParameter)),
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index a906bd2..fad7ad9 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -344,6 +344,7 @@
List<_PointMapping> mappingsOnLines = [];
for (var line in sourceMap.lines) {
for (var entry in line.entries) {
+ if (entry.sourceLine == null) continue;
if (entry.sourceLine >= breakOnLine &&
entry.sourceLine < breakOnLine + 4) {
mappingsOnLines.add(new _PointMapping(
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 6f1ff40..2fc8bf6 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -12,7 +12,7 @@
import 'package:kernel/src/tool/batch_util.dart' as batch_util;
import 'package:kernel/target/targets.dart' show TargetFlags;
import 'package:kernel/target/vm.dart' show VmTarget;
-import 'package:vm/kernel_front_end.dart' show compileToKernel;
+import 'package:vm/kernel_front_end.dart' show compileToKernel, ErrorDetector;
final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
..addOption('platform',
@@ -60,7 +60,7 @@
final bool strongMode = options['strong-mode'];
final bool aot = options['aot'];
- int errors = 0;
+ ErrorDetector errorDetector = new ErrorDetector();
final CompilerOptions compilerOptions = new CompilerOptions()
..strongMode = strongMode
@@ -68,18 +68,13 @@
..linkedDependencies = <Uri>[Uri.base.resolve(platformKernel)]
..packagesFileUri = packages != null ? Uri.base.resolve(packages) : null
..reportMessages = true
- ..onError = (CompilationMessage message) {
- if ((message.severity != Severity.nit) &&
- (message.severity != Severity.warning)) {
- ++errors;
- }
- };
+ ..onError = errorDetector;
Program program = await compileToKernel(
Uri.base.resolve(filename), compilerOptions,
aot: aot);
- if ((errors > 0) || (program == null)) {
+ if (errorDetector.hasCompilationErrors || (program == null)) {
return _compileTimeErrorExitCode;
}
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 5ec3890..8df5e10 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -185,6 +185,8 @@
final bool strong = request[5];
final int isolateId = request[6];
final List sourceFiles = request[7];
+ // TODO(bkonyi): this still needs to be hooked in.
+ // final bool suppressWarnings = request[8];
Compiler compiler;
// TODO(aam): There should be no need to have an option to choose
@@ -284,7 +286,8 @@
false /* incremental */,
false /* strong */,
1 /* isolateId chosen randomly */,
- null /* source files */
+ null /* source files */,
+ false /* suppress warnings */,
];
_processLoadRequest(request);
}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 11506fc..7f7158b 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -7,13 +7,17 @@
import 'dart:async';
-import 'package:front_end/src/api_prototype/compiler_options.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show CompilerOptions, ErrorHandler;
import 'package:front_end/src/api_prototype/kernel_generator.dart'
show kernelForProgram;
+import 'package:front_end/src/api_prototype/compilation_message.dart'
+ show CompilationMessage, Severity;
+import 'package:front_end/src/fasta/severity.dart' show Severity;
import 'package:kernel/ast.dart' show Program;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'transformations/cha_devirtualization.dart' as chaDevirtualization
+import 'transformations/devirtualization.dart' as devirtualization
show transformProgram;
/// Generates a kernel representation of the program whose main library is in
@@ -23,9 +27,18 @@
///
Future<Program> compileToKernel(Uri source, CompilerOptions options,
{bool aot: false}) async {
+ // Replace error handler to detect if there are compilation errors.
+ final errorDetector =
+ new ErrorDetector(previousErrorHandler: options.onError);
+ options.onError = errorDetector;
+
final program = await kernelForProgram(source, options);
- if (aot && (program != null)) {
+ // Restore error handler (in case 'options' are reused).
+ options.onError = errorDetector.previousErrorHandler;
+
+ // Run global transformations only if program is correct.
+ if (aot && (program != null) && !errorDetector.hasCompilationErrors) {
_runGlobalTransformations(program, options.strongMode);
}
@@ -33,11 +46,25 @@
}
_runGlobalTransformations(Program program, bool strongMode) {
- final coreTypes = new CoreTypes(program);
-
- // TODO(alexmarkov): AOT-specific whole-program transformations.
-
if (strongMode) {
- chaDevirtualization.transformProgram(coreTypes, program);
+ final coreTypes = new CoreTypes(program);
+
+ devirtualization.transformProgram(coreTypes, program);
+ }
+}
+
+class ErrorDetector {
+ final ErrorHandler previousErrorHandler;
+ bool hasCompilationErrors = false;
+
+ ErrorDetector({this.previousErrorHandler});
+
+ void call(CompilationMessage message) {
+ if ((message.severity != Severity.nit) &&
+ (message.severity != Severity.warning)) {
+ hasCompilationErrors = true;
+ }
+
+ previousErrorHandler?.call(message);
}
}
diff --git a/pkg/vm/lib/transformations/cha_devirtualization.dart b/pkg/vm/lib/transformations/cha_devirtualization.dart
deleted file mode 100644
index cdc2ce4..0000000
--- a/pkg/vm/lib/transformations/cha_devirtualization.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library vm.transformations.cha_devirtualization;
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/class_hierarchy.dart' show ClosedWorldClassHierarchy;
-
-import '../metadata/direct_call.dart';
-
-/// Devirtualization of method invocations based on the class hierarchy
-/// analysis. Assumes strong mode and closed world.
-Program transformProgram(CoreTypes coreTypes, Program program) {
- new _Devirtualization(coreTypes, program).visitProgram(program);
- return program;
-}
-
-/// Resolves targets of instance method invocations, property getter
-/// invocations and property setters invocations using strong mode
-/// types / interface targets and closed-world class hierarchy analysis.
-/// If direct target is determined, the invocation node is annotated
-/// with direct call metadata.
-class _Devirtualization extends RecursiveVisitor<Null> {
- /// Toggles tracing (useful for debugging).
- static const _trace = const bool.fromEnvironment('trace.devirtualization');
-
- final ClosedWorldClassHierarchy _hierarchy;
- final DirectCallMetadataRepository _metadata;
- Set<Name> _objectMemberNames;
-
- _Devirtualization(CoreTypes coreTypes, Program program)
- : _hierarchy = new ClosedWorldClassHierarchy(program),
- _metadata = new DirectCallMetadataRepository() {
- _objectMemberNames = new Set<Name>.from(_hierarchy
- .getInterfaceMembers(coreTypes.objectClass)
- .map((Member m) => m.name));
- program.addMetadataRepository(_metadata);
- }
-
- bool _isMethod(Member member) => (member is Procedure) && !member.isGetter;
-
- bool _isFieldOrGetter(Member member) =>
- (member is Field) || ((member is Procedure) && member.isGetter);
-
- bool _isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
- final FunctionNode func = target.function;
-
- final positionalArgs = arguments.positional.length;
- if ((positionalArgs < func.requiredParameterCount) ||
- (positionalArgs > func.positionalParameters.length)) {
- return false;
- }
-
- if (arguments.named.isNotEmpty) {
- final names = arguments.named.map((v) => v.name).toSet();
- names.removeAll(func.namedParameters.map((v) => v.name));
- if (names.isNotEmpty) {
- return false;
- }
- }
-
- return true;
- }
-
- _makeDirectCall(TreeNode node, Member target, Member singleTarget) {
- if (_trace) {
- print("[devirt] Resolving ${target} to ${singleTarget}");
- }
- _metadata.mapping[node] = new DirectCallMetadata(singleTarget, true);
- }
-
- @override
- visitLibrary(Library node) {
- if (_trace) {
- String external = node.isExternal ? " (external)" : "";
- print("[devirt] Processing library ${node.name}${external}");
- }
- super.visitLibrary(node);
- }
-
- @override
- visitMethodInvocation(MethodInvocation node) {
- super.visitMethodInvocation(node);
-
- Member target = node.interfaceTarget;
- if ((target != null) &&
- _isMethod(target) &&
- !_objectMemberNames.contains(target.name)) {
- Member singleTarget =
- _hierarchy.getSingleTargetForInterfaceInvocation(target);
- // TODO(dartbug.com/30480): Convert _isLegalTargetForMethodInvocation()
- // check into an assertion once front-end implements override checks.
- if ((singleTarget != null) &&
- _isMethod(singleTarget) &&
- _isLegalTargetForMethodInvocation(singleTarget, node.arguments)) {
- _makeDirectCall(node, target, singleTarget);
- }
- }
- }
-
- @override
- visitPropertyGet(PropertyGet node) {
- super.visitPropertyGet(node);
-
- Member target = node.interfaceTarget;
- if ((target != null) &&
- _isFieldOrGetter(target) &&
- !_objectMemberNames.contains(target.name)) {
- Member singleTarget =
- _hierarchy.getSingleTargetForInterfaceInvocation(target);
- if ((singleTarget != null) && _isFieldOrGetter(singleTarget)) {
- _makeDirectCall(node, target, singleTarget);
- }
- }
- }
-
- @override
- visitPropertySet(PropertySet node) {
- super.visitPropertySet(node);
-
- Member target = node.interfaceTarget;
- if (target != null) {
- Member singleTarget = _hierarchy
- .getSingleTargetForInterfaceInvocation(target, setter: true);
- if (singleTarget != null) {
- _makeDirectCall(node, target, singleTarget);
- }
- }
- }
-}
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
new file mode 100644
index 0000000..9d8685b
--- /dev/null
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.transformations.cha_devirtualization;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/class_hierarchy.dart'
+ show ClassHierarchy, ClosedWorldClassHierarchy;
+
+import '../metadata/direct_call.dart';
+
+/// Devirtualization of method invocations based on the class hierarchy
+/// analysis. Assumes strong mode and closed world.
+Program transformProgram(CoreTypes coreTypes, Program program) {
+ new CHADevirtualization(
+ coreTypes, program, new ClosedWorldClassHierarchy(program))
+ .visitProgram(program);
+ return program;
+}
+
+/// Base class for implementing devirtualization of method invocations.
+/// Subclasses should implement particular devirtualization strategy in
+/// [getDirectCall] method. Once direct target is determined, the invocation
+/// node is annotated with direct call metadata.
+abstract class Devirtualization extends RecursiveVisitor<Null> {
+ /// Toggles tracing (useful for debugging).
+ static const _trace = const bool.fromEnvironment('trace.devirtualization');
+
+ final DirectCallMetadataRepository _metadata;
+ Set<Name> _objectMemberNames;
+
+ Devirtualization(
+ CoreTypes coreTypes, Program program, ClassHierarchy hierarchy)
+ : _metadata = new DirectCallMetadataRepository() {
+ _objectMemberNames = new Set<Name>.from(hierarchy
+ .getInterfaceMembers(coreTypes.objectClass)
+ .map((Member m) => m.name));
+ program.addMetadataRepository(_metadata);
+ }
+
+ bool isMethod(Member member) => (member is Procedure) && !member.isGetter;
+
+ bool isFieldOrGetter(Member member) =>
+ (member is Field) || ((member is Procedure) && member.isGetter);
+
+ bool isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
+ final FunctionNode func = target.function;
+
+ final positionalArgs = arguments.positional.length;
+ if ((positionalArgs < func.requiredParameterCount) ||
+ (positionalArgs > func.positionalParameters.length)) {
+ return false;
+ }
+
+ if (arguments.named.isNotEmpty) {
+ final names = arguments.named.map((v) => v.name).toSet();
+ names.removeAll(func.namedParameters.map((v) => v.name));
+ if (names.isNotEmpty) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ DirectCallMetadata getDirectCall(TreeNode node, Member target,
+ {bool setter = false});
+
+ makeDirectCall(TreeNode node, Member target, DirectCallMetadata directCall) {
+ if (_trace) {
+ print("[devirt] Resolving ${target} to ${directCall.target}"
+ " at ${node.location}");
+ }
+ _metadata.mapping[node] = directCall;
+ }
+
+ @override
+ visitLibrary(Library node) {
+ if (_trace) {
+ String external = node.isExternal ? " (external)" : "";
+ print("[devirt] Processing library ${node.name}${external}");
+ }
+ super.visitLibrary(node);
+ }
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ super.visitMethodInvocation(node);
+
+ Member target = node.interfaceTarget;
+ if ((target != null) &&
+ isMethod(target) &&
+ !_objectMemberNames.contains(target.name)) {
+ DirectCallMetadata directCall = getDirectCall(node, target);
+ // TODO(dartbug.com/30480): Convert _isLegalTargetForMethodInvocation()
+ // check into an assertion once front-end implements override checks.
+ if ((directCall != null) &&
+ isMethod(directCall.target) &&
+ isLegalTargetForMethodInvocation(directCall.target, node.arguments)) {
+ makeDirectCall(node, target, directCall);
+ }
+ }
+ }
+
+ @override
+ visitPropertyGet(PropertyGet node) {
+ super.visitPropertyGet(node);
+
+ Member target = node.interfaceTarget;
+ if ((target != null) &&
+ isFieldOrGetter(target) &&
+ !_objectMemberNames.contains(target.name)) {
+ DirectCallMetadata directCall = getDirectCall(node, target);
+ if ((directCall != null) && isFieldOrGetter(directCall.target)) {
+ makeDirectCall(node, target, directCall);
+ }
+ }
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ super.visitPropertySet(node);
+
+ Member target = node.interfaceTarget;
+ if (target != null) {
+ DirectCallMetadata directCall = getDirectCall(node, target, setter: true);
+ if (directCall != null) {
+ makeDirectCall(node, target, directCall);
+ }
+ }
+ }
+}
+
+/// Devirtualization based on the closed-world class hierarchy analysis.
+class CHADevirtualization extends Devirtualization {
+ final ClosedWorldClassHierarchy _hierarchy;
+
+ CHADevirtualization(CoreTypes coreTypes, Program program, this._hierarchy)
+ : super(coreTypes, program, _hierarchy);
+
+ @override
+ DirectCallMetadata getDirectCall(TreeNode node, Member target,
+ {bool setter = false}) {
+ Member singleTarget = _hierarchy
+ .getSingleTargetForInterfaceInvocation(target, setter: setter);
+ if (singleTarget == null) {
+ return null;
+ }
+ return new DirectCallMetadata(singleTarget, true);
+ }
+}
diff --git a/pkg/vm/tool/dart_precompiled_runtime2 b/pkg/vm/tool/dart_precompiled_runtime2
index d8c490a..eeb33e3 100755
--- a/pkg/vm/tool/dart_precompiled_runtime2
+++ b/pkg/vm/tool/dart_precompiled_runtime2
@@ -36,4 +36,5 @@
exec "$BIN_DIR"/dart_precompiled_runtime \
--strong \
--reify-generic-functions \
+ --limit-ints-to-64-bits \
"$@"
diff --git a/pkg/vm/tool/gen_kernel b/pkg/vm/tool/gen_kernel
index 5b96047..e5687b8 100755
--- a/pkg/vm/tool/gen_kernel
+++ b/pkg/vm/tool/gen_kernel
@@ -8,6 +8,13 @@
set -e
+# Enable Dart 2.0 fixed-size integers for gen_kernel if running in strong mode.
+for arg in "$@"; do
+ if [ "$arg" == "--strong-mode" ]; then
+ DART_VM_FLAGS="--limit-ints-to-64-bits $DART_VM_FLAGS"
+ fi
+done
+
function follow_links() {
file="$1"
while [ -h "$file" ]; do
@@ -35,4 +42,4 @@
OUT_DIR="$SDK_DIR/out"
fi
-exec "$DART" "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" $@
+exec "$DART" $DART_VM_FLAGS "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" $@
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index a3aee3a..faf92c0 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -67,7 +67,9 @@
BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
# Step 1: Generate Kernel binary from the input Dart source.
-"$BIN_DIR"/dart "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" \
+"$BIN_DIR"/dart \
+ --limit-ints-to-64-bits \
+ "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" \
--platform "${BIN_DIR}/vm_platform_strong.dill" \
--aot \
$PACKAGES \
@@ -78,6 +80,7 @@
exec "$BIN_DIR"/dart_bootstrap \
--strong \
--reify-generic-functions \
+ --limit-ints-to-64-bits \
--snapshot-kind=app-aot \
--use-blobs \
--snapshot="$SNAPSHOT_FILE" \
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 192a332..b1141b2 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -84,13 +84,56 @@
return Dart_NewExternalTypedData(Dart_TypedData_kUint64, kernel_program, 1);
}
+class WindowsPathSanitizer {
+ public:
+ explicit WindowsPathSanitizer(const char* path) {
+ // For Windows we need to massage the paths a bit according to
+ // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+ //
+ // Convert
+ // C:\one\two\three
+ // to
+ // /C:/one/two/three
+ //
+ // (see builtin.dart#_sanitizeWindowsPath)
+ intptr_t len = strlen(path);
+ sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
+ if (sanitized_uri_ == NULL) {
+ OUT_OF_MEMORY();
+ }
+ char* s = sanitized_uri_;
+ if (len > 2 && path[1] == ':') {
+ *s++ = '/';
+ }
+ for (const char *p = path; *p; ++p, ++s) {
+ *s = *p == '\\' ? '/' : *p;
+ }
+ *s = '\0';
+ }
+ ~WindowsPathSanitizer() { free(sanitized_uri_); }
+
+ const char* sanitized_uri() { return sanitized_uri_; }
+
+ private:
+ char* sanitized_uri_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowsPathSanitizer);
+};
+
void* DFE::CompileAndReadScript(const char* script_uri,
char** error,
int* exit_code) {
// TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
// instead of vm_platform.dill to Frontend for compilation.
+#if defined(HOST_OS_WINDOWS)
+ WindowsPathSanitizer path_sanitizer(script_uri);
+ const char* sanitized_uri = path_sanitizer.sanitized_uri();
+#else
+ const char* sanitized_uri = script_uri;
+#endif
+
Dart_KernelCompilationResult result =
- Dart_CompileToKernel(script_uri, GetPlatformBinaryFilename());
+ Dart_CompileToKernel(sanitized_uri, GetPlatformBinaryFilename());
switch (result.status) {
case Dart_KernelCompilationStatus_Ok:
return Dart_ReadKernelBinary(result.kernel, result.kernel_size,
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 57d33f8..56139f95 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1425,10 +1425,6 @@
return kErrorExitCode;
}
- if (commandline_packages_file != NULL) {
- AddDependency(commandline_packages_file);
- }
-
Dart_QualifiedFunctionName* entry_points =
ParseEntryPointsManifestIfPresent();
SetupStubNativeResolversForPrecompilation(entry_points);
diff --git a/runtime/observatory/tests/service/break_on_default_constructor_test.dart b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
new file mode 100644
index 0000000..93901a8
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:observatory/debugger.dart';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/service.dart' as S;
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class Foo {}
+
+code() {
+ new Foo();
+}
+
+class TestDebugger extends Debugger {
+ TestDebugger(this.isolate, this.stack);
+
+ VM get vm => isolate.vm;
+ Isolate isolate;
+ ServiceMap stack;
+ int currentFrame = 0;
+}
+
+Future<Debugger> initDebugger(Isolate isolate) {
+ return isolate.getStack().then((stack) {
+ return new TestDebugger(isolate, stack);
+ });
+}
+
+List<String> stops = [];
+
+var tests = [
+ hasPausedAtStart,
+ // Load the isolate's libraries
+ (Isolate isolate) async {
+ for (var lib in isolate.libraries) {
+ await lib.load();
+ }
+ },
+
+ (Isolate isolate) async {
+ var debugger = await initDebugger(isolate);
+ var loc = await DebuggerLocation.parse(debugger, 'Foo');
+
+ if (loc.valid) {
+ if (loc.function != null) {
+ try {
+ await debugger.isolate.addBreakpointAtEntry(loc.function);
+ } on S.ServerRpcException catch (e) {
+ if (e.code == S.ServerRpcException.kCannotAddBreakpoint) {
+ // Expected
+ } else {
+ fail("Got unexpected error $e");
+ }
+ }
+ } else {
+ fail("Expected to find function");
+ }
+ } else {
+ fail("Expected to find function");
+ }
+
+ isolate.resume();
+ },
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/step_through_constructor_test.dart b/runtime/observatory/tests/service/step_through_constructor_test.dart
new file mode 100644
index 0000000..42fc5d6
--- /dev/null
+++ b/runtime/observatory/tests/service/step_through_constructor_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 17;
+const String file = "step_through_constructor_test.dart";
+
+code() {
+ new Foo();
+}
+
+class Foo {
+ Foo() {
+ print("Hello from Foo!");
+ }
+}
+
+List<String> stops = [];
+List<String> expected = [
+ "$file:${LINE+0}:5", // on 'print'
+ "$file:${LINE+1}:3", // on ending '}'
+];
+
+var tests = [
+ hasPausedAtStart,
+ setBreakpointAtLine(LINE),
+ runStepIntoThroughProgramRecordingStops(stops),
+ checkRecordedStops(stops, expected,
+ debugPrint: true, debugPrintFile: file, debugPrintLine: LINE)
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart b/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart
new file mode 100644
index 0000000..eb82966
--- /dev/null
+++ b/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Note: below we are using tear-offs instead of calling methods directly
+// to guarantee very specific compilation order:
+//
+// - compile main, add get:methodM and get:callMethodM to selector set.
+// - compile A.callMethodM and add get:createB to selector set.
+// - compile A.createB and mark B as allocated.
+//
+// Class B is not marked as allocated until A.createB is compiled, which means
+// that when A.callMethodM is compiled only class A has get:methodM method
+// extractor injected.
+//
+// This test is verifying that optimizing compiler does not treat this method
+// extractor as a single target for this.get:methodM call.
+main() {
+ // This adds selector 'get:methodM' into the sent selector set and
+ // marks class A as allocated.
+ new A().methodM;
+
+ // This adds get:callMethodM to the sent selector set.
+ final callMethodMOnA = new A().callMethodM;
+ final b = callMethodMOnA("A");
+ final callMethodMOnB = b.callMethodM;
+ callMethodMOnB("B");
+}
+
+class A {
+ B callMethodM(String expected) {
+ final f = methodM;
+ Expect.equals(expected, f());
+
+ final newB = createB;
+ return newB();
+ }
+
+ B createB() => new B();
+
+ String methodM() => 'A';
+}
+
+class B extends A {
+ @override
+ String methodM() => 'B';
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 407b338..63981da 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -67,9 +67,6 @@
cc/Mixin_PrivateSuperResolution: Skip
cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
-[ $compiler == dartkp ]
-dart/truncating_ints_test: CompileTimeError # Issue 31339
-
[ $compiler == precompiler ]
dart/byte_array_test: Skip # Incompatible flag --disable_alloc_stubs_after_gc
@@ -353,6 +350,9 @@
dart/spawn_infinite_loop_test: Crash # Please triage.
dart/truncating_ints_test: CompileTimeError # Please triage.
+[ $compiler == dartkp && !$strong ]
+dart/truncating_ints_test: Skip # This test cannot be run in dartkp/legacy mode (gen_kernel does not pass --limit-ints-to-64-bits in legacy mode).
+
[ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
dart/data_uri_import_test/base64: CompileTimeError
dart/data_uri_import_test/nocharset: CompileTimeError
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index bc75dd7..1f74a04 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -75,6 +75,10 @@
# TODO(zra): When the platform-specific timeline code is moved out to
# the embedder, this can go away.
"//zircon/system/ulib/fbl",
+ # TODO(US-399): Remove time_service specific code when it is no longer
+ # necessary.
+ "//garnet/public/lib/time_service/fidl",
+ "//garnet/public/lib/app/cpp",
]
}
public_configs = [ ":libdart_vm_config" ]
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 2db84f6..13190f9 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -719,10 +719,18 @@
for (intptr_t i = 0; i < class_ids.length(); i++) {
const intptr_t cid = class_ids[i];
cls = isolate()->class_table()->At(cid);
+ // Even if we are resolving get:M on a class that has method M
+ // ResolveForReceiverClass would not inject a method extractor into
+ // a class becuase FLAG_lazy_dispatchers is set to false during AOT
+ // compilation. Precompiler however does inject method extractors
+ // (see Precompiler::CheckForNewDynamicFunctions). This means that that
+ // lookup for get:m might overlook a method M in subclass and return
+ // get:m (method extractor for M) from a superclass.
+ // For this reason we abort optimization if lookup returns any
+ // artificial functions that can be inserted lazily.
target = instr->ResolveForReceiverClass(cls);
- if (target.IsNull()) {
- // Can't resolve the target. It might be a noSuchMethod,
- // call through getter or closurization.
+ if (target.IsNull() || target.IsMethodExtractor() ||
+ target.IsInvokeFieldDispatcher()) {
single_target = Function::null();
ic_data = ICData::null();
break;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 675351a..a85c3bc 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -878,8 +878,7 @@
// To check that, we compute value & ~object and skip the write barrier
// if the bit is not set. We can't destroy the object.
bic(TMP, value, Operand(object));
- tsti(TMP, Immediate(kNewObjectAlignmentOffset));
- b(no_update, EQ);
+ tbz(no_update, TMP, kNewObjectBitPosition);
}
// Preserves object and value registers.
@@ -888,11 +887,10 @@
Label* no_update) {
// For the value we are only interested in the new/old bit and the tag bit.
// And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
- and_(TMP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
+ and_(TMP, value, Operand(value, LSL, kNewObjectBitPosition));
// And the result with the negated space bit of the object.
bic(TMP, TMP, Operand(object));
- tsti(TMP, Immediate(kNewObjectAlignmentOffset));
- b(no_update, EQ);
+ tbz(no_update, TMP, kNewObjectBitPosition);
}
void Assembler::StoreIntoObjectOffset(Register object,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index af1079b..363261f 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1856,18 +1856,12 @@
void Assembler::StoreIntoObjectFilter(Register object,
Register value,
Label* no_update) {
- // For the value we are only interested in the new/old bit and the tag bit.
- andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
- // Shift the tag bit into the carry.
- shrl(value, Immediate(1));
- // Add the tag bits together, if the value is not a Smi the addition will
- // overflow into the next bit, leaving us with a zero low bit.
- adcl(value, object);
- // Mask out higher, uninteresting bits which were polluted by dest.
- andl(value, Immediate(kObjectAlignment - 1));
- // Compare with the expected bit pattern.
- cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
- kOldObjectAlignmentOffset + kHeapObjectTag));
+ ASSERT(kNewObjectAlignmentOffset == 4);
+ ASSERT(kHeapObjectTag == 1);
+ // Detect value being ...101 and object being ...001.
+ andl(value, Immediate(7));
+ leal(value, Address(value, object, TIMES_2, 9));
+ testl(value, Immediate(0xf));
j(NOT_ZERO, no_update, Assembler::kNearJump);
}
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 74dae8e..123ce31 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1199,18 +1199,12 @@
void Assembler::StoreIntoObjectFilter(Register object,
Register value,
Label* no_update) {
- // For the value we are only interested in the new/old bit and the tag bit.
- andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
- // Shift the tag bit into the carry.
- shrl(value, Immediate(1));
- // Add the tag bits together, if the value is not a Smi the addition will
- // overflow into the next bit, leaving us with a zero low bit.
- adcl(value, object);
- // Mask out higher, uninteresting bits which were polluted by dest.
- andl(value, Immediate(kObjectAlignment - 1));
- // Compare with the expected bit pattern.
- cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
- kOldObjectAlignmentOffset + kHeapObjectTag));
+ ASSERT(kNewObjectAlignmentOffset == 8);
+ ASSERT(kHeapObjectTag == 1);
+ // Detect value being ...1001 and object being ...0001.
+ andl(value, Immediate(0xf));
+ leal(value, Address(value, object, TIMES_2, 0x15));
+ testl(value, Immediate(0x1f));
j(NOT_ZERO, no_update, Assembler::kNearJump);
}
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 5a9e9b0..32d0160 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -406,6 +406,7 @@
RA(Q, movq, 0x8B)
RR(L, movl, 0x8B)
RA(Q, leaq, 0x8D)
+ RA(L, leal, 0x8D)
AR(L, cmpxchgl, 0xB1, 0x0F)
AR(Q, cmpxchgq, 0xB1, 0x0F)
RA(L, cmpxchgl, 0xB1, 0x0F)
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d30b351..35bc55b 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -9207,6 +9207,9 @@
} else if (tag == kField) {
FieldHelper field_helper(this);
field_helper.ReadUntilExcluding(FieldHelper::kEnd);
+ } else if (tag == kClass) {
+ ClassHelper class_helper(this);
+ class_helper.ReadUntilExcluding(ClassHelper::kEnd);
} else {
H.ReportError("Unsupported tag at this point: %d.", tag);
UNREACHABLE();
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 3035c75..9196276 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -322,6 +322,7 @@
enum Flag {
kConst = 1 << 0,
kExternal = 1 << 1,
+ kSyntheticDefault = 1 << 2,
};
explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
@@ -340,6 +341,7 @@
bool IsExternal() { return (flags_ & kExternal) != 0; }
bool IsConst() { return (flags_ & kConst) != 0; }
+ bool IsSyntheticDefault() { return (flags_ & kSyntheticDefault) != 0; }
NameIndex canonical_name_;
TokenPosition position_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index def0b90..9e776f9 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2676,35 +2676,53 @@
if (entry.IsClass()) {
const Class& klass = Class::Cast(entry);
entry_script = klass.script();
- if (!entry_script.IsNull() && script.kernel_script_index() ==
- entry_script.kernel_script_index()) {
+ if (!entry_script.IsNull() &&
+ (script.kernel_script_index() ==
+ entry_script.kernel_script_index()) &&
+ (script.kernel_string_offsets() ==
+ entry_script.kernel_string_offsets())) {
token_positions.Add(klass.token_pos().value());
}
- Array& array = Array::Handle(zone_, klass.fields());
- Field& field = Field::Handle(Z);
- for (intptr_t i = 0; i < array.Length(); ++i) {
- field ^= array.At(i);
- if (field.kernel_offset() <= 0) {
- // Skip artificially injected fields.
- continue;
+ if (klass.is_finalized()) {
+ Array& array = Array::Handle(Z, klass.fields());
+ Field& field = Field::Handle(Z);
+ for (intptr_t i = 0; i < array.Length(); ++i) {
+ field ^= array.At(i);
+ if (field.kernel_offset() <= 0) {
+ // Skip artificially injected fields.
+ continue;
+ }
+ data = field.KernelData();
+ entry_script = field.Script();
+ ProcessTokenPositionsEntry(
+ data, script, entry_script, field.kernel_offset(),
+ field.KernelDataProgramOffset(), Z, &helper, &token_positions,
+ &yield_positions);
}
- data = field.KernelData();
- entry_script = field.Script();
- ProcessTokenPositionsEntry(
- data, script, entry_script, field.kernel_offset(),
- field.KernelDataProgramOffset(), zone_, &helper, &token_positions,
- &yield_positions);
- }
- array = klass.functions();
- Function& function = Function::Handle(Z);
- for (intptr_t i = 0; i < array.Length(); ++i) {
- function ^= array.At(i);
- data = function.KernelData();
- entry_script = function.script();
- ProcessTokenPositionsEntry(
- data, script, entry_script, function.kernel_offset(),
- function.KernelDataProgramOffset(), zone_, &helper,
- &token_positions, &yield_positions);
+ array = klass.functions();
+ Function& function = Function::Handle(Z);
+ for (intptr_t i = 0; i < array.Length(); ++i) {
+ function ^= array.At(i);
+ data = function.KernelData();
+ entry_script = function.script();
+ ProcessTokenPositionsEntry(
+ data, script, entry_script, function.kernel_offset(),
+ function.KernelDataProgramOffset(), Z, &helper,
+ &token_positions, &yield_positions);
+ }
+ } else {
+ // Class isn't finalized yet: read the data attached to it.
+ ASSERT(klass.kernel_offset() > 0);
+ data = lib.kernel_data();
+ ASSERT(!data.IsNull());
+ const intptr_t library_kernel_offset = lib.kernel_offset();
+ ASSERT(library_kernel_offset > 0);
+ const intptr_t class_offset = klass.kernel_offset();
+
+ entry_script = klass.script();
+ ProcessTokenPositionsEntry(data, script, entry_script, class_offset,
+ library_kernel_offset, Z, &helper,
+ &token_positions, &yield_positions);
}
} else if (entry.IsFunction()) {
const Function& function = Function::Cast(entry);
@@ -2712,7 +2730,7 @@
entry_script = function.script();
ProcessTokenPositionsEntry(data, script, entry_script,
function.kernel_offset(),
- function.KernelDataProgramOffset(), zone_,
+ function.KernelDataProgramOffset(), Z,
&helper, &token_positions, &yield_positions);
} else if (entry.IsField()) {
const Field& field = Field::Cast(entry);
@@ -2724,8 +2742,8 @@
entry_script = field.Script();
ProcessTokenPositionsEntry(data, script, entry_script,
field.kernel_offset(),
- field.KernelDataProgramOffset(), zone_,
- &helper, &token_positions, &yield_positions);
+ field.KernelDataProgramOffset(), Z, &helper,
+ &token_positions, &yield_positions);
}
}
}
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 16e5074..7043b36 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -978,7 +978,7 @@
EXPECT_VALID(result);
EXPECT(fits);
- Dart_Handle above_max = Dart_NewIntegerFromHexCString("0x8000000000000000");
+ Dart_Handle above_max = Dart_NewIntegerFromHexCString("0x10000000000000000");
if (FLAG_limit_ints_to_64_bits) {
EXPECT(Dart_IsApiError(above_max));
} else {
@@ -996,7 +996,7 @@
EXPECT_VALID(result);
EXPECT(fits);
- Dart_Handle below_min = Dart_NewIntegerFromHexCString("-0x8000000000000001");
+ Dart_Handle below_min = Dart_NewIntegerFromHexCString("-0x10000000000000001");
if (FLAG_limit_ints_to_64_bits) {
EXPECT(Dart_IsApiError(below_min));
} else {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6a868de..5c508f0 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2827,6 +2827,10 @@
BreakpointLocation* bpt_location = SetBreakpoint(
script, target_function.token_pos(), target_function.end_token_pos(), -1,
-1 /* no requested line/col */);
+ if (bpt_location == NULL) {
+ return NULL;
+ }
+
if (single_shot) {
return bpt_location->AddSingleShot(this);
} else {
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index f74e67a..9b804c7 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -34,6 +34,10 @@
show_kernel_isolate,
false,
"Show Kernel service isolate as normal isolate.");
+DEFINE_FLAG(bool,
+ suppress_fe_warnings,
+ false,
+ "Suppress warnings from the FE.");
const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
@@ -361,6 +365,11 @@
} else {
files.type = Dart_CObject_kNull;
}
+
+ Dart_CObject suppress_warnings;
+ suppress_warnings.type = Dart_CObject_kBool;
+ suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+
Dart_CObject* message_arr[] = {&tag,
&send_port,
&uri,
@@ -368,7 +377,8 @@
&dart_incremental,
&dart_strong,
&isolate_id,
- &files};
+ &files,
+ &suppress_warnings};
message.value.as_array.values = message_arr;
message.value.as_array.length = ARRAY_SIZE(message_arr);
// Send the message.
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 50fa689..5d8388c 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -986,6 +986,10 @@
true, // is_method
false, // is_closure
&function_node_helper);
+ if (constructor_helper.IsSyntheticDefault()) {
+ function.set_is_debuggable(false);
+ }
+
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
constructor_helper.SetJustRead(ConstructorHelper::kFunction);
constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 1e98057..090091d 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3565,16 +3565,37 @@
}
TokenPosition Class::ComputeEndTokenPos() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return TokenPosition::kNoSource;
+#else
// Return the begin token for synthetic classes.
if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) {
return token_pos();
}
- Zone* zone = Thread::Current()->zone();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
const Script& scr = Script::Handle(zone, script());
ASSERT(!scr.IsNull());
if (scr.kind() == RawScript::kKernelTag) {
+ ASSERT(kernel_offset() > 0);
+ const Library& lib = Library::Handle(zone, library());
+ const TypedData& kernel_data = TypedData::Handle(zone, lib.kernel_data());
+ ASSERT(!kernel_data.IsNull());
+ const intptr_t library_kernel_offset = lib.kernel_offset();
+ ASSERT(library_kernel_offset > 0);
+ const intptr_t class_offset = kernel_offset();
+
+ kernel::TranslationHelper helper(thread);
+ helper.InitFromScript(scr);
+ kernel::StreamingFlowGraphBuilder builder_(&helper, scr, zone, kernel_data,
+ 0);
+ builder_.SetOffset(class_offset);
+ kernel::ClassHelper class_helper(&builder_);
+ class_helper.ReadUntilIncluding(kernel::ClassHelper::kEndPosition);
+ if (class_helper.end_position_.IsReal()) return class_helper.end_position_;
+
TokenPosition largest_seen = token_pos();
// Walk through all functions and get their end_tokens to find the classes
@@ -3613,6 +3634,7 @@
}
UNREACHABLE();
return TokenPosition::kNoSource;
+#endif
}
int32_t Class::SourceFingerprint() const {
@@ -3799,13 +3821,19 @@
}
bool Class::IsFutureClass() const {
- return (library() == Library::AsyncLibrary()) &&
- (Name() == Symbols::Future().raw());
+ // Looking up future_class in the object store would not work, because
+ // this function is called during class finalization, before the object store
+ // field would be initialized by InitKnownObjects().
+ return (Name() == Symbols::Future().raw()) &&
+ (library() == Library::AsyncLibrary());
}
bool Class::IsFutureOrClass() const {
- return (library() == Library::AsyncLibrary()) &&
- (Name() == Symbols::FutureOr().raw());
+ // Looking up future_or_class in the object store would not work, because
+ // this function is called during class finalization, before the object store
+ // field would be initialized by InitKnownObjects().
+ return (Name() == Symbols::FutureOr().raw()) &&
+ (library() == Library::AsyncLibrary());
}
// If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T.
@@ -3829,10 +3857,10 @@
Isolate* isolate = thread->isolate();
Class& this_class = Class::Handle(zone, cls.raw());
while (true) {
- // Check for DynamicType.
// Each occurrence of DynamicType in type T is interpreted as the dynamic
- // type, a supertype of all types.
- if (other.IsDynamicClass()) {
+ // type, a supertype of all types. So are Object and void types.
+ if (other.IsDynamicClass() || other.IsObjectClass() ||
+ other.IsVoidClass()) {
return true;
}
// Check for NullType, which, as of Dart 1.5, is a subtype of (and is more
@@ -3858,11 +3886,6 @@
if (this_class.IsDynamicClass()) {
return !isolate->strong() && (test_kind == Class::kIsSubtypeOf);
}
- // Check for ObjectType. Any type that is not NullType or DynamicType
- // (already checked above), is more specific than ObjectType/VoidType.
- if (other.IsObjectClass() || other.IsVoidClass()) {
- return true;
- }
// If other is neither Object, dynamic or void, then ObjectType/VoidType
// can't be a subtype of other.
if (this_class.IsObjectClass() || this_class.IsVoidClass()) {
@@ -3880,7 +3903,7 @@
// below), we only check a subvector of the proper length.
// Check for covariance.
if (other_type_arguments.IsNull() ||
- other_type_arguments.IsRaw(from_index, num_type_params)) {
+ other_type_arguments.IsTopTypes(from_index, num_type_params)) {
return true;
}
if (type_arguments.IsNull() ||
@@ -4003,8 +4026,7 @@
}
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
- if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
- other_type_arg.IsVoidType()) {
+ if (other_type_arg.IsTopType()) {
return true;
}
if (!type_arguments.IsNull() && IsFutureClass()) {
@@ -4776,6 +4798,18 @@
return true;
}
+bool TypeArguments::IsTopTypes(intptr_t from_index, intptr_t len) const {
+ ASSERT(Length() >= (from_index + len));
+ AbstractType& type = AbstractType::Handle();
+ for (intptr_t i = 0; i < len; i++) {
+ type = TypeAt(from_index + i);
+ if (type.IsNull() || !type.IsTopType()) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool TypeArguments::TypeTest(TypeTestKind test_kind,
const TypeArguments& other,
intptr_t from_index,
@@ -6587,7 +6621,7 @@
if (Isolate::Current()->strong()) {
const AbstractType& param_type =
AbstractType::Handle(ParameterTypeAt(parameter_position));
- if (param_type.IsDynamicType()) {
+ if (param_type.IsTopType()) {
return true;
}
const AbstractType& other_param_type =
@@ -6687,14 +6721,20 @@
// Check the result type.
const AbstractType& other_res_type =
AbstractType::Handle(zone, other.result_type());
- if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
- const AbstractType& res_type = AbstractType::Handle(zone, result_type());
- if (isolate->strong()) {
+ if (isolate->strong()) {
+ // In strong mode, 'void Function()' is a subtype of 'Object Function()'.
+ if (!other_res_type.IsTopType()) {
+ const AbstractType& res_type = AbstractType::Handle(zone, result_type());
if (!res_type.IsSubtypeOf(other_res_type, bound_error, bound_trail,
space)) {
return false;
}
- } else {
+ }
+ } else {
+ // In Dart 1.0, 'void Function()' is not a subtype of 'Object Function()',
+ // but it is a subtype of 'dynamic Function()' and of 'void Function()'.
+ if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
+ const AbstractType& res_type = AbstractType::Handle(zone, result_type());
if (res_type.IsVoidType()) {
return false;
}
@@ -11521,7 +11561,7 @@
lib_url = lib.url();
map.InsertNewOrGetValue(lib_url, lib);
}
- // Now rememeber these in the isolate's object store.
+ // Now remember these in the isolate's object store.
isolate->object_store()->set_libraries(libs);
isolate->object_store()->set_libraries_map(map.Release());
}
@@ -15737,7 +15777,7 @@
Isolate* isolate = thread->isolate();
const Class& cls = Class::Handle(zone, clazz());
if (cls.IsClosureClass()) {
- if (other.IsObjectType() || other.IsDartFunctionType() ||
+ if (other.IsTopType() || other.IsDartFunctionType() ||
other.IsDartClosureType()) {
return true;
}
@@ -15754,9 +15794,7 @@
if (instantiated_other.IsTypeRef()) {
instantiated_other = TypeRef::Cast(instantiated_other).type();
}
- if (instantiated_other.IsDynamicType() ||
- instantiated_other.IsObjectType() ||
- instantiated_other.IsVoidType() ||
+ if (instantiated_other.IsTopType() ||
instantiated_other.IsDartFunctionType()) {
return true;
}
@@ -15812,8 +15850,7 @@
if (instantiated_other.IsTypeRef()) {
instantiated_other = TypeRef::Cast(instantiated_other).type();
}
- if (instantiated_other.IsDynamicType() ||
- instantiated_other.IsObjectType() || instantiated_other.IsVoidType()) {
+ if (instantiated_other.IsTopType()) {
return true;
}
}
@@ -15877,8 +15914,7 @@
TypeArguments::Handle(zone, other.arguments());
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
- if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
- other_type_arg.IsVoidType()) {
+ if (other_type_arg.IsTopType()) {
return true;
}
if (Class::Handle(zone, clazz()).IsFutureClass()) {
@@ -16448,76 +16484,93 @@
if (IsCanonical()) {
return raw() == Object::dynamic_type().raw();
}
- return HasResolvedTypeClass() && (type_class() == Object::dynamic_class());
+ return HasResolvedTypeClass() && (type_class_id() == kDynamicCid);
}
bool AbstractType::IsVoidType() const {
+ // The void type is always canonical, because void is a keyword.
return raw() == Object::void_type().raw();
}
+bool AbstractType::IsObjectType() const {
+ return HasResolvedTypeClass() && (type_class_id() == kInstanceCid);
+}
+
+bool AbstractType::IsTopType() const {
+ if (IsVoidType()) {
+ return true;
+ }
+ if (!HasResolvedTypeClass()) {
+ return false;
+ }
+ classid_t cid = type_class_id();
+ return (cid == kDynamicCid) || (cid == kInstanceCid);
+}
+
bool AbstractType::IsNullType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
- (type_class() == Isolate::Current()->object_store()->null_class());
+ return HasResolvedTypeClass() && (type_class_id() == kNullCid);
}
bool AbstractType::IsBoolType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
- (type_class() == Isolate::Current()->object_store()->bool_class());
+ return HasResolvedTypeClass() && (type_class_id() == kBoolCid);
}
bool AbstractType::IsIntType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::IntType()).type_class());
}
bool AbstractType::IsInt64Type() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::Int64Type()).type_class());
}
bool AbstractType::IsDoubleType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::Double()).type_class());
}
bool AbstractType::IsFloat32x4Type() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ // kFloat32x4Cid refers to the private class and cannot be used here.
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::Float32x4()).type_class());
}
bool AbstractType::IsFloat64x2Type() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ // kFloat64x2Cid refers to the private class and cannot be used here.
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::Float64x2()).type_class());
}
bool AbstractType::IsInt32x4Type() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ // kInt32x4Cid refers to the private class and cannot be used here.
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::Int32x4()).type_class());
}
bool AbstractType::IsNumberType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
- (type_class() == Type::Handle(Type::Number()).type_class());
+ return HasResolvedTypeClass() && (type_class_id() == kNumberCid);
}
bool AbstractType::IsSmiType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
- (type_class() == Type::Handle(Type::SmiType()).type_class());
+ return HasResolvedTypeClass() && (type_class_id() == kSmiCid);
}
bool AbstractType::IsStringType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::StringType()).type_class());
}
bool AbstractType::IsDartFunctionType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
+ return HasResolvedTypeClass() &&
(type_class() == Type::Handle(Type::DartFunctionType()).type_class());
}
bool AbstractType::IsDartClosureType() const {
+ // Non-typedef function types have '_Closure' class as type class, but are not
+ // the Dart '_Closure' type.
return !IsFunctionType() && HasResolvedTypeClass() &&
- (type_class() == Isolate::Current()->object_store()->closure_class());
+ (type_class_id() == kClosureCid);
}
bool AbstractType::TypeTest(TypeTestKind test_kind,
@@ -16558,8 +16611,7 @@
// comparing function-types).
// As of Dart 1.5, the Null type is a subtype of (and is more specific than)
// any type.
- if (other.IsObjectType() || other.IsDynamicType() || other.IsVoidType() ||
- IsNullType()) {
+ if (other.IsTopType() || IsNullType()) {
return true;
}
Thread* thread = Thread::Current();
@@ -16724,8 +16776,7 @@
TypeArguments::Handle(zone, other.arguments());
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
- if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
- other_type_arg.IsVoidType()) {
+ if (other_type_arg.IsTopType()) {
return true;
}
// Retry the TypeTest function after unwrapping type arg of FutureOr.
@@ -17105,7 +17156,7 @@
if (IsMalbounded() != other_type.IsMalbounded()) {
return false; // Do not drop bound error.
}
- if (type_class() != other_type.type_class()) {
+ if (type_class_id() != other_type.type_class_id()) {
return false;
}
if (!IsFinalized() || !other_type.IsFinalized()) {
@@ -17413,13 +17464,11 @@
// Since void is a keyword, we never have to canonicalize the void type after
// it is canonicalized once by the vm isolate. The parser does the mapping.
- ASSERT((type_class() != Object::void_class()) ||
- (isolate == Dart::vm_isolate()));
+ ASSERT((type_class_id() != kVoidCid) || (isolate == Dart::vm_isolate()));
// Since dynamic is not a keyword, the parser builds a type that requires
// canonicalization.
- if ((type_class() == Object::dynamic_class()) &&
- (isolate != Dart::vm_isolate())) {
+ if ((type_class_id() == kDynamicCid) && (isolate != Dart::vm_isolate())) {
ASSERT(Object::dynamic_type().IsCanonical());
return Object::dynamic_type().raw();
}
@@ -17527,7 +17576,7 @@
if (IsMalformed() || IsRecursive()) {
return true;
}
- if (type_class() == Object::dynamic_class()) {
+ if (type_class_id() == kDynamicCid) {
return (raw() == Object::dynamic_type().raw());
}
Zone* zone = thread->zone();
@@ -17593,7 +17642,7 @@
ASSERT(IsFinalized());
uint32_t result = 1;
if (IsMalformed()) return result;
- result = CombineHashes(result, Class::Handle(type_class()).id());
+ result = CombineHashes(result, type_class_id());
result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash());
if (IsFunctionType()) {
const Function& sig_fun = Function::Handle(signature());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 9da8f8c..5b9fdea 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5665,6 +5665,11 @@
return IsDynamicTypes(true, 0, len);
}
+ // Check if the subvector of length 'len' starting at 'from_index' of this
+ // type argument vector consists solely of DynamicType, ObjectType, or
+ // VoidType.
+ bool IsTopTypes(intptr_t from_index, intptr_t len) const;
+
// Check the subtype relationship, considering only a subvector of length
// 'len' starting at 'from_index'.
bool IsSubtypeOf(const TypeArguments& other,
@@ -5985,10 +5990,12 @@
// Check if this type represents the 'Null' type.
bool IsNullType() const;
- bool IsObjectType() const {
- return !IsFunctionType() && HasResolvedTypeClass() &&
- Class::Handle(type_class()).IsObjectClass();
- }
+ // Check if this type represents the 'Object' type.
+ bool IsObjectType() const;
+
+ // Check if this type represents a top type, i.e. 'dynamic', 'Object', or
+ // 'void' type.
+ bool IsTopType() const;
// Check if this type represents the 'bool' type.
bool IsBoolType() const;
@@ -6265,6 +6272,9 @@
}
RawAbstractType* type() const { return raw_ptr()->type_; }
void set_type(const AbstractType& value) const;
+ virtual classid_t type_class_id() const {
+ return AbstractType::Handle(type()).type_class_id();
+ }
virtual RawClass* type_class() const {
return AbstractType::Handle(type()).type_class();
}
@@ -6440,6 +6450,9 @@
virtual bool HasResolvedTypeClass() const {
return AbstractType::Handle(type()).HasResolvedTypeClass();
}
+ virtual classid_t type_class_id() const {
+ return AbstractType::Handle(type()).type_class_id();
+ }
virtual RawClass* type_class() const {
return AbstractType::Handle(type()).type_class();
}
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index becd0b8..4c030df 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -8,14 +8,20 @@
#include "vm/os.h"
#include <errno.h>
+#include <fdio/util.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>
+#include "lib/app/cpp/environment_services.h"
+#include "lib/time_service/fidl/time_service.fidl.h"
+
#include "platform/assert.h"
#include "vm/zone.h"
+static constexpr char kTimeServiceName[] = "time_service::TimeService";
+
namespace dart {
#ifndef PRODUCT
@@ -35,36 +41,53 @@
return static_cast<intptr_t>(getpid());
}
-static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
- time_t seconds = static_cast<time_t>(seconds_since_epoch);
- if (seconds != seconds_since_epoch) {
- return false;
+static zx_status_t GetTimeServicePtr(
+ time_service::TimeServiceSyncPtr* time_svc) {
+ zx::channel service_root = app::subtle::CreateStaticServiceRootHandle();
+ zx::channel time_svc_channel = GetSynchronousProxy(time_svc).PassChannel();
+ return fdio_service_connect_at(service_root.get(), kTimeServiceName,
+ time_svc_channel.release());
+}
+
+static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
+ int32_t* local_offset,
+ int32_t* dst_offset) {
+ time_service::TimeServiceSyncPtr time_svc;
+ zx_status_t status = GetTimeServicePtr(&time_svc);
+ if (status == ZX_OK) {
+ time_svc->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000, local_offset,
+ dst_offset);
+ *local_offset *= 60;
+ *dst_offset *= 60;
}
- struct tm* error_code = localtime_r(&seconds, tm_result);
- return error_code != NULL;
+ return status;
}
const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
- tm decomposed;
- bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
- // If unsuccessful, return an empty string like V8 does.
- return (succeeded && (decomposed.tm_zone != NULL)) ? decomposed.tm_zone : "";
+ time_service::TimeServiceSyncPtr time_svc;
+ if (GetTimeServicePtr(&time_svc) == ZX_OK) {
+ fidl::String res;
+ time_svc->GetTimezoneId(&res);
+ char* tz_name = Thread::Current()->zone()->Alloc<char>(res.size() + 1);
+ memmove(tz_name, res.get().c_str(), res.size());
+ tz_name[res.size()] = '\0';
+ return tz_name;
+ }
+ return "";
}
int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
- tm decomposed;
- bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
- // Even if the offset was 24 hours it would still easily fit into 32 bits.
- // If unsuccessful, return zero like V8 does.
- return succeeded ? static_cast<int>(decomposed.tm_gmtoff) : 0;
+ int32_t local_offset, dst_offset;
+ zx_status_t status = GetLocalAndDstOffsetInSeconds(
+ seconds_since_epoch, &local_offset, &dst_offset);
+ return status == ZX_OK ? local_offset + dst_offset : 0;
}
int OS::GetLocalTimeZoneAdjustmentInSeconds() {
- // TODO(floitsch): avoid excessive calls to tzset?
- tzset();
- // Even if the offset was 24 hours it would still easily fit into 32 bits.
- // Note that Unix and Dart disagree on the sign.
- return static_cast<int>(-timezone);
+ int32_t local_offset, dst_offset;
+ zx_status_t status = GetLocalAndDstOffsetInSeconds(
+ zx_time_get(ZX_CLOCK_UTC) / ZX_SEC(1), &local_offset, &dst_offset);
+ return status == ZX_OK ? local_offset : 0;
}
int64_t OS::GetCurrentTimeMillis() {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index e2bcab8..da39187 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -223,6 +223,7 @@
// Alignment offsets are used to determine object age.
kNewObjectAlignmentOffset = kWordSize,
kOldObjectAlignmentOffset = 0,
+ kNewObjectBitPosition = kWordSizeLog2,
// Object sizes are aligned to kObjectAlignment.
kObjectAlignment = 2 * kWordSize,
kObjectAlignmentLog2 = kWordSizeLog2 + 1,
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 7d21d3d..0a0dd08 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -44,7 +44,7 @@
# ........dartfmt.dart.snapshot
# ........dartdevc.dart.snapshot
# ........dartdevk.dart.snapshot
-# ........front_end_worker.dart.snapshot
+# ........kernel_summary_worker.dart.snapshot
# ........pub.dart.snapshot
# ........utils_wrapper.dart.snapshot
#.........resources/
@@ -163,8 +163,8 @@
"../utils/dartfmt",
],
[
- "front_end_worker",
- "../utils/front_end:front_end_worker",
+ "kernel_summary_worker",
+ "../utils/bazel:kernel_summary_worker",
],
[
"pub",
@@ -315,50 +315,58 @@
}
# Copies the Dart VM binary into bin/
-copy("copy_dart") {
- visibility = [ ":create_common_sdk" ]
- deps = [
- "../runtime/bin:dart",
- ]
- dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
- if (is_win) {
- sources = [
- "$dart_out/dart.exe",
+if (is_fuchsia_host) {
+ # In the Fuchsia build, this has to use a symlink for two reasons.
+ # First, it makes the lookup of shared libraries relative to $ORIGIN
+ # (Linux) or @loader_path (macOS) find the libraries where they are,
+ # since those lookups use the directory of the symlink target rather
+ # than of the link itself (as they would for a copy or hard link).
+ # Second, when the dart binary is built as a "variant" (e.g. with a
+ # sanitizer), then $root_out_dir/dart is itself a symlink to the real
+ # binary in the selected variant toolchain's $root_out_dir and since
+ # the "copy" tool is actually a hard link rather than a copy, it will
+ # make a link to the symlink rather than the symlink's target, and the
+ # relative symlink interpreted from a different containing directory
+ # will not find the actual binary.
+ action("copy_dart") {
+ visibility = [ ":create_common_sdk" ]
+ dart_label = "../runtime/bin:dart"
+ deps = [
+ dart_label,
]
- } else {
+ dart_out = get_label_info(dart_label, "root_out_dir")
sources = [
"$dart_out/$dart_stripped_binary",
]
+ outputs = [
+ "$root_out_dir/dart-sdk/bin/$dart_stripped_binary",
+ ]
+ script = "/bin/ln"
+ args = [
+ "-snf",
+ rebase_path(sources[0], get_path_info(outputs[0], "dir")),
+ rebase_path(outputs[0]),
+ ]
}
- if (is_win) {
- sources += [ "$dart_out/dart.lib" ]
- }
- outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
- ]
-}
-
-# Copies dynamically linked libraries into bin/. This is currently only needed
-# for Fuchsia when building for Linux hosts.
-if (is_fuchsia_host && is_linux) {
- copy("copy_dylibs") {
+} else {
+ copy("copy_dart") {
visibility = [ ":create_common_sdk" ]
deps = [
- "//third_party/boringssl:crypto",
- "//third_party/boringssl:ssl",
- "//third_party/zlib",
+ "../runtime/bin:dart",
]
- crypto_out =
- get_label_info("//third_party/boringssl:crypto", "root_out_dir")
- crypto_name = get_label_info("//third_party/boringssl:crypto", "name")
- ssl_out = get_label_info("//third_party/boringssl:ssl", "root_out_dir")
- ssl_name = get_label_info("//third_party/boringssl:ssl", "name")
- zlib_out = get_label_info("//third_party/zlib", "root_out_dir")
- sources = [
- "$crypto_out/lib${crypto_name}.so",
- "$ssl_out/lib${ssl_name}.so",
- "$zlib_out/libz.so",
- ]
+ dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
+ if (is_win) {
+ sources = [
+ "$dart_out/dart.exe",
+ ]
+ } else {
+ sources = [
+ "$dart_out/$dart_stripped_binary",
+ ]
+ }
+ if (is_win) {
+ sources += [ "$dart_out/dart.lib" ]
+ }
outputs = [
"$root_out_dir/dart-sdk/bin/{{source_file_part}}",
]
@@ -557,8 +565,8 @@
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
- "$gen_dir/ddc_sdk.sum",
"$gen_dir/ddc_sdk.dill",
+ "$gen_dir/ddc_sdk.sum",
]
outputs = [
"$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
@@ -830,22 +838,19 @@
":copy_api_readme",
":copy_dart",
":copy_dartdoc_files",
- ":copy_vm_dill_files",
":copy_headers",
":copy_libraries_dart",
":copy_license",
":copy_platform_files",
":copy_pub_assets",
":copy_readme",
+ ":copy_vm_dill_files",
":write_revision_file",
":write_version_file",
]
if (is_win) {
deps += [ ":copy_7zip" ]
}
- if (is_fuchsia_host && is_linux) {
- deps += [ ":copy_dylibs" ]
- }
}
# Parts specific to the platform SDK.
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index a0d0bc8..b2603af 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -95,14 +95,6 @@
'returns:bool;effects:none;depends:none', JsBuiltin.isFunctionType, type);
}
-/// Creates a function type object.
-// TODO(floitsch): move this to foreign_helper.dart or similar.
-@ForceInline()
-createDartFunctionTypeRti() {
- return JS_BUILTIN('returns:=Object;effects:none;depends:none',
- JsBuiltin.createFunctionTypeRti);
-}
-
/// Retrieves the class name from type information stored on the constructor of
/// [type].
// TODO(floitsch): move this to foreign_helper.dart or similar.
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 2fff7ec..5b40739 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -387,11 +387,6 @@
/// JS_BUILTIN('bool', JsBuiltin.isFunctionType, o)
isFunctionType,
- /// Returns a new function type object.
- ///
- /// JS_BUILTIN('=Object', JsBuiltin.createFunctionType)
- createFunctionTypeRti,
-
/// Returns the JavaScript-constructor name given an rti encoding.
///
/// JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti)
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 09a775c..0eb0458 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -30324,8 +30324,8 @@
var completer = new Completer();
_setLocalDescription(description, () {
completer.complete();
- }, (error) {
- completer.completeError(error);
+ }, (exception) {
+ completer.completeError(exception);
});
return completer.future;
}
@@ -30344,8 +30344,8 @@
var completer = new Completer();
_setRemoteDescription(description, () {
completer.complete();
- }, (error) {
- completer.completeError(error);
+ }, (exception) {
+ completer.completeError(exception);
});
return completer.future;
}
@@ -37965,6 +37965,8 @@
@DocsEditable()
void _moveTo(int x, int y) native;
+ @JSName('openDatabase')
+
/// *Deprecated.*
@DomName('Window.openDatabase')
@DocsEditable()
@@ -37974,7 +37976,7 @@
// http://www.w3.org/TR/webdatabase/
@Experimental() // deprecated
@Creates('SqlDatabase')
- SqlDatabase openDatabase(
+ SqlDatabase _openDatabase(
String name, String version, String displayName, int estimatedSize,
[DatabaseCallback creationCallback]) native;
@@ -38921,6 +38923,28 @@
_moveTo(p.x, p.y);
}
+ @JSName('openDatabase')
+ @DomName('Window.openDatabase')
+ @DocsEditable()
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental()
+ @Creates('SqlDatabase')
+ SqlDatabase openDatabase(
+ String name, String version, String displayName, int estimatedSize,
+ [DatabaseCallback creationCallback]) {
+ var db;
+ if (creationCallback == null)
+ db = _openDatabase(name, version, displayName, estimatedSize);
+ else
+ db = _openDatabase(
+ name, version, displayName, estimatedSize, creationCallback);
+
+ applyExtension('Database', db);
+
+ return db;
+ }
+
@DomName('Window.pageXOffset')
@DocsEditable()
int get pageXOffset => JS('num', '#.pageXOffset', this).round();
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 69af259..9a84406 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -23,6 +23,7 @@
import 'dart:_js_helper'
show
+ applyExtension,
convertDartClosureToJS,
Creates,
JSName,
@@ -128,6 +129,20 @@
void transaction(SqlTransactionCallback callback,
[SqlTransactionErrorCallback errorCallback,
VoidCallback successCallback]) native;
+
+ @JSName('transaction')
+ @DomName('Database.transaction')
+ @DocsEditable()
+ Future<SqlTransaction> transaction_future() {
+ var completer = new Completer<SqlTransaction>();
+ transaction((value) {
+ applyExtension('SQLTransaction', value);
+ completer.complete(value);
+ }, (error) {
+ completer.completeError(error);
+ });
+ return completer.future;
+ }
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -304,10 +319,26 @@
throw new UnsupportedError("Not supported");
}
+ @JSName('executeSql')
@DomName('SQLTransaction.executeSql')
@DocsEditable()
- void executeSql(String sqlStatement,
+ void _executeSql(String sqlStatement,
[List arguments,
SqlStatementCallback callback,
SqlStatementErrorCallback errorCallback]) native;
+
+ @JSName('executeSql')
+ @DomName('SQLTransaction.executeSql')
+ @DocsEditable()
+ Future<SqlResultSet> executeSql(String sqlStatement, [List arguments]) {
+ var completer = new Completer<SqlResultSet>();
+ _executeSql(sqlStatement, arguments, (transaction, resultSet) {
+ applyExtension('SQLResultSet', resultSet);
+ applyExtension('SQLResultSetRowList', resultSet.rows);
+ completer.complete(resultSet);
+ }, (transaction, error) {
+ completer.completeError(error);
+ });
+ return completer.future;
+ }
}
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
similarity index 100%
rename from tests/compiler/dart2js/async_await_js_transform_test.dart
rename to tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
diff --git a/tests/compiler/dart2js/class_codegen_test.dart b/tests/compiler/dart2js/class_codegen_test.dart
deleted file mode 100644
index d744468..0000000
--- a/tests/compiler/dart2js/class_codegen_test.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Test that parameters keep their names in the output.
-
-import "package:expect/expect.dart";
-import "package:async_helper/async_helper.dart";
-import 'compiler_helper.dart';
-
-const String TEST_ONE = r"""
-class A { }
-class B { }
-
-main() {
- new A();
- new B();
-}
-""";
-
-const String TEST_TWO = r"""
-class A { }
-class B extends A { }
-
-main() {
- new A();
- new B();
-}
-""";
-
-const String TEST_THREE = r"""
-class B extends A { }
-class A { }
-
-main() {
- new B();
- new A();
-}
-""";
-
-const String TEST_FOUR = r"""
-class A {
- var x;
-}
-
-class B extends A {
- var y;
- var z;
-}
-
-main() {
- new B();
-}
-""";
-
-const String TEST_FIVE = r"""
-class A {
- var a;
- A(a) : this.a = a {}
-}
-
-main() {
- new A(3);
-}
-""";
-
-twoClasses() {
- asyncTest(() => compileAll(TEST_ONE).then((generated) {
- Expect.isTrue(
- generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"')));
- Expect.isTrue(
- generated.contains(new RegExp('B: {[ \n]*"\\^": "Object;"')));
- }));
-}
-
-subClass() {
- checkOutput(String generated) {
- Expect.isTrue(generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"')));
- Expect.isTrue(generated.contains(new RegExp('B: {[ \n]*"\\^": "A;"')));
- }
-
- asyncTest(() => compileAll(TEST_TWO).then(checkOutput));
- asyncTest(() => compileAll(TEST_THREE).then(checkOutput));
-}
-
-fieldTest() {
- asyncTest(() => compileAll(TEST_FOUR).then((generated) {
- Expect.isTrue(generated
- .contains(new RegExp('B: {[ \n]*"\\^": "A;y,z,x",[ \n]*static:')));
- }));
-}
-
-constructor1() {
- asyncTest(() => compileAll(TEST_FIVE).then((generated) {
- Expect.isTrue(generated.contains(new RegExp(r"new [$A-Z]+\.A\(a\);")));
- }));
-}
-
-main() {
- twoClasses();
- subClass();
- fieldTest();
- constructor1();
-}
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index 8a9fe87..6f446e6 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -17,7 +17,9 @@
void main() {
asyncTest(() async {
+ print('--test from ast---------------------------------------------------');
await testAll(CompileMode.memory);
+ print('--test from kernel------------------------------------------------');
await testAll(CompileMode.kernel);
});
}
diff --git a/tests/compiler/dart2js/closure_codegen_test.dart b/tests/compiler/dart2js/closure_codegen_test.dart
deleted file mode 100644
index 6f947e6..0000000
--- a/tests/compiler/dart2js/closure_codegen_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Test that parameters keep their names in the output.
-
-import 'dart:async';
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
-
-const String TEST_INVOCATION0 = r"""
-main() {
- var o = null;
- o();
-}
-""";
-
-const String TEST_INVOCATION1 = r"""
-main() {
- var o = null;
- o(1);
-}
-""";
-
-const String TEST_INVOCATION2 = r"""
-main() {
- var o = null;
- o(1, 2);
-}
-""";
-
-const String TEST_BAILOUT = r"""
-class A {
- var x;
- foo(_) { // make sure only g has no arguments
- var f = () { return 499; };
- return 499 + x + f();
- }
-}
-
-main() { new A().foo(1); }
-""";
-
-Future closureInvocation(bool minify, String prefix) {
- return Future.wait([
- compile(TEST_INVOCATION0, minify: minify, check: (String generated) {
- Expect.isTrue(generated.contains(".$prefix\$0()"));
- }),
- compile(TEST_INVOCATION1, minify: minify, check: (String generated) {
- Expect.isTrue(generated.contains(".$prefix\$1(1)"));
- }),
- compile(TEST_INVOCATION2, minify: minify, check: (String generated) {
- Expect.isTrue(generated.contains(".$prefix\$2(1,${minify ? "" : " "}2)"));
- })
- ]);
-}
-
-// Make sure that the bailout version does not introduce a second version of
-// the closure.
-Future closureBailout(bool minify, String prefix) {
- return compileAll(TEST_BAILOUT, minify: minify).then((generated) {
- RegExp regexp = new RegExp("$prefix\\\$0:${minify ? "" : " "}function");
- Iterator<Match> matches = regexp.allMatches(generated).iterator;
- checkNumberOfMatches(matches, 1);
- });
-}
-
-main() {
- asyncTest(() => Future.wait([
- closureInvocation(false, "call"),
- closureInvocation(true, ""),
- closureBailout(false, "call"),
- closureBailout(true, ""),
- ]));
-}
diff --git a/tests/compiler/dart2js/closure_tracer_28919_test.dart b/tests/compiler/dart2js/closure_tracer_28919_test.dart
deleted file mode 100644
index 122ba8b..0000000
--- a/tests/compiler/dart2js/closure_tracer_28919_test.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-
-import 'compiler_helper.dart';
-import 'type_mask_test_helper.dart';
-import 'package:compiler/src/types/types.dart';
-
-bool isContainer(TypeMask mask) {
- return mask is ContainerTypeMask;
-}
-
-const String TEST = '''
-
-foo1() {
- final methods = [];
- var res, sum;
- for (int i = 0; i != 3; i++) {
- methods.add((int x) { res = x; sum = x + i; });
- }
- methods[0](499);
- probe1res(res);
- probe1sum(sum);
- probe1methods(methods);
-}
-probe1res(x) => x;
-probe1sum(x) => x;
-probe1methods(x) => x;
-
-nonContainer(choice) {
- var m = choice == 0 ? [] : "<String>";
- if (m is !List) throw 123;
- // The union then filter leaves us with a non-container type.
- return m;
-}
-
-foo2(int choice) {
- final methods = nonContainer(choice);
- var res, sum;
- for (int i = 0; i != 3; i++) {
- methods.add((int x) { res = x; sum = x + i; });
- }
- methods[0](499);
- probe2res(res);
- probe2methods(methods);
-}
-probe2res(x) => x;
-probe2methods(x) => x;
-
-main() {
- foo1();
- foo2(0);
- foo2(1);
-}
-''';
-
-void main() {
- Uri uri = new Uri(scheme: 'source');
- var compiler = compilerFor(TEST, uri);
- asyncTest(() => compiler.run(uri).then((_) {
- var typesInferrer = compiler.globalInference.typesInferrerInternal;
- var closedWorld = typesInferrer.closedWorld;
- var commonMasks = closedWorld.commonMasks;
-
- typeOf(String name) {
- MemberElement member = findElement(compiler, name);
- return typesInferrer.getReturnTypeOfMember(member);
- }
-
- checkType(String name, type) {
- var mask = typeOf(name);
- Expect.equals(type.nullable(), simplify(mask, closedWorld), name);
- }
-
- checkContainer(String name, bool value) {
- var mask = typeOf(name);
- Expect.equals(
- value, isContainer(mask), '$name is container (mask: $mask)');
- }
-
- checkContainer('probe1methods', true);
- checkType('probe1res', commonMasks.uint31Type);
- checkType('probe1sum', commonMasks.positiveIntType);
-
- checkContainer('probe2methods', false);
- checkType('probe2res', commonMasks.dynamicType);
- }));
-}
diff --git a/tests/compiler/dart2js/code_motion_test.dart b/tests/compiler/dart2js/code_motion_test.dart
deleted file mode 100644
index 69f1800..0000000
--- a/tests/compiler/dart2js/code_motion_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
-
-const String TEST_ONE = r"""
-foo(int a, int b, bool param2) {
- // Make sure a and b become numbers.
- var c = a - b;
- for (int i = 0; i < 1; i++) {
- if (param2) {
- print(a + b);
- } else {
- print(a + b);
- }
- }
- return c;
-}
-""";
-
-main() {
- asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) {
- RegExp regexp = new RegExp('a \\+ b');
- Iterator matches = regexp.allMatches(generated).iterator;
- Expect.isTrue(matches.moveNext());
- Expect.isFalse(matches.moveNext());
- }));
-}
diff --git a/tests/compiler/dart2js/arithmetic_simplification_test.dart b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
similarity index 83%
rename from tests/compiler/dart2js/arithmetic_simplification_test.dart
rename to tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
index 6c2d57d..f213526 100644
--- a/tests/compiler/dart2js/arithmetic_simplification_test.dart
+++ b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
@@ -4,7 +4,7 @@
// Test constant folding on numbers.
import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
+import '../compiler_helper.dart';
const String INT_PLUS_ZERO = """
int foo(x) => x;
@@ -78,29 +78,29 @@
var timesOne = new RegExp(r"\* 1");
var oneTimes = new RegExp(r"1 \*");
- test(CompileMode compileMode) async {
+ test({bool useKernel}) async {
await compileAndDoNotMatch(INT_PLUS_ZERO, 'main', plusZero,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndDoNotMatch(ZERO_PLUS_INT, 'main', zeroPlus,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndMatch(NUM_PLUS_ZERO, 'main', plusZero,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndMatch(ZERO_PLUS_NUM, 'main', zeroPlus,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndDoNotMatch(INT_TIMES_ONE, 'main', timesOne,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndDoNotMatch(ONE_TIMES_INT, 'main', oneTimes,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndDoNotMatch(NUM_TIMES_ONE, 'main', timesOne,
- compileMode: compileMode);
+ useKernel: useKernel);
await compileAndDoNotMatch(ONE_TIMES_NUM, 'main', oneTimes,
- compileMode: compileMode);
+ useKernel: useKernel);
}
asyncTest(() async {
print('--test from ast---------------------------------------------------');
- await test(CompileMode.memory);
+ await test(useKernel: false);
print('--test from kernel------------------------------------------------');
- await test(CompileMode.kernel);
+ await test(useKernel: true);
});
}
diff --git a/tests/compiler/dart2js/array_static_intercept_test.dart b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
similarity index 80%
rename from tests/compiler/dart2js/array_static_intercept_test.dart
rename to tests/compiler/dart2js/codegen/array_static_intercept_test.dart
index 0ad768d..95bddad 100644
--- a/tests/compiler/dart2js/array_static_intercept_test.dart
+++ b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
@@ -4,7 +4,7 @@
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
+import '../compiler_helper.dart';
const String TEST_ONE = r"""
foo(a) {
@@ -15,8 +15,8 @@
""";
main() {
- test(CompileMode compileMode) async {
- await compile(TEST_ONE, entry: 'foo', compileMode: compileMode,
+ test({bool useKernel}) async {
+ await compile(TEST_ONE, entry: 'foo', useKernel: useKernel,
check: (String generated) {
Expect.isTrue(generated.contains(r'.add$1('));