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(')); Expect.isTrue(generated.contains(r'.removeLast$0(')); @@ -27,8 +27,8 @@ 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/boolify_test.dart b/tests/compiler/dart2js/codegen/boolify_test.dart similarity index 77% rename from tests/compiler/dart2js/boolify_test.dart rename to tests/compiler/dart2js/codegen/boolify_test.dart index fb382cb..afaefc5 100644 --- a/tests/compiler/dart2js/boolify_test.dart +++ b/tests/compiler/dart2js/codegen/boolify_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = r""" foo() { @@ -17,8 +17,8 @@ """; main() { - test(CompileMode compileMode) async { - await compile(TEST, entry: 'foo', compileMode: compileMode, + test({bool useKernel}) async { + await compile(TEST, entry: 'foo', useKernel: useKernel, check: (String generated) { Expect.isTrue(generated.contains('foo() !== true)')); }); @@ -26,8 +26,8 @@ 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/builtin_equals_test.dart b/tests/compiler/dart2js/codegen/builtin_equals_test.dart similarity index 82% rename from tests/compiler/dart2js/builtin_equals_test.dart rename to tests/compiler/dart2js/codegen/builtin_equals_test.dart index 6571c34..9adc8fa 100644 --- a/tests/compiler/dart2js/builtin_equals_test.dart +++ b/tests/compiler/dart2js/codegen/builtin_equals_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 = r""" foo() { @@ -18,11 +18,11 @@ """; main() { - test(CompileMode compileMode) async { + test({bool useKernel}) async { await compile(TEST, entry: 'foo', enableTypeAssertions: true, - compileMode: compileMode, check: (String generated) { + useKernel: useKernel, check: (String generated) { Expect.isTrue(!generated.contains('eqB')); RegExp regexp = new RegExp('=='); @@ -33,8 +33,8 @@ 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/builtin_interceptor_test.dart b/tests/compiler/dart2js/codegen/builtin_interceptor_test.dart similarity index 74% rename from tests/compiler/dart2js/builtin_interceptor_test.dart rename to tests/compiler/dart2js/codegen/builtin_interceptor_test.dart index 19533c0..1384a0f 100644 --- a/tests/compiler/dart2js/builtin_interceptor_test.dart +++ b/tests/compiler/dart2js/codegen/builtin_interceptor_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() { @@ -25,16 +25,16 @@ """; 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("return 3;")); }); - await compile(TEST_TWO, entry: 'foo', compileMode: compileMode, + await compile(TEST_TWO, entry: 'foo', useKernel: useKernel, check: (String generated) { Expect.isTrue(generated.contains("return 3;")); }); - await compile(TEST_THREE, entry: 'foo', compileMode: compileMode, + await compile(TEST_THREE, entry: 'foo', useKernel: useKernel, check: (String generated) { Expect.isTrue(generated.contains("push(2);")); }); @@ -42,8 +42,8 @@ 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/class_codegen2_test.dart b/tests/compiler/dart2js/codegen/class_codegen2_test.dart similarity index 71% rename from tests/compiler/dart2js/class_codegen2_test.dart rename to tests/compiler/dart2js/codegen/class_codegen2_test.dart index f85d0f3..8577b77 100644 --- a/tests/compiler/dart2js/class_codegen2_test.dart +++ b/tests/compiler/dart2js/codegen/class_codegen2_test.dart
@@ -6,7 +6,7 @@ import 'dart:async'; 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""" class A { foo() => 499; } @@ -89,10 +89,17 @@ // { a: true, }. Make sure this doesn't happen again. RegExp danglingComma = new RegExp(r',[ \n]*}'); - asyncTest( - () => Future.forEach([TEST_ONE, TEST_TWO, TEST_THREE, TEST_FOUR], (test) { - return compileAll(test).then((generated) { - Expect.isFalse(danglingComma.hasMatch(generated)); - }); - })); + Future runTests(CompileMode compileMode) async { + for (String test in [TEST_ONE, TEST_TWO, TEST_THREE, TEST_FOUR]) { + String generated = await compileAll(test, compileMode: compileMode); + Expect.isFalse(danglingComma.hasMatch(generated)); + } + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); + }); }
diff --git a/tests/compiler/dart2js/codegen/class_codegen_test.dart b/tests/compiler/dart2js/codegen/class_codegen_test.dart new file mode 100644 index 0000000..693e934 --- /dev/null +++ b/tests/compiler/dart2js/codegen/class_codegen_test.dart
@@ -0,0 +1,107 @@ +// 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(CompileMode compileMode) async { + String generated = await compileAll(TEST_ONE, compileMode: compileMode); + Expect.isTrue(generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"'))); + Expect.isTrue(generated.contains(new RegExp('B: {[ \n]*"\\^": "Object;"'))); +} + +subClass(CompileMode compileMode) async { + checkOutput(String generated) { + Expect.isTrue(generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"'))); + Expect.isTrue(generated.contains(new RegExp('B: {[ \n]*"\\^": "A;"'))); + } + + checkOutput(await compileAll(TEST_TWO, compileMode: compileMode)); + checkOutput(await compileAll(TEST_THREE, compileMode: compileMode)); +} + +fieldTest(CompileMode compileMode) async { + String generated = await compileAll(TEST_FOUR, compileMode: compileMode); + Expect.isTrue(generated + .contains(new RegExp('B: {[ \n]*"\\^": "A;y,z,x",[ \n]*static:'))); +} + +constructor1(CompileMode compileMode) async { + String generated = await compileAll(TEST_FIVE, compileMode: compileMode); + Expect.isTrue(generated.contains(new RegExp(r"new [$A-Z]+\.A\(a\);"))); +} + +main() { + runTests(CompileMode compileMode) async { + await twoClasses(compileMode); + await subClass(compileMode); + await fieldTest(compileMode); + await constructor1(compileMode); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); + }); +}
diff --git a/tests/compiler/dart2js/class_order_test.dart b/tests/compiler/dart2js/codegen/class_order_test.dart similarity index 61% rename from tests/compiler/dart2js/class_order_test.dart rename to tests/compiler/dart2js/codegen/class_order_test.dart index e3629c1..1946305 100644 --- a/tests/compiler/dart2js/class_order_test.dart +++ b/tests/compiler/dart2js/codegen/class_order_test.dart
@@ -5,7 +5,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""" class A { foo() => 499; } @@ -36,11 +36,18 @@ // we just verify that their members are in the correct order. RegExp regexp = new RegExp(r"foo\$0?:(.|\n)*bar\$0:(.|\n)*gee\$0:"); - asyncTest(() => compileAll(TEST_ONE).then((generated) { - Expect.isTrue(regexp.hasMatch(generated)); - })); + runTests(CompileMode compileMode) async { + String generated1 = await compileAll(TEST_ONE, compileMode: compileMode); + Expect.isTrue(regexp.hasMatch(generated1)); - asyncTest(() => compileAll(TEST_TWO).then((generated) { - Expect.isTrue(regexp.hasMatch(generated)); - })); + String generated2 = await compileAll(TEST_TWO, compileMode: compileMode); + Expect.isTrue(regexp.hasMatch(generated2)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); + }); }
diff --git a/tests/compiler/dart2js/codegen/closure_codegen_test.dart b/tests/compiler/dart2js/codegen/closure_codegen_test.dart new file mode 100644 index 0000000..07650a2 --- /dev/null +++ b/tests/compiler/dart2js/codegen/closure_codegen_test.dart
@@ -0,0 +1,87 @@ +// 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 useKernel, bool minify, String prefix}) async { + await compile(TEST_INVOCATION0, useKernel: useKernel, minify: minify, + check: (String generated) { + Expect.isTrue(generated.contains(".$prefix\$0()")); + }); + await compile(TEST_INVOCATION1, useKernel: useKernel, minify: minify, + check: (String generated) { + Expect.isTrue(generated.contains(".$prefix\$1(1)")); + }); + await compile(TEST_INVOCATION2, useKernel: useKernel, 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(CompileMode compileMode, + {bool minify, String prefix}) async { + String generated = + await compileAll(TEST_BAILOUT, compileMode: compileMode, minify: minify); + RegExp regexp = new RegExp("$prefix\\\$0:${minify ? "" : " "}function"); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); +} + +main() { + runTests({bool useKernel}) async { + await closureInvocation( + useKernel: useKernel, minify: false, prefix: "call"); + await closureInvocation(useKernel: useKernel, minify: true, prefix: ""); + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + await closureBailout(compileMode, minify: false, prefix: "call"); + await closureBailout(compileMode, minify: true, prefix: ""); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/code_motion_test.dart b/tests/compiler/dart2js/codegen/code_motion_test.dart new file mode 100644 index 0000000..f800e33 --- /dev/null +++ b/tests/compiler/dart2js/codegen/code_motion_test.dart
@@ -0,0 +1,41 @@ +// 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() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, useKernel: useKernel, 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()); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart b/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart new file mode 100644 index 0000000..d576b64 --- /dev/null +++ b/tests/compiler/dart2js/codegen/constant_folding_codeUnitAt_test.dart
@@ -0,0 +1,53 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test constant folding on numbers. + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_1 = """ +foo() { + var a = 'Hello'; + var b = 0; + return a.codeUnitAt(b); +} +"""; + +// No folding of index type error. +const String TEST_2 = """ +foo() { + var a = 'Hello'; + var b = 1.5; + return a.codeUnitAt(b); +} +"""; + +// No folding of index range error. +const String TEST_3 = """ +foo() { + var a = 'Hello'; + var b = 55; + return a.codeUnitAt(b); +} +"""; + +main() { + runTests({bool useKernel}) async { + await compileAndMatch(TEST_1, 'foo', new RegExp(r'return 72'), + useKernel: useKernel); + await compileAndDoNotMatch(TEST_1, 'foo', new RegExp(r'Hello'), + useKernel: useKernel); + await compileAndMatch(TEST_2, 'foo', new RegExp(r'Hello'), + useKernel: useKernel); + await compileAndMatch(TEST_3, 'foo', new RegExp(r'Hello'), + useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/constant_folding_test.dart b/tests/compiler/dart2js/codegen/constant_folding_test.dart new file mode 100644 index 0000000..80bcac7 --- /dev/null +++ b/tests/compiler/dart2js/codegen/constant_folding_test.dart
@@ -0,0 +1,99 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test constant folding on numbers. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String NUMBER_FOLDING = """ +void main() { + var a = 4; + var b = 3; + print(a + b); +} +"""; + +const String NEGATIVE_NUMBER_FOLDING = """ +void main() { + var a = 4; + var b = -3; + print(a + b); +} +"""; + +const String NULL_EQUALS_FOLDING = """ +foo(a, b, c, d) { + if (a == null) return 1; + if (null == b) return 2; + if (4 == c) return 3; + if ("foo" == d) return 3; +} +"""; + +const String LIST_LENGTH_FOLDING = """ +foo() { + return const [1, 2, 3].length; +} +"""; + +const String STRING_LENGTH_FOLDING = """ +foo() { + return '123'.length; +} +"""; + +const String LIST_INDEX_FOLDING = """ +foo() { + return const [1, 2, 3][0]; +} +"""; + +const String RANGE_ERROR_INDEX_FOLDING = """ +foo() { + return [1][1]; +} +"""; + +main() { + runTests({bool useKernel}) async { + await compileAndMatch(NUMBER_FOLDING, 'main', new RegExp(r"print\(7\)"), + useKernel: useKernel); + await compileAndMatch( + NEGATIVE_NUMBER_FOLDING, 'main', new RegExp(r"print\(1\)"), + useKernel: useKernel); + await compile(NULL_EQUALS_FOLDING, useKernel: useKernel, entry: 'foo', + check: (String generated) { + RegExp regexp = new RegExp(r'a == null'); + Expect.isTrue(regexp.hasMatch(generated)); + + regexp = new RegExp(r'null == b'); + Expect.isTrue(regexp.hasMatch(generated)); + + regexp = new RegExp(r'4 === c'); + Expect.isTrue(regexp.hasMatch(generated)); + + regexp = new RegExp('"foo" === d'); + Expect.isTrue(regexp.hasMatch(generated)); + }); + await compileAndMatch(LIST_LENGTH_FOLDING, 'foo', new RegExp(r"return 3"), + useKernel: useKernel); + await compileAndMatch(LIST_INDEX_FOLDING, 'foo', new RegExp(r"return 1"), + useKernel: useKernel); + await compileAndDoNotMatch(LIST_INDEX_FOLDING, 'foo', new RegExp(r"ioore"), + useKernel: useKernel); + await compileAndMatch(STRING_LENGTH_FOLDING, 'foo', new RegExp(r"return 3"), + useKernel: useKernel); + await compileAndMatch( + RANGE_ERROR_INDEX_FOLDING, 'foo', new RegExp(r"ioore"), + useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/constant_namer_test.dart b/tests/compiler/dart2js/codegen/constant_namer_test.dart new file mode 100644 index 0000000..14d93ce --- /dev/null +++ b/tests/compiler/dart2js/codegen/constant_namer_test.dart
@@ -0,0 +1,46 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" + class Token { + final name; + final value; + const Token(this.name, [this.value]); + use() { print(this); } + } + test() { + const [12,53].use(); + const Token('start').use(); + const Token('end').use(); + const Token('yes', 12).use(); + const Token(true, false).use(); + } +"""; + +main() { + check(String generated, String text) { + Expect.isTrue(generated.contains(text), text); + } + + runTests({bool useKernel}) async { + String generated = + await compile(TEST_ONE, useKernel: useKernel, entry: 'test'); + check(generated, '.List_12_53.'); + check(generated, '.Token_start_null.'); + check(generated, '.Token_end_null.'); + check(generated, '.Token_yes_12.'); + check(generated, '.Token_true_false.'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/dead_code_test.dart b/tests/compiler/dart2js/codegen/dead_code_test.dart new file mode 100644 index 0000000..56f42d1 --- /dev/null +++ b/tests/compiler/dart2js/codegen/dead_code_test.dart
@@ -0,0 +1,32 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +String TEST = r''' +main() { + foo(null); +} +foo(a) { + if (a != null) return 42; + return 54; +} +'''; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isFalse(generated.contains('return 42'), 'dead code not eliminated'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart b/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart new file mode 100644 index 0000000..aa5597e --- /dev/null +++ b/tests/compiler/dart2js/codegen/dead_phi_eliminator_test.dart
@@ -0,0 +1,35 @@ +// 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""" +void foo(bar) { + var toBeRemoved = 1; + if (bar) { + toBeRemoved = 2; + } else { + toBeRemoved = 3; + } +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, useKernel: useKernel, entry: 'foo', + check: (String generated) { + RegExp regexp = new RegExp("toBeRemoved"); + Expect.isTrue(!regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/declare_once_test.dart b/tests/compiler/dart2js/codegen/declare_once_test.dart new file mode 100644 index 0000000..68e0036 --- /dev/null +++ b/tests/compiler/dart2js/codegen/declare_once_test.dart
@@ -0,0 +1,37 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test that parameters keep their names in the output. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +main() { + // For a function with only one variable we declare it inline for more + // compactness. Test that we don't also declare it at the start of the + // method. + runTest({bool useKernel}) async { + String generated = await compile( + 'final List a = const ["bar", "baz"];' + 'int foo() {' + ' for (int i = 0; i < a.length; i++) {' + ' print(a[i]);' + ' }' + '}', + useKernel: useKernel, + entry: 'foo', + minify: false); + RegExp re = new RegExp(r"var "); + Expect.isTrue(re.hasMatch(generated)); + print(generated); + Expect.equals(1, re.allMatches(generated).length); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart b/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart new file mode 100644 index 0000000..f7a3db9 --- /dev/null +++ b/tests/compiler/dart2js/codegen/elide_callthrough_stub_test.dart
@@ -0,0 +1,69 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Check that calls through fields elide the call-through stub. This +// optimization is done by the simplifier, so inlining does not need to be +// enabled. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +const String TEST1 = r''' +class W { + final Function _fun; + W(this._fun); + foo(zzz) => _fun(zzz); // this._fun$1(zzz) --> this._fun.call$1(zzz) +} +add1(x) => x + 1; +main() { + var w = new W(add1); + var x = w.foo(42); +} +'''; + +const String TEST2 = r''' +class W { + final Function __fun; + Function get _fun => __fun; + W(this.__fun); + foo(zzz) => _fun(zzz); // this._fun$1(zzz) stays same. +} +add1(x) => x + 1; +main() { + var w = new W(add1); + var x = w.foo(42); +} +'''; + +main() { + runTests({bool useKernel}) async { + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + String generated1 = await compileAll(TEST1, compileMode: compileMode); + // Direct call through field. + Expect.isTrue(generated1.contains(r'this._fun.call$1(zzz)')); + // No stub. + Expect.isFalse(generated1.contains(r'_fun$1:')); + // No call to stub. + Expect.isFalse(generated1.contains(r'_fun$1(')); + + String generated2 = await compileAll(TEST2, compileMode: compileMode); + // No call through field. + Expect.isFalse(generated2.contains(r'this._fun.call$1(zzz)')); + // Call through stub. + Expect.isTrue(generated2.contains(r'this._fun$1(zzz)')); + // Stub is generated. + Expect.isTrue(generated2.contains(r'_fun$1:')); + // Call through getter (inside stub). + Expect.isTrue(generated2.contains(r'get$_fun().call$1')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/emit_const_fields_test.dart b/tests/compiler/dart2js/codegen/emit_const_fields_test.dart new file mode 100644 index 0000000..8a7eea4 --- /dev/null +++ b/tests/compiler/dart2js/codegen/emit_const_fields_test.dart
@@ -0,0 +1,35 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test that unused static consts are not emitted. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST_GUIDE = r""" +class Guide { + static const LTUAE = 42; + static const TITLE = 'Life, the Universe and Everything'; +} + +main() { + return "${Guide.LTUAE}, ${Guide.TITLE}"; +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST_GUIDE, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isTrue(generated.contains("42")); + Expect.isFalse(generated.contains("TITLE")); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/expect_annotations2_test.dart b/tests/compiler/dart2js/codegen/expect_annotations2_test.dart similarity index 75% rename from tests/compiler/dart2js/expect_annotations2_test.dart rename to tests/compiler/dart2js/codegen/expect_annotations2_test.dart index 981ba57..3dea0f3 100644 --- a/tests/compiler/dart2js/expect_annotations2_test.dart +++ b/tests/compiler/dart2js/codegen/expect_annotations2_test.dart
@@ -5,7 +5,8 @@ import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; import 'package:compiler/compiler_new.dart'; -import 'memory_compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': ''' @@ -36,10 +37,12 @@ }; void main() { - asyncTest(() async { + runTest({bool useKernel}) async { OutputCollector collector = new OutputCollector(); await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); // Simply check that the constants of the small functions are still in the // output, and that we don't see the result of constant folding. String jsOutput = collector.getOutput('', OutputType.js); @@ -51,5 +54,12 @@ Expect.isFalse(jsOutput.contains('211109')); Expect.isFalse(jsOutput.contains('82155031')); Expect.isFalse(jsOutput.contains('4712')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/codegen/expect_annotations_test.dart b/tests/compiler/dart2js/codegen/expect_annotations_test.dart new file mode 100644 index 0000000..d4cacfa --- /dev/null +++ b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
@@ -0,0 +1,143 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints; +import 'package:compiler/src/types/types.dart'; +import 'package:compiler/src/world.dart' show ClosedWorld; +import '../inference/type_mask_test_helper.dart'; +import '../memory_compiler.dart'; + +const Map MEMORY_SOURCE_FILES = const { + 'main.dart': r""" +import 'package:expect/expect.dart'; + +int method(String arg) => arg.length; + +@AssumeDynamic() +int methodAssumeDynamic(String arg) => arg.length; + +@TrustTypeAnnotations() +int methodTrustTypeAnnotations(String arg) => arg.length; + +@NoInline() +int methodNoInline(String arg) => arg.length; + +@NoInline() @TrustTypeAnnotations() +int methodNoInlineTrustTypeAnnotations(String arg) => arg.length; + +@AssumeDynamic() @TrustTypeAnnotations() +int methodAssumeDynamicTrustTypeAnnotations(String arg) => arg.length; + + +void main(List<String> args) { + print(method(args[0])); + print(methodAssumeDynamic('foo')); + print(methodTrustTypeAnnotations(42)); + print(methodTrustTypeAnnotations("fourtyTwo")); + print(methodNoInline('bar')); + print(methodNoInlineTrustTypeAnnotations(42)); + print(methodNoInlineTrustTypeAnnotations("fourtyTwo")); + print(methodAssumeDynamicTrustTypeAnnotations(null)); +} +""" +}; + +main() { + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +} + +runTest({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); + Compiler compiler = result.compiler; + ClosedWorld closedWorld = compiler.backendClosedWorldForTesting; + Expect.isFalse(compiler.compilationFailed, 'Unsuccessful compilation'); + Expect.isNotNull(closedWorld.commonElements.expectNoInlineClass, + 'NoInlineClass is unresolved.'); + Expect.isNotNull(closedWorld.commonElements.expectTrustTypeAnnotationsClass, + 'TrustTypeAnnotations is unresolved.'); + Expect.isNotNull(closedWorld.commonElements.expectAssumeDynamicClass, + 'AssumeDynamicClass is unresolved.'); + + void testTypeMatch(FunctionEntity function, TypeMask expectedParameterType, + TypeMask expectedReturnType, TypesInferrer inferrer) { + compiler.codegenWorldBuilder.forEachParameterAsLocal(function, + (Local parameter) { + TypeMask type = inferrer.getTypeOfParameter(parameter); + Expect.equals( + expectedParameterType, simplify(type, closedWorld), "$parameter"); + }); + if (expectedReturnType != null) { + TypeMask type = inferrer.getReturnTypeOfMember(function); + Expect.equals( + expectedReturnType, simplify(type, closedWorld), "$function"); + } + } + + void test(String name, + {bool expectNoInline: false, + bool expectTrustTypeAnnotations: false, + TypeMask expectedParameterType: null, + TypeMask expectedReturnType: null, + bool expectAssumeDynamic: false}) { + LibraryEntity mainApp = closedWorld.elementEnvironment.mainLibrary; + FunctionEntity method = + closedWorld.elementEnvironment.lookupLibraryMember(mainApp, name); + Expect.isNotNull(method); + Expect.equals( + expectNoInline, + optimizerHints.noInline( + closedWorld.elementEnvironment, closedWorld.commonElements, method), + "Unexpected annotation of @NoInline on '$method'."); + Expect.equals( + expectTrustTypeAnnotations, + optimizerHints.trustTypeAnnotations( + closedWorld.elementEnvironment, closedWorld.commonElements, method), + "Unexpected annotation of @TrustTypeAnnotations on '$method'."); + Expect.equals( + expectAssumeDynamic, + optimizerHints.assumeDynamic( + closedWorld.elementEnvironment, closedWorld.commonElements, method), + "Unexpected annotation of @AssumeDynamic on '$method'."); + TypesInferrer inferrer = compiler.globalInference.typesInferrerInternal; + if (expectTrustTypeAnnotations && expectedParameterType != null) { + testTypeMatch( + method, expectedParameterType, expectedReturnType, inferrer); + } else if (expectAssumeDynamic) { + testTypeMatch( + method, closedWorld.commonMasks.dynamicType, null, inferrer); + } + } + + TypeMask jsStringType = closedWorld.commonMasks.stringType; + TypeMask jsIntType = closedWorld.commonMasks.intType; + TypeMask coreStringType = + new TypeMask.subtype(closedWorld.commonElements.stringClass, closedWorld); + + test('method'); + test('methodAssumeDynamic', expectAssumeDynamic: true); + test('methodTrustTypeAnnotations', + expectTrustTypeAnnotations: true, expectedParameterType: jsStringType); + test('methodNoInline', expectNoInline: true); + test('methodNoInlineTrustTypeAnnotations', + expectNoInline: true, + expectTrustTypeAnnotations: true, + expectedParameterType: jsStringType, + expectedReturnType: jsIntType); + test('methodAssumeDynamicTrustTypeAnnotations', + expectAssumeDynamic: true, + expectTrustTypeAnnotations: true, + expectedParameterType: coreStringType); +}
diff --git a/tests/compiler/dart2js/codegen/field_codegen_test.dart b/tests/compiler/dart2js/codegen/field_codegen_test.dart new file mode 100644 index 0000000..e77a1c2 --- /dev/null +++ b/tests/compiler/dart2js/codegen/field_codegen_test.dart
@@ -0,0 +1,40 @@ +// 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_NULL0 = r""" +class A { static var x; } + +main() { return A.x; } +"""; + +const String TEST_NULL1 = r""" +var x; + +main() { return x; } +"""; + +main() { + runTests({bool useKernel}) async { + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + + String generated1 = await compileAll(TEST_NULL0, compileMode: compileMode); + Expect.isTrue(generated1.contains("null")); + + String generated2 = await compileAll(TEST_NULL1, compileMode: compileMode); + Expect.isTrue(generated2.contains("null")); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/field_update_test.dart b/tests/compiler/dart2js/codegen/field_update_test.dart new file mode 100644 index 0000000..8f809b5 --- /dev/null +++ b/tests/compiler/dart2js/codegen/field_update_test.dart
@@ -0,0 +1,106 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +// Test for emitting JavaScript pre- and post-increment and assignment ops. + +const String TEST_1 = """ +class A { + var a = 42; + int foo() { var r = a; a = a + 1; return r; } // this.a++ +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +const String TEST_2 = """ +class A { + var a = 42; + int foo() { var r = a; a = a + 1; return a; } // ++this.a +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +const String TEST_3 = """ +class A { + var a = 42; + int foo() { var r = a; a = a - 1; return r; } // this.a-- +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +const String TEST_4 = """ +class A { + var a = 42; + int foo() { var r = a; a = a - 1; return a; } // --this.a +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +const String TEST_5 = """ +class A { + var a = 42; + int foo() { var r = a; a = a - 2; return a; } // this.a -= 2 +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +const String TEST_6 = """ +class A { + var a = 42; + int foo() { var r = a; a = a * 2; return a; } // this.a *= 2 +} + +void main() { + var a = new A(); + print(a.foo()); +} +"""; + +main() { + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +} + +runTests({bool useKernel}) async { + test(String code, Function f) async { + String generated = await compileAll(code, + disableInlining: true, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isTrue(f(generated)); + } + + await test(TEST_1, (generated) => generated.contains(r'return this.a++;')); + await test(TEST_2, (generated) => generated.contains(r'return ++this.a;')); + await test(TEST_3, (generated) => generated.contains(r'return this.a--;')); + await test(TEST_4, (generated) => generated.contains(r'return --this.a;')); + await test(TEST_5, (generated) => generated.contains(r' this.a -= 2;')); + await test(TEST_6, (generated) => generated.contains(r' this.a *= 2;')); +}
diff --git a/tests/compiler/dart2js/codegen/for_in_test.dart b/tests/compiler/dart2js/codegen/for_in_test.dart new file mode 100644 index 0000000..2ae009d --- /dev/null +++ b/tests/compiler/dart2js/codegen/for_in_test.dart
@@ -0,0 +1,46 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +foo(a) { + int x = 0; + for (int i in a) { + x += i; + } + return x; +} +"""; + +const String TEST_TWO = r""" +foo(a) { + int x = 0; + for (int i in a) { + if (i == 5) continue; + x += i; + } + return x; +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', check: (String generated) { + Expect.isTrue(!generated.contains(r'break')); + }, useKernel: useKernel); + await compile(TEST_TWO, entry: 'foo', check: (String generated) { + Expect.isTrue(generated.contains(r'continue')); + }, useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/forloop_box_test.dart b/tests/compiler/dart2js/codegen/forloop_box_test.dart new file mode 100644 index 0000000..915cbf4 --- /dev/null +++ b/tests/compiler/dart2js/codegen/forloop_box_test.dart
@@ -0,0 +1,70 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +String SHOULD_NOT_BE_BOXED_TEST = r''' +main() { + var a; + for (var i=0; i<10; i++) { + a = () => i; + } + print(a()); +} +'''; + +String SHOULD_BE_BOXED_TEST = r''' +run(f) => f(); +main() { + var a; + for (var i=0; i<10; run(() => i++)) { + a = () => i; + } + print(a()); +} +'''; + +String ONLY_UPDATE_LOOP_VAR_TEST = r''' +run(f) => f(); +main() { + var a; + for (var i=0; i<10; run(() => i++)) { + var b = 3; + a = () => b = i; + } + print(a()); +} +'''; + +main() { + runTests({bool useKernel}) async { + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + + String generated1 = + await compileAll(SHOULD_NOT_BE_BOXED_TEST, compileMode: compileMode); + Expect.isTrue(generated1.contains('main_closure(i)'), + 'for-loop variable should not have been boxed'); + + String generated2 = + await compileAll(SHOULD_BE_BOXED_TEST, compileMode: compileMode); + Expect.isFalse(generated2.contains('main_closure(i)'), + 'for-loop variable should have been boxed'); + + String generated3 = await compileAll(ONLY_UPDATE_LOOP_VAR_TEST); + Expect.isFalse(generated3.contains('main_closure(i)'), + 'for-loop variable should have been boxed'); + Expect.isFalse(generated3.contains(', _box_0.b = 3,'), + 'non for-loop captured variable should not be updated in loop'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/generate_at_use_site_test.dart b/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart similarity index 62% rename from tests/compiler/dart2js/generate_at_use_site_test.dart rename to tests/compiler/dart2js/codegen/generate_at_use_site_test.dart index c951836..a7e3bf48 100644 --- a/tests/compiler/dart2js/generate_at_use_site_test.dart +++ b/tests/compiler/dart2js/codegen/generate_at_use_site_test.dart
@@ -2,10 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:async'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String FIB = r""" fib(n) { @@ -51,17 +50,27 @@ """; main() { - asyncTest(() => Future.wait([ - // Make sure we don't introduce a new variable. - compileAndDoNotMatch(FIB, 'fib', new RegExp("var $anyIdentifier =")), + runTests({bool useKernel}) async { + // Make sure we don't introduce a new variable. + await compileAndDoNotMatch(FIB, 'fib', new RegExp("var $anyIdentifier ="), + useKernel: useKernel); - compileAndDoNotMatch(BAR, 'bar', new RegExp("isLeaf")), + await compileAndDoNotMatch(BAR, 'bar', new RegExp("isLeaf"), + useKernel: useKernel); - compile(TEST, entry: 'foo', check: (String generated) { - Expect.isFalse(generated.contains('else')); - // Regression check to ensure that there is no floating variable - // expression. - Expect.isFalse(new RegExp('^[ ]*a;').hasMatch(generated)); - }), - ])); + await compile(TEST, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isFalse(generated.contains('else')); + // Regression check to ensure that there is no floating variable + // expression. + Expect.isFalse(new RegExp('^[ ]*a;').hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart new file mode 100644 index 0000000..7d03a19 --- /dev/null +++ b/tests/compiler/dart2js/codegen/gvn_dynamic_field_get_test.dart
@@ -0,0 +1,63 @@ +// 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 dart2js gvns dynamic getters that don't have side +// effects. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; +import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/elements/names.dart'; +import 'package:compiler/src/universe/selector.dart' show Selector; +import 'package:compiler/src/world.dart'; +import '../memory_compiler.dart'; + +const String TEST = r""" +class A { + var foo; + bar(a) { + return a.foo + a.foo; + } +} + +main() { + new A().bar(new Object()); +} +"""; + +main() { + runTests({bool useKernel}) async { + OutputCollector outputCollector = new OutputCollector(); + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, + outputProvider: outputCollector, + options: useKernel ? [Flags.useKernel] : []); + Compiler compiler = result.compiler; + ClosedWorldBase closedWorld = + compiler.resolutionWorldBuilder.closedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; + + String generated = outputCollector.getOutput('', OutputType.js); + RegExp regexp = new RegExp(r"get\$foo"); + Iterator matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); + dynamic cls = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'A'); + Expect.isNotNull(cls); + String name = 'foo'; + var element = elementEnvironment.lookupClassMember(cls, name); + Expect.isNotNull(element); + Selector selector = new Selector.getter(new PublicName(name)); + Expect.isFalse(closedWorld.hasAnyUserDefinedGetter(selector, null)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/gvn_test.dart b/tests/compiler/dart2js/codegen/gvn_test.dart new file mode 100644 index 0000000..b9962bc --- /dev/null +++ b/tests/compiler/dart2js/codegen/gvn_test.dart
@@ -0,0 +1,154 @@ +// 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""" +void foo(bar) { + for (int i = 0; i < 1; i++) { + print(1 + bar); + print(1 + bar); + } +} +"""; + +// Check that modulo does not have any side effect and we are +// GVN'ing the length of [:list:]. +const String TEST_TWO = r""" +void foo(a) { + var list = new List<int>(); + list[0] = list[0 % a]; + list[1] = list[1 % a]; +} +"""; + +// Check that is checks get GVN'ed. +const String TEST_THREE = r""" +void foo(a) { + print(42); // Make sure numbers are used. + print(a is num); + print(a is num); +} +"""; + +// Check that instructions that don't have a builtin equivalent can +// still be GVN'ed. +const String TEST_FOUR = r""" +void foo(a) { + print(1 >> a); + print(1 >> a); +} +"""; + +// Check that [HCheck] instructions do not prevent GVN. +const String TEST_FIVE = r""" +class A { + var foo = 21; +} + +class B {} + +main() { + var a = [new B(), new A()][0]; + var b = a.foo; + var c = a.foo; + if (a is B) { + c = a.foo; + } + return b + c; +} +"""; + +// Check that a gvn'able instruction in the loop header gets hoisted. +const String TEST_SIX = r""" +class A { + final field = 54; +} + +main() { + var a = new A(); + while (a.field == 54) { a.field = 42; } +} +"""; + +// Check that a gvn'able instruction that may throw in the loop header +// gets hoisted. +const String TEST_SEVEN = r""" +class A { + final field; + A() : field = null; + A.bar() : field = 42; +} + +main() { + var a = new A(); + var b = new A.bar(); + while (a.field == 54) { a.field = 42; b.field = 42; } +} +"""; + +// Check that a check in a loop header gets hoisted. +const String TEST_EIGHT = r""" +class A { + final field; + A() : field = null; + A.bar() : field = 42; +} + +main() { + var a = new A(); + var b = new A.bar(); + for (int i = 0; i < a.field; i++) { a.field = 42; b.field = 42; } +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + RegExp regexp = new RegExp(r"1 \+ [a-z]+"); + checkNumberOfMatches(regexp.allMatches(generated).iterator, 1); + }); + await compile(TEST_TWO, entry: 'foo', useKernel: useKernel, + check: (String generated) { + checkNumberOfMatches( + new RegExp("length").allMatches(generated).iterator, 1); + }); + await compile(TEST_THREE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + checkNumberOfMatches( + new RegExp("number").allMatches(generated).iterator, 1); + }); + await compile(TEST_FOUR, entry: 'foo', useKernel: useKernel, + check: (String generated) { + checkNumberOfMatches(new RegExp("shr").allMatches(generated).iterator, 1); + }); + + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + + await compileAll(TEST_FIVE, compileMode: compileMode).then((generated) { + checkNumberOfMatches( + new RegExp("get\\\$foo").allMatches(generated).iterator, 1); + }); + await compileAll(TEST_SIX, compileMode: compileMode).then((generated) { + Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)')); + }); + await compileAll(TEST_SEVEN, compileMode: compileMode).then((generated) { + Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)')); + }); + await compileAll(TEST_EIGHT, compileMode: compileMode).then((generated) { + Expect.isTrue(generated.contains('for (; i < t1; ++i)')); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/identity_test.dart b/tests/compiler/dart2js/codegen/identity_test.dart new file mode 100644 index 0000000..78f65cd --- /dev/null +++ b/tests/compiler/dart2js/codegen/identity_test.dart
@@ -0,0 +1,40 @@ +// 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""" +class A {} +bool foo(bar) { + var x = new A(); + var y = new A(); + return identical(x, y); +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Check that no boolify code is generated. + RegExp regexp = new RegExp("=== true"); + Iterator matches = regexp.allMatches(generated).iterator; + Expect.isFalse(matches.moveNext()); + + regexp = new RegExp("==="); + matches = regexp.allMatches(generated).iterator; + Expect.isTrue(matches.moveNext()); + Expect.isFalse(matches.moveNext()); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/if_do_while_test.dart b/tests/compiler/dart2js/codegen/if_do_while_test.dart new file mode 100644 index 0000000..ff6b8d0 --- /dev/null +++ b/tests/compiler/dart2js/codegen/if_do_while_test.dart
@@ -0,0 +1,38 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST = r""" +foo(param0, param1, param2) { + if (param0) + do { + param1(); + } while(param2()); + else { + param2(); + } +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Check that the do-while in the 'then' is enclosed in braces. + // Otherwise Android 4.0 stock browser has a syntax error. See issue 10923. + Expect.isTrue( + new RegExp(r'if[ ]*\([^)]+\)[ ]*\{[\n ]*do').hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/inferrer_factory_test.dart b/tests/compiler/dart2js/codegen/inferrer_factory_test.dart new file mode 100644 index 0000000..59f39ab --- /dev/null +++ b/tests/compiler/dart2js/codegen/inferrer_factory_test.dart
@@ -0,0 +1,40 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST1 = r""" +class A implements List { + factory A() { + // Avoid inlining by using try/catch. + try { + return new List(); + } catch (e) { + } + } +} + +main() { + new A()[0] = 42; +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST1, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + // Check that we're using the index operator on the object returned + // by the A factory. + Expect.isTrue(generated.contains('[0] = 42')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart b/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart new file mode 100644 index 0000000..b9b1783 --- /dev/null +++ b/tests/compiler/dart2js/codegen/interceptor_almost_constant_test.dart
@@ -0,0 +1,32 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" + foo(b) { + var a = b ? [1,2,3] : null; + print(a.first); + } +"""; + +main() { + runTest({bool useKernel}) async { + // Check that almost-constant interceptor is used. + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + String re = r'a && [\w\.]*_methods'; + Expect.isTrue(generated.contains(new RegExp(re)), 'contains /$re/'); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/interceptor_test.dart b/tests/compiler/dart2js/codegen/interceptor_test.dart new file mode 100644 index 0000000..3955b33 --- /dev/null +++ b/tests/compiler/dart2js/codegen/interceptor_test.dart
@@ -0,0 +1,56 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" + foo(a) { + var myVariableName = a.toString(); + print(myVariableName); + print(myVariableName); + } +"""; + +const String TEST_TWO = r""" + class A { + var length; + } + foo(a) { + print([]); // Make sure the array class is instantiated. + return new A().length + a.length; + } +"""; + +main() { + runTests({bool useKernel}) async { + // Check that one-shot interceptors preserve variable names, see + // https://code.google.com/p/dart/issues/detail?id=8106. + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue( + generated.contains(new RegExp(r'[$A-Z]+\.toString\$0\$\(a\)'))); + Expect.isTrue(generated.contains('myVariableName')); + }); + // Check that an intercepted getter that does not need to be + // intercepted, is turned into a regular getter call or field + // access. + await compile(TEST_TWO, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isFalse(generated.contains(r'a.get$length()')); + Expect + .isTrue(generated.contains(new RegExp(r'[$A-Z]+\.A\$\(\)\.length'))); + Expect.isTrue( + generated.contains(new RegExp(r'[$A-Z]+\.get\$length\$as\(a\)'))); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/interpolation_folding_test.dart b/tests/compiler/dart2js/codegen/interpolation_folding_test.dart new file mode 100644 index 0000000..68f13e6 --- /dev/null +++ b/tests/compiler/dart2js/codegen/interpolation_folding_test.dart
@@ -0,0 +1,69 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +// Tests for +const String TEST_1 = r""" + foo() { + int a = 120; + String b = 'hello'; + return 'u${a}v${b}w'; + } +"""; + +const String TEST_2 = r""" + foo(a, b) { + return 'aaaaa${a}xxxxx' + "yyyyy${b}zzzzz"; + } +"""; + +const String TEST_3 = r""" + foo(a) { + var b = '$a#'; + return '${b}x${b}'; + } +"""; + +const String TEST_4 = r""" + foo(a) { + var b = []; + if (a) b.add(123); + return '${b.length}'; + } +"""; + +main() { + runTests({bool useKernel}) async { + check(String test, String contained) async { + String generated = + await compile(test, entry: 'foo', useKernel: useKernel); + Expect.isTrue(generated.contains(contained), contained); + } + + // Full substitution. + await check(TEST_1, r'"u120vhellow"'); + + // Adjacent string fragments get merged. + await check(TEST_2, r'"xxxxxyyyyy"'); + + // 1. No merging of fragments that are multi-use. Prevents exponential code + // and keeps author's manual CSE. + // 2. Know string values require no stringification. + await check(TEST_3, r'return b + "x" + b'); + + // Known int value can be formatted directly. + await check(TEST_4, r'return "" + b.length'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/inverse_operator_test.dart b/tests/compiler/dart2js/codegen/inverse_operator_test.dart new file mode 100644 index 0000000..eb1cee1 --- /dev/null +++ b/tests/compiler/dart2js/codegen/inverse_operator_test.dart
@@ -0,0 +1,31 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String MAIN = r""" +int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1)); +main() { + var x = 1; + if (inscrutable(x) == 0) { + main(); + x = 2; + } + print(!(1 < x)); +}"""; + +main() { + runTest({bool useKernel}) async { + // Make sure we don't introduce a new variable. + await compileAndMatchFuzzy(MAIN, 'main', "1 >= x", useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/is_function_test.dart b/tests/compiler/dart2js/codegen/is_function_test.dart similarity index 64% rename from tests/compiler/dart2js/is_function_test.dart rename to tests/compiler/dart2js/codegen/is_function_test.dart index 59d7d45..d594a90 100644 --- a/tests/compiler/dart2js/is_function_test.dart +++ b/tests/compiler/dart2js/codegen/is_function_test.dart
@@ -10,7 +10,7 @@ import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/js_emitter/model.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const String SOURCE = ''' import 'dart:isolate'; @@ -18,15 +18,18 @@ '''; main() { - asyncTest(() async { - var result = await runCompiler( - memorySourceFiles: {'main.dart': SOURCE}, - options: [Flags.enableCheckedMode]); + runTest({bool useKernel}) async { + List<String> options = [Flags.enableCheckedMode]; + if (useKernel) { + options.add(Flags.useKernel); + } + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': SOURCE}, options: options); Expect.isTrue(result.isSuccess); Compiler compiler = result.compiler; Program program = compiler.backend.emitter.emitter.programForTesting; - var name = compiler.backend.namer - .operatorIs(compiler.frontendStrategy.commonElements.functionClass); + var name = compiler.backend.namer.operatorIs( + compiler.backendClosedWorldForTesting.commonElements.functionClass); for (Fragment fragment in program.fragments) { for (Library library in fragment.libraries) { for (Class cls in library.classes) { @@ -38,5 +41,12 @@ } } } + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/codegen/is_inference2_test.dart b/tests/compiler/dart2js/codegen/is_inference2_test.dart new file mode 100644 index 0000000..e2bff2a --- /dev/null +++ b/tests/compiler/dart2js/codegen/is_inference2_test.dart
@@ -0,0 +1,33 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_IF_BOOL_FIRST_INSTRUCTION = r""" +negate(x) { + if (x is bool) return !x; + return x; +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_IF_BOOL_FIRST_INSTRUCTION, + entry: 'negate', useKernel: useKernel, check: (String generated) { + Expect.isTrue(generated.contains("!")); // We want to see !x. + Expect.isFalse(generated.contains("!=")); // And not !== true. + Expect.isFalse(generated.contains("true")); + Expect.isFalse(generated.contains("false")); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/is_inference_test.dart b/tests/compiler/dart2js/codegen/is_inference_test.dart similarity index 67% rename from tests/compiler/dart2js/is_inference_test.dart rename to tests/compiler/dart2js/codegen/is_inference_test.dart index a5d7f8b..9915918 100644 --- a/tests/compiler/dart2js/is_inference_test.dart +++ b/tests/compiler/dart2js/codegen/is_inference_test.dart
@@ -5,7 +5,7 @@ import 'dart:async'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST_IF = r""" test(param) { @@ -71,8 +71,9 @@ } """; -Future compileAndTest(String code) { - return compile(code, entry: 'test', check: (String generated) { +Future compileAndTest(String code, {bool useKernel}) { + return compile(code, entry: 'test', useKernel: useKernel, + check: (String generated) { RegExp validAdd = new RegExp("($anyIdentifier \\+ 42)|($anyIdentifier \\+= 42)"); RegExp invalidAdd = new RegExp("$anyIdentifier \\+ 53"); @@ -82,12 +83,19 @@ } main() { - asyncTest(() => Future.wait([ - compileAndTest(TEST_IF), - compileAndTest(TEST_IF_ELSE), - compileAndTest(TEST_IF_RETURN), - compileAndTest(TEST_IF_NOT_ELSE), - compileAndTest(TEST_IF_NOT_RETURN), - compileAndTest(TEST_IF_NOT_ELSE_RETURN), - ])); + runTests({bool useKernel}) async { + await compileAndTest(TEST_IF, useKernel: useKernel); + await compileAndTest(TEST_IF_ELSE, useKernel: useKernel); + await compileAndTest(TEST_IF_RETURN, useKernel: useKernel); + await compileAndTest(TEST_IF_NOT_ELSE, useKernel: useKernel); + await compileAndTest(TEST_IF_NOT_RETURN, useKernel: useKernel); + await compileAndTest(TEST_IF_NOT_ELSE_RETURN, useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/licm_test.dart b/tests/compiler/dart2js/codegen/licm_test.dart new file mode 100644 index 0000000..f6fee65 --- /dev/null +++ b/tests/compiler/dart2js/codegen/licm_test.dart
@@ -0,0 +1,39 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Check that we hoist instructions in a loop condition, even if that +// condition involves control flow. + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST = ''' +var a = [1]; + +main() { + int count = int.parse('42') == 42 ? 42 : null; + for (int i = 0; i < count && i < a[0]; i++) { + print(i); + } + a.removeLast(); + // Ensure we don't try to generate a bailout method based on a check + // of [count]. + count.removeLast(); +} +'''; + +main() { + runTest({bool useKernel}) async { + await compileAndMatch(TEST, 'main', + new RegExp('if \\(typeof count !== "number"\\)(.|\\n)*while'), + useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/literal_list_test.dart b/tests/compiler/dart2js/codegen/literal_list_test.dart new file mode 100644 index 0000000..fa05bec --- /dev/null +++ b/tests/compiler/dart2js/codegen/literal_list_test.dart
@@ -0,0 +1,34 @@ +// 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() { + print([1, 2]); + print([3]); + var c = [4, 5]; + print(c); +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains('print([1, 2]);')); + Expect.isTrue(generated.contains('print([3]);')); + Expect.isTrue(generated.contains('print([4, 5]);')); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/literal_map_test.dart b/tests/compiler/dart2js/codegen/literal_map_test.dart new file mode 100644 index 0000000..363a8e2 --- /dev/null +++ b/tests/compiler/dart2js/codegen/literal_map_test.dart
@@ -0,0 +1,36 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST = """ +foo() { + var a = {}; + var index = foo(); // Make sure we want to optimize this method. + while (true) a[index] = 1; +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Make sure we have all the type information we need. + Expect.isFalse(generated.contains('bailout')); + Expect.isFalse(generated.contains('interceptor')); + // Make sure we don't go through an interceptor. + Expect.isTrue(generated.contains(r'a.$indexSet(a') || + generated.contains(r'.$indexSet(0')); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/load_elimination_test.dart b/tests/compiler/dart2js/codegen/load_elimination_test.dart similarity index 66% rename from tests/compiler/dart2js/load_elimination_test.dart rename to tests/compiler/dart2js/codegen/load_elimination_test.dart index efbc841..2a8935e 100644 --- a/tests/compiler/dart2js/load_elimination_test.dart +++ b/tests/compiler/dart2js/codegen/load_elimination_test.dart
@@ -2,10 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:async'; import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST_1 = """ class A { @@ -235,33 +234,41 @@ """; main() { - test(String code, String expected) { - return () => compileAll(code, disableInlining: false).then((generated) { - Expect.isTrue( - generated.contains(expected), - "Generated code didn't contain '$expected'.\n" - "Test:\n$code, Generated:\n$generated"); - }); + runTests({bool useKernel}) async { + test(String code, String expected) async { + String generated = await compileAll(code, + disableInlining: false, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isTrue( + generated.contains(expected), + "Generated code didn't contain '$expected'.\n" + "Test:\n$code, Generated:\n$generated"); + } + + await test(TEST_1, 'return 42'); + await test(TEST_2, 'return 42'); + await test(TEST_3, 'return 84'); + await test(TEST_4, 'return t1 + t1'); + await test(TEST_5, 'return 84'); + await test(TEST_6, 'return 84'); + await test(TEST_7, 'return 32'); + await test(TEST_8, 'return a.a'); + await test(TEST_9, 'return a.a'); + await test(TEST_10, 'return 2'); + await test(TEST_11, 'return a.a'); + await test(TEST_12, 'return 6'); + await test(TEST_13, 'return 6'); + await test(TEST_14, 'return t1[0]'); + await test(TEST_15, 'return 42'); + await test(TEST_16, 'return \$.a'); + await test(TEST_17, 'return t1'); + await test(TEST_18, 'return t1'); } - asyncTest(() => Future.forEach([ - test(TEST_1, 'return 42'), - test(TEST_2, 'return 42'), - test(TEST_3, 'return 84'), - test(TEST_4, 'return t1 + t1'), - test(TEST_5, 'return 84'), - test(TEST_6, 'return 84'), - test(TEST_7, 'return 32'), - test(TEST_8, 'return a.a'), - test(TEST_9, 'return a.a'), - test(TEST_10, 'return 2'), - test(TEST_11, 'return a.a'), - test(TEST_12, 'return 6'), - test(TEST_13, 'return 6'), - test(TEST_14, 'return t1[0]'), - test(TEST_15, 'return 42'), - test(TEST_16, 'return \$.a'), - test(TEST_17, 'return t1'), - test(TEST_18, 'return t1'), - ], (f) => f())); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/logical_expression_test.dart b/tests/compiler/dart2js/codegen/logical_expression_test.dart new file mode 100644 index 0000000..8ed8e00 --- /dev/null +++ b/tests/compiler/dart2js/codegen/logical_expression_test.dart
@@ -0,0 +1,61 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that logical or-expressions don't introduce unnecessary nots. + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +foo(bar, gee) { + bool cond1 = bar(); + if (cond1 || gee()) gee(); + if (cond1 || gee()) gee(); +} +"""; + +const String TEST_TWO = r""" +void foo(list, bar) { + if (list == null) bar(); + if (list == null || bar()) bar(); + if (list == null || bar()) bar(); +} +"""; + +main() { + runTests({bool useKernel}) async { + // We want something like: + // var t1 = bar.call$0() === true; + // if (t1 || gee.call$0() === true) gee.call$0(); + // if (t1 || gee.call$0() === true) gee.call$0(); + await compileAndDoNotMatchFuzzy( + TEST_ONE, + 'foo', + r"""var x = [a-zA-Z0-9$.]+\(\) == true; + if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+; + if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+;""", + useKernel: useKernel); + + // We want something like: + // var t1 = list == null; + // if (t1) bar.call$0(); + // if (t1 || bar.call$0() === true) bar.call$0(); + // if (t1 || bar.call$0() === true) bar.call$0(); + await compileAndMatchFuzzy( + TEST_TWO, + 'foo', + r"""var x = x == null; + if \(x\) [^;]+; + if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+; + if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+;""", + useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/loop_test.dart b/tests/compiler/dart2js/codegen/loop_test.dart new file mode 100644 index 0000000..3594325 --- /dev/null +++ b/tests/compiler/dart2js/codegen/loop_test.dart
@@ -0,0 +1,81 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +foo(a) { + int x = 0; + for (int i = 0; i < 10; i++) { + x += i; + } + return x; +} +"""; + +const String TEST_TWO = r""" +foo(a) { + int x = 0; + int i = 0; + while (i < 10) { + x += i; + i++; + } + return x; +} +"""; + +const String TEST_THREE = r""" +foo(a) { + int x = 0; + for (int i = 0; i < 10; i++) { + if (i == 5) continue; + x += i; + } + return x; +} +"""; + +const String TEST_FOUR = r""" +foo(a) { + int x = 0; + int i = 0; + while (i < 10) { + i++; + if (i == 5) continue; + x += i; + } + return x; +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r'for (')); + }); + await compile(TEST_TWO, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(!generated.contains(r'break')); + }); + await compile(TEST_THREE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r'continue')); + }); + await compile(TEST_FOUR, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r'continue')); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/minify_many_locals_test.dart b/tests/compiler/dart2js/codegen/minify_many_locals_test.dart new file mode 100644 index 0000000..ed902ed --- /dev/null +++ b/tests/compiler/dart2js/codegen/minify_many_locals_test.dart
@@ -0,0 +1,55 @@ +// 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. +// Test that parameters keep their names in the output. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +main() { + runTests({bool useKernel, int numberOfParameters}) async { + StringBuffer buffer = new StringBuffer(); + buffer.write("foo("); + for (int i = 0; i < numberOfParameters; i++) { + buffer.write("x$i, "); + } + buffer.write("x) { int i = "); + for (int i = 0; i < numberOfParameters; i++) { + buffer.write("x$i+"); + } + buffer.write("$numberOfParameters; return i; }"); + String code = buffer.toString(); + + String generated = + await compile(code, entry: 'foo', minify: true, useKernel: useKernel); + RegExp re = new RegExp(r"\(a,b,c"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"x,y,z,a0,a1,a2"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"y,z,a0,a1,a2,a3,a4,a5,a6"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"g8,g9,h0,h1"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"z8,z9,aa0,aa1,aa2"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"aa9,ab0,ab1"); + Expect.isTrue(re.hasMatch(generated)); + + re = new RegExp(r"az9,ba0,ba1"); + Expect.isTrue(re.hasMatch(generated)); + } + + asyncTest(() async { + // The [numberOfParameters] values are somewhat arbitrary. + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false, numberOfParameters: 1800); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true, numberOfParameters: 2000); + }); +}
diff --git a/tests/compiler/dart2js/modulo_remainder_test.dart b/tests/compiler/dart2js/codegen/modulo_remainder_test.dart similarity index 67% rename from tests/compiler/dart2js/modulo_remainder_test.dart rename to tests/compiler/dart2js/codegen/modulo_remainder_test.dart index aef3238..29d8b1b 100644 --- a/tests/compiler/dart2js/modulo_remainder_test.dart +++ b/tests/compiler/dart2js/codegen/modulo_remainder_test.dart
@@ -2,9 +2,8 @@ // for 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:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String MOD1 = r""" foo(param) { @@ -66,16 +65,26 @@ """; main() { - Future check(String test) { - return compile(test, entry: 'foo', check: checkerForAbsentPresent(test)); + runTests({bool useKernel}) async { + check(String test) async { + await compile(test, + entry: 'foo', + useKernel: useKernel, + check: checkerForAbsentPresent(test)); + } + + await check(MOD1); + await check(MOD2); + await check(MOD3); + await check(REM1); + await check(REM2); + await check(REM3); } - asyncTest(() => Future.wait([ - check(MOD1), - check(MOD2), - check(MOD3), - check(REM1), - check(REM2), - check(REM3), - ])); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/no_constructor_body_test.dart b/tests/compiler/dart2js/codegen/no_constructor_body_test.dart new file mode 100644 index 0000000..3d3e8ec --- /dev/null +++ b/tests/compiler/dart2js/codegen/no_constructor_body_test.dart
@@ -0,0 +1,35 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST = r""" +class A { + A.foo() {} + A(); +} +main() { + new A(); + new A.foo(); +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + + Expect.isTrue(generated + .contains(new RegExp('A: {[ \n]*"\\^": "Object;",[ \n]*static:'))); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart new file mode 100644 index 0000000..b90eba5 --- /dev/null +++ b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body2_test.dart
@@ -0,0 +1,39 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../compiler_helper.dart'; +import "package:async_helper/async_helper.dart"; + +const String CODE = """ +var x = 0; +class A { + A() { x++; } +} + +class B extends A { + B(); +} + +main() { + new B(); + new A(); +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(CODE, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + RegExp regexp = new RegExp(r'A\$0: function'); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart new file mode 100644 index 0000000..6bba7dd --- /dev/null +++ b/tests/compiler/dart2js/codegen/no_duplicate_constructor_body_test.dart
@@ -0,0 +1,33 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String CODE = """ +class A { + A(String b) { b.length; } +} + +main() { + new A("foo"); +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(CODE, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + RegExp regexp = new RegExp(r'\A: {[ \n]*"\^": "[A-Za-z]+;"'); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart b/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart new file mode 100644 index 0000000..2c9e0bb6 --- /dev/null +++ b/tests/compiler/dart2js/codegen/no_duplicate_stub_test.dart
@@ -0,0 +1,46 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST = r""" +class A { + foo({a, b}) {} +} + +class B extends A { +} + +main() { + var a = [bar, baz]; + a[0](new A()); + a[1](new A()); +} + +bar(a) { + if (a is A) a.foo(a: 42); +} + +baz(a) { + if (a is B) a.foo(a: 42); +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + RegExp regexp = new RegExp('foo\\\$1\\\$a: function'); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/null_check_test.dart b/tests/compiler/dart2js/codegen/null_check_test.dart new file mode 100644 index 0000000..34bf897 --- /dev/null +++ b/tests/compiler/dart2js/codegen/null_check_test.dart
@@ -0,0 +1,32 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import '../compiler_helper.dart'; +import "package:async_helper/async_helper.dart"; + +const String TEST1 = r""" +main() { + var foo; + if (main() == 5) { + foo = [0]; + } + return foo[0]; +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST1, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isFalse(generated.contains('foo.length')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/boolify_test.dart b/tests/compiler/dart2js/codegen/null_type_test.dart similarity index 60% copy from tests/compiler/dart2js/boolify_test.dart copy to tests/compiler/dart2js/codegen/null_type_test.dart index fb382cb..353e424 100644 --- a/tests/compiler/dart2js/boolify_test.dart +++ b/tests/compiler/dart2js/codegen/null_type_test.dart
@@ -2,32 +2,29 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library boolify_test; - import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; -const String TEST = r""" +const String TEST_ONE = r""" foo() { - var a = foo(); - if (!a) return 1; - return 2; + var c = null; + while (true) c = 1 + c; } """; main() { - test(CompileMode compileMode) async { - await compile(TEST, entry: 'foo', compileMode: compileMode, + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, check: (String generated) { - Expect.isTrue(generated.contains('foo() !== true)')); + Expect.isFalse(generated.contains('typeof (void 0)')); }); } asyncTest(() async { print('--test from ast---------------------------------------------------'); - await test(CompileMode.memory); + await runTest(useKernel: false); print('--test from kernel------------------------------------------------'); - await test(CompileMode.kernel); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/number_output_test.dart b/tests/compiler/dart2js/codegen/number_output_test.dart similarity index 70% rename from tests/compiler/dart2js/number_output_test.dart rename to tests/compiler/dart2js/codegen/number_output_test.dart index 42bd65b..81bc5bc 100644 --- a/tests/compiler/dart2js/number_output_test.dart +++ b/tests/compiler/dart2js/codegen/number_output_test.dart
@@ -5,8 +5,9 @@ import 'dart:async'; import 'package:expect/expect.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:async_helper/async_helper.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': ''' @@ -18,12 +19,19 @@ }''' }; -Future test({bool minify}) async { +Future test({bool useKernel, bool minify}) async { OutputCollector collector = new OutputCollector(); + List<String> options = <String>[]; + if (useKernel) { + options.add(Flags.useKernel); + } + if (minify) { + options.add(Flags.minify); + } await runCompiler( memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector, - options: minify ? ['--minify'] : []); + options: options); // Check that we use the shorter exponential representations. String jsOutput = collector.getOutput('', OutputType.js); @@ -47,8 +55,15 @@ } main() { + runTest({bool useKernel}) async { + await test(useKernel: useKernel, minify: true); + await test(useKernel: useKernel, minify: false); + } + asyncTest(() async { - await test(minify: true); - await test(minify: false); + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart b/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart new file mode 100644 index 0000000..29f6992 --- /dev/null +++ b/tests/compiler/dart2js/codegen/parameter_phi_elimination_test.dart
@@ -0,0 +1,32 @@ +// 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. + +// Regression test. Failed due to trying to detach an HLocal twice. + +// VMOptions=--enable_asserts + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String SOURCE = r""" +bool baz(int a, int b) { + while (a == b || a < b) { + a = a + b; + } + return a == b; +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(SOURCE, entry: "baz", useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/pretty_parameter_test.dart b/tests/compiler/dart2js/codegen/pretty_parameter_test.dart new file mode 100644 index 0000000..d2ca04e --- /dev/null +++ b/tests/compiler/dart2js/codegen/pretty_parameter_test.dart
@@ -0,0 +1,113 @@ +// 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. +// 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 FOO = r""" +void foo(var a, var b) { +} +"""; + +const String BAR = r""" +void bar(var eval, var $eval) { +} +"""; + +const String PARAMETER_AND_TEMP = r""" +void bar(var t0, var b) { + { + var t0 = 2; + if (b) { + bar(1, 2); + t0 = 4; + } else { + t0 = 3; + } + print(t0); + } + print(t0); +} +"""; + +const String NO_LOCAL = r""" +foo(bar, baz) { + if (bar) { + baz = 2; + } else { + baz = 3; + } + return baz; +} +"""; + +const String MULTIPLE_PHIS_ONE_LOCAL = r""" +foo(param1, param2, param3) { + var a = 2; + if (param1) { + if (param2) { + if (param3) { + a = 42; + } + print(a); + } + print(a); + } + print(a); +} +"""; + +const String PARAMETER_INIT = r""" +int foo(var start, bool test) { + var result = start; + if (test) { + foo(1, 2); + result = 42; + } + print(result); +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(FOO, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r"function(a, b) {")); + }); + await compile(BAR, entry: 'bar', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r"function($eval, $$eval) {")); + }); + await compile(PARAMETER_AND_TEMP, entry: 'bar', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains(r"print(t00)")); + // Check that the second 't0' got another name. + Expect.isTrue(generated.contains(r"print(t01)")); + }); + await compile(MULTIPLE_PHIS_ONE_LOCAL, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isTrue(generated.contains("var a;")); + // Check that there is only one var declaration. + checkNumberOfMatches(new RegExp("var").allMatches(generated).iterator, 1); + }); + await compile(NO_LOCAL, entry: 'foo', useKernel: useKernel, + check: (String generated) { + Expect.isFalse(generated.contains('var')); + }); + await compile(PARAMETER_INIT, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Check that there is only one var declaration. + checkNumberOfMatches(new RegExp("var").allMatches(generated).iterator, 1); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart b/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart new file mode 100644 index 0000000..e18c6e3 --- /dev/null +++ b/tests/compiler/dart2js/codegen/redundant_phi_eliminator_test.dart
@@ -0,0 +1,52 @@ +// 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""" +void foo(bar) { + var toBeRemoved = 1; + if (bar) { + } else { + } + print(toBeRemoved); +} +"""; + +const String TEST_TWO = r""" +void foo() { + var temp = 0; + var toBeRemoved = temp; + for (var i = 0; i == 0; i = i + 1) { + toBeRemoved = temp; + } + print(toBeRemoved); +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + RegExp regexp = new RegExp("toBeRemoved"); + Expect.isTrue(!regexp.hasMatch(generated)); + }); + await compile(TEST_TWO, entry: 'foo', useKernel: useKernel, + check: (String generated) { + RegExp regexp = new RegExp("toBeRemoved"); + Expect.isTrue(!regexp.hasMatch(generated)); + regexp = new RegExp("temp"); + Expect.isTrue(!regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/regress_10231_test.dart b/tests/compiler/dart2js/codegen/regress_10231_test.dart new file mode 100644 index 0000000..2c2c242 --- /dev/null +++ b/tests/compiler/dart2js/codegen/regress_10231_test.dart
@@ -0,0 +1,42 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Regression test for http://dartbug.com/10231. + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String SOURCE = """ +test(a, b, c, d) { + if (a is !num) throw 'a not num'; + if (b is !num) throw 'b not num'; + if (c is !num) throw 'c not num'; + if (d is !num) throw 'd not num'; + return a + b + c + d; +} + +main() { + test(1, 2, 3, 4); + test('x', 'y', 'z', 'w'); + test([], {}, [], {}); +} +"""; + +void main() { + runTests({bool useKernel}) async { + String code = + await compile(SOURCE, useKernel: useKernel, methodName: 'test'); + Expect.isNotNull(code); + Expect.equals(0, new RegExp('add').allMatches(code).length); + Expect.equals(3, new RegExp('\\+').allMatches(code).length); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart b/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart new file mode 100644 index 0000000..4d87085 --- /dev/null +++ b/tests/compiler/dart2js/codegen/side_effect_tdiv_regression_test.dart
@@ -0,0 +1,39 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; + +import '../compiler_helper.dart'; + +const String TEST = r''' +class A { + var field = 42; +} +main() { + var a = new A(); + var b = [42, -1]; + // Force a setter on [field]. + if (false) a.field = 12; + var c = a.field; + print(b[0] ~/ b[1]); + return c + a.field; +} +'''; + +void main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST, + compileMode: useKernel ? CompileMode.kernel : CompileMode.mock); + Expect.isTrue(generated.contains('return c + c;')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + // TODO(johnniwinther): This test only works with the mock compiler. + //print('--test from kernel----------------------------------------------'); + //await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/simple_function_subtype_test.dart b/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart similarity index 67% rename from tests/compiler/dart2js/simple_function_subtype_test.dart rename to tests/compiler/dart2js/codegen/simple_function_subtype_test.dart index a1b3a73..7821d4a 100644 --- a/tests/compiler/dart2js/simple_function_subtype_test.dart +++ b/tests/compiler/dart2js/codegen/simple_function_subtype_test.dart
@@ -8,7 +8,7 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = r""" typedef Args0(); @@ -51,13 +51,23 @@ """; main() { - asyncTest(() => compile(TEST, entry: 'foo', check: (String generated) { - for (int i = 0; i <= 15; i++) { - String predicateCheck = '.\$is_args$i'; - Expect.isTrue(generated.contains(predicateCheck), - 'Expected predicate check $predicateCheck'); - } - Expect.isFalse(generated.contains('checkFunctionSubtype'), - 'Unexpected use of checkFunctionSubtype'); - })); + runTest({bool useKernel}) async { + await compile(TEST, entry: 'foo', useKernel: useKernel, + check: (String generated) { + for (int i = 0; i <= 15; i++) { + String predicateCheck = '.\$is_args$i'; + Expect.isTrue(generated.contains(predicateCheck), + 'Expected predicate check $predicateCheck'); + } + Expect.isFalse(generated.contains('checkFunctionSubtype'), + 'Unexpected use of checkFunctionSubtype'); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart b/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart new file mode 100644 index 0000000..8aa46ad --- /dev/null +++ b/tests/compiler/dart2js/codegen/ssa_phi_codegen_test.dart
@@ -0,0 +1,107 @@ +// 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:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +void foo(bar) { + var a = 1; + if (bar) { + a = 2; + } else { + a = 3; + } + print(a); + print(a); +} +"""; + +const String TEST_TWO = r""" +void main() { + var t = 0; + for (var i = 0; i == 0; i = i + 1) { + t = t + 10; + } + print(t); +} +"""; + +const String TEST_THREE = r""" +foo(b, c, d) { + var val = 42; + if (b) { + c = c && d; + if (c) { + val = 43; + } + } + return val; +} +"""; + +const String TEST_FOUR = r""" +foo() { + var a = true; + var b = false; + for (var i = 0; a; i = i + 1) { + if (i == 9) a = false; + for (var j = 0; b; j = j + 1) { + if (j == 9) b = false; + } + } + print(a); + print(b); +} +"""; + +const String TEST_FIVE = r""" +void main() { + var hash = 0; + for (var i = 0; i == 0; i = i + 1) { + hash = hash + 10; + hash = hash + 42; + } + print(t); +} +"""; + +main() { + runTests({bool useKernel}) async { + await compileAndMatchFuzzy(TEST_ONE, 'foo', "var x = x === true \\? 2 : 3;", + useKernel: useKernel); + await compileAndMatchFuzzy(TEST_ONE, 'foo', "print\\(x\\);", + useKernel: useKernel); + + await compileAndMatchFuzzy(TEST_TWO, 'main', "x \\+= 10", + useKernel: useKernel); + await compileAndMatchFuzzy(TEST_TWO, 'main', "\\+\\+x", + useKernel: useKernel); + + // Check that we don't have 'd = d' (using regexp back references). + await compileAndDoNotMatchFuzzy(TEST_THREE, 'foo', '(x) = \1', + useKernel: useKernel); + await compileAndMatchFuzzy(TEST_THREE, 'foo', 'return x', + useKernel: useKernel); + + // Check that a store just after the declaration of the local + // only generates one instruction. + await compileAndMatchFuzzy(TEST_THREE, 'foo', 'x = 42', + useKernel: useKernel); + + await compileAndDoNotMatchFuzzy(TEST_FOUR, 'foo', '(x) = \1;', + useKernel: useKernel); + + await compileAndDoNotMatch(TEST_FIVE, 'main', new RegExp('hash0'), + useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/static_closure_test.dart b/tests/compiler/dart2js/codegen/static_closure_test.dart new file mode 100644 index 0000000..67fe7d1 --- /dev/null +++ b/tests/compiler/dart2js/codegen/static_closure_test.dart
@@ -0,0 +1,35 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that static functions are closurized as expected. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +main() { + runTest({bool useKernel}) async { + String code = await compileAll(r'''main() { print(main); }''', + compileMode: useKernel ? CompileMode.kernel : CompileMode.mock); + // At some point, we will have to closurize global functions + // differently, at which point this test will break. Then it is time + // to implement a way to call a Dart closure from JS foreign + // functions. + + // If this test fail, please take a look at the use of + // toStringWrapper in captureStackTrace in js_helper.dart. + Expect.isTrue( + code.contains( + new RegExp(r'print\([$A-Z]+\.lib___main\$closure\(\)\);')), + code); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + // TODO(johnniwinther): This test only works with the mock compiler. + //print('--test from kernel----------------------------------------------'); + //await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/strength_eq_test.dart b/tests/compiler/dart2js/codegen/strength_eq_test.dart new file mode 100644 index 0000000..c8d9f29 --- /dev/null +++ b/tests/compiler/dart2js/codegen/strength_eq_test.dart
@@ -0,0 +1,40 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Test constant folding on numbers. + +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String CODE = """ +class A { + var link; +} +int foo(x) { + if (new DateTime.now().millisecondsSinceEpoch == 42) return null; + var a = new A(); + if (new DateTime.now().millisecondsSinceEpoch == 42) return a; + a.link = a; + return a; +} +void main() { + var x = foo(0); + return x == x.link; +} +"""; + +main() { + runTest({bool useKernel}) async { + // The `==` is strengthened to a HIdentity instruction. The HIdentity follows + // `x.link`, so x cannot be `null`. + var compare = new RegExp(r'x === x\.get\$link\(\)'); + await compileAndMatch(CODE, 'main', compare, useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/string_add_test.dart b/tests/compiler/dart2js/codegen/string_add_test.dart new file mode 100644 index 0000000..1be733a --- /dev/null +++ b/tests/compiler/dart2js/codegen/string_add_test.dart
@@ -0,0 +1,22 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +main() { + runTest({bool useKernel}) async { + String code = await compileAll(r'''main() { return "foo" + "bar"; }''', + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isTrue(!code.contains(r'$add')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/string_escapes_test.dart b/tests/compiler/dart2js/codegen/string_escapes_test.dart new file mode 100644 index 0000000..14b69d8 --- /dev/null +++ b/tests/compiler/dart2js/codegen/string_escapes_test.dart
@@ -0,0 +1,84 @@ +// 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 'dart:async'; +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +// Test that the compiler handles string literals containing line terminators. + +main() { + runTests({bool useKernel}) async { + Future<String> compileExpression(String expression) { + var source = "foo() { return $expression; }"; + return compile(source, entry: "foo", useKernel: useKernel); + } + + await compileExpression("''' \n\r\u2028\u2029'''").then((String generated) { + Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || + generated.contains(r"'\r\u2028\u2029'")); + }); + await compileExpression("r''' \n\r\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || + generated.contains(r"'\r\u2028\u2029'")); + }); + await compileExpression("r''' \r\n\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + await compileExpression("r''' \r\u2028\u2029'''").then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + await compileExpression("r''' \n\u2028\u2029'''").then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + await compileExpression( + "r'''\t\t \t\t \t\t \t \t \n\r\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || + generated.contains(r"'\r\u2028\u2029'")); + }); + await compileExpression( + "r'''\\\t\\\t \\ \\ \t\\\t \t \\\n\r\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || + generated.contains(r"'\r\u2028\u2029'")); + }); + await compileExpression( + "r'''\t\t \t\t \t\t \t \t \\\n\r\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || + generated.contains(r"'\r\u2028\u2029'")); + }); + await compileExpression( + "r'''\\\t\\\t \\ \\ \t\\\t \\\r\n\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + await compileExpression( + "r'''\\\t\\\t \\ \\ \t\\\t \\\r\u2028\u2029'''") + .then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + await compileExpression("'\u2028\u2029'").then((String generated) { + Expect.isTrue(generated.contains(r'"\u2028\u2029"') || + generated.contains(r"'\u2028\u2029'")); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + // TODO(johnniwinther): This test doesn't work with kernel. + //print('--test from kernel----------------------------------------------'); + //await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/string_interpolation_test.dart b/tests/compiler/dart2js/codegen/string_interpolation_test.dart new file mode 100644 index 0000000..13cbbfa --- /dev/null +++ b/tests/compiler/dart2js/codegen/string_interpolation_test.dart
@@ -0,0 +1,31 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +main() { + runTests({bool useKernel}) async { + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + + String code1 = await compileAll( + r'''main() { return "${2}${true}${'a'}${3.14}"; }''', + compileMode: compileMode); + Expect.isTrue(code1.contains(r'2truea3.14')); + + String code2 = await compileAll( + r'''main() { return "foo ${new Object()}"; }''', + compileMode: compileMode); + Expect.isFalse(code2.contains(r'$add')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/switch_empty_default_test.dart b/tests/compiler/dart2js/codegen/switch_empty_default_test.dart similarity index 70% rename from tests/compiler/dart2js/switch_empty_default_test.dart rename to tests/compiler/dart2js/codegen/switch_empty_default_test.dart index cbddf01..1250ef7 100644 --- a/tests/compiler/dart2js/switch_empty_default_test.dart +++ b/tests/compiler/dart2js/codegen/switch_empty_default_test.dart
@@ -3,9 +3,8 @@ // BSD-style license that can be found in the LICENSE file. // Test constant folding on numbers. -import 'dart:async'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String SIMPLY_EMPTY = """ int foo(x) => x; @@ -120,12 +119,19 @@ var defOrCase3 = new RegExp(r"(default:|case 3):"); var case3 = new RegExp(r"case 3:"); - asyncTest(() => Future.wait([ - compileAndDoNotMatch(SIMPLY_EMPTY, 'main', def), - compileAndDoNotMatch(TOTAL, 'main', defOrCase3), - compileAndDoNotMatch(OPTIMIZED, 'main', def), - compileAndMatch(LABEL, 'main', case3), - compileAndMatch(DEFLABEL, 'main', def), - compileAndMatch(EMPTYDEFLABEL, 'main', def), - ])); + runTests({bool useKernel}) async { + await compileAndDoNotMatch(SIMPLY_EMPTY, 'main', def, useKernel: useKernel); + await compileAndDoNotMatch(TOTAL, 'main', defOrCase3, useKernel: useKernel); + await compileAndDoNotMatch(OPTIMIZED, 'main', def, useKernel: useKernel); + await compileAndMatch(LABEL, 'main', case3, useKernel: useKernel); + await compileAndMatch(DEFLABEL, 'main', def, useKernel: useKernel); + await compileAndMatch(EMPTYDEFLABEL, 'main', def, useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/tdiv_test.dart b/tests/compiler/dart2js/codegen/tdiv_test.dart similarity index 69% rename from tests/compiler/dart2js/tdiv_test.dart rename to tests/compiler/dart2js/codegen/tdiv_test.dart index 73b6ecf..f894754 100644 --- a/tests/compiler/dart2js/tdiv_test.dart +++ b/tests/compiler/dart2js/codegen/tdiv_test.dart
@@ -6,7 +6,7 @@ import 'dart:async'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST1 = r""" foo(param) { @@ -61,15 +61,25 @@ """; main() { - Future check(String test) { - return compile(test, entry: 'foo', check: checkerForAbsentPresent(test)); + runTests({bool useKernel}) async { + Future check(String test) { + return compile(test, + entry: 'foo', + useKernel: useKernel, + check: checkerForAbsentPresent(test)); + } + + await check(TEST1); + await check(TEST2); + await check(TEST3); + await check(TEST4); + await check(TEST5); } - asyncTest(() => Future.wait([ - check(TEST1), - check(TEST2), - check(TEST3), - check(TEST4), - check(TEST5), - ])); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart b/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart new file mode 100644 index 0000000..277c631 --- /dev/null +++ b/tests/compiler/dart2js/codegen/top_level_closure_tree_shake_test.dart
@@ -0,0 +1,42 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +main() { + var f = use; + if (false) { + // This statement and the use of 'foo' should be optimized away, causing + // 'foo' to be absent from the final code. + f(foo); + } + f(bar); +} + +foo() => 'Tarantula!'; +bar() => 'Coelacanth!'; + +use(x) { + print(x()); +} +"""; + +main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST_ONE, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isFalse(generated.contains('Tarantula!'), "failed to remove 'foo'"); + Expect.isTrue(generated.contains('Coelacanth!')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/tree_shaking_test.dart b/tests/compiler/dart2js/codegen/tree_shaking_test.dart new file mode 100644 index 0000000..4d47a5f --- /dev/null +++ b/tests/compiler/dart2js/codegen/tree_shaking_test.dart
@@ -0,0 +1,43 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST = r""" +class A { + foo() => bar(); + bar() => 42; +} +class B extends A { + bar() => 54; +} +class C implements A { + bar() => 68; +} +main() { + new A(); + new B(); + new C(); + new A().foo(); +} +"""; + +void main() { + runTest({bool useKernel}) async { + String generated = await compileAll(TEST, + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + Expect.isTrue(generated.contains('return 42')); + Expect.isTrue(generated.contains('return 54')); + Expect.isFalse(generated.contains('return 68')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart new file mode 100644 index 0000000..40e7651 --- /dev/null +++ b/tests/compiler/dart2js/codegen/trust_type_annotations2_test.dart
@@ -0,0 +1,48 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; +import 'package:compiler/src/commandline_options.dart'; +import '../memory_compiler.dart'; + +const MEMORY_SOURCE_FILES = const { + 'main.dart': ''' + +foo(int x, int y) { + return x + y; +} + +main (x, y) { + if (x != null) { + if (y != null) { + return foo(x, y); + } + } +} +''', +}; + +main() { + runTest({bool useKernel}) async { + var options = [Flags.trustTypeAnnotations]; + if (useKernel) { + options.add(Flags.useKernel); + } + var result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, options: options); + var compiler = result.compiler; + var element = + compiler.backendClosedWorldForTesting.elementEnvironment.mainFunction; + var code = compiler.backend.getGeneratedCode(element); + Expect.isTrue(code.contains('+'), code); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart new file mode 100644 index 0000000..1f09909 --- /dev/null +++ b/tests/compiler/dart2js/codegen/trust_type_annotations_test.dart
@@ -0,0 +1,97 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import '../compiler_helper.dart'; +import '../memory_compiler.dart'; + +const String TEST = """ +class A { + int aField; + + A(this.aField); + + // Test return type annotation. + int foo(a) => a; + // Test parameter type annotation. + faa (int a) => a; + // Test annotations on locals. + baz(x) { + int y = x; + return y; + } + // Test tear-off closure type annotations. + int bar(x) => x; + int tear(x) { + var torn = bar; + // Have torn escape through closure to disable tracing. + var fail = (() => torn)(); + return fail(x); + } +} + +main () { + var a = new A("42"); + print(a.aField); + print(a.foo("42")); + print(a.foo(42)); + print(a.faa("42")); + print(a.faa(42)); + print(a.baz("42")); + print(a.baz(42)); + // Test trusting types of tear off closures. + print(a.tear("42")); + print(a.tear(42)); +} +"""; + +void main() { + runTest({bool useKernel}) async { + var options = [Flags.trustTypeAnnotations]; + if (useKernel) { + options.add(Flags.useKernel); + } + var result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, options: options); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + + ClassEntity classA = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, "A"); + + checkReturn(String name, TypeMask type) { + MemberEntity element = elementEnvironment.lookupClassMember(classA, name); + var mask = typesInferrer.getReturnTypeOfMember(element); + Expect.isTrue(type.containsMask(mask, closedWorld)); + } + + checkType(String name, type) { + MemberEntity element = elementEnvironment.lookupClassMember(classA, name); + Expect.isTrue(type.containsMask( + typesInferrer.getTypeOfMember(element), closedWorld)); + } + + var intMask = + new TypeMask.subtype(closedWorld.commonElements.intClass, closedWorld); + + checkReturn('foo', intMask); + checkReturn('faa', intMask); + checkType('aField', intMask); + checkReturn('bar', intMask); + checkReturn('baz', intMask); + checkReturn('tear', intMask); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart b/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart new file mode 100644 index 0000000..43bd9e8 --- /dev/null +++ b/tests/compiler/dart2js/codegen/type_guard_unuser_test.dart
@@ -0,0 +1,78 @@ +// 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(a) { + int b = foo(true); + if (a) b = foo(2); + return b; +} +"""; + +const String TEST_TWO = r""" +bar(a) {} +foo(d) { + int a = 1; + int c = foo(1); + if (true) {} + return a + c; +} +"""; + +const String TEST_THREE = r""" +foo(int a, int b) { + return 0 + a + b; +} +"""; + +const String TEST_THREE_WITH_BAILOUT = r""" +foo(int a, int b) { + var t; + for (int i = 0; i < 1; i++) { + t = 0 + a + b; + } + return t; +} +"""; + +main() { + runTests({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', check: (String generated) { + RegExp regexp = new RegExp(getIntTypeCheck(anyIdentifier)); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 0); + Expect.isTrue(generated.contains( + new RegExp(r'return a === true \? [$A-Z]+\.foo\(2\) : b;'))); + }); + await compile(TEST_TWO, entry: 'foo', check: (String generated) { + RegExp regexp = new RegExp("foo\\(1\\)"); + Iterator<Match> matches = regexp.allMatches(generated).iterator; + checkNumberOfMatches(matches, 1); + }); + await compile(TEST_THREE, entry: 'foo', check: (String generated) { + RegExp regexp = new RegExp(getNumberTypeCheck('a')); + Expect.isTrue(regexp.hasMatch(generated)); + regexp = new RegExp(getNumberTypeCheck('b')); + Expect.isTrue(regexp.hasMatch(generated)); + }); + await compile(TEST_THREE_WITH_BAILOUT, entry: 'foo', + check: (String generated) { + RegExp regexp = new RegExp(getNumberTypeCheck('a')); + Expect.isTrue(regexp.hasMatch(generated)); + regexp = new RegExp(getNumberTypeCheck('b')); + Expect.isTrue(regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/type_inference2_test.dart b/tests/compiler/dart2js/codegen/type_inference2_test.dart new file mode 100644 index 0000000..60b8899 --- /dev/null +++ b/tests/compiler/dart2js/codegen/type_inference2_test.dart
@@ -0,0 +1,27 @@ +// 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:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +sum(param0, param1) { + var sum = 0; + for (var i = param0; i < param1; i += 1) sum = sum + i; + return sum; +} +"""; + +main() { + runTest({bool useKernel}) async { + await compileAndMatchFuzzy(TEST_ONE, 'sum', r"\+\+x", useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/type_inference3_test.dart b/tests/compiler/dart2js/codegen/type_inference3_test.dart new file mode 100644 index 0000000..1173171 --- /dev/null +++ b/tests/compiler/dart2js/codegen/type_inference3_test.dart
@@ -0,0 +1,32 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import '../compiler_helper.dart'; + +const String TEST_ONE = r""" +sum(param0, param1) { + var sum = 0; + for (var i = param0; i < param1; i += 1) sum = sum + i; + return sum; +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'sum', useKernel: useKernel, + check: (String generated) { + RegExp regexp = new RegExp(getNumberTypeCheck('(param1|b)')); + Expect.isTrue(regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/type_inference4_test.dart b/tests/compiler/dart2js/codegen/type_inference4_test.dart new file mode 100644 index 0000000..300826d --- /dev/null +++ b/tests/compiler/dart2js/codegen/type_inference4_test.dart
@@ -0,0 +1,39 @@ +// 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(j) { + var array = [1, 2, 3]; + if (j < 0) j = 0; + for (var i = j; i < 3; i++) { + array[i]; + } +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Test for absence of an illegal argument exception. This means that the + // arguments are known to be integers. + Expect.isFalse(generated.contains('iae')); + // Also make sure that we are not just in bailout mode without speculative + // types by grepping for the integer-bailout check on argument j. + RegExp regexp = new RegExp(getIntTypeCheck('[aji]')); + Expect.isTrue(regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/type_inference5_test.dart b/tests/compiler/dart2js/codegen/type_inference5_test.dart new file mode 100644 index 0000000..3e43f2b --- /dev/null +++ b/tests/compiler/dart2js/codegen/type_inference5_test.dart
@@ -0,0 +1,41 @@ +// 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(j) { + var a = [1, 2, 3]; + for (var i = j; i < 3; i++) { + a[i]; + } +} +"""; + +main() { + runTest({bool useKernel}) async { + await compile(TEST_ONE, entry: 'foo', useKernel: useKernel, + check: (String generated) { + // Test for absence of an illegal argument exception. This means that the + // arguments are known to be integers. + Expect.isFalse(generated.contains('iae')); + // Also make sure that we are not just in bailout mode without speculative + // types by grepping for the integer-bailout check on argument j. + var argname = new RegExp(r'function(?: [a-z]+)?\(([a-zA-Z0-9_]+)\)') + .firstMatch(generated)[1]; + print(argname); + RegExp regexp = new RegExp(getIntTypeCheck("(i|$argname)")); + Expect.isTrue(regexp.hasMatch(generated)); + }); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart b/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart new file mode 100644 index 0000000..02d60de --- /dev/null +++ b/tests/compiler/dart2js/codegen/types_of_captured_variables_test.dart
@@ -0,0 +1,62 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; +import '../compiler_helper.dart'; + +const String TEST1 = r""" +main() { + var a = 52; + var f = () => a + 87; + f(); +} +"""; + +const String TEST2 = r""" +main() { + var a = 52; + var g = () { a = 48; }; + var f = () => a + 87; + f(); + g(); +} +"""; + +const String TEST3 = r""" +main() { + var a = 52; + var g = () { a = 'foo'; }; + var f = () => a + 87; + f(); + g(); +} +"""; + +main() { + runTests({bool useKernel}) async { + CompileMode compileMode = + useKernel ? CompileMode.kernel : CompileMode.memory; + + // Test that we know the type of captured, non-mutated variables. + String generated1 = await compileAll(TEST1, compileMode: compileMode); + Expect.isTrue(generated1.contains('+ 87')); + + // Test that we know the type of captured, mutated variables. + String generated2 = await compileAll(TEST2, compileMode: compileMode); + Expect.isTrue(generated2.contains('+ 87')); + + // Test that we know when types of a captured, mutated variable + // conflict. + String generated3 = await compileAll(TEST3, compileMode: compileMode); + Expect.isFalse(generated3.contains('+ 87')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/unused_empty_map_test.dart b/tests/compiler/dart2js/codegen/unused_empty_map_test.dart similarity index 62% rename from tests/compiler/dart2js/unused_empty_map_test.dart rename to tests/compiler/dart2js/codegen/unused_empty_map_test.dart index 62e6e06..0b52c0c 100644 --- a/tests/compiler/dart2js/unused_empty_map_test.dart +++ b/tests/compiler/dart2js/codegen/unused_empty_map_test.dart
@@ -4,10 +4,11 @@ // Ensure that unused empty HashMap nodes are dropped from the output. -import 'package:expect/expect.dart'; -import 'package:compiler/compiler_new.dart'; import 'package:async_helper/async_helper.dart'; -import 'memory_compiler.dart'; +import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; +import '../memory_compiler.dart'; const TEST_SOURCE = const { "main.dart": r""" @@ -21,11 +22,20 @@ const HASHMAP_EMPTY_CONSTRUCTOR = r"LinkedHashMap_LinkedHashMap$_empty"; main() { - asyncTest(() async { + runTest({bool useKernel}) async { var collector = new OutputCollector(); await runCompiler( - memorySourceFiles: TEST_SOURCE, outputProvider: collector); + memorySourceFiles: TEST_SOURCE, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); String generated = collector.getOutput('', OutputType.js); Expect.isFalse(generated.contains(HASHMAP_EMPTY_CONSTRUCTOR)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/codegen/use_checks_test.dart b/tests/compiler/dart2js/codegen/use_checks_test.dart new file mode 100644 index 0000000..7647e8f --- /dev/null +++ b/tests/compiler/dart2js/codegen/use_checks_test.dart
@@ -0,0 +1,45 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; +import '../memory_compiler.dart'; + +const MEMORY_SOURCE_FILES = const { + 'main.dart': ''' +main (x, y) { + if (x != null) { + if (y != null) { + // Forces x and y to be int-checked. + int a = x; + int b = y; + // Now we must be able to do a direct "+" operation in JS. + return x + y; + } + } +} +''', +}; + +main() { + runTest({bool useKernel}) async { + var options = [Flags.enableCheckedMode]; + if (useKernel) options.add(Flags.useKernel); + var result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, options: options); + var compiler = result.compiler; + var element = + compiler.backendClosedWorldForTesting.elementEnvironment.mainFunction; + var code = compiler.backend.getGeneratedCode(element); + Expect.isTrue(code.contains('+'), code); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/use_strict_test.dart b/tests/compiler/dart2js/codegen/use_strict_test.dart similarity index 76% rename from tests/compiler/dart2js/use_strict_test.dart rename to tests/compiler/dart2js/codegen/use_strict_test.dart index 4e86dbb..b11d254 100644 --- a/tests/compiler/dart2js/use_strict_test.dart +++ b/tests/compiler/dart2js/codegen/use_strict_test.dart
@@ -4,8 +4,9 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; // Use strict does not allow parameters or locals named "arguments" or "eval". @@ -47,10 +48,12 @@ }; main() { - OutputCollector collector = new OutputCollector(); - asyncTest(() async { + runTest({bool useKernel}) async { + OutputCollector collector = new OutputCollector(); await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); String jsOutput = collector.getOutput('', OutputType.js); // Skip comments. @@ -64,5 +67,12 @@ // 'arguments'. RegExp re = new RegExp(r'[^\w$](arguments|eval)[^\w$]'); Expect.isFalse(re.hasMatch(filtered)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/value_range2_test.dart b/tests/compiler/dart2js/codegen/value_range2_test.dart similarity index 100% rename from tests/compiler/dart2js/value_range2_test.dart rename to tests/compiler/dart2js/codegen/value_range2_test.dart
diff --git a/tests/compiler/dart2js/codegen/value_range3_test.dart b/tests/compiler/dart2js/codegen/value_range3_test.dart new file mode 100644 index 0000000..9296662 --- /dev/null +++ b/tests/compiler/dart2js/codegen/value_range3_test.dart
@@ -0,0 +1,44 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that global analysis in dart2js propagates positive integers. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; +import '../memory_compiler.dart'; + +const MEMORY_SOURCE_FILES = const { + 'main.dart': ''' + +var a = [42]; + +main() { + var value = a[0]; + if (value < 42) { + return new List(42)[value]; + } +} +''', +}; + +main() { + runTest({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var element = + compiler.backendClosedWorldForTesting.elementEnvironment.mainFunction; + var code = compiler.backend.getGeneratedCode(element); + Expect.isFalse(code.contains('ioore')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/value_range_kernel_test.dart b/tests/compiler/dart2js/codegen/value_range_kernel_test.dart new file mode 100644 index 0000000..1e133d6 --- /dev/null +++ b/tests/compiler/dart2js/codegen/value_range_kernel_test.dart
@@ -0,0 +1,14 @@ +// 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:async_helper/async_helper.dart'; +import 'value_range_test_helper.dart'; + +main() { + asyncTest(() async { + // AST part tested in 'value_range_test.dart'. + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/codegen/value_range_test.dart b/tests/compiler/dart2js/codegen/value_range_test.dart new file mode 100644 index 0000000..e03aa79 --- /dev/null +++ b/tests/compiler/dart2js/codegen/value_range_test.dart
@@ -0,0 +1,14 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'value_range_test_helper.dart'; + +main() { + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + // Kernel part tested in 'value_range_kernel_test.dart'. + }); +}
diff --git a/tests/compiler/dart2js/value_range_test.dart b/tests/compiler/dart2js/codegen/value_range_test_helper.dart similarity index 88% rename from tests/compiler/dart2js/value_range_test.dart rename to tests/compiler/dart2js/codegen/value_range_test_helper.dart index fe7c1de..c486048 100644 --- a/tests/compiler/dart2js/value_range_test.dart +++ b/tests/compiler/dart2js/codegen/value_range_test_helper.dart
@@ -1,11 +1,10 @@ -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// 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:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const int REMOVED = 0; const int ABOVE_ZERO = 1; @@ -242,11 +241,8 @@ BELOW_ZERO_CHECK, ]; -// TODO(ahe): It would probably be better if this test used the real -// core library sources, as its purpose is to detect failure to -// optimize fixed-sized arrays. -Future expect(String code, int kind) { - return compile(code, check: (String generated) { +Future expect(String code, int kind, {bool useKernel}) { + return compile(code, useKernel: useKernel, check: (String generated) { switch (kind) { case REMOVED: Expect.isTrue(!generated.contains('ioore')); @@ -287,14 +283,8 @@ }); } -main() { - int i = 0; - Future testNext() { - return expect(TESTS[i], TESTS[i + 1]).then((_) { - i += 2; - if (i < TESTS.length) return testNext(); - }); +runTests({bool useKernel}) async { + for (int i = 0; i < TESTS.length; i += 2) { + await expect(TESTS[i], TESTS[i + 1], useKernel: useKernel); } - - asyncTest(() => testNext()); }
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart deleted file mode 100644 index a5f37bc..0000000 --- a/tests/compiler/dart2js/codegen_helper.dart +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:compiler/src/options.dart' show CompilerOptions; -import 'package:compiler/src/null_compiler_output.dart'; -import 'memory_source_file_helper.dart'; - -Future<Map<String, String>> generate(String code, - [List<String> options = const []]) { - Uri script = currentDirectory.resolveUri(Platform.script); - Uri libraryRoot = script.resolve('../../../sdk/'); - Uri packageRoot = script.resolve('./packages/'); - - var provider = new MemorySourceFileProvider({'main.dart': code}); - var handler = new FormattingDiagnosticHandler(provider); - - Uri uri = Uri.parse('memory:main.dart'); - CompilerImpl compiler = new CompilerImpl( - provider, - const NullCompilerOutput(), - handler, - new CompilerOptions.parse( - entryPoint: uri, - libraryRoot: libraryRoot, - packageRoot: packageRoot, - options: options)); - return compiler.run(uri).then((success) { - Expect.isTrue(success); - Map<String, String> result = new Map<String, String>(); - var backend = compiler.backend; - for (dynamic element in backend.generatedCode.keys) { - if (element.compilationUnit.script.readableUri != uri) continue; - var name = element.name; - var code = backend.getGeneratedCode(element); - result[name] = code; - } - return result; - }); -}
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart index 9462622..05f79fd 100644 --- a/tests/compiler/dart2js/compiler_helper.dart +++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -16,12 +16,8 @@ export 'package:compiler/src/elements/elements.dart'; import 'package:compiler/src/js_backend/js_backend.dart' as js; -import 'package:compiler/src/js_backend/element_strategy.dart' - show ElementCodegenWorkItem; import 'package:compiler/src/commandline_options.dart'; -import 'package:compiler/src/common/codegen.dart'; -import 'package:compiler/src/common/resolution.dart'; export 'package:compiler/src/diagnostics/messages.dart'; export 'package:compiler/src/diagnostics/source_span.dart'; @@ -38,17 +34,17 @@ export 'package:compiler/src/tree/tree.dart'; -import 'mock_compiler.dart'; -export 'mock_compiler.dart'; +import 'old_frontend/mock_compiler.dart'; +export 'old_frontend/mock_compiler.dart'; -import 'memory_compiler.dart' hide compilerFor; +import 'memory_compiler.dart'; import 'output_collector.dart'; export 'output_collector.dart'; enum CompileMode { mock, memory, kernel } -/// Compile [code] and returns either the code for [entry] or, if [returnAll] is +/// Compile [code] and returns either the code for [methodName] or, if [returnAll] is /// true, the code for the entire program. /// /// If [check] is provided, it is executed on the code for [entry] before @@ -56,97 +52,61 @@ /// compilation, otherwise the memory compiler is used. Future<String> compile(String code, {String entry: 'main', + String methodName, bool enableTypeAssertions: false, bool minify: false, bool analyzeAll: false, bool disableInlining: true, bool trustJSInteropTypeAnnotations: false, - CompileMode compileMode: CompileMode.memory, + bool useKernel: false, void check(String generatedEntry), bool returnAll: false}) async { OutputCollector outputCollector = returnAll ? new OutputCollector() : null; - if (compileMode == CompileMode.mock) { - // TODO(johnniwinther): Remove this when no longer needed by - // `arithmetic_simplication_test.dart`. - MockCompiler compiler = new MockCompiler.internal( - enableTypeAssertions: enableTypeAssertions, - // Type inference does not run when manually - // compiling a method. - disableTypeInference: true, - enableMinification: minify, - disableInlining: disableInlining, - trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations, - outputProvider: outputCollector); - await compiler.init(); - compiler.parseScript(code); - ElementEnvironment elementEnvironment = - compiler.frontendStrategy.elementEnvironment; - MethodElement element = compiler.mainApp.find(entry); - if (element == null) return null; - compiler.phase = Compiler.PHASE_RESOLVING; - compiler.processQueue(elementEnvironment, compiler.enqueuer.resolution, - element, compiler.libraryLoader.libraries); - ResolutionWorkItem resolutionWork = - new ResolutionWorkItem(compiler.resolution, element); - resolutionWork.run(); - ClosedWorld closedWorld = compiler.closeResolution(element).closedWorld; - CodegenWorkItem work = - new ElementCodegenWorkItem(compiler.backend, closedWorld, element); - compiler.phase = Compiler.PHASE_COMPILING; - work.run(); - js.JavaScriptBackend backend = compiler.backend; - String generated = backend.getGeneratedCode(element); - if (check != null) { - check(generated); - } - return returnAll ? outputCollector.getOutput('', OutputType.js) : generated; - } else { - List<String> options = <String>[Flags.disableTypeInference]; - if (enableTypeAssertions) { - options.add(Flags.enableCheckedMode); - } - if (minify) { - options.add(Flags.minify); - } - if (analyzeAll) { - options.add(Flags.analyzeAll); - } - if (trustJSInteropTypeAnnotations) { - options.add(Flags.trustJSInteropTypeAnnotations); - } - if (compileMode == CompileMode.kernel) { - options.add(Flags.useKernel); - } - - if (disableInlining) { - options.add(Flags.disableInlining); - } - - Map<String, String> source; - if (entry != 'main') { - source = {'main.dart': "$code\n\nmain() => $entry;"}; - } else { - source = {'main.dart': code}; - } - - CompilationResult result = await runCompiler( - memorySourceFiles: source, - options: options, - outputProvider: outputCollector); - Expect.isTrue(result.isSuccess); - Compiler compiler = result.compiler; - ClosedWorld closedWorld = compiler.backendClosedWorldForTesting; - ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; - LibraryEntity mainLibrary = elementEnvironment.mainLibrary; - FunctionEntity element = - elementEnvironment.lookupLibraryMember(mainLibrary, entry); - js.JavaScriptBackend backend = compiler.backend; - String generated = backend.getGeneratedCode(element); - if (check != null) { - check(generated); - } - return returnAll ? outputCollector.getOutput('', OutputType.js) : generated; + List<String> options = <String>[Flags.disableTypeInference]; + if (enableTypeAssertions) { + options.add(Flags.enableCheckedMode); } + if (minify) { + options.add(Flags.minify); + } + if (analyzeAll) { + options.add(Flags.analyzeAll); + } + if (trustJSInteropTypeAnnotations) { + options.add(Flags.trustJSInteropTypeAnnotations); + } + if (useKernel) { + options.add(Flags.useKernel); + } + if (disableInlining) { + options.add(Flags.disableInlining); + } + + Map<String, String> source; + methodName ??= entry; + if (entry != 'main') { + source = {'main.dart': "$code\n\nmain() => $entry;"}; + } else { + source = {'main.dart': code}; + } + + CompilationResult result = await runCompiler( + memorySourceFiles: source, + options: options, + outputProvider: outputCollector); + Expect.isTrue(result.isSuccess); + Compiler compiler = result.compiler; + ClosedWorld closedWorld = compiler.backendClosedWorldForTesting; + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; + LibraryEntity mainLibrary = elementEnvironment.mainLibrary; + FunctionEntity element = + elementEnvironment.lookupLibraryMember(mainLibrary, methodName); + js.JavaScriptBackend backend = compiler.backend; + String generated = backend.getGeneratedCode(element); + if (check != null) { + check(generated); + } + return returnAll ? outputCollector.getOutput('', OutputType.js) : generated; } Future<String> compileAll(String code, @@ -155,32 +115,62 @@ bool trustTypeAnnotations: false, bool minify: false, int expectedErrors, - int expectedWarnings}) { - Uri uri = new Uri(scheme: 'source'); + int expectedWarnings, + CompileMode compileMode: CompileMode.mock}) async { OutputCollector outputCollector = new OutputCollector(); - MockCompiler compiler = compilerFor(code, uri, - coreSource: coreSource, - disableInlining: disableInlining, - minify: minify, - expectedErrors: expectedErrors, - trustTypeAnnotations: trustTypeAnnotations, - expectedWarnings: expectedWarnings, - outputProvider: outputCollector); - compiler.diagnosticHandler = createHandler(compiler, code); - return compiler.run(uri).then((compilationSucceded) { + if (compileMode == CompileMode.mock) { + Uri uri = new Uri(scheme: 'source'); + MockCompiler compiler = mockCompilerFor(code, uri, + coreSource: coreSource, + disableInlining: disableInlining, + minify: minify, + expectedErrors: expectedErrors, + trustTypeAnnotations: trustTypeAnnotations, + expectedWarnings: expectedWarnings, + outputProvider: outputCollector); + compiler.diagnosticHandler = createHandler(compiler, code); + bool compilationSucceeded = await compiler.run(uri); Expect.isTrue( - compilationSucceded, + compilationSucceeded, 'Unexpected compilation error(s): ' '${compiler.diagnosticCollector.errors}'); - return outputCollector.getOutput('', OutputType.js); - }); + } else { + DiagnosticCollector diagnosticCollector = new DiagnosticCollector(); + if (coreSource != null) { + throw new UnsupportedError( + 'coreSource is not supported for $compileMode'); + } + List<String> options = <String>[]; + if (disableInlining) { + options.add(Flags.disableInlining); + } + if (trustTypeAnnotations) { + options.add(Flags.trustTypeAnnotations); + } + if (minify) { + options.add(Flags.minify); + } + if (compileMode == CompileMode.kernel) { + options.add(Flags.useKernel); + } + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': code}, + options: options, + outputProvider: outputCollector, + diagnosticHandler: diagnosticCollector); + Expect.isTrue( + result.isSuccess, + 'Unexpected compilation error(s): ' + '${diagnosticCollector.errors}'); + } + return outputCollector.getOutput('', OutputType.js); } Future analyzeAndCheck( String code, String name, check(MockCompiler compiler, Element element), {int expectedErrors, int expectedWarnings}) { Uri uri = new Uri(scheme: 'source'); - MockCompiler compiler = compilerFor(code, uri, + MockCompiler compiler = mockCompilerFor(code, uri, expectedErrors: expectedErrors, expectedWarnings: expectedWarnings, analyzeOnly: true); @@ -196,7 +186,7 @@ Uri mainUri = base.resolve('main.dart'); String mainCode = sources['main.dart']; Expect.isNotNull(mainCode, 'No source code found for "main.dart"'); - MockCompiler compiler = compilerFor(mainCode, mainUri); + MockCompiler compiler = mockCompilerFor(mainCode, mainUri); sources.forEach((String path, String code) { if (path == 'main.dart') return; compiler.registerSource(base.resolve(path), code); @@ -239,8 +229,8 @@ } Future compileAndMatch(String code, String entry, RegExp regexp, - {CompileMode compileMode: CompileMode.memory}) { - return compile(code, entry: entry, compileMode: compileMode, + {bool useKernel: false}) { + return compile(code, entry: entry, useKernel: useKernel, check: (String generated) { Expect.isTrue( regexp.hasMatch(generated), '"$generated" does not match /$regexp/'); @@ -248,8 +238,8 @@ } Future compileAndDoNotMatch(String code, String entry, RegExp regexp, - {CompileMode compileMode: CompileMode.memory}) { - return compile(code, entry: entry, compileMode: compileMode, + {bool useKernel: false}) { + return compile(code, entry: entry, useKernel: useKernel, check: (String generated) { Expect.isFalse( regexp.hasMatch(generated), '"$generated" has a match in /$regexp/'); @@ -260,17 +250,22 @@ // Does a compile and then a match where every 'x' is replaced by something // that matches any variable, and every space is optional. -Future compileAndMatchFuzzy(String code, String entry, String regexp) { - return compileAndMatchFuzzyHelper(code, entry, regexp, true); +Future compileAndMatchFuzzy(String code, String entry, String regexp, + {bool useKernel: false}) { + return compileAndMatchFuzzyHelper(code, entry, regexp, + shouldMatch: true, useKernel: useKernel); } -Future compileAndDoNotMatchFuzzy(String code, String entry, String regexp) { - return compileAndMatchFuzzyHelper(code, entry, regexp, false); +Future compileAndDoNotMatchFuzzy(String code, String entry, String regexp, + {bool useKernel: false}) { + return compileAndMatchFuzzyHelper(code, entry, regexp, + shouldMatch: false, useKernel: useKernel); } -Future compileAndMatchFuzzyHelper( - String code, String entry, String regexp, bool shouldMatch) { - return compile(code, entry: entry, check: (String generated) { +Future compileAndMatchFuzzyHelper(String code, String entry, String regexp, + {bool shouldMatch, bool useKernel: false}) { + return compile(code, entry: entry, useKernel: useKernel, + check: (String generated) { final xRe = new RegExp('\\bx\\b'); regexp = regexp.replaceAll(xRe, '(?:$anyIdentifier)'); final spaceRe = new RegExp('\\s+');
diff --git a/tests/compiler/dart2js/constant_folding_codeUnitAt_test.dart b/tests/compiler/dart2js/constant_folding_codeUnitAt_test.dart deleted file mode 100644 index 5e2ff3c..0000000 --- a/tests/compiler/dart2js/constant_folding_codeUnitAt_test.dart +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Test constant folding on numbers. - -import 'dart:async'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_1 = """ -foo() { - var a = 'Hello'; - var b = 0; - return a.codeUnitAt(b); -} -"""; - -// No folding of index type error. -const String TEST_2 = """ -foo() { - var a = 'Hello'; - var b = 1.5; - return a.codeUnitAt(b); -} -"""; - -// No folding of index range error. -const String TEST_3 = """ -foo() { - var a = 'Hello'; - var b = 55; - return a.codeUnitAt(b); -} -"""; - -main() { - asyncTest(() => Future.wait([ - compileAndMatch(TEST_1, 'foo', new RegExp(r'return 72')), - compileAndDoNotMatch(TEST_1, 'foo', new RegExp(r'Hello')), - compileAndMatch(TEST_2, 'foo', new RegExp(r'Hello')), - compileAndMatch(TEST_3, 'foo', new RegExp(r'Hello')), - ])); -}
diff --git a/tests/compiler/dart2js/constant_folding_test.dart b/tests/compiler/dart2js/constant_folding_test.dart deleted file mode 100644 index 0c25553..0000000 --- a/tests/compiler/dart2js/constant_folding_test.dart +++ /dev/null
@@ -1,84 +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 constant folding on numbers. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String NUMBER_FOLDING = """ -void main() { - var a = 4; - var b = 3; - print(a + b); -} -"""; - -const String NEGATIVE_NUMBER_FOLDING = """ -void main() { - var a = 4; - var b = -3; - print(a + b); -} -"""; - -const String NULL_EQUALS_FOLDING = """ -foo(a, b, c, d) { - if (a == null) return 1; - if (null == b) return 2; - if (4 == c) return 3; - if ("foo" == d) return 3; -} -"""; - -const String LIST_LENGTH_FOLDING = """ -foo() { - return const [1, 2, 3].length; -} -"""; - -const String STRING_LENGTH_FOLDING = """ -foo() { - return '123'.length; -} -"""; - -const String LIST_INDEX_FOLDING = """ -foo() { - return const [1, 2, 3][0]; -} -"""; - -const String RANGE_ERROR_INDEX_FOLDING = """ -foo() { - return [1][1]; -} -"""; - -main() { - asyncTest(() => Future.wait([ - compileAndMatch(NUMBER_FOLDING, 'main', new RegExp(r"print\(7\)")), - compileAndMatch( - NEGATIVE_NUMBER_FOLDING, 'main', new RegExp(r"print\(1\)")), - compile(NULL_EQUALS_FOLDING, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp(r'a == null'); - Expect.isTrue(regexp.hasMatch(generated)); - - regexp = new RegExp(r'null == b'); - Expect.isTrue(regexp.hasMatch(generated)); - - regexp = new RegExp(r'4 === c'); - Expect.isTrue(regexp.hasMatch(generated)); - - regexp = new RegExp('"foo" === d'); - Expect.isTrue(regexp.hasMatch(generated)); - }), - compileAndMatch(LIST_LENGTH_FOLDING, 'foo', new RegExp(r"return 3")), - compileAndMatch(LIST_INDEX_FOLDING, 'foo', new RegExp(r"return 1")), - compileAndDoNotMatch(LIST_INDEX_FOLDING, 'foo', new RegExp(r"ioore")), - compileAndMatch(STRING_LENGTH_FOLDING, 'foo', new RegExp(r"return 3")), - compileAndMatch(RANGE_ERROR_INDEX_FOLDING, 'foo', new RegExp(r"ioore")), - ])); -}
diff --git a/tests/compiler/dart2js/constant_namer_test.dart b/tests/compiler/dart2js/constant_namer_test.dart deleted file mode 100644 index b59fbf66..0000000 --- a/tests/compiler/dart2js/constant_namer_test.dart +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" - class Token { - final name; - final value; - const Token(this.name, [this.value]); - use() { print(this); } - } - test() { - const [12,53].use(); - const Token('start').use(); - const Token('end').use(); - const Token('yes', 12).use(); - const Token(true, false).use(); - } -"""; - -main() { - check(generated, text) { - Expect.isTrue(generated.contains(text), text); - } - - asyncTest(() => compile(TEST_ONE, entry: 'test').then((String generated) { - check(generated, '.List_12_53.'); - check(generated, '.Token_start_null.'); - check(generated, '.Token_end_null.'); - check(generated, '.Token_yes_12.'); - check(generated, '.Token_true_false.'); - })); -}
diff --git a/tests/compiler/dart2js/container_mask_equal_test.dart b/tests/compiler/dart2js/container_mask_equal_test.dart deleted file mode 100644 index 978797d..0000000 --- a/tests/compiler/dart2js/container_mask_equal_test.dart +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Regression test for dart2js that used to have a bogus -// implementation of var.== and -// var.hashCode. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; - -const MEMORY_SOURCE_FILES = const { - 'main.dart': ''' - -import 'dart:typed_data'; - -a() => [0]; -b() => [1, 2]; -c() => new Uint8List(1); -d() => new Uint8List(2); - -main() { - print(a); print(b); print(c); print(d); -} -''', -}; - -main() { - asyncTest(() async { - var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); - var compiler = result.compiler; - var typesInferrer = compiler.globalInference.typesInferrerInternal; - var closedWorld = typesInferrer.closedWorld; - - var element = - compiler.frontendStrategy.elementEnvironment.mainLibrary.find('a'); - var mask1 = typesInferrer.getReturnTypeOfMember(element); - - element = - compiler.frontendStrategy.elementEnvironment.mainLibrary.find('b'); - var mask2 = typesInferrer.getReturnTypeOfMember(element); - - element = - compiler.frontendStrategy.elementEnvironment.mainLibrary.find('c'); - var mask3 = typesInferrer.getReturnTypeOfMember(element); - - element = - compiler.frontendStrategy.elementEnvironment.mainLibrary.find('d'); - var mask4 = typesInferrer.getReturnTypeOfMember(element); - - Expect.notEquals( - mask1.union(mask2, closedWorld), mask3.union(mask4, closedWorld)); - }); -}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status index 71a41a9..5984d35 100644 --- a/tests/compiler/dart2js/dart2js.status +++ b/tests/compiler/dart2js/dart2js.status
@@ -4,25 +4,35 @@ analyze_dart_test: Slow, Pass analyze_test: Slow, Pass async_await_syntax_test: Pass # DON'T CHANGE THIS LINE -- Don't mark these tests as failing. Instead, fix the errors/warnings that they report or update the whitelist in the test-files to temporarily allow digression. -backend_dart/opt_cyclic_redundant_phi_test: Fail # Issue 20159 boolified_operator_test: Fail # Issue 8001 -old_frontend/check_elements_invariants_test: Skip # Times out even with Slow marker. Slow due to inlining in the CPS backend -old_frontend/compile_with_empty_libraries_test: Fail # Issue 24223 +codegen/gvn_dynamic_field_get_test: Fail # Issue 18519 +codegen/load_elimination_test: Pass, Slow +codegen/logical_expression_test: Fail # Issue 17027 +codegen/simple_function_subtype_test: Fail # simple_function_subtype_test is temporarily(?) disabled due to new method for building function type tests. +deferred_loading/deferred_loading_test: Slow, Pass equivalence/id_equivalence_test: Pass, Slow -gvn_dynamic_field_get_test: Fail # Issue 18519 inference/inference_test: Slow, Pass +inference/simple_inferrer_const_closure2_test: Fail # Issue 16507 +inference/simple_inferrer_const_closure_test: Fail # Issue 16507 +inference/simple_inferrer_global_field_closure_test: Fail # Issue 16507 inference/swarm_test: Slow, Pass inlining/inlining_test: Slow, Pass kernel/*: Slow, Pass -logical_expression_test: Fail # Issue 17027 +kernel/compile_from_dill_fast_startup_test: RuntimeError # Test must be updated to support FE with patching. +kernel/compile_from_dill_test: RuntimeError # Test must be updated to support FE with patching. mirrors/library_exports_hidden_test: Fail mirrors/library_exports_shown_test: Fail mirrors/library_imports_hidden_test: Fail mirrors/library_imports_prefixed_show_hide_test: Fail mirrors/library_imports_prefixed_test: Fail mirrors/library_imports_shown_test: Fail +no_such_method_enabled_test: Pass, Slow +old_frontend/check_elements_invariants_test: Skip # Times out even with Slow marker. Slow due to inlining in the CPS backend +old_frontend/check_elements_invariants_test: Skip # Times out even with Slow marker. Slow due to inlining in the CPS backend +old_frontend/compile_with_empty_libraries_test: Fail # Issue 24223 +old_frontend/compile_with_empty_libraries_test: Fail # Issue 24223 +old_frontend/patch_test/bug: RuntimeError # Issue 21132 packages/*: Skip # Skip packages folder -patch_test/bug: RuntimeError # Issue 21132 quarantined/http_test: Pass, Slow serialization/analysis1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority. serialization/analysis3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority. @@ -41,66 +51,58 @@ serialization/model5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority. serialization/model_1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority. serialization/native_data_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority. -simple_function_subtype_test: Fail # simple_function_subtype_test is temporarily(?) disabled due to new method for building function type tests. -simple_inferrer_const_closure2_test: Fail # Issue 16507 -simple_inferrer_const_closure_test: Fail # Issue 16507 -simple_inferrer_global_field_closure_test: Fail # Issue 16507 sourcemaps/source_mapping_invokes_test: Pass, Slow sourcemaps/source_mapping_operators_test: Pass, Slow sourcemaps/source_mapping_test: Pass, Slow subtype_test: Slow, Pass uri_retention_test: Fail # Issue 26504 -kernel/compile_from_dill_fast_startup_test: RuntimeError # Test must be updated to support FE with patching. -kernel/compile_from_dill_test: RuntimeError # Test must be updated to support FE with patching. -kernel/closed_world2_test: RuntimeError # Test must be updated to support FE with patching. -inference/swarm_test: RuntimeError # Test must be updated to support FE with patching. [ $mode == debug ] +deferred/load_graph_segmentation_test: Pass, Slow +deferred/load_mapping_test: Pass, Slow +end_to_end/dart2js_batch_test: Pass, Slow +end_to_end/exit_code_test: Pass, Slow +in_user_code_test: Pass, Slow +mirrors/deferred_mirrors_test: Pass, Slow +mirrors/import_mirrors_test: Pass, Slow +mirrors/mirror_final_field_inferrer2_test: Crash, Pass, Slow # Issue 15581 old_frontend/analyze_api_test: Pass, Slow # DON'T CHANGE THIS LINE -- Don't mark these tests as failing. Instead, fix the errors/warnings that they report or update the whitelist in the test-files to temporarily allow digression. old_frontend/analyze_dart2js_test: Pass, Slow # DON'T CHANGE THIS LINE -- Don't mark these tests as failing. Instead, fix the errors/warnings that they report or update the whitelist in the test-files to temporarily allow digression. old_frontend/analyze_unused_dart2js_test: Pass, Slow old_frontend/check_elements_invariants_test: Skip # Slow and only needs to be run in one configuration old_frontend/check_members_test: Pass, Slow -dart2js_batch_test: Pass, Slow -deferred_load_graph_segmentation_test: Pass, Slow -deferred_load_mapping_test: Pass, Slow -deferred_mirrors_test: Pass, Slow -duplicate_library_test: Pass, Slow -exit_code_test: Pass, Slow -import_mirrors_test: Pass, Slow -in_user_code_test: Pass, Slow -message_kind_test: Pass, Slow -mirror_final_field_inferrer2_test: Crash, Pass, Slow # Issue 15581 +old_frontend/duplicate_library_test: Pass, Slow +old_frontend/message_kind_test: Pass, Slow show_package_warnings_test: Pass, Slow -source_map_pub_build_validity_test: Pass, Slow +sourcemaps/source_map_pub_build_validity_test: Pass, Slow [ $system == linux ] dart2js_batch2_test: Pass, RuntimeError # Issue 29021 [ $checked ] +codegen/value_range_test: Pass, Slow +codegen/value_range_kernel_test: Pass, Slow +end_to_end/exit_code_test: Pass, Slow +jsinterop/declaration_test: Slow, Pass +jsinterop/interop_anonymous_unreachable_test: Pass, Slow +jsinterop/world_test: Pass, Slow +kernel/visitor_test: Pass, Slow +mirrors/deferred_mirrors_test: Pass, Slow +mirrors/import_mirrors_test: Slow, Pass +mirrors/mirror_final_field_inferrer2_test: Pass, Slow +mirrors/preserve_uris_test: Pass, Slow old_frontend/analyze_dart2js_helpers_test: Pass, Slow old_frontend/analyze_dart2js_test: Pass, Slow old_frontend/analyze_unused_dart2js_test: Pass, Slow -dart2js_resolver_test: Pass, Slow -deferred_mirrors_test: Pass, Slow -duplicate_library_test: Pass, Slow -exit_code_test: Pass, Slow -import_mirrors_test: Slow, Pass -interop_anonymous_unreachable_test: Pass, Slow -jsinterop/declaration_test: Slow, Pass -jsinterop/world_test: Pass, Slow -kernel/visitor_test: Pass, Slow -mirror_final_field_inferrer2_test: Pass, Slow +old_frontend/duplicate_library_test: Pass, Slow output_type_test: Pass, Slow -preserve_uris_test: Pass, Slow serialization*: Slow, Pass -source_map_pub_build_validity_test: Pass, Slow +sourcemaps/source_map_pub_build_validity_test: Pass, Slow sourcemaps/stacktrace_test: Pass, Slow uri_retention_test: Pass, Slow -value_range_test: Pass, Slow [ !$checked ] -exit_code_test: Skip # This tests requires checked mode. +end_to_end/exit_code_test: Skip # This tests requires checked mode. jsinterop/declaration_test: Slow, Pass serialization*: Slow, Pass
diff --git a/tests/compiler/dart2js/dead_code_test.dart b/tests/compiler/dart2js/dead_code_test.dart deleted file mode 100644 index eace363..0000000 --- a/tests/compiler/dart2js/dead_code_test.dart +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -String TEST = r''' -main() { - foo(null); -} -foo(a) { - if (a != null) return 42; - return 54; -} -'''; - -main() { - asyncTest(() => compileAll(TEST).then((generated) { - Expect.isFalse( - generated.contains('return 42'), 'dead code not eliminated'); - })); -}
diff --git a/tests/compiler/dart2js/dead_phi_eliminator_test.dart b/tests/compiler/dart2js/dead_phi_eliminator_test.dart deleted file mode 100644 index 6b0b67b..0000000 --- a/tests/compiler/dart2js/dead_phi_eliminator_test.dart +++ /dev/null
@@ -1,25 +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""" -void foo(bar) { - var toBeRemoved = 1; - if (bar) { - toBeRemoved = 2; - } else { - toBeRemoved = 3; - } -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp("toBeRemoved"); - Expect.isTrue(!regexp.hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/declare_once_test.dart b/tests/compiler/dart2js/declare_once_test.dart deleted file mode 100644 index 63535eb..0000000 --- a/tests/compiler/dart2js/declare_once_test.dart +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Test that parameters keep their names in the output. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -main() { - // For a function with only one variable we declare it inline for more - // compactness. Test that we don't also declare it at the start of the - // method. - asyncTest(() => compile( - 'final List a = const ["bar", "baz"];' - 'int foo() {' - ' for (int i = 0; i < a.length; i++) {' - ' print(a[i]);' - ' }' - '}', - entry: 'foo', - minify: false).then((String generated) { - RegExp re = new RegExp(r"var "); - Expect.isTrue(re.hasMatch(generated)); - print(generated); - Expect.equals(1, re.allMatches(generated).length); - })); -}
diff --git a/tests/compiler/dart2js/deferred_closures_test.dart b/tests/compiler/dart2js/deferred/closures_test.dart similarity index 84% rename from tests/compiler/dart2js/deferred_closures_test.dart rename to tests/compiler/dart2js/deferred/closures_test.dart index 747b9a9..30279cc 100644 --- a/tests/compiler/dart2js/deferred_closures_test.dart +++ b/tests/compiler/dart2js/deferred/closures_test.dart
@@ -9,17 +9,19 @@ import 'package:compiler/src/commandline_options.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; -import 'output_collector.dart'; +import '../memory_compiler.dart'; +import '../output_collector.dart'; void main() { asyncTest(() async { - await runTest(false); - await runTest(true); + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); } -runTest(bool useKernel) async { +runTest({bool useKernel}) async { OutputCollector collector = new OutputCollector(); var options = useKernel ? [Flags.useKernel] : []; await runCompiler(
diff --git a/tests/compiler/dart2js/deferred/custom_element_test.dart b/tests/compiler/dart2js/deferred/custom_element_test.dart new file mode 100644 index 0000000..385e3c1 --- /dev/null +++ b/tests/compiler/dart2js/deferred/custom_element_test.dart
@@ -0,0 +1,65 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test of the graph segmentation algorithm used by deferred loading +// to determine which elements can be deferred and which libraries +// much be included in the initial download (loaded eagerly). + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; +import '../memory_compiler.dart'; + +void main() { + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +} + +runTest({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); + Compiler compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity; + var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit; + var elementEnvironment = closedWorld.elementEnvironment; + dynamic lib = elementEnvironment.lookupLibrary(Uri.parse("memory:lib.dart")); + var customType = elementEnvironment.lookupClass(lib, "CustomType"); + var foo = elementEnvironment.lookupLibraryMember(lib, "foo"); + Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo)); + // Native elements are not deferred + Expect.equals(mainOutputUnit, outputUnitForEntity(customType)); +} + +// The main library imports a file defining a custom element. +// Registering this class implicitly causes the constructors to be +// live. Check that this is handled. +const Map MEMORY_SOURCE_FILES = const { + "main.dart": """ +import "lib.dart" deferred as a; +import 'dart:html'; + +main() { + document.registerElement("foo-tag", a.a); + a.foo(); +} +""", + "lib.dart": """ +import 'dart:html'; +var a = CustomType; + +class CustomType extends HtmlElement { + factory CustomType() => null; + CustomType.created() : super.created() ; +} + +foo() {} +""", +};
diff --git a/tests/compiler/dart2js/deferred_dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart similarity index 80% rename from tests/compiler/dart2js/deferred_dont_inline_deferred_constants_test.dart rename to tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart index d6c9f69d..ddb130f 100644 --- a/tests/compiler/dart2js/deferred_dont_inline_deferred_constants_test.dart +++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -7,35 +7,40 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/compiler.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; -import 'output_collector.dart'; +import '../memory_compiler.dart'; +import '../output_collector.dart'; void main() { - asyncTest(() async { + runTest({bool useKernel}) async { OutputCollector collector = new OutputCollector(); CompilationResult result = await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); Compiler compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; lookupLibrary(name) { - return compiler.libraryLoader.lookupLibrary(Uri.parse(name)); + return elementEnvironment.lookupLibrary(Uri.parse(name)); } var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity; dynamic lib1 = lookupLibrary("memory:lib1.dart"); - var foo1 = lib1.find("foo"); + var foo1 = elementEnvironment.lookupLibraryMember(lib1, "foo"); var ou_lib1 = outputUnitForEntity(foo1); dynamic lib2 = lookupLibrary("memory:lib2.dart"); - var foo2 = lib2.find("foo"); + var foo2 = elementEnvironment.lookupLibraryMember(lib2, "foo"); var ou_lib2 = outputUnitForEntity(foo2); - dynamic mainApp = compiler.frontendStrategy.elementEnvironment.mainLibrary; - var fooMain = mainApp.find("foo"); + dynamic mainApp = elementEnvironment.mainLibrary; + var fooMain = elementEnvironment.lookupLibraryMember(mainApp, "foo"); var ou_lib1_lib2 = outputUnitForEntity(fooMain); String mainOutput = collector.getOutput("", OutputType.js); @@ -80,6 +85,14 @@ Expect.isTrue(new RegExp(r"= .string4").hasMatch(lib1Output)); Expect.isTrue(new RegExp(r"= .string4").hasMatch(lib2Output)); Expect.isFalse(new RegExp(r"= .string4").hasMatch(lib12Output)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + // TODO(sigmund): Handle this for kernel. + //print('--test from kernel------------------------------------------------'); + //await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_dont_inline_deferred_globals_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart similarity index 68% rename from tests/compiler/dart2js/deferred_dont_inline_deferred_globals_test.dart rename to tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart index a036a6a..af56ad9 100644 --- a/tests/compiler/dart2js/deferred_dont_inline_deferred_globals_test.dart +++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
@@ -7,26 +7,32 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/compiler.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; -import 'output_collector.dart'; +import '../memory_compiler.dart'; +import '../output_collector.dart'; void main() { - OutputCollector collector = new OutputCollector(); - asyncTest(() async { + runTest({bool useKernel}) async { + OutputCollector collector = new OutputCollector(); CompilationResult result = await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); Compiler compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; + lookupLibrary(name) { - return compiler.libraryLoader.lookupLibrary(Uri.parse(name)); + return elementEnvironment.lookupLibrary(Uri.parse(name)); } var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity; dynamic lib1 = lookupLibrary("memory:lib1.dart"); - var foo1 = lib1.find("finalVar"); + var foo1 = elementEnvironment.lookupLibraryMember(lib1, "finalVar"); var ou_lib1 = outputUnitForEntity(foo1); String mainOutput = collector.getOutput("", OutputType.js); @@ -39,6 +45,13 @@ Expect.isTrue(re2.hasMatch(lib1Output)); Expect.isFalse(re1.hasMatch(mainOutput)); Expect.isFalse(re2.hasMatch(mainOutput)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart similarity index 76% rename from tests/compiler/dart2js/deferred_emit_type_checks_test.dart rename to tests/compiler/dart2js/deferred/emit_type_checks_test.dart index 1751a3c..e1aedd5b 100644 --- a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart +++ b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
@@ -7,17 +7,20 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/js_backend/js_backend.dart' show JavaScriptBackend; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; -import 'output_collector.dart'; +import '../memory_compiler.dart'; +import '../output_collector.dart'; void main() { - asyncTest(() async { + runTest({bool useKernel}) async { OutputCollector collector = new OutputCollector(); CompilationResult result = await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); Compiler compiler = result.compiler; String mainOutput = collector.getOutput('', OutputType.js); String deferredOutput = collector.getOutput('out_1', OutputType.jsPart); @@ -28,6 +31,13 @@ "Deferred output doesn't contain '${isPrefix}A: 1':\n" "$deferredOutput"); Expect.isFalse(mainOutput.contains('${isPrefix}A: 1')); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart similarity index 81% rename from tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart rename to tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart index 4bf9cb6..f309a9c 100644 --- a/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart +++ b/tests/compiler/dart2js/deferred/follow_constant_dependencies_test.dart
@@ -5,15 +5,17 @@ // Test that constants depended on by other constants are correctly deferred. import 'package:async_helper/async_helper.dart'; -import 'package:compiler/src/constants/values.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/constants/values.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { - asyncTest(() async { - CompilationResult result = - await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); + runTest({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); Compiler compiler = result.compiler; var outputUnitForConstant = compiler.backend.outputUnitData.outputUnitForConstant; @@ -40,6 +42,13 @@ "Constant value ${constant.toStructuredText()} " "is in the main output unit."); } + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_follow_implicit_super_regression_test.dart b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart similarity index 65% rename from tests/compiler/dart2js/deferred_follow_implicit_super_regression_test.dart rename to tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart index 566ad29..93ca8bc 100644 --- a/tests/compiler/dart2js/deferred_follow_implicit_super_regression_test.dart +++ b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
@@ -2,33 +2,44 @@ // for 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 'memory_compiler.dart'; - +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/compiler.dart' as dart2js; +import 'package:expect/expect.dart'; + +import '../memory_compiler.dart'; void main() { - asyncTest(() async { - CompilationResult result = - await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); + runTest({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); dart2js.Compiler compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; lookupLibrary(name) { - return compiler.libraryLoader.lookupLibrary(Uri.parse(name)); + return elementEnvironment.lookupLibrary(Uri.parse(name)); } var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity; dynamic lib = lookupLibrary("memory:lib.dart"); - var a = lib.find("a"); - var b = lib.find("b"); - var c = lib.find("c"); - var d = lib.find("d"); + var a = elementEnvironment.lookupLibraryMember(lib, "a"); + var b = elementEnvironment.lookupLibraryMember(lib, "b"); + var c = elementEnvironment.lookupLibraryMember(lib, "c"); + var d = elementEnvironment.lookupLibraryMember(lib, "d"); Expect.equals(outputUnitForEntity(a), outputUnitForEntity(b)); Expect.equals(outputUnitForEntity(a), outputUnitForEntity(c)); Expect.equals(outputUnitForEntity(a), outputUnitForEntity(d)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_inline_restrictions_test.dart b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart similarity index 98% rename from tests/compiler/dart2js/deferred_inline_restrictions_test.dart rename to tests/compiler/dart2js/deferred/inline_restrictions_test.dart index a7293c4..12585ca 100644 --- a/tests/compiler/dart2js/deferred_inline_restrictions_test.dart +++ b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
@@ -9,7 +9,7 @@ import 'package:compiler/compiler_new.dart'; import 'package:compiler/src/compiler.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart similarity index 97% rename from tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart rename to tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart index 9578590..8043235 100644 --- a/tests/compiler/dart2js/deferred_load_graph_segmentation2_test.dart +++ b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
@@ -9,7 +9,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/compiler.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart similarity index 98% rename from tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart rename to tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart index 626a0ad..028be89 100644 --- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart +++ b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
@@ -10,7 +10,7 @@ import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/deferred_load.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred_load_mapping_test.dart b/tests/compiler/dart2js/deferred/load_mapping_test.dart similarity index 94% rename from tests/compiler/dart2js/deferred_load_mapping_test.dart rename to tests/compiler/dart2js/deferred/load_mapping_test.dart index e4aebd3..c5de70f 100644 --- a/tests/compiler/dart2js/deferred_load_mapping_test.dart +++ b/tests/compiler/dart2js/deferred/load_mapping_test.dart
@@ -3,10 +3,10 @@ // BSD-style license that can be found in the LICENSE file. import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; +import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; -import 'memory_source_file_helper.dart'; -import "memory_compiler.dart"; +import '../memory_source_file_helper.dart'; +import '../memory_compiler.dart'; void main() { asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred_not_in_main_test.dart b/tests/compiler/dart2js/deferred/not_in_main_test.dart similarity index 98% rename from tests/compiler/dart2js/deferred_not_in_main_test.dart rename to tests/compiler/dart2js/deferred/not_in_main_test.dart index 7927ee2..b495e9a 100644 --- a/tests/compiler/dart2js/deferred_not_in_main_test.dart +++ b/tests/compiler/dart2js/deferred/not_in_main_test.dart
@@ -9,7 +9,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/compiler.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { deferredTest1();
diff --git a/tests/compiler/dart2js/unneeded_part_js_test.dart b/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart similarity index 71% rename from tests/compiler/dart2js/unneeded_part_js_test.dart rename to tests/compiler/dart2js/deferred/unneeded_part_js_test.dart index 7a13c83..2ef6af6 100644 --- a/tests/compiler/dart2js/unneeded_part_js_test.dart +++ b/tests/compiler/dart2js/deferred/unneeded_part_js_test.dart
@@ -5,20 +5,29 @@ // Test that no parts are emitted when deferred loading isn't used. import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; main() { - asyncTest(() async { + runTest({bool useKernel}) async { DiagnosticCollector diagnostics = new DiagnosticCollector(); OutputCollector output = new OutputCollector(); CompilationResult result = await runCompiler( memorySourceFiles: MEMORY_SOURCE_FILES, diagnosticHandler: diagnostics, - outputProvider: output); + outputProvider: output, + options: useKernel ? [Flags.useKernel] : []); Expect.isFalse(diagnostics.hasRegularMessages); Expect.isFalse(output.hasExtraOutput); Expect.isTrue(result.isSuccess); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/deferred_custom_element_test.dart b/tests/compiler/dart2js/deferred_custom_element_test.dart deleted file mode 100644 index e3a667a..0000000 --- a/tests/compiler/dart2js/deferred_custom_element_test.dart +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Test of the graph segmentation algorithm used by deferred loading -// to determine which elements can be deferred and which libraries -// much be included in the initial download (loaded eagerly). - -import 'package:async_helper/async_helper.dart'; -import 'package:compiler/src/compiler.dart'; -import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; - -void main() { - asyncTest(() async { - CompilationResult result = - await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); - Compiler compiler = result.compiler; - var outputUnitForEntity = - compiler.backend.outputUnitData.outputUnitForEntity; - var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit; - dynamic lib = - compiler.libraryLoader.lookupLibrary(Uri.parse("memory:lib.dart")); - var customType = lib.find("CustomType"); - var foo = lib.find("foo"); - Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo)); - // Native elements are not deferred - Expect.equals(mainOutputUnit, outputUnitForEntity(customType)); - }); -} - -// The main library imports a file defining a custom element. -// Registering this class implicitly causes the constructors to be -// live. Check that this is handled. -const Map MEMORY_SOURCE_FILES = const { - "main.dart": """ -import "lib.dart" deferred as a; -import 'dart:html'; - -main() { - document.registerElement("foo-tag", a.a); - a.foo(); -} -""", - "lib.dart": """ -import 'dart:html'; -var a = CustomType; - -class CustomType extends HtmlElement { - factory CustomType() => null; - CustomType.created() : super.created() ; -} - -foo() {} -""", -};
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart new file mode 100644 index 0000000..b7d44ab --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
@@ -0,0 +1,9 @@ +// 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 '../libs/basic_deferred_lib.dart' deferred as lib; + +/*element: main:OutputUnit(main, {})*/ +main() => lib.loadLibrary().then((_) { + (lib.funky)(); + });
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart new file mode 100644 index 0000000..0ded6cf --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
@@ -0,0 +1,12 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../libs/deferred_class_library.dart' deferred as lib; + +/*element: main:OutputUnit(main, {})*/ +main() { + lib.loadLibrary().then((_) { + return new lib.MyClass().foo(87); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart new file mode 100644 index 0000000..513d43b --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
@@ -0,0 +1,14 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../libs/deferred_constant1_lib1.dart' as lib1 hide C2, C3; +import '../libs/deferred_constant1_lib2.dart' deferred as lib2; + +/*element: main:OutputUnit(main, {})*/ +main() async { + lib1.C1.value; + await lib2.loadLibrary(); + lib2.C2.value; + lib2.C3.value; +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart new file mode 100644 index 0000000..9f82270 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
@@ -0,0 +1,14 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; + +import '../libs/deferred_constant2_lib.dart' deferred as lib; + +/*element: main:OutputUnit(main, {})*/ +main() { + lib.loadLibrary().then((_) { + Expect.equals(499, lib.C1.value); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart new file mode 100644 index 0000000..819032b --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
@@ -0,0 +1,48 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that when a deferred import fails to load, it is possible to retry. + +import "../libs/deferred_fail_and_retry_lib.dart" deferred as lib; +import "package:expect/expect.dart"; +import "package:async_helper/async_helper.dart"; +import "dart:js" as js; + +/*element: main:OutputUnit(main, {})*/ +main() { + // We patch document.body.appendChild to change the script src on first + // invocation. + js.context.callMethod("eval", [ + """ + if (self.document) { + oldAppendChild = document.body.appendChild; + document.body.appendChild = function(element) { + element.src = "non_existing.js"; + document.body.appendChild = oldAppendChild; + document.body.appendChild(element); + } + } + if (self.load) { + oldLoad = load; + load = function(uri) { + load = oldLoad; + load("non_existing.js"); + } + } + """ + ]); + + asyncStart(); + lib.loadLibrary().then((_) { + Expect.fail("Library should not have loaded"); + }, onError: (error) { + lib.loadLibrary().then((_) { + Expect.equals("loaded", lib.foo()); + }, onError: (error) { + Expect.fail("Library should have loaded this time"); + }).whenComplete(() { + asyncEnd(); + }); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart new file mode 100644 index 0000000..d8895f7 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
@@ -0,0 +1,21 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Test that loading of a library (with top-level functions only) can +// be deferred. + +import '../libs/deferred_function_lib.dart' deferred as lib; + +/*element: readFoo:OutputUnit(main, {})*/ +readFoo() { + return lib.foo; +} + +/*element: main:OutputUnit(main, {})*/ +main() { + lib.loadLibrary().then((_) { + lib.foo('b'); + readFoo(); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart new file mode 100644 index 0000000..ea2354b --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
@@ -0,0 +1,17 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "../libs/deferred_overlapping_lib1.dart" deferred as lib1; +import "../libs/deferred_overlapping_lib2.dart" deferred as lib2; + +// lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk. +/*element: main:OutputUnit(main, {})*/ +void main() { + lib1.loadLibrary().then((_) { + new lib1.C1(); + lib2.loadLibrary().then((_) { + new lib2.C2(); + }); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart new file mode 100644 index 0000000..47347ea --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_constants.dart
@@ -0,0 +1,7 @@ +// 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. + +// TODO(sigmund): remove this indirection and move the main code here. This is +// needed because of the id-equivalence frameworks overrides the entrypoint URI. +export '../libs/dont_inline_deferred_constants_main.dart';
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart new file mode 100644 index 0000000..58669a5 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
@@ -0,0 +1,15 @@ +// 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 '../libs/dont_inline_deferred_global_lib.dart' deferred as lib; + +/*element: main:OutputUnit(main, {})*/ +void main() { + lib.loadLibrary().then((_) { + print(lib.finalVar); + print(lib.globalVar); + lib.globalVar = "foobar"; + print(lib.globalVar); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart new file mode 100644 index 0000000..ec84fcd --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -0,0 +1,172 @@ +// 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:io' hide Link; +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/common.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/deferred_load.dart'; +import 'package:compiler/src/elements/elements.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/kernel/element_map.dart'; +import 'package:compiler/src/kernel/kernel_backend_strategy.dart'; +import 'package:expect/expect.dart'; +import '../equivalence/id_equivalence.dart'; +import '../equivalence/id_equivalence_helper.dart'; +import 'package:compiler/src/constants/values.dart'; + +import 'package:kernel/ast.dart' as ir; + +const List<String> skipForKernel = const <String>[ + 'dont_inline_deferred_constants.dart', +]; + +/// Add in options to pass to the compiler like +/// `Flags.disableTypeInference` or `Flags.disableInlining` +const List<String> compilerOptions = const <String>[]; + +/// Compute the [OutputUnit]s for all source files involved in the test, and +/// ensure that the compiler is correctly calculating what is used and what is +/// not. We expect all test entry points to be in the `data` directory and any +/// or all supporting libraries to be in the `libs` folder, starting with the +/// same name as the original file in `data`. +main(List<String> args) { + asyncTest(() async { + Directory dataDir = new Directory.fromUri(Platform.script.resolve('data')); + await checkTests( + dataDir, computeAstOutputUnitData, computeKernelOutputUnitData, + libDirectory: new Directory.fromUri(Platform.script.resolve('libs')), + forMainLibraryOnly: false, + forUserSourceFilesOnly: true, + skipForKernel: skipForKernel, + options: compilerOptions, + args: args, setUpFunction: () { + importPrefixes.clear(); + }); + }); +} + +// For ease of testing and making our tests easier to read, we impose an +// artificial constraint of requiring every deferred import use a different +// named prefix per test. We enforce this constraint here by checking that no +// prefix name responds to two different libraries. +Map<String, Uri> importPrefixes = <String, Uri>{}; + +/// Create a consistent string representation of [OutputUnit]s for both +/// KImportEntities and ImportElements. +String outputUnitString(OutputUnit unit) { + if (unit == null) return 'null'; + StringBuffer sb = new StringBuffer(); + bool first = true; + for (ImportEntity import in unit.importsForTesting) { + if (!first) sb.write(', '); + sb.write('${import.name}'); + first = false; + Expect.isTrue(import.isDeferred); + + if (importPrefixes.containsKey(import.name)) { + Expect.equals( + importPrefixes[import.name], import.enclosingLibrary.canonicalUri); + } + importPrefixes[import.name] = import.enclosingLibrary.canonicalUri; + } + return 'OutputUnit(${unit.name}, {$sb})'; +} + +/// Compute closure data mapping for [member] as a [MemberElement]. +/// +/// Fills [actualMap] with the data computed about what the resulting OutputUnit +/// is. +void computeAstOutputUnitData( + Compiler compiler, MemberEntity _member, Map<Id, ActualData> actualMap, + {bool verbose: false}) { + MemberElement member = _member; + OutputUnitData data = compiler.backend.outputUnitData; + String value = outputUnitString(data.outputUnitForEntity(member)); + + _registerValue(computeElementId(member), value, member, member.sourcePosition, + actualMap, compiler.reporter); + + if (member is FieldElement && member.isConst) { + var node = member.initializer; + var constant = compiler.constants.getConstantValue(member.constant); + _registerValue( + new NodeId(node.getBeginToken().charOffset, IdKind.node), + outputUnitString(data.outputUnitForConstant(constant)), + member, + new SourceSpan(member.resolvedAst.sourceUri, + node.getBeginToken().charOffset, node.getEndToken().charEnd), + actualMap, + compiler.reporter); + } +} + +/// OutputData for [member] as a kernel based element. +/// +/// At this point the compiler has already been run, so it is holding the +/// relevant OutputUnits, we just need to extract that information from it. We +/// fill [actualMap] with the data computed about what the resulting OutputUnit +/// is. +void computeKernelOutputUnitData( + Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap, + {bool verbose: false}) { + OutputUnitData data = compiler.backend.outputUnitData; + String value = outputUnitString(data.outputUnitForEntity(member)); + + KernelBackendStrategy backendStrategy = compiler.backendStrategy; + KernelToElementMapForBuilding elementMap = backendStrategy.elementMap; + MemberDefinition definition = elementMap.getMemberDefinition(member); + + _registerValue( + computeEntityId(definition.node), + value, + member, + computeSourceSpanFromTreeNode(definition.node), + actualMap, + compiler.reporter); + + ir.Member memberNode = definition.node; + if (memberNode is ir.Field && memberNode.isConst) { + ir.Expression node = memberNode.initializer; + ConstantValue constant = elementMap.getConstantValue(node); + SourceSpan span = computeSourceSpanFromTreeNode(node); + if (node is ir.ConstructorInvocation || + node is ir.ListLiteral || + node is ir.MapLiteral) { + // Adjust the source-span to match the AST-based location. The kernel FE + // skips the "const" keyword for the expression offset (-6 is an + // approximation assuming that there is just a single space after "const", + // this is likely good enough for our small unit tests). + span = new SourceSpan(span.uri, span.begin - 6, span.end - 6); + } + _registerValue( + new NodeId(span.begin, IdKind.node), + outputUnitString(data.outputUnitForConstant(constant)), + member, + computeSourceSpanFromTreeNode(node), + actualMap, + compiler.reporter); + } +} + +/// Set [actualMap] to hold a key of [id] with the computed data [value] +/// corresponding to [object] at location [sourceSpan]. We also perform error +/// checking to ensure that the same [id] isn't added twice. +void _registerValue(Id id, String value, Object object, SourceSpan sourceSpan, + Map<Id, ActualData> actualMap, CompilerDiagnosticReporter reporter) { + if (actualMap.containsKey(id)) { + ActualData existingData = actualMap[id]; + reportHere(reporter, sourceSpan, + "Duplicate id ${id}, value=$value, object=$object"); + reportHere( + reporter, + sourceSpan, + "Duplicate id ${id}, value=${existingData.value}, " + "object=${existingData.object}"); + Expect.fail("Duplicate id $id."); + } + if (value != null) { + actualMap[id] = new ActualData(new IdValue(id, value), sourceSpan, object); + } +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart new file mode 100644 index 0000000..bbd9bae --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
@@ -0,0 +1,11 @@ +// 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. + +/*element: defaultArg:OutputUnit(1, {lib})*/ +defaultArg() => ""; + +/*element: funky:OutputUnit(1, {lib})*/ +funky([x = defaultArg]) => x(); + +final int notUsed = 3;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart new file mode 100644 index 0000000..95f54b4 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
@@ -0,0 +1,18 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Imported by deferred_class.dart. + +library deferred_class_library; + +class MyClass { + /*element: MyClass.:OutputUnit(1, {lib})*/ + const MyClass(); + + /*element: MyClass.foo:OutputUnit(1, {lib})*/ + foo(x) { + print('MyClass.foo($x)'); + return (x - 3) ~/ 2; + } +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart new file mode 100644 index 0000000..7758772 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib1.dart
@@ -0,0 +1,34 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library deferred_constants1_lib1; + +class C { + /*element: C.value:OutputUnit(main, {})*/ + final value; + /*element: C.:OutputUnit(main, {})*/ + const C(this.value); +} + +/// --------------------------------------------------------------------------- +/// Constant used from main: not deferred. +/// --------------------------------------------------------------------------- + +/*element: C1:OutputUnit(main, {})*/ +const C1 = /*OutputUnit(main, {})*/ const C(1); + +/// --------------------------------------------------------------------------- +/// Constant completely deferred. +/// --------------------------------------------------------------------------- + +/*element: C2:OutputUnit(1, {lib2})*/ +const C2 = /*OutputUnit(1, {lib2})*/ const C(2); + +/// --------------------------------------------------------------------------- +/// Constant field not used from main, but the constant value is: so the field +/// and the constant value are in different output units. +/// --------------------------------------------------------------------------- + +/*element: C3:OutputUnit(1, {lib2})*/ +const C3 = /*OutputUnit(main, {})*/ const C(1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart new file mode 100644 index 0000000..d21aec4 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib2.dart
@@ -0,0 +1,7 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library deferred_constants1_lib2; + +export 'deferred_constant1_lib1.dart' show C2, C3;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart new file mode 100644 index 0000000..1967a3c --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
@@ -0,0 +1,53 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library deferred_constants2_lib; + +class MyClass { + const MyClass(); + + foo(x) { + print('MyClass.foo($x)'); + return (x - 3) ~/ 2; + } +} + +class Constant { + /*element: Constant.value:OutputUnit(1, {lib})*/ + final value; + /*element: Constant.:OutputUnit(1, {lib})*/ + const Constant(this.value); + + /*element: Constant.==:OutputUnit(1, {lib})*/ + operator ==(other) => other is Constant && value == other.value; + /*element: Constant.hashCode:OutputUnit(1, {lib})*/ + get hashCode => 0; +} + +/*element: C1:OutputUnit(1, {lib})*/ +const C1 = /*OutputUnit(1, {lib})*/ const Constant(499); + +const C2 = const [const Constant(99)]; + +foo([x = const Constant(42)]) => x; +bar() => const Constant(777); + +class Gee { + get value => c.value; + final c; + + Gee([this.c = const Constant(111)]); + const Gee.n321([this.c = const Constant(321)]); + Gee.n135({arg: const Constant(135)}) : this.c = arg; + const Gee.n246({arg: const Constant(246)}) : this.c = arg; + const Gee.n888() : this.c = const Constant(888); + const Gee.constant(this.c); +} + +class Gee2 extends Gee { + Gee2() : super(const Constant(979)); + const Gee2.n321() : super.n321(); + const Gee2.n151() : super.constant(const Constant(151)); + const Gee2.n888() : super.n888(); +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart new file mode 100644 index 0000000..ed22832 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
@@ -0,0 +1,8 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/*element: foo:OutputUnit(1, {lib})*/ +foo() { + return "loaded"; +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart new file mode 100644 index 0000000..5d40356 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
@@ -0,0 +1,13 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Imported by deferred_function.dart and + +library deferred_function_library; + +/*element: foo:OutputUnit(1, {lib})*/ +foo(x) { + print('foo($x)'); + return 42; +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart new file mode 100644 index 0000000..e1c3a03 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
@@ -0,0 +1,8 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "deferred_overlapping_lib3.dart"; + +/*element: C1.:OutputUnit(1, {lib1})*/ +class C1 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart new file mode 100644 index 0000000..4d7c620 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
@@ -0,0 +1,8 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "deferred_overlapping_lib3.dart"; + +/*element: C2.:OutputUnit(3, {lib2})*/ +class C2 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart new file mode 100644 index 0000000..6804b23 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
@@ -0,0 +1,6 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/*element: C3.:OutputUnit(2, {lib1, lib2})*/ +class C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart new file mode 100644 index 0000000..14e96f5 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
@@ -0,0 +1,31 @@ +// 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 "dont_inline_deferred_constants_main.dart" as main; + +/*element: C1:OutputUnit(1, {lib1})*/ +const C1 = /*OutputUnit(1, {lib1})*/ "string1"; + +/*element: C2:OutputUnit(1, {lib1})*/ +const C2 = /*OutputUnit(1, {lib1})*/ 1010; + +class C { + /*element: C.C3:OutputUnit(1, {lib1})*/ + static const C3 = /*OutputUnit(1, {lib1})*/ "string2"; +} + +/*element: C4:OutputUnit(1, {lib1})*/ +const C4 = /*OutputUnit(main, {})*/ "string4"; + +/*element: C5:OutputUnit(1, {lib1})*/ +const C5 = /*OutputUnit(main, {})*/ const main.C(1); + +/*element: C6:OutputUnit(1, {lib1})*/ +const C6 = /*OutputUnit(2, {lib1, lib2})*/ const main.C(2); + +/*element: foo:OutputUnit(1, {lib1})*/ +foo() { + print("lib1"); + main.foo(); +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart new file mode 100644 index 0000000..16ed499 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.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. + +import "dont_inline_deferred_constants_main.dart" as main; + +/*element: C4:OutputUnit(3, {lib2})*/ +const C4 = /*OutputUnit(main, {})*/ "string4"; + +/*element: C5:OutputUnit(3, {lib2})*/ +const C5 = /*OutputUnit(main, {})*/ const main.C(1); + +/*element: C6:OutputUnit(3, {lib2})*/ +const C6 = /*OutputUnit(2, {lib1, lib2})*/ const main.C(2); + +/*element: foo:OutputUnit(3, {lib2})*/ +foo() { + print("lib2"); + main.foo(); +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart new file mode 100644 index 0000000..8d3ed21 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
@@ -0,0 +1,42 @@ +// 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 'dont_inline_deferred_constants_lib1.dart' deferred as lib1; +import 'dont_inline_deferred_constants_lib2.dart' deferred as lib2; + +/*element: c:OutputUnit(main, {})*/ +const c = /*OutputUnit(main, {})*/ "string3"; + +class C { + /*element: C.p:OutputUnit(main, {})*/ + final p; + + /*element: C.:OutputUnit(main, {})*/ + const C(this.p); +} + +/*element: foo:OutputUnit(2, {lib1, lib2})*/ +foo() => print("main"); + +/*element: main:OutputUnit(main, {})*/ +void main() { + lib1.loadLibrary().then((_) { + lib2.loadLibrary().then((_) { + lib1.foo(); + lib2.foo(); + print(lib1.C1); + print(lib1.C2); + print(lib1.C.C3); + print(c); + print(lib1.C4); + print(lib2.C4); + print(lib1.C5); + print(lib2.C5); + print(lib1.C6); + print(lib2.C6); + print("string4"); + print(const C(1)); + }); + }); +}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart new file mode 100644 index 0000000..626b672 --- /dev/null +++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
@@ -0,0 +1,9 @@ +// 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. + +/*element: finalVar:OutputUnit(1, {lib})*/ +final finalVar = "string1"; + +/*element: globalVar:OutputUnit(1, {lib})*/ +var globalVar = "string2";
diff --git a/tests/compiler/dart2js/dictionary_types_test.dart b/tests/compiler/dart2js/dictionary_types_test.dart deleted file mode 100644 index f58280d..0000000 --- a/tests/compiler/dart2js/dictionary_types_test.dart +++ /dev/null
@@ -1,158 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; -import 'compiler_helper.dart' show findElement; - -var SOURCES = const { - 'AddAll.dart': """ - var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, - 'list': []}; - var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5, - 'list': []}; - var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84}; - var int = 0; - var anotherInt = 0; - var nullOrInt = 0; - var dynamic = 0; - - main() { - dictionaryA.addAll(otherDict); - dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84}); - int = dictionaryB['int']; - anotherInt = otherDict['intTwo']; - dynamic = dictionaryA['int']; - nullOrInt = dictionaryB['intTwo']; - } -""", - 'Union.dart': """ - var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, - 'list': []}; - var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []}; - var nullOrInt = 0; - var aString = ""; - var doubleOrNull = 22.2; - var key = "string"; - - main() { - var union = dictionaryA['foo'] ? dictionaryA : dictionaryB; - nullOrInt = union['intTwo']; - aString = union['string']; - doubleOrNull = union['double']; - } -""", - 'ValueType.dart': """ - var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []}; - var keyD = 'double'; - var keyI = 'int'; - var keyN = 'notFoundInMap'; - var knownDouble = 42.2; - var intOrNull = dictionary[keyI]; - var justNull = dictionary[keyN]; - - main() { - knownDouble = dictionary[keyD]; - var x = [intOrNull, justNull]; - } -""", - 'Propagation.dart': """ - class A { - A(); - foo(value) { - return value['anInt']; - } - } - - class B { - B(); - foo(value) { - return 0; - } - } - - main() { - var dictionary = {'anInt': 42, 'aString': "theString"}; - var it; - if ([true, false][0]) { - it = new A(); - } else { - it = new B(); - } - print(it.foo(dictionary) + 2); - } -""", - 'Bailout.dart': """ - var dict = makeMap([1,2]); - var notInt = 0; - var alsoNotInt = 0; - - makeMap(values) { - return {'moo': values[0], 'boo': values[1]}; - } - - main () { - dict['goo'] = 42; - var closure = () => dict; - notInt = closure()['boo']; - alsoNotInt = dict['goo']; - print("\$notInt and \$alsoNotInt."); - } -""" -}; - -void main() { - asyncTest(() async { - await compileAndTest("AddAll.dart", (types, getType, closedWorld) { - Expect.equals(getType('int'), types.uint31Type); - Expect.equals(getType('anotherInt'), types.uint31Type); - Expect.equals(getType('dynamic'), types.dynamicType); - Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); - }); - await compileAndTest("Union.dart", (types, getType, closedWorld) { - Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); - Expect.isTrue(getType('aString').containsOnlyString(closedWorld)); - Expect.equals(getType('doubleOrNull'), types.doubleType.nullable()); - }); - await compileAndTest("ValueType.dart", (types, getType, closedWorld) { - Expect.equals(getType('knownDouble'), types.doubleType); - Expect.equals(getType('intOrNull'), types.uint31Type.nullable()); - Expect.equals(getType('justNull'), types.nullType); - }); - await compileAndTest("Propagation.dart", (code) { - Expect.isFalse(code.contains("J.\$add\$ns")); - }, createCode: true); - await compileAndTest("Bailout.dart", (types, getType, closedWorld) { - Expect.equals(getType('notInt'), types.dynamicType); - Expect.equals(getType('alsoNotInt'), types.dynamicType); - Expect.isFalse(getType('dict').isDictionary); - }); - }); -} - -compileAndTest(source, checker, {createCode: false}) async { - CompilationResult result = await runCompiler( - entryPoint: Uri.parse('memory:' + source), - memorySourceFiles: SOURCES, - beforeRun: (compiler) { - compiler.stopAfterTypeInference = !createCode; - }); - var compiler = result.compiler; - var typesInferrer = compiler.globalInference.typesInferrerInternal; - var closedWorld = typesInferrer.closedWorld; - var commonMasks = closedWorld.commonMasks; - getType(String name) { - var element = findElement(compiler, name); - return typesInferrer.getTypeOfMember(element); - } - - if (!createCode) { - checker(commonMasks, getType, closedWorld); - } else { - var element = compiler.frontendStrategy.elementEnvironment.mainFunction; - var code = compiler.backend.getGeneratedCode(element); - checker(code); - } -}
diff --git a/tests/compiler/dart2js/dump_info_test.dart b/tests/compiler/dart2js/dump_info_test.dart index e7fbc5e..f6280196 100644 --- a/tests/compiler/dart2js/dump_info_test.dart +++ b/tests/compiler/dart2js/dump_info_test.dart
@@ -4,8 +4,9 @@ // Test that parameters keep their names in the output. import 'dart:convert'; -import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; import 'memory_compiler.dart'; const String TEST_BASIC = r""" @@ -96,17 +97,19 @@ typedef void JsonTaking(Map<String, dynamic> json); -jsonTest(String program, JsonTaking testFn) async { +jsonTest(String program, JsonTaking testFn, {bool useKernel}) async { + var options = ['--out=out.js', Flags.dumpInfo]; + if (useKernel) { + options.add(Flags.useKernel); + } var result = await runCompiler( - memorySourceFiles: {'main.dart': program}, - options: ['--out=out.js', '--dump-info']); + memorySourceFiles: {'main.dart': program}, options: options); var compiler = result.compiler; Expect.isFalse(compiler.compilationFailed); var dumpTask = compiler.dumpInfoTask; StringBuffer sb = new StringBuffer(); - dumpTask.dumpInfoJson( - sb, compiler.resolutionWorldBuilder.closedWorldForTesting); + dumpTask.dumpInfoJson(sb, compiler.backendClosedWorldForTesting); String jsonString = sb.toString(); Map<String, dynamic> map = json.decode(jsonString); @@ -114,10 +117,15 @@ } main() { - asyncTest(runTests); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); } -runTests() async { +runTests({bool useKernel}) async { await jsonTest(TEST_BASIC, (map) { Expect.isTrue(map['elements'].isNotEmpty); Expect.isTrue(map['elements']['function'].isNotEmpty); @@ -131,7 +139,7 @@ Expect.isTrue(map['elements']['function'].values.any((fun) { return fun['name'] == 'f'; })); - }); + }, useKernel: useKernel); await jsonTest(TEST_CLOSURES, (map) { var functions = map['elements']['function'].values; @@ -141,7 +149,7 @@ Expect.isTrue(functions.any((fn) { return fn['name'] == 'foo' && fn['children'].length == 10; })); - }); + }, useKernel: useKernel); await jsonTest(TEST_STATICS, (map) { var functions = map['elements']['function'].values; @@ -152,7 +160,7 @@ Expect.isTrue(classes.any((cls) { return cls['name'] == 'ContainsStatics' && cls['children'].length >= 1; })); - }); + }, useKernel: useKernel); await jsonTest(TEST_INLINED_1, (map) { var functions = map['elements']['function'].values; @@ -163,7 +171,7 @@ Expect.isTrue(classes.any((cls) { return cls['name'] == 'Doubler' && cls['children'].length >= 1; })); - }); + }, useKernel: useKernel); await jsonTest(TEST_INLINED_2, (map) { var functions = map['elements']['function'].values; @@ -179,5 +187,5 @@ Expect.isTrue(deps.containsKey(fn2['id'])); Expect.isTrue(deps[main_['id']].any((dep) => dep['id'] == fn1['id'])); Expect.isTrue(deps[fn1['id']].any((dep) => dep['id'] == fn2['id'])); - }); + }, useKernel: useKernel); }
diff --git a/tests/compiler/dart2js/elide_callthrough_stub_test.dart b/tests/compiler/dart2js/elide_callthrough_stub_test.dart deleted file mode 100644 index 2ae8f1d..0000000 --- a/tests/compiler/dart2js/elide_callthrough_stub_test.dart +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Check that calls through fields elide the call-through stub. This -// optimization is done by the simplifier, so inlining does not need to be -// enabled. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -const String TEST1 = r''' -class W { - final Function _fun; - W(this._fun); - foo(zzz) => _fun(zzz); // this._fun$1(zzz) --> this._fun.call$1(zzz) -} -add1(x) => x + 1; -main() { - var w = new W(add1); - var x = w.foo(42); -} -'''; - -const String TEST2 = r''' -class W { - final Function __fun; - Function get _fun => __fun; - W(this.__fun); - foo(zzz) => _fun(zzz); // this._fun$1(zzz) stays same. -} -add1(x) => x + 1; -main() { - var w = new W(add1); - var x = w.foo(42); -} -'''; - -main() { - asyncTest(() => compileAll(TEST1).then((generated) { - // Direct call through field. - Expect.isTrue(generated.contains(r'this._fun.call$1(zzz)')); - // No stub. - Expect.isFalse(generated.contains(r'_fun$1:')); - // No call to stub. - Expect.isFalse(generated.contains(r'_fun$1(')); - })); - - asyncTest(() => compileAll(TEST2).then((generated) { - // No call through field. - Expect.isFalse(generated.contains(r'this._fun.call$1(zzz)')); - // Call through stub. - Expect.isTrue(generated.contains(r'this._fun$1(zzz)')); - // Stub is generated. - Expect.isTrue(generated.contains(r'_fun$1:')); - // Call through getter (inside stub). - Expect.isTrue(generated.contains(r'get$_fun().call$1')); - })); -}
diff --git a/tests/compiler/dart2js/emit_const_fields_test.dart b/tests/compiler/dart2js/emit_const_fields_test.dart deleted file mode 100644 index 3076df7..0000000 --- a/tests/compiler/dart2js/emit_const_fields_test.dart +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Test that unused static consts are not emitted. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST_GUIDE = r""" -class Guide { - static const LTUAE = 42; - static const TITLE = 'Life, the Universe and Everything'; -} - -main() { - return "${Guide.LTUAE}, ${Guide.TITLE}"; -} -"""; - -main() { - asyncTest(() => compileAll(TEST_GUIDE).then((generated) { - Expect.isTrue(generated.contains("42")); - Expect.isFalse(generated.contains("TITLE")); - })); -}
diff --git a/tests/compiler/dart2js/async_compiler_input_provider_test.dart b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart similarity index 87% rename from tests/compiler/dart2js/async_compiler_input_provider_test.dart rename to tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart index 7ce403a0..ba08d5c 100644 --- a/tests/compiler/dart2js/async_compiler_input_provider_test.dart +++ b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
@@ -11,7 +11,6 @@ import "package:async_helper/async_helper.dart"; import 'package:compiler/compiler.dart' as compiler; -import 'package:compiler/src/filenames.dart'; const SOURCES = const { "/main.dart": """ @@ -44,9 +43,8 @@ var entrypoint = Uri.parse("file:///main.dart"); // Find the path to sdk/ in the repo relative to this script. - Uri script = currentDirectory.resolveUri(Platform.script); - Uri libraryRoot = script.resolve('../../../sdk/'); - Uri packageRoot = script.resolve('./packages/'); + Uri libraryRoot = Uri.base.resolve('sdk/'); + Uri packageRoot = Uri.base.resolve('packages/'); asyncTest(() => compiler.compile(entrypoint, libraryRoot, packageRoot, provideInput, handleDiagnostic, []).then((code) {
diff --git a/tests/compiler/dart2js/bad_output_io_test.dart b/tests/compiler/dart2js/end_to_end/bad_output_io_test.dart similarity index 100% rename from tests/compiler/dart2js/bad_output_io_test.dart rename to tests/compiler/dart2js/end_to_end/bad_output_io_test.dart
diff --git a/tests/compiler/dart2js/command_line_split_test.dart b/tests/compiler/dart2js/end_to_end/command_line_split_test.dart similarity index 100% rename from tests/compiler/dart2js/command_line_split_test.dart rename to tests/compiler/dart2js/end_to_end/command_line_split_test.dart
diff --git a/tests/compiler/dart2js/command_line_test.dart b/tests/compiler/dart2js/end_to_end/command_line_test.dart similarity index 96% rename from tests/compiler/dart2js/command_line_test.dart rename to tests/compiler/dart2js/end_to_end/command_line_test.dart index 95cf063..a45172b 100644 --- a/tests/compiler/dart2js/command_line_test.dart +++ b/tests/compiler/dart2js/end_to_end/command_line_test.dart
@@ -19,6 +19,8 @@ asyncTest(() async { await test([], exitCode: 1); await test(['foo.dart']); + await test([Flags.useKernel], exitCode: 1); + await test([Flags.useKernel, 'foo.dart']); await test([Flags.resolveOnly, 'foo.dart'], resolveOnly: true, resolutionOutput: Uri.base.resolve('out.data')); await test(['--resolution-input=bar.dart', 'foo.dart'],
diff --git a/tests/compiler/dart2js/dart2js_batch2_test.dart b/tests/compiler/dart2js/end_to_end/dart2js_batch2_test.dart similarity index 92% rename from tests/compiler/dart2js/dart2js_batch2_test.dart rename to tests/compiler/dart2js/end_to_end/dart2js_batch2_test.dart index 931b803..76d0448 100644 --- a/tests/compiler/dart2js/dart2js_batch2_test.dart +++ b/tests/compiler/dart2js/end_to_end/dart2js_batch2_test.dart
@@ -39,7 +39,7 @@ tmpDir = directory; String newPath = path.join(directory.path, "dart2js_batch2_run.dart"); File source = new File.fromUri( - Platform.script.resolve("data/dart2js_batch2_run.dart")); + Platform.script.resolve("../data/dart2js_batch2_run.dart")); source.copySync(newPath); }); } @@ -51,8 +51,8 @@ Future<Process> launchDart2Js(_) { String ext = Platform.isWindows ? '.bat' : ''; - String command = path.normalize(path.join( - path.fromUri(Platform.script), '../../../../sdk/bin/dart2js${ext}')); + String command = path + .normalize(path.join(path.fromUri(Uri.base), 'sdk/bin/dart2js${ext}')); print("Running '$command --batch' from '${tmpDir}'."); return Process.start(command, ['--batch'], workingDirectory: tmpDir.path); }
diff --git a/tests/compiler/dart2js/dart2js_batch_test.dart b/tests/compiler/dart2js/end_to_end/dart2js_batch_test.dart similarity index 93% rename from tests/compiler/dart2js/dart2js_batch_test.dart rename to tests/compiler/dart2js/end_to_end/dart2js_batch_test.dart index bd43218..1f59093 100644 --- a/tests/compiler/dart2js/dart2js_batch_test.dart +++ b/tests/compiler/dart2js/end_to_end/dart2js_batch_test.dart
@@ -39,8 +39,8 @@ Future setup() { return createTempDir().then((Directory directory) { tmpDir = directory; - Directory sunflowerDir = new Directory.fromUri( - Platform.script.resolve('../../../third_party/sunflower')); + Directory sunflowerDir = + new Directory.fromUri(Uri.base.resolve('third_party/sunflower')); print("Copying '${sunflowerDir.path}' to '${tmpDir.path}'."); copyDirectory(sunflowerDir, tmpDir); @@ -55,7 +55,7 @@ Future<Process> launchDart2Js(_) { return Process.start( // Use an absolute path because we are changing the cwd below. - path.fromUri(Uri.base.resolve(Platform.executable)), + path.absolute(Platform.executable), dart2JsCommand(['--batch']), workingDirectory: tmpDir.path); }
diff --git a/tests/compiler/dart2js/diagnostic_reporter_helper.dart b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart similarity index 97% rename from tests/compiler/dart2js/diagnostic_reporter_helper.dart rename to tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart index 0ca8649..7a3c4c7 100644 --- a/tests/compiler/dart2js/diagnostic_reporter_helper.dart +++ b/tests/compiler/dart2js/end_to_end/diagnostic_reporter_helper.dart
@@ -9,8 +9,8 @@ import 'package:compiler/src/diagnostics/source_span.dart'; import 'package:compiler/src/diagnostics/spannable.dart'; import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/options.dart'; import 'package:front_end/src/fasta/scanner.dart'; -import 'options_helper.dart'; abstract class DiagnosticReporterWrapper extends DiagnosticReporter { DiagnosticReporter get reporter;
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart similarity index 98% rename from tests/compiler/dart2js/exit_code_test.dart rename to tests/compiler/dart2js/end_to_end/exit_code_test.dart index fe5784a..9898b8b 100644 --- a/tests/compiler/dart2js/exit_code_test.dart +++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -5,7 +5,6 @@ // Test the exit code of dart2js in case of exceptions, errors, warnings, etc. import 'dart:async'; -import 'dart:io' show Platform; import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; @@ -242,7 +241,7 @@ entry.compileFunc = compile; List<String> args = new List<String>.from(options) - ..add("--library-root=${Platform.script.resolve('../../../sdk/')}") + ..add("--library-root=${Uri.base.resolve('sdk/')}") ..add("tests/compiler/dart2js/data/exit_code_helper.dart"); Future result = entry.internalMain(args); return result.catchError((e, s) {
diff --git a/tests/compiler/dart2js/launch_helper.dart b/tests/compiler/dart2js/end_to_end/launch_helper.dart similarity index 100% rename from tests/compiler/dart2js/launch_helper.dart rename to tests/compiler/dart2js/end_to_end/launch_helper.dart
diff --git a/tests/compiler/dart2js/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart similarity index 98% rename from tests/compiler/dart2js/library_env_test.dart rename to tests/compiler/dart2js/end_to_end/library_env_test.dart index 0960b39..f6496d2 100644 --- a/tests/compiler/dart2js/library_env_test.dart +++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -7,7 +7,7 @@ import 'dart:async'; -import 'memory_source_file_helper.dart'; +import '../memory_source_file_helper.dart'; import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart index 2bb2070..2d0a4ed 100644 --- a/tests/compiler/dart2js/equivalence/id_equivalence.dart +++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -211,15 +211,6 @@ TreeElements get elements => resolvedAst.elements; - ElementId computeElementId(AstElement element) { - String memberName = element.name; - if (element.isSetter) { - memberName += '='; - } - String className = element.enclosingClass?.name; - return new ElementId.internal(memberName, className); - } - ast.Node computeAccessPosition(ast.Send node, AccessSemantics access) { switch (access.kind) { case AccessKind.THIS_PROPERTY: @@ -522,6 +513,29 @@ } } +/// Compute a canonical [Id] for AST-based nodes. +ElementId computeElementId(AstElement element) { + String memberName = element.name; + if (element.isSetter) { + memberName += '='; + } + String className = element.enclosingClass?.name; + return new ElementId.internal(memberName, className); +} + +/// Compute a canonical [Id] for kernel-based nodes. +Id computeEntityId(ir.Member node) { + String className; + if (node.enclosingClass != null) { + className = node.enclosingClass.name; + } + String memberName = node.name.name; + if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) { + memberName += '='; + } + return new ElementId.internal(memberName, className); +} + /// Abstract IR visitor for computing data corresponding to a node or element, /// and record it with a generic [Id] abstract class IrDataExtractor extends ir.Visitor with DataRegistry { @@ -539,20 +553,9 @@ String computeNodeValue(Id id, ir.TreeNode node); IrDataExtractor(this.reporter, this.actualMap); - Id computeElementId(ir.Member node) { - String className; - if (node.enclosingClass != null) { - className = node.enclosingClass.name; - } - String memberName = node.name.name; - if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) { - memberName += '='; - } - return new ElementId.internal(memberName, className); - } void computeForMember(ir.Member member) { - ElementId id = computeElementId(member); + ElementId id = computeEntityId(member); if (id == null) return; String value = computeMemberValue(id, member); registerValue(computeSourceSpan(member), id, value, member);
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart index c3d22e2..a19dc4b 100644 --- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart +++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -77,8 +77,7 @@ /// Compute actual data for all members defined in the program with the /// [entryPoint] and [memorySourceFiles]. /// -/// Actual data is computed using [computeMemberData] and [code] is compiled -/// using [compileFunction]. +/// Actual data is computed using [computeMemberData]. Future<CompiledData> computeData( Uri entryPoint, Map<String, String> memorySourceFiles, @@ -87,21 +86,33 @@ bool verbose: false, bool forMainLibraryOnly: true, bool skipUnprocessedMembers: false, - bool skipFailedCompilations: false}) async { - Compiler compiler = - compilerFor(memorySourceFiles: memorySourceFiles, options: options); - compiler.stopAfterTypeInference = options.contains(stopAfterTypeInference); - await compiler.run(entryPoint); - if (compiler.compilationFailed) { + bool skipFailedCompilations: false, + bool forUserSourceFilesOnly: false}) async { + CompilationResult result = await runCompiler( + entryPoint: entryPoint, + memorySourceFiles: memorySourceFiles, + options: options, + beforeRun: (compiler) { + compiler.stopAfterTypeInference = + options.contains(stopAfterTypeInference); + }); + if (!result.isSuccess) { if (skipFailedCompilations) return null; - Expect.isFalse(compiler.compilationFailed, "Unexpected compilation error."); + Expect.isTrue(result.isSuccess, "Unexpected compilation error."); } + Compiler compiler = result.compiler; ClosedWorld closedWorld = compiler.backendClosedWorldForTesting; ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; Map<Uri, Map<Id, ActualData>> actualMaps = <Uri, Map<Id, ActualData>>{}; Map<Id, ActualData> actualMapFor(Entity entity) { + if (entity is Element) { + // TODO(johnniwinther): Remove this when patched members from kernel are + // no longer ascribed to the patch file. + Element element = entity; + entity = element.implementation; + } SourceSpan span = compiler.backendStrategy.spanFromSpannable(entity, entity); Uri uri = resolveFastaUri(span.uri); @@ -134,7 +145,7 @@ computeMemberData(compiler, member, actualMapFor(member), verbose: verbose); } - if (forMainLibraryOnly) { + if (forMainLibraryOnly && !forUserSourceFilesOnly) { LibraryEntity mainLibrary = elementEnvironment.mainLibrary; elementEnvironment.forEachClass(mainLibrary, (ClassEntity cls) { if (!elementEnvironment.isEnumClass(cls)) { @@ -143,6 +154,11 @@ elementEnvironment.forEachLocalClassMember(cls, processMember); }); elementEnvironment.forEachLibraryMember(mainLibrary, processMember); + } else if (forUserSourceFilesOnly) { + closedWorld.processedMembers + .where((MemberEntity member) => + userFiles.contains(member.library.canonicalUri.pathSegments.last)) + .forEach(processMember); } else { closedWorld.processedMembers.forEach(processMember); } @@ -172,7 +188,7 @@ } Map<int, List<String>> computeDiffAnnotationsAgainst( - Map<Id, ActualData> thisMap, Map<Id, ActualData> otherMap, + Map<Id, ActualData> thisMap, Map<Id, ActualData> otherMap, Uri uri, {bool includeMatches: false}) { Map<int, List<String>> annotations = <int, List<String>>{}; thisMap.forEach((Id id, ActualData data1) { @@ -192,8 +208,7 @@ otherMap.forEach((Id id, ActualData data2) { if (!thisMap.containsKey(id)) { int offset = compiler.reporter - .spanFromSpannable( - computeSpannable(elementEnvironment, mainUri, id)) + .spanFromSpannable(computeSpannable(elementEnvironment, uri, id)) .begin; String value1 = '---'; String value2 = '${data2.value}'; @@ -230,34 +245,39 @@ /// Data collected by [computeData]. class IdData { - final AnnotatedCode code; - final Map<Id, IdValue> expectedMap; + final Map<Uri, AnnotatedCode> code; + final MemberAnnotations<IdValue> expectedMaps; final CompiledData compiledData; + final MemberAnnotations<ActualData> _actualMaps = new MemberAnnotations(); - IdData(this.code, this.expectedMap, this.compiledData); + IdData(this.code, this.expectedMaps, this.compiledData) { + for (Uri uri in code.keys) { + _actualMaps[uri] = compiledData.actualMaps[uri] ?? <Id, ActualData>{}; + } + } Compiler get compiler => compiledData.compiler; ElementEnvironment get elementEnvironment => compiledData.elementEnvironment; Uri get mainUri => compiledData.mainUri; - Map<Id, ActualData> get actualMap => compiledData.actualMaps[mainUri]; + MemberAnnotations<ActualData> get actualMaps => _actualMaps; - String get actualCode { + String actualCode(Uri uri) { Map<int, List<String>> annotations = <int, List<String>>{}; - actualMap.forEach((Id id, ActualData data) { + actualMaps[uri].forEach((Id id, ActualData data) { annotations .putIfAbsent(data.sourceSpan.begin, () => []) .add('${data.value}'); }); - return withAnnotations(code.sourceCode, annotations); + return withAnnotations(code[uri].sourceCode, annotations); } - String get diffCode { + String diffCode(Uri uri) { Map<int, List<String>> annotations = <int, List<String>>{}; - actualMap.forEach((Id id, ActualData data) { - IdValue value = expectedMap[id]; + actualMaps[uri].forEach((Id id, ActualData data) { + IdValue value = expectedMaps[uri][id]; if (data.value != value || value == null && data.value.value != '') { String expected = value?.toString() ?? ''; - int offset = getOffsetFromId(id); + int offset = getOffsetFromId(id, uri); String value1 = '${expected}'; String value2 = '${data.value}'; annotations @@ -265,9 +285,9 @@ .add(colorizeDiff(value1, ' | ', value2)); } }); - expectedMap.forEach((Id id, IdValue expected) { - if (!actualMap.containsKey(id)) { - int offset = getOffsetFromId(id); + expectedMaps[uri].forEach((Id id, IdValue expected) { + if (!actualMaps[uri].containsKey(id)) { + int offset = getOffsetFromId(id, uri); String value1 = '${expected}'; String value2 = '---'; annotations @@ -275,28 +295,73 @@ .add(colorizeDiff(value1, ' | ', value2)); } }); - return withAnnotations(code.sourceCode, annotations); + return withAnnotations(code[uri].sourceCode, annotations); } - int getOffsetFromId(Id id) { + int getOffsetFromId(Id id, Uri uri) { return compiler.reporter - .spanFromSpannable(computeSpannable(elementEnvironment, mainUri, id)) + .spanFromSpannable(computeSpannable(elementEnvironment, uri, id)) .begin; } } +/// Encapsulates the member data computed for each source file of interest. +/// It's a glorified wrapper around a map of maps, but written this way to +/// provide a little more information about what it's doing. [DataType] refers +/// to the type this map is holding -- it is either [IdValue] or [ActualData]. +class MemberAnnotations<DataType> { + /// For each Uri, we create a map associating an element id with its + /// corresponding annotations. + final Map<Uri, Map<Id, DataType>> _computedDataForEachFile = + new Map<Uri, Map<Id, DataType>>(); + + void operator []=(Uri file, Map<Id, DataType> computedData) { + _computedDataForEachFile[file] = computedData; + } + + void forEach(void f(Uri file, Map<Id, DataType> computedData)) { + _computedDataForEachFile.forEach(f); + } + + Map<Id, DataType> operator [](Uri file) { + if (!_computedDataForEachFile.containsKey(file)) { + _computedDataForEachFile[file] = <Id, DataType>{}; + } + return _computedDataForEachFile[file]; + } +} + +typedef void Callback(); + /// Check code for all test files int [data] using [computeFromAst] and /// [computeFromKernel] from the respective front ends. If [skipForKernel] /// contains the name of the test file it isn't tested for kernel. +/// +/// [libDirectory] contains the directory for any supporting libraries that need +/// to be loaded. We expect supporting libraries to have the same prefix as the +/// original test in [dataDir]. So, for example, if testing `foo.dart` in +/// [dataDir], then this function will consider any files named `foo.*\.dart`, +/// such as `foo2.dart`, `foo_2.dart`, and `foo_blah_blah_blah.dart` in +/// [libDirectory] to be supporting library files for `foo.dart`. +/// [setUpFunction] is called once for every test that is executed. +/// If [forUserSourceFilesOnly] is true, we examine the elements in the main +/// file and any supporting libraries. Future checkTests(Directory dataDir, ComputeMemberDataFunction computeFromAst, ComputeMemberDataFunction computeFromKernel, {List<String> skipforAst: const <String>[], List<String> skipForKernel: const <String>[], bool filterActualData(IdValue idValue, ActualData actualData), List<String> options: const <String>[], - List<String> args: const <String>[]}) async { + List<String> args: const <String>[], + Directory libDirectory: null, + bool forMainLibraryOnly: true, + bool forUserSourceFilesOnly: false, + Callback setUpFunction}) async { args = args.toList(); bool verbose = args.remove('-v'); + + var relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, ''); + print('Data dir: ${relativeDir}'); await for (FileSystemEntity entity in dataDir.list()) { String name = entity.uri.pathSegments.last; if (args.isNotEmpty && !args.contains(name)) continue; @@ -305,99 +370,149 @@ testOptions.add(Flags.enableAsserts); } print('----------------------------------------------------------------'); - print('Checking ${entity.uri}'); - print('----------------------------------------------------------------'); + print('Test: $name'); // Pretend this is a dart2js_native test to allow use of 'native' keyword // and import of private libraries. + String commonTestPath = 'sdk/tests/compiler'; Uri entryPoint = - Uri.parse('memory:sdk/tests/compiler/dart2js_native/main.dart'); + Uri.parse('memory:$commonTestPath/dart2js_native/main.dart'); String annotatedCode = await new File.fromUri(entity.uri).readAsString(); - AnnotatedCode code = - new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd); - List<Map<Id, IdValue>> expectedMaps = computeExpectedMap(code); - Map<String, String> memorySourceFiles = {entryPoint.path: code.sourceCode}; + userFiles.add('main.dart'); + Map<Uri, AnnotatedCode> code = { + entryPoint: + new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd) + }; + Map<String, MemberAnnotations<IdValue>> expectedMaps = { + astMarker: new MemberAnnotations<IdValue>(), + kernelMarker: new MemberAnnotations<IdValue>() + }; + computeExpectedMap(entryPoint, code[entryPoint], expectedMaps); + Map<String, String> memorySourceFiles = { + entryPoint.path: code[entryPoint].sourceCode + }; + + if (libDirectory != null) { + print('Supporting libraries:'); + String filePrefix = name.substring(0, name.lastIndexOf('.')); + await for (FileSystemEntity libEntity in libDirectory.list()) { + String libFileName = libEntity.uri.pathSegments.last; + if (libFileName.startsWith(filePrefix)) { + print(' - libs/$libFileName'); + Uri libFileUri = + Uri.parse('memory:$commonTestPath/libs/$libFileName'); + userFiles.add(libEntity.uri.pathSegments.last); + String libCode = await new File.fromUri(libEntity.uri).readAsString(); + AnnotatedCode annotatedLibCode = + new AnnotatedCode.fromText(libCode, commentStart, commentEnd); + memorySourceFiles[libFileUri.path] = annotatedLibCode.sourceCode; + code[libFileUri] = annotatedLibCode; + computeExpectedMap(libFileUri, annotatedLibCode, expectedMaps); + } + } + } + + if (setUpFunction != null) setUpFunction(); if (skipforAst.contains(name)) { - print('--skipped for kernel------------------------------------------'); + print('--skipped for ast-----------------------------------------------'); } else { print('--from ast------------------------------------------------------'); CompiledData compiledData1 = await computeData( entryPoint, memorySourceFiles, computeFromAst, - options: testOptions, verbose: verbose); - await checkCode(code, expectedMaps[0], compiledData1); + options: testOptions, + verbose: verbose, + forMainLibraryOnly: forMainLibraryOnly, + forUserSourceFilesOnly: forUserSourceFilesOnly); + await checkCode(code, expectedMaps[astMarker], compiledData1); } if (skipForKernel.contains(name)) { - print('--skipped for kernel------------------------------------------'); + print('--skipped for kernel--------------------------------------------'); } else { print('--from kernel---------------------------------------------------'); CompiledData compiledData2 = await computeData( entryPoint, memorySourceFiles, computeFromKernel, - options: [Flags.useKernel]..addAll(testOptions), verbose: verbose); - await checkCode(code, expectedMaps[1], compiledData2, + options: [Flags.useKernel]..addAll(testOptions), + verbose: verbose, + forMainLibraryOnly: forMainLibraryOnly, + forUserSourceFilesOnly: forUserSourceFilesOnly); + await checkCode(code, expectedMaps[kernelMarker], compiledData2, filterActualData: filterActualData); } } } +final Set<String> userFiles = new Set<String>(); + /// Checks [compiledData] against the expected data in [expectedMap] derived /// from [code]. -Future checkCode( - AnnotatedCode code, Map<Id, IdValue> expectedMap, CompiledData compiledData, +Future checkCode(Map<Uri, AnnotatedCode> code, + MemberAnnotations<IdValue> expectedMaps, CompiledData compiledData, {bool filterActualData(IdValue expected, ActualData actualData)}) async { - IdData data = new IdData(code, expectedMap, compiledData); + IdData data = new IdData(code, expectedMaps, compiledData); - data.actualMap.forEach((Id id, ActualData actualData) { - IdValue actual = actualData.value; - if (!data.expectedMap.containsKey(id)) { - if (actual.value != '') { - reportHere( - data.compiler.reporter, - actualData.sourceSpan, - 'Id $id = ${actual} for ${actualData.object} ' - '(${actualData.object.runtimeType}) ' - 'not expected in ${data.expectedMap.keys}'); - print('--annotations diff--------------------------------------------'); - print(data.diffCode); - print('--------------------------------------------------------------'); + data.actualMaps.forEach((Uri uri, Map<Id, ActualData> actualMap) { + actualMap.forEach((Id id, ActualData actualData) { + IdValue actual = actualData.value; + if (!data.expectedMaps[uri].containsKey(id)) { + if (actual.value != '') { + reportHere( + data.compiler.reporter, + actualData.sourceSpan, + 'Id $id = ${actual} for ${actualData.object} ' + '(${actualData.object.runtimeType}) ' + 'not expected in ${data.expectedMaps[uri].keys}'); + print('--annotations diff [${uri.pathSegments.last}]---------------'); + print(data.diffCode(uri)); + print('------------------------------------------------------------'); + } + if (filterActualData == null || filterActualData(null, actualData)) { + Expect.equals('', actual.value); + } + } else { + IdValue expected = data.expectedMaps[uri][id]; + if (actual != expected) { + reportHere( + data.compiler.reporter, + actualData.sourceSpan, + 'Object: ${actualData.object} (${actualData.object.runtimeType}), ' + 'expected: ${expected}, actual: ${actual}'); + print('--annotations diff [${uri.pathSegments.last}]---------------'); + print(data.diffCode(uri)); + print('------------------------------------------------------------'); + } + if (filterActualData == null || + filterActualData(expected, actualData)) { + Expect.equals(expected, actual); + } } - if (filterActualData == null || filterActualData(null, actualData)) { - Expect.equals('', actual.value); - } - } else { - IdValue expected = data.expectedMap[id]; - if (actual != expected) { - reportHere( - data.compiler.reporter, - actualData.sourceSpan, - 'Object: ${actualData.object} (${actualData.object.runtimeType}), ' - 'expected: ${expected}, actual: ${actual}'); - print('--annotations diff--------------------------------------------'); - print(data.diffCode); - print('--------------------------------------------------------------'); - } - if (filterActualData == null || filterActualData(expected, actualData)) { - Expect.equals(expected, actual); - } - } + }); }); Set<Id> missingIds = new Set<Id>(); - data.expectedMap.forEach((Id id, IdValue expected) { - if (!data.actualMap.containsKey(id)) { - missingIds.add(id); - StringBuffer sb = new StringBuffer(); - for (Id id in data.actualMap.keys /*.where((d) => d.kind == id.kind)*/) { - sb.write('\n $id'); + StringBuffer combinedAnnotationsDiff = new StringBuffer(); + data.expectedMaps.forEach((Uri uri, Map<Id, IdValue> expectedMap) { + expectedMap.forEach((Id id, IdValue expected) { + if (!data.actualMaps[uri].containsKey(id)) { + missingIds.add(id); + StringBuffer sb = new StringBuffer(); + for (Id id + in data.actualMaps[uri].keys /*.where((d) => d.kind == id.kind)*/) { + sb.write('\n $id'); + } + reportHere( + data.compiler.reporter, + computeSpannable(data.elementEnvironment, uri, id), + 'Expected $expected for id $id missing in${sb}'); } - reportHere( - data.compiler.reporter, - computeSpannable(data.elementEnvironment, data.mainUri, id), - 'Expected $expected for id $id missing in${sb}'); + }); + if (missingIds.isNotEmpty) { + combinedAnnotationsDiff.write('Missing in $uri:\n'); + combinedAnnotationsDiff.write('${data.diffCode(uri)}\n'); } }); - if (missingIds.isNotEmpty) { + if (combinedAnnotationsDiff.isNotEmpty) { print('--annotations diff--------------------------------------------'); - print(data.diffCode); + print(combinedAnnotationsDiff.toString()); print('--------------------------------------------------------------'); } Expect.isTrue(missingIds.isEmpty, "Ids not found: ${missingIds}."); @@ -443,7 +558,8 @@ const String astMarker = 'ast.'; const String kernelMarker = 'kernel.'; -/// Compute two expectancy maps from [code]; one corresponding to the old +/// Compute two [MemberAnnotations] objects from [code] specifying the expected +/// annotations we anticipate encountering; one corresponding to the old /// implementation, one for the new implementation. /// /// If an annotation starts with 'ast.' it is only expected for the old @@ -452,23 +568,22 @@ /// /// Most nodes have the same and expectations should match this by using /// annotations without prefixes. -List<Map<Id, IdValue>> computeExpectedMap(AnnotatedCode code) { - Map<String, AnnotatedCode> split = - splitByPrefixes(code, [astMarker, kernelMarker]); +void computeExpectedMap(Uri sourceUri, AnnotatedCode code, + Map<String, MemberAnnotations<IdValue>> maps) { + List<String> mapKeys = [astMarker, kernelMarker]; + Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys); - List<Map<Id, IdValue>> maps = []; split.forEach((String marker, AnnotatedCode code) { - Map<Id, IdValue> map = <Id, IdValue>{}; + MemberAnnotations<IdValue> fileAnnotations = maps[marker]; + Map<Id, IdValue> expectedValues = fileAnnotations[sourceUri]; for (Annotation annotation in code.annotations) { String text = annotation.text; IdValue idValue = IdValue.decode(annotation.offset, text); - Expect.isFalse(map.containsKey(idValue.id), + Expect.isFalse(expectedValues.containsKey(idValue.id), "Duplicate annotations for ${idValue.id}."); - map[idValue.id] = idValue; + expectedValues[idValue.id] = idValue; } - maps.add(map); }); - return maps; } Future<bool> compareData( @@ -480,7 +595,8 @@ bool forMainLibraryOnly: true, bool skipUnprocessedMembers: false, bool skipFailedCompilations: false, - bool verbose: false}) async { + bool verbose: false, + bool whiteList(Uri uri, Id id)}) async { print('--from ast----------------------------------------------------------'); CompiledData data1 = await computeData( entryPoint, memorySourceFiles, computeAstData, @@ -498,12 +614,19 @@ skipFailedCompilations: skipFailedCompilations); if (data2 == null) return false; await compareCompiledData(data1, data2, - skipMissingUris: !forMainLibraryOnly, verbose: verbose); + whiteList: whiteList, + skipMissingUris: !forMainLibraryOnly, + verbose: verbose); return true; } Future compareCompiledData(CompiledData data1, CompiledData data2, - {bool skipMissingUris: false, bool verbose: false}) async { + {bool skipMissingUris: false, + bool verbose: false, + bool whiteList(Uri uri, Id id)}) async { + if (whiteList == null) { + whiteList = (uri, id) => false; + } bool hasErrors = false; String libraryRoot1; @@ -549,7 +672,9 @@ if (value1 != value2) { reportHere(data1.compiler.reporter, actualData1.sourceSpan, '$id: from source:${value1},from dill:${value2}'); - hasErrors = hasErrorsInUri = true; + if (!whiteList(uri1, id)) { + hasErrors = hasErrorsInUri = true; + } } }); actualMap2.forEach((Id id, ActualData actualData2) { @@ -558,14 +683,16 @@ if (value1 != value2) { reportHere(data2.compiler.reporter, actualData2.sourceSpan, '$id: from source:${value1},from dill:${value2}'); - hasErrors = hasErrorsInUri = true; + if (!whiteList(uri1, id)) { + hasErrors = hasErrorsInUri = true; + } } }); if (hasErrorsInUri) { print('--annotations diff $uri1---------------------------------------'); print(withAnnotations( sourceCode1, - data1.computeDiffAnnotationsAgainst(actualMap1, actualMap2, + data1.computeDiffAnnotationsAgainst(actualMap1, actualMap2, uri1, includeMatches: verbose))); print('----------------------------------------------------------'); }
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart deleted file mode 100644 index 09ab2e9..0000000 --- a/tests/compiler/dart2js/expect_annotations_test.dart +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'package:compiler/src/compiler.dart'; -import 'package:compiler/src/elements/elements.dart'; -import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints; -import 'package:compiler/src/types/types.dart'; -import 'package:compiler/src/world.dart' show ClosedWorld; -import 'type_mask_test_helper.dart'; -import 'memory_compiler.dart'; - -const Map MEMORY_SOURCE_FILES = const { - 'main.dart': r""" -import 'package:expect/expect.dart'; - -int method(String arg) => arg.length; - -@AssumeDynamic() -int methodAssumeDynamic(String arg) => arg.length; - -@TrustTypeAnnotations() -int methodTrustTypeAnnotations(String arg) => arg.length; - -@NoInline() -int methodNoInline(String arg) => arg.length; - -@NoInline() @TrustTypeAnnotations() -int methodNoInlineTrustTypeAnnotations(String arg) => arg.length; - -@AssumeDynamic() @TrustTypeAnnotations() -int methodAssumeDynamicTrustTypeAnnotations(String arg) => arg.length; - - -void main(List<String> args) { - print(method(args[0])); - print(methodAssumeDynamic('foo')); - print(methodTrustTypeAnnotations(42)); - print(methodTrustTypeAnnotations("fourtyTwo")); - print(methodNoInline('bar')); - print(methodNoInlineTrustTypeAnnotations(42)); - print(methodNoInlineTrustTypeAnnotations("fourtyTwo")); - print(methodAssumeDynamicTrustTypeAnnotations(null)); -} -""" -}; - -main() { - asyncTest(() async { - CompilationResult result = - await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); - Compiler compiler = result.compiler; - ClosedWorld closedWorld = - compiler.resolutionWorldBuilder.closedWorldForTesting; - Expect.isFalse(compiler.compilationFailed, 'Unsuccessful compilation'); - Expect.isNotNull(closedWorld.commonElements.expectNoInlineClass, - 'NoInlineClass is unresolved.'); - Expect.isNotNull(closedWorld.commonElements.expectTrustTypeAnnotationsClass, - 'TrustTypeAnnotations is unresolved.'); - Expect.isNotNull(closedWorld.commonElements.expectAssumeDynamicClass, - 'AssumeDynamicClass is unresolved.'); - - void testTypeMatch(MethodElement function, TypeMask expectedParameterType, - TypeMask expectedReturnType, TypesInferrer inferrer) { - for (ParameterElement parameter in function.parameters) { - TypeMask type = inferrer.getTypeOfParameter(parameter); - Expect.equals( - expectedParameterType, simplify(type, closedWorld), "$parameter"); - } - if (expectedReturnType != null) { - TypeMask type = inferrer.getReturnTypeOfMember(function); - Expect.equals( - expectedReturnType, simplify(type, closedWorld), "$function"); - } - } - - void test(String name, - {bool expectNoInline: false, - bool expectTrustTypeAnnotations: false, - TypeMask expectedParameterType: null, - TypeMask expectedReturnType: null, - bool expectAssumeDynamic: false}) { - LibraryElement mainApp = - compiler.frontendStrategy.elementEnvironment.mainLibrary; - MethodElement method = mainApp.find(name); - Expect.isNotNull(method); - Expect.equals( - expectNoInline, - optimizerHints.noInline(closedWorld.elementEnvironment, - closedWorld.commonElements, method), - "Unexpected annotation of @NoInline on '$method'."); - Expect.equals( - expectTrustTypeAnnotations, - optimizerHints.trustTypeAnnotations(closedWorld.elementEnvironment, - closedWorld.commonElements, method), - "Unexpected annotation of @TrustTypeAnnotations on '$method'."); - Expect.equals( - expectAssumeDynamic, - optimizerHints.assumeDynamic(closedWorld.elementEnvironment, - closedWorld.commonElements, method), - "Unexpected annotation of @AssumeDynamic on '$method'."); - TypesInferrer inferrer = compiler.globalInference.typesInferrerInternal; - if (expectTrustTypeAnnotations && expectedParameterType != null) { - testTypeMatch( - method, expectedParameterType, expectedReturnType, inferrer); - } else if (expectAssumeDynamic) { - testTypeMatch( - method, closedWorld.commonMasks.dynamicType, null, inferrer); - } - } - - TypeMask jsStringType = closedWorld.commonMasks.stringType; - TypeMask jsIntType = closedWorld.commonMasks.intType; - TypeMask coreStringType = new TypeMask.subtype( - closedWorld.commonElements.stringClass, closedWorld); - - test('method'); - test('methodAssumeDynamic', expectAssumeDynamic: true); - test('methodTrustTypeAnnotations', - expectTrustTypeAnnotations: true, expectedParameterType: jsStringType); - test('methodNoInline', expectNoInline: true); - test('methodNoInlineTrustTypeAnnotations', - expectNoInline: true, - expectTrustTypeAnnotations: true, - expectedParameterType: jsStringType, - expectedReturnType: jsIntType); - test('methodAssumeDynamicTrustTypeAnnotations', - expectAssumeDynamic: true, - expectTrustTypeAnnotations: true, - expectedParameterType: coreStringType); - }); -}
diff --git a/tests/compiler/dart2js/field_codegen_test.dart b/tests/compiler/dart2js/field_codegen_test.dart deleted file mode 100644 index 893bc1f..0000000 --- a/tests/compiler/dart2js/field_codegen_test.dart +++ /dev/null
@@ -1,30 +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_NULL0 = r""" -class A { static var x; } - -main() { return A.x; } -"""; - -const String TEST_NULL1 = r""" -var x; - -main() { return x; } -"""; - -main() { - asyncTest(() => compileAll(TEST_NULL0).then((generated) { - Expect.isTrue(generated.contains("null")); - })); - - asyncTest(() => compileAll(TEST_NULL1).then((generated) { - Expect.isTrue(generated.contains("null")); - })); -}
diff --git a/tests/compiler/dart2js/field_update_test.dart b/tests/compiler/dart2js/field_update_test.dart deleted file mode 100644 index c81422a..0000000 --- a/tests/compiler/dart2js/field_update_test.dart +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -// Test for emitting JavaScript pre- and post-increment and assignment ops. - -const String TEST_1 = """ -class A { - var a = 42; - int foo() { var r = a; a = a + 1; return r; } // this.a++ -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -const String TEST_2 = """ -class A { - var a = 42; - int foo() { var r = a; a = a + 1; return a; } // ++this.a -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -const String TEST_3 = """ -class A { - var a = 42; - int foo() { var r = a; a = a - 1; return r; } // this.a-- -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -const String TEST_4 = """ -class A { - var a = 42; - int foo() { var r = a; a = a - 1; return a; } // --this.a -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -const String TEST_5 = """ -class A { - var a = 42; - int foo() { var r = a; a = a - 2; return a; } // this.a -= 2 -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -const String TEST_6 = """ -class A { - var a = 42; - int foo() { var r = a; a = a * 2; return a; } // this.a *= 2 -} - -void main() { - var a = new A(); - print(a.foo()); -} -"""; - -main() { - test(String code, Function f) { - asyncTest(() => compileAll(code, disableInlining: true).then((generated) { - Expect.isTrue(f(generated)); - })); - } - - test(TEST_1, (generated) => generated.contains(r'return this.a++;')); - test(TEST_2, (generated) => generated.contains(r'return ++this.a;')); - test(TEST_3, (generated) => generated.contains(r'return this.a--;')); - test(TEST_4, (generated) => generated.contains(r'return --this.a;')); - test(TEST_5, (generated) => generated.contains(r' this.a -= 2;')); - test(TEST_6, (generated) => generated.contains(r' this.a *= 2;')); -}
diff --git a/tests/compiler/dart2js/for_in_test.dart b/tests/compiler/dart2js/for_in_test.dart deleted file mode 100644 index 3f02023..0000000 --- a/tests/compiler/dart2js/for_in_test.dart +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -foo(a) { - int x = 0; - for (int i in a) { - x += i; - } - return x; -} -"""; - -const String TEST_TWO = r""" -foo(a) { - int x = 0; - for (int i in a) { - if (i == 5) continue; - x += i; - } - return x; -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isTrue(!generated.contains(r'break')); - }), - compile(TEST_TWO, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains(r'continue')); - }), - ])); -}
diff --git a/tests/compiler/dart2js/forloop_box_test.dart b/tests/compiler/dart2js/forloop_box_test.dart deleted file mode 100644 index f27995f..0000000 --- a/tests/compiler/dart2js/forloop_box_test.dart +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -String SHOULD_NOT_BE_BOXED_TEST = r''' -main() { - var a; - for (var i=0; i<10; i++) { - a = () => i; - } - print(a()); -} -'''; - -String SHOULD_BE_BOXED_TEST = r''' -run(f) => f(); -main() { - var a; - for (var i=0; i<10; run(() => i++)) { - a = () => i; - } - print(a()); -} -'''; - -String ONLY_UPDATE_LOOP_VAR_TEST = r''' -run(f) => f(); -main() { - var a; - for (var i=0; i<10; run(() => i++)) { - var b = 3; - a = () => b = i; - } - print(a()); -} -'''; - -main() { - asyncTest(() => compileAll(SHOULD_NOT_BE_BOXED_TEST).then((generated) { - Expect.isTrue(generated.contains('main_closure(i)'), - 'for-loop variable should not have been boxed'); - })); - asyncTest(() => compileAll(SHOULD_BE_BOXED_TEST).then((generated) { - Expect.isFalse(generated.contains('main_closure(i)'), - 'for-loop variable should have been boxed'); - })); - asyncTest(() => compileAll(ONLY_UPDATE_LOOP_VAR_TEST).then((generated) { - Expect.isFalse(generated.contains('main_closure(i)'), - 'for-loop variable should have been boxed'); - Expect.isFalse(generated.contains(', _box_0.b = 3,'), - 'non for-loop captured variable should not be updated in loop'); - })); -}
diff --git a/tests/compiler/dart2js/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart similarity index 96% rename from tests/compiler/dart2js/function_type_variable_test.dart rename to tests/compiler/dart2js/generic_methods/function_type_variable_test.dart index ba64289..c302094 100644 --- a/tests/compiler/dart2js/function_type_variable_test.dart +++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -3,10 +3,10 @@ // BSD-style license that can be found in the LICENSE file. import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/elements/types.dart'; -import 'package:compiler/src/kernel/element_map_impl.dart'; import 'package:expect/expect.dart'; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; const List<FunctionTypeData> existentialTypeData = const <FunctionTypeData>[ // TODO(johnniwinther): Test generic bounds when #31531 is fixed. @@ -21,13 +21,12 @@ ]; main() { - DartTypeConverter.enableFunctionTypeVariables = true; asyncTest(() async { var env = await TypeEnvironment .create(createTypedefs(existentialTypeData, additionalData: """ class C1 {} class C2 {} - """), compileMode: CompileMode.kernel); + """), compileMode: CompileMode.kernel, options: [Flags.strongMode]); testToString(FunctionType type, String expectedToString) { Expect.equals(expectedToString, type.toString());
diff --git a/tests/compiler/dart2js/generic_method_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart similarity index 89% rename from tests/compiler/dart2js/generic_method_test.dart rename to tests/compiler/dart2js/generic_methods/generic_method_type_test.dart index 8f01ba3..0357757 100644 --- a/tests/compiler/dart2js/generic_method_test.dart +++ b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
@@ -3,12 +3,12 @@ // BSD-style license that can be found in the LICENSE file. import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/types.dart'; -import 'package:compiler/src/kernel/element_map_impl.dart'; import 'package:compiler/src/universe/call_structure.dart'; import 'package:expect/expect.dart'; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; List<FunctionTypeData> signatures = const <FunctionTypeData>[ const FunctionTypeData("void", "0", "()"), @@ -21,13 +21,14 @@ ]; main() { - DartTypeConverter.enableFunctionTypeVariables = true; - asyncTest(() async { - TypeEnvironment env = await TypeEnvironment.create(""" + TypeEnvironment env = await TypeEnvironment.create( + """ ${createTypedefs(signatures, prefix: 't')} ${createMethods(signatures, prefix: 'm')} - """, compileMode: CompileMode.kernel); + """, + compileMode: CompileMode.kernel, + options: [Flags.strongMode]); for (FunctionTypeData data in signatures) { FunctionType functionType = env.getElementType('t${data.name}');
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart deleted file mode 100644 index d7c0bec..0000000 --- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart +++ /dev/null
@@ -1,43 +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 dart2js gvns dynamic getters that don't have side -// effects. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; -import 'package:compiler/src/elements/names.dart'; -import 'package:compiler/src/universe/selector.dart' show Selector; - -const String TEST = r""" -class A { - var foo; - bar(a) { - return a.foo + a.foo; - } -} - -main() { - new A().bar(new Object()); -} -"""; - -main() { - Uri uri = new Uri(scheme: 'source'); - dynamic compiler = compilerFor(TEST, uri); - asyncTest(() => compiler.run(uri).then((_) { - String generated = compiler.assembledCode; - RegExp regexp = new RegExp(r"get\$foo"); - Iterator matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 1); - dynamic cls = findElement(compiler, 'A'); - Expect.isNotNull(cls); - String name = 'foo'; - var element = cls.lookupLocalMember(name); - Expect.isNotNull(element); - Selector selector = new Selector.getter(new PublicName(name)); - Expect.isFalse(compiler.resolutionWorldBuilder.closedWorldForTesting - .hasAnyUserDefinedGetter(selector, null)); - })); -}
diff --git a/tests/compiler/dart2js/gvn_test.dart b/tests/compiler/dart2js/gvn_test.dart deleted file mode 100644 index 2497dc9..0000000 --- a/tests/compiler/dart2js/gvn_test.dart +++ /dev/null
@@ -1,141 +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 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -void foo(bar) { - for (int i = 0; i < 1; i++) { - print(1 + bar); - print(1 + bar); - } -} -"""; - -// Check that modulo does not have any side effect and we are -// GVN'ing the length of [:list:]. -const String TEST_TWO = r""" -void foo(a) { - var list = new List<int>(); - list[0] = list[0 % a]; - list[1] = list[1 % a]; -} -"""; - -// Check that is checks get GVN'ed. -const String TEST_THREE = r""" -void foo(a) { - print(42); // Make sure numbers are used. - print(a is num); - print(a is num); -} -"""; - -// Check that instructions that don't have a builtin equivalent can -// still be GVN'ed. -const String TEST_FOUR = r""" -void foo(a) { - print(1 >> a); - print(1 >> a); -} -"""; - -// Check that [HCheck] instructions do not prevent GVN. -const String TEST_FIVE = r""" -class A { - var foo = 21; -} - -class B {} - -main() { - var a = [new B(), new A()][0]; - var b = a.foo; - var c = a.foo; - if (a is B) { - c = a.foo; - } - return b + c; -} -"""; - -// Check that a gvn'able instruction in the loop header gets hoisted. -const String TEST_SIX = r""" -class A { - final field = 54; -} - -main() { - var a = new A(); - while (a.field == 54) { a.field = 42; } -} -"""; - -// Check that a gvn'able instruction that may throw in the loop header -// gets hoisted. -const String TEST_SEVEN = r""" -class A { - final field; - A() : field = null; - A.bar() : field = 42; -} - -main() { - var a = new A(); - var b = new A.bar(); - while (a.field == 54) { a.field = 42; b.field = 42; } -} -"""; - -// Check that a check in a loop header gets hoisted. -const String TEST_EIGHT = r""" -class A { - final field; - A() : field = null; - A.bar() : field = 42; -} - -main() { - var a = new A(); - var b = new A.bar(); - for (int i = 0; i < a.field; i++) { a.field = 42; b.field = 42; } -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(TEST_ONE, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp(r"1 \+ [a-z]+"); - checkNumberOfMatches(regexp.allMatches(generated).iterator, 1); - }), - compile(TEST_TWO, entry: 'foo', check: (String generated) { - checkNumberOfMatches( - new RegExp("length").allMatches(generated).iterator, 1); - }), - compile(TEST_THREE, entry: 'foo', check: (String generated) { - checkNumberOfMatches( - new RegExp("number").allMatches(generated).iterator, 1); - }), - compile(TEST_FOUR, entry: 'foo', check: (String generated) { - checkNumberOfMatches( - new RegExp("shr").allMatches(generated).iterator, 1); - }), - compileAll(TEST_FIVE).then((generated) { - checkNumberOfMatches( - new RegExp("get\\\$foo").allMatches(generated).iterator, 1); - }), - compileAll(TEST_SIX).then((generated) { - Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)')); - }), - compileAll(TEST_SEVEN).then((generated) { - Expect.isTrue(generated.contains('for (t1 = a.field === 54; t1;)')); - }), - compileAll(TEST_EIGHT).then((generated) { - Expect.isTrue(generated.contains('for (; i < t1; ++i)')); - }), - ])); -}
diff --git a/tests/compiler/dart2js/identity_test.dart b/tests/compiler/dart2js/identity_test.dart deleted file mode 100644 index f534e29..0000000 --- a/tests/compiler/dart2js/identity_test.dart +++ /dev/null
@@ -1,30 +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""" -class A {} -bool foo(bar) { - var x = new A(); - var y = new A(); - return identical(x, y); -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - // Check that no boolify code is generated. - RegExp regexp = new RegExp("=== true"); - Iterator matches = regexp.allMatches(generated).iterator; - Expect.isFalse(matches.moveNext()); - - regexp = new RegExp("==="); - matches = regexp.allMatches(generated).iterator; - Expect.isTrue(matches.moveNext()); - Expect.isFalse(matches.moveNext()); - })); -}
diff --git a/tests/compiler/dart2js/if_do_while_test.dart b/tests/compiler/dart2js/if_do_while_test.dart deleted file mode 100644 index 929e76b..0000000 --- a/tests/compiler/dart2js/if_do_while_test.dart +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST = r""" -foo(param0, param1, param2) { - if (param0) - do { - param1(); - } while(param2()); - else { - param2(); - } -} -"""; - -main() { - print("foo"); - asyncTest(() => compile(TEST, entry: 'foo', check: (String generated) { - // Check that the do-while in the 'then' is enclosed in braces. - // Otherwise Android 4.0 stock browser has a syntax error. See issue 10923. - Expect.isTrue( - new RegExp(r'if[ ]*\([^)]+\)[ ]*\{[\n ]*do').hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/inference/assert_message_throw_test.dart b/tests/compiler/dart2js/inference/assert_message_throw_test.dart index b6f202b..d64ba79 100644 --- a/tests/compiler/dart2js/inference/assert_message_throw_test.dart +++ b/tests/compiler/dart2js/inference/assert_message_throw_test.dart
@@ -11,8 +11,8 @@ import 'package:compiler/src/types/masks.dart'; import 'package:compiler/src/world.dart' show ClosedWorld; import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; import '../memory_compiler.dart'; -import '../type_mask_test_helper.dart'; const String SOURCE = ''' main(args) {
diff --git a/tests/compiler/dart2js/inference/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/inference/call_site_simple_type_inferer_test.dart index 1337230..4047641 100644 --- a/tests/compiler/dart2js/inference/call_site_simple_type_inferer_test.dart +++ b/tests/compiler/dart2js/inference/call_site_simple_type_inferer_test.dart
@@ -3,19 +3,20 @@ // BSD-style license that can be found in the LICENSE file. /// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/elements/elements.dart'; import 'package:compiler/src/types/masks.dart'; import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; import '../compiler_helper.dart'; -import '../type_mask_test_helper.dart'; void compileAndFind(String code, String className, String memberName, bool disableInlining, check(compiler, element)) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(code, uri, disableInlining: disableInlining); + var compiler = mockCompilerFor(code, uri, disableInlining: disableInlining); asyncTest(() => compiler.run(uri).then((_) { ClassElement cls = findElement(compiler, className); var member = cls.lookupLocalMember(memberName);
diff --git a/tests/compiler/dart2js/inference/closure_tracer_28919_test.dart b/tests/compiler/dart2js/inference/closure_tracer_28919_test.dart new file mode 100644 index 0000000..46ad3d3 --- /dev/null +++ b/tests/compiler/dart2js/inference/closure_tracer_28919_test.dart
@@ -0,0 +1,114 @@ +// 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. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/common_elements.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/inferrer/type_graph_inferrer.dart'; +import 'package:compiler/src/types/types.dart'; +import 'package:compiler/src/world.dart'; +import 'package:expect/expect.dart'; + +import 'type_mask_test_helper.dart'; +import '../memory_compiler.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() { + runTest({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, + options: useKernel ? [Flags.useKernel] : []); + Expect.isTrue(result.isSuccess); + Compiler compiler = result.compiler; + + TypeGraphInferrer typesInferrer = + compiler.globalInference.typesInferrerInternal; + ClosedWorld closedWorld = typesInferrer.closedWorld; + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; + CommonMasks commonMasks = closedWorld.commonMasks; + + typeOf(String name) { + LibraryEntity library = elementEnvironment.mainLibrary; + MemberEntity member = + elementEnvironment.lookupLibraryMember(library, 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); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/closure_tracer_test.dart b/tests/compiler/dart2js/inference/closure_tracer_test.dart similarity index 94% rename from tests/compiler/dart2js/closure_tracer_test.dart rename to tests/compiler/dart2js/inference/closure_tracer_test.dart index c9f519b..be82ef3 100644 --- a/tests/compiler/dart2js/closure_tracer_test.dart +++ b/tests/compiler/dart2js/inference/closure_tracer_test.dart
@@ -2,11 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = ''' testFunctionStatement() { @@ -152,7 +155,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/inference/concrete_type_inference_test.dart similarity index 95% rename from tests/compiler/dart2js/concrete_type_inference_test.dart rename to tests/compiler/dart2js/inference/concrete_type_inference_test.dart index 5beabf3..4b1b6b5 100644 --- a/tests/compiler/dart2js/concrete_type_inference_test.dart +++ b/tests/compiler/dart2js/inference/concrete_type_inference_test.dart
@@ -2,14 +2,16 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'dart:async'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; Future compileAndFind(String code, String name, check(compiler, element)) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(code, uri); + var compiler = mockCompilerFor(code, uri); return compiler.run(uri).then((_) { var element = findElement(compiler, name); check(compiler, element);
diff --git a/tests/compiler/dart2js/inference/container_mask_equal_test.dart b/tests/compiler/dart2js/inference/container_mask_equal_test.dart new file mode 100644 index 0000000..5f8af3a --- /dev/null +++ b/tests/compiler/dart2js/inference/container_mask_equal_test.dart
@@ -0,0 +1,68 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +// Regression test for dart2js that used to have a bogus +// implementation of var.== and +// var.hashCode. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; +import '../memory_compiler.dart'; + +const MEMORY_SOURCE_FILES = const { + 'main.dart': ''' + +import 'dart:typed_data'; + +a() => [0]; +b() => [1, 2]; +c() => new Uint8List(1); +d() => new Uint8List(2); + +main() { + print(a); print(b); print(c); print(d); +} +''', +}; + +main() { + runTests({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + + var element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, 'a'); + var mask1 = typesInferrer.getReturnTypeOfMember(element); + + element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, 'b'); + var mask2 = typesInferrer.getReturnTypeOfMember(element); + + element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, 'c'); + var mask3 = typesInferrer.getReturnTypeOfMember(element); + + element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, 'd'); + var mask4 = typesInferrer.getReturnTypeOfMember(element); + + Expect.notEquals( + mask1.union(mask2, closedWorld), mask3.union(mask4, closedWorld)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/inference/data/foreign.dart b/tests/compiler/dart2js/inference/data/foreign.dart index 4f9c9be..525c027 100644 --- a/tests/compiler/dart2js/inference/data/foreign.dart +++ b/tests/compiler/dart2js/inference/data/foreign.dart
@@ -18,7 +18,6 @@ jsCallVoid(); jsCallUnion(); - jsBuiltin_createFunctionTypeRti(); jsBuiltin_rawRtiToJsConstructorName(); jsEmbeddedGlobal_getTypeFromName(); @@ -41,12 +40,6 @@ /*element: jsCallUnion:Union([exact=JSString], [subclass=JSInt])*/ jsCallUnion() => JS('int|String', '#', 0); -/*element: jsBuiltin_createFunctionTypeRti:[exact=Object]*/ -jsBuiltin_createFunctionTypeRti() { - return JS_BUILTIN('returns:=Object;effects:none;depends:none', - JsBuiltin.createFunctionTypeRti); -} - /*element: jsBuiltin_rawRtiToJsConstructorName:[exact=JSString]*/ jsBuiltin_rawRtiToJsConstructorName() { return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
diff --git a/tests/compiler/dart2js/inference/dictionary_types_test.dart b/tests/compiler/dart2js/inference/dictionary_types_test.dart new file mode 100644 index 0000000..1d934e6 --- /dev/null +++ b/tests/compiler/dart2js/inference/dictionary_types_test.dart
@@ -0,0 +1,173 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; + +import '../memory_compiler.dart'; + +var SOURCES = const { + 'AddAll.dart': """ + var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, + 'list': []}; + var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5, + 'list': []}; + var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84}; + var int = 0; + var anotherInt = 0; + var nullOrInt = 0; + var dynamic = 0; + + main() { + dictionaryA.addAll(otherDict); + dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84}); + int = dictionaryB['int']; + anotherInt = otherDict['intTwo']; + dynamic = dictionaryA['int']; + nullOrInt = dictionaryB['intTwo']; + } +""", + 'Union.dart': """ + var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, + 'list': []}; + var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []}; + var nullOrInt = 0; + var aString = ""; + var doubleOrNull = 22.2; + var key = "string"; + + main() { + var union = dictionaryA['foo'] ? dictionaryA : dictionaryB; + nullOrInt = union['intTwo']; + aString = union['string']; + doubleOrNull = union['double']; + } +""", + 'ValueType.dart': """ + var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []}; + var keyD = 'double'; + var keyI = 'int'; + var keyN = 'notFoundInMap'; + var knownDouble = 42.2; + var intOrNull = dictionary[keyI]; + var justNull = dictionary[keyN]; + + main() { + knownDouble = dictionary[keyD]; + var x = [intOrNull, justNull]; + } +""", + 'Propagation.dart': """ + class A { + A(); + foo(value) { + return value['anInt']; + } + } + + class B { + B(); + foo(value) { + return 0; + } + } + + main() { + var dictionary = {'anInt': 42, 'aString': "theString"}; + var it; + if ([true, false][0]) { + it = new A(); + } else { + it = new B(); + } + print(it.foo(dictionary) + 2); + } +""", + 'Bailout.dart': """ + var dict = makeMap([1,2]); + var notInt = 0; + var alsoNotInt = 0; + + makeMap(values) { + return {'moo': values[0], 'boo': values[1]}; + } + + main () { + dict['goo'] = 42; + var closure = () => dict; + notInt = closure()['boo']; + alsoNotInt = dict['goo']; + print("\$notInt and \$alsoNotInt."); + } +""" +}; + +void main() { + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +} + +runTests({bool useKernel}) async { + await compileAndTest("AddAll.dart", (types, getType, closedWorld) { + Expect.equals(getType('int'), types.uint31Type); + Expect.equals(getType('anotherInt'), types.uint31Type); + Expect.equals(getType('dynamic'), types.dynamicType); + Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); + }, useKernel: useKernel); + await compileAndTest("Union.dart", (types, getType, closedWorld) { + Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); + Expect.isTrue(getType('aString').containsOnlyString(closedWorld)); + Expect.equals(getType('doubleOrNull'), types.doubleType.nullable()); + }, useKernel: useKernel); + await compileAndTest("ValueType.dart", (types, getType, closedWorld) { + Expect.equals(getType('knownDouble'), types.doubleType); + Expect.equals(getType('intOrNull'), types.uint31Type.nullable()); + Expect.equals(getType('justNull'), types.nullType); + }, useKernel: useKernel); + await compileAndTest("Propagation.dart", (code) { + Expect.isFalse(code.contains("J.\$add\$ns")); + }, createCode: true, useKernel: useKernel); + await compileAndTest("Bailout.dart", (types, getType, closedWorld) { + Expect.equals(getType('notInt'), types.dynamicType); + Expect.equals(getType('alsoNotInt'), types.dynamicType); + Expect.isFalse(getType('dict').isDictionary); + }, useKernel: useKernel); +} + +compileAndTest(source, checker, + {bool createCode: false, bool useKernel}) async { + CompilationResult result = await runCompiler( + entryPoint: Uri.parse('memory:' + source), + memorySourceFiles: SOURCES, + beforeRun: (compiler) { + compiler.stopAfterTypeInference = !createCode; + }, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + var commonMasks = closedWorld.commonMasks; + getType(String name) { + var element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, name); + Expect.isNotNull(element, "No class '$name' found."); + return typesInferrer.getTypeOfMember(element); + } + + if (!createCode) { + checker(commonMasks, getType, closedWorld); + } else { + var element = elementEnvironment.mainFunction; + var code = compiler.backend.getGeneratedCode(element); + checker(code); + } +}
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/inference/field_type_simple_inferer_test.dart similarity index 97% rename from tests/compiler/dart2js/field_type_simple_inferer_test.dart rename to tests/compiler/dart2js/inference/field_type_simple_inferer_test.dart index 07ee7dc..6b46ce7 100644 --- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart +++ b/tests/compiler/dart2js/inference/field_type_simple_inferer_test.dart
@@ -2,18 +2,21 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/types/types.dart' show TypeMask; import 'package:compiler/src/world.dart' show ClosedWorld; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; void compileAndFind(String code, String className, String memberName, bool disableInlining, check(compiler, element)) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(code, uri, disableInlining: disableInlining); + var compiler = mockCompilerFor(code, uri, disableInlining: disableInlining); asyncTest(() => compiler.run(uri).then((_) { dynamic cls = findElement(compiler, className); var member = cls.lookupMember(memberName);
diff --git a/tests/compiler/dart2js/inference/inference_equivalence.dart b/tests/compiler/dart2js/inference/inference_equivalence.dart index c793404..2641692 100644 --- a/tests/compiler/dart2js/inference/inference_equivalence.dart +++ b/tests/compiler/dart2js/inference/inference_equivalence.dart
@@ -13,12 +13,14 @@ import 'package:compiler/src/resolution/class_hierarchy.dart'; import '../equivalence/id_equivalence_helper.dart'; import 'inference_test_helper.dart'; +import '../equivalence/id_equivalence.dart'; main(List<String> args) { mainInternal(args); } -Future<bool> mainInternal(List<String> args) async { +Future<bool> mainInternal(List<String> args, + {bool whiteList(Uri uri, Id id)}) async { ArgParser argParser = new ArgParser(allowTrailingOptions: true); argParser.addFlag('verbose', negatable: true, defaultsTo: false); argParser.addFlag('colors', negatable: true); @@ -52,7 +54,7 @@ try { print('--$uri------------------------------------------------------'); bool isSuccess = await runZoned(() { - return testUri(uri, verbose: verbose); + return testUri(uri, verbose: verbose, whiteList: whiteList); }, zoneSpecification: specification); if (!isSuccess) { success = false; @@ -69,12 +71,14 @@ return success; } -Future<bool> testUri(Uri uri, {bool verbose: false}) { +Future<bool> testUri(Uri uri, + {bool verbose: false, bool whiteList(Uri uri, Id id)}) { return compareData( uri, const {}, computeMemberAstTypeMasks, computeMemberIrTypeMasks, options: [stopAfterTypeInference], forMainLibraryOnly: false, skipUnprocessedMembers: true, skipFailedCompilations: true, - verbose: verbose); + verbose: verbose, + whiteList: whiteList); }
diff --git a/tests/compiler/dart2js/inference/issue13354_test.dart b/tests/compiler/dart2js/inference/issue13354_test.dart new file mode 100644 index 0000000..e5c7b4ea --- /dev/null +++ b/tests/compiler/dart2js/inference/issue13354_test.dart
@@ -0,0 +1,73 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart'; + +const String TEST = """ +bar() => 42; +baz() => bar; + +class A { + foo() => 42; +} + +class B extends A { + foo() => super.foo; +} + +main() { + baz(); + new B().foo(); +} +"""; + +void main() { + runTest({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + var commonMasks = closedWorld.commonMasks; + + checkReturn(String name, type) { + MemberEntity element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, name); + Expect.equals( + type, + simplify(typesInferrer.getReturnTypeOfMember(element), closedWorld), + name); + } + + checkReturnInClass(String className, String methodName, type) { + dynamic cls = elementEnvironment.lookupClass( + elementEnvironment.mainLibrary, className); + var element = elementEnvironment.lookupClassMember(cls, methodName); + Expect.equals(type, + simplify(typesInferrer.getReturnTypeOfMember(element), closedWorld)); + } + + checkReturn('bar', commonMasks.uint31Type); + checkReturn('baz', commonMasks.functionType); + + checkReturnInClass('A', 'foo', commonMasks.uint31Type); + checkReturnInClass('B', 'foo', commonMasks.functionType); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/inference/list_tracer2_test.dart b/tests/compiler/dart2js/inference/list_tracer2_test.dart new file mode 100644 index 0000000..b76158d --- /dev/null +++ b/tests/compiler/dart2js/inference/list_tracer2_test.dart
@@ -0,0 +1,52 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +// We used to always nullify the element type of a list we are tracing in +// the presence of a fixed length list constructor call. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/types/types.dart' show ContainerTypeMask; +import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart'; + +const String TEST = r''' +var myList = [42]; +main() { + var a = new List(42); + return myList[0]; +} +'''; + +void main() { + runTest({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + + checkType(String name, type) { + MemberEntity element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, name); + ContainerTypeMask mask = typesInferrer.getTypeOfMember(element); + Expect.equals(type, simplify(mask.elementType, closedWorld), name); + } + + checkType('myList', typesInferrer.closedWorld.commonMasks.uint31Type); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/list_tracer3_test.dart b/tests/compiler/dart2js/inference/list_tracer3_test.dart similarity index 86% rename from tests/compiler/dart2js/list_tracer3_test.dart rename to tests/compiler/dart2js/inference/list_tracer3_test.dart index c68ce62..b229cf6 100644 --- a/tests/compiler/dart2js/list_tracer3_test.dart +++ b/tests/compiler/dart2js/inference/list_tracer3_test.dart
@@ -2,6 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + // We used to always nullify the element type of a list we are tracing in // the presence of a fixed length list constructor call. @@ -9,8 +12,8 @@ import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show ContainerTypeMask; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = r''' var myList = []; @@ -24,7 +27,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/list_tracer_length_test.dart b/tests/compiler/dart2js/inference/list_tracer_length_test.dart similarity index 92% rename from tests/compiler/dart2js/list_tracer_length_test.dart rename to tests/compiler/dart2js/inference/list_tracer_length_test.dart index e2d7b6a..01523e2 100644 --- a/tests/compiler/dart2js/list_tracer_length_test.dart +++ b/tests/compiler/dart2js/inference/list_tracer_length_test.dart
@@ -2,9 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST1 = r""" var a = [42];
diff --git a/tests/compiler/dart2js/list_tracer_node_type_test.dart b/tests/compiler/dart2js/inference/list_tracer_node_type_test.dart similarity index 93% rename from tests/compiler/dart2js/list_tracer_node_type_test.dart rename to tests/compiler/dart2js/inference/list_tracer_node_type_test.dart index 7c91c8c..62b25da 100644 --- a/tests/compiler/dart2js/list_tracer_node_type_test.dart +++ b/tests/compiler/dart2js/inference/list_tracer_node_type_test.dart
@@ -2,9 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST1 = r""" main() {
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/inference/list_tracer_test.dart similarity index 96% rename from tests/compiler/dart2js/list_tracer_test.dart rename to tests/compiler/dart2js/inference/list_tracer_test.dart index e448b57..b9f5e819 100644 --- a/tests/compiler/dart2js/list_tracer_test.dart +++ b/tests/compiler/dart2js/inference/list_tracer_test.dart
@@ -2,12 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; String generateTest(String listAllocation) { return """ @@ -195,7 +198,7 @@ void doTest(String allocation, {bool nullify}) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(generateTest(allocation), uri, + var compiler = mockCompilerFor(generateTest(allocation), uri, expectedErrors: 0, expectedWarnings: 1); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal;
diff --git a/tests/compiler/dart2js/inference/list_tracer_typed_data_length_test.dart b/tests/compiler/dart2js/inference/list_tracer_typed_data_length_test.dart new file mode 100644 index 0000000..f0c9780 --- /dev/null +++ b/tests/compiler/dart2js/inference/list_tracer_typed_data_length_test.dart
@@ -0,0 +1,58 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/types/types.dart' show TypeMask, ContainerTypeMask; +import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart'; + +const TEST = const { + 'main.dart': r''' +import 'dart:typed_data'; + +var myList = new Float32List(42); +var myOtherList = new Uint8List(32); + +main() { + var a = new Float32List(9); + return myList[0] + myOtherList[0]; +} +''' +}; + +void main() { + runTest({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: TEST, options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + + checkType(String name, type, length) { + MemberEntity element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, name); + TypeMask mask = typesInferrer.getTypeOfMember(element); + Expect.isTrue(mask.isContainer); + ContainerTypeMask container = mask; + Expect.equals(type, simplify(container.elementType, closedWorld), name); + Expect.equals(container.length, length); + } + + checkType('myList', closedWorld.commonMasks.numType, 42); + checkType('myOtherList', closedWorld.commonMasks.uint31Type, 32); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/inference/map_tracer_const_test.dart b/tests/compiler/dart2js/inference/map_tracer_const_test.dart new file mode 100644 index 0000000..391a38e --- /dev/null +++ b/tests/compiler/dart2js/inference/map_tracer_const_test.dart
@@ -0,0 +1,57 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// TODO(johnniwinther): Port this test to use the equivalence framework. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:expect/expect.dart'; +import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart'; + +const String TEST = ''' +int closure(int x) { + return x; +} + +class A { + static const DEFAULT = const {'fun' : closure}; + + final map; + + A([maparg]) : map = maparg == null ? DEFAULT : maparg; +} + +main() { + var a = new A(); + a.map['fun'](3.3); + print(closure(22)); +} +'''; + +void main() { + runTest({bool useKernel}) async { + var result = await runCompiler( + memorySourceFiles: {'main.dart': TEST}, + options: useKernel ? [Flags.useKernel] : []); + var compiler = result.compiler; + var typesInferrer = compiler.globalInference.typesInferrerInternal; + var closedWorld = typesInferrer.closedWorld; + var elementEnvironment = closedWorld.elementEnvironment; + var commonMasks = closedWorld.commonMasks; + + MemberEntity element = elementEnvironment.lookupLibraryMember( + elementEnvironment.mainLibrary, 'closure'); + var mask = typesInferrer.getReturnTypeOfMember(element); + Expect.equals(commonMasks.numType, simplify(mask, closedWorld)); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/map_tracer_keys_test.dart b/tests/compiler/dart2js/inference/map_tracer_keys_test.dart similarity index 90% rename from tests/compiler/dart2js/map_tracer_keys_test.dart rename to tests/compiler/dart2js/inference/map_tracer_keys_test.dart index d5ee14f..e968733 100644 --- a/tests/compiler/dart2js/map_tracer_keys_test.dart +++ b/tests/compiler/dart2js/inference/map_tracer_keys_test.dart
@@ -2,11 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; String generateTest(String key, String value, bool initial) { return """ @@ -54,7 +57,7 @@ bool bail: false, bool initial: false}) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(generateTest(key, value, initial), uri, + var compiler = mockCompilerFor(generateTest(key, value, initial), uri, expectedErrors: 0, expectedWarnings: 0); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal;
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/inference/map_tracer_test.dart similarity index 97% rename from tests/compiler/dart2js/map_tracer_test.dart rename to tests/compiler/dart2js/inference/map_tracer_test.dart index 399d5b0..ddac6fd 100644 --- a/tests/compiler/dart2js/map_tracer_test.dart +++ b/tests/compiler/dart2js/inference/map_tracer_test.dart
@@ -2,12 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. +/// Currently it only works with the mock compiler. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show MapTypeMask, TypeMask; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; String generateTest(String mapAllocation) { return """ @@ -210,7 +213,7 @@ void doTest(String allocation, [String keyElementName, String valueElementName]) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(generateTest(allocation), uri, + var compiler = mockCompilerFor(generateTest(allocation), uri, expectedErrors: 0, expectedWarnings: 1); asyncTest(() => compiler.run(uri).then((_) { var keyType, valueType;
diff --git a/tests/compiler/dart2js/mixin_constructor_default_parameter_values_test.dart b/tests/compiler/dart2js/inference/mixin_constructor_default_parameter_values_test.dart similarity index 67% rename from tests/compiler/dart2js/mixin_constructor_default_parameter_values_test.dart rename to tests/compiler/dart2js/inference/mixin_constructor_default_parameter_values_test.dart index 4ff2338..c0d8ade 100644 --- a/tests/compiler/dart2js/mixin_constructor_default_parameter_values_test.dart +++ b/tests/compiler/dart2js/inference/mixin_constructor_default_parameter_values_test.dart
@@ -2,13 +2,16 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + // Ensure that the inferrer looks at default values for parameters in // synthetic constructors using the correct context. If the constructor call // to D without optional parameters is inferred using D's context, the default // value `_SECRET` will not be visible and compilation will fail. import 'package:async_helper/async_helper.dart'; -import 'memory_compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import '../memory_compiler.dart'; const Map MEMORY_SOURCE_FILES = const { "main.dart": r""" @@ -41,5 +44,16 @@ }; main() { - asyncTest(() => runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES)); + runTest({bool useKernel}) async { + await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/inference/side_effects/foreign.dart b/tests/compiler/dart2js/inference/side_effects/foreign.dart index 00f8667..9c4e18a 100644 --- a/tests/compiler/dart2js/inference/side_effects/foreign.dart +++ b/tests/compiler/dart2js/inference/side_effects/foreign.dart
@@ -24,13 +24,6 @@ jsCallEffectsNoInstanceDependsNoStatic() => JS('effects:no-instance;depends:no-static', '#', 0); -/*element: jsBuiltin_createFunctionTypeRti:SideEffects(reads static; writes nothing)*/ -jsBuiltin_createFunctionTypeRti() { - // TODO(johnniwinther): Why doesn't this have `Depends on nothing`? - return JS_BUILTIN('returns:=Object;effects:none;depends:none', - JsBuiltin.createFunctionTypeRti); -} - /*element: jsBuiltin_rawRtiToJsConstructorName:SideEffects(reads anything; writes anything)*/ jsBuiltin_rawRtiToJsConstructorName() { return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null); @@ -59,7 +52,6 @@ jsCallEffectsAllDependsNoIndex(); jsCallEffectsNoInstanceDependsNoStatic(); - jsBuiltin_createFunctionTypeRti(); jsBuiltin_rawRtiToJsConstructorName(); jsEmbeddedGlobal_getTypeFromName();
diff --git a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_and_or_test.dart similarity index 94% rename from tests/compiler/dart2js/simple_inferrer_and_or_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_and_or_test.dart index c026c54..eaacd3e 100644 --- a/tests/compiler/dart2js/simple_inferrer_and_or_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_and_or_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ class X {} @@ -94,7 +96,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_callers_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_callers_test.dart similarity index 92% rename from tests/compiler/dart2js/simple_inferrer_callers_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_callers_test.dart index 6c3b15f..91fd918 100644 --- a/tests/compiler/dart2js/simple_inferrer_callers_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_callers_test.dart
@@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + // Test that computation of callers of an element works when two // elements of the same name are being invoked in the same method. @@ -11,7 +13,7 @@ import 'package:compiler/src/inferrer/type_graph_inferrer.dart'; import 'package:compiler/src/world.dart' show ClosedWorld, ClosedWorldRefiner; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ class A { @@ -38,7 +40,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri, analyzeOnly: true); + var compiler = mockCompilerFor(TEST, uri, analyzeOnly: true); asyncTest(() => compiler.run(uri).then((_) { ElementEnvironment elementEnvironment = compiler.frontendStrategy.elementEnvironment;
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_closure_test.dart similarity index 95% rename from tests/compiler/dart2js/simple_inferrer_closure_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_closure_test.dart index 570304c..9b418e9 100644 --- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_closure_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ returnInt1() { @@ -116,7 +118,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure2_test.dart similarity index 87% rename from tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure2_test.dart index 200fb71..d7c416e 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure2_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure2_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -26,7 +28,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure3_test.dart similarity index 88% rename from tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure3_test.dart index e8c30ef..0904d1c 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure3_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure3_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -26,7 +28,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure4_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure4_test.dart index e51c434..31af6f6 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure4_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure4_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -27,7 +29,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure5_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure5_test.dart index 0344ebb..3546e9c 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure5_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure5_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -27,7 +29,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure_default_test.dart similarity index 94% rename from tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure_default_test.dart index ae936f5..b16c576 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure_default_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -40,7 +42,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_const_closure_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_const_closure_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_const_closure_test.dart index 738a43d..0c2d202 100644 --- a/tests/compiler/dart2js/simple_inferrer_const_closure_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_const_closure_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -35,7 +37,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_final_field2_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_final_field2_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_final_field2_test.dart index 5d522e8..53db6e1 100644 --- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_final_field2_test.dart
@@ -2,13 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + // Test that a non-used generative constructor does not prevent // inferring types for fields. import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -26,7 +28,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal;
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_final_field3_test.dart similarity index 88% rename from tests/compiler/dart2js/simple_inferrer_final_field3_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_final_field3_test.dart index fa81111..20c319a 100644 --- a/tests/compiler/dart2js/simple_inferrer_final_field3_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_final_field3_test.dart
@@ -2,12 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + // Test that we are analyzing field parameters correctly. import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -25,7 +27,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_final_field_test.dart similarity index 91% rename from tests/compiler/dart2js/simple_inferrer_final_field_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_final_field_test.dart index d470de8..233ab02 100644 --- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_final_field_test.dart
@@ -2,11 +2,13 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -29,7 +31,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_global_field_closure2_test.dart similarity index 88% rename from tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_global_field_closure2_test.dart index 44eeee8..45bcf56 100644 --- a/tests/compiler/dart2js/simple_inferrer_global_field_closure2_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_global_field_closure2_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -26,7 +28,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_global_field_closure_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_global_field_closure_test.dart index d81580f..c087cf8 100644 --- a/tests/compiler/dart2js/simple_inferrer_global_field_closure_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_global_field_closure_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -35,7 +37,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_no_such_method_test.dart similarity index 94% rename from tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_no_such_method_test.dart index 8abe812..50a2f86 100644 --- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_no_such_method_test.dart
@@ -2,12 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/types/types.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST1 = """ class A { @@ -172,7 +174,7 @@ test1() async { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST1, uri); + var compiler = mockCompilerFor(TEST1, uri); await compiler.run(uri); var closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; checkReturn(compiler, 'test1', closedWorld.commonMasks.uint31Type); @@ -188,7 +190,7 @@ test2() async { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST2, uri); + var compiler = mockCompilerFor(TEST2, uri); await compiler.run(uri); var closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; checkReturn(compiler, 'test1', closedWorld.commonMasks.mapType.nonNullable()); @@ -207,7 +209,7 @@ test3() async { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST3, uri); + var compiler = mockCompilerFor(TEST3, uri); await compiler.run(uri); var closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; checkReturn(compiler, 'test1', const TypeMask.nonNullEmpty()); @@ -220,7 +222,7 @@ test4() async { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST4, uri); + var compiler = mockCompilerFor(TEST4, uri); await compiler.run(uri); var closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; checkReturn(compiler, 'test1', const TypeMask.nonNullEmpty());
diff --git a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_postfix_prefix_test.dart similarity index 95% rename from tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_postfix_prefix_test.dart index 290856e..ff472fb 100644 --- a/tests/compiler/dart2js/simple_inferrer_postfix_prefix_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_postfix_prefix_test.dart
@@ -2,11 +2,13 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ @@ -64,7 +66,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_relations_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_relations_test.dart similarity index 93% rename from tests/compiler/dart2js/simple_inferrer_relations_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_relations_test.dart index db2e48d..9125ad8 100644 --- a/tests/compiler/dart2js/simple_inferrer_relations_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_relations_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; // Test that if (x == y) where we know nothing about x and y will get optimized // to if ($.$eq(x, y)) and not
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_test.dart similarity index 98% rename from tests/compiler/dart2js/simple_inferrer_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_test.dart index 6a42b2f..9f79e36 100644 --- a/tests/compiler/dart2js/simple_inferrer_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_test.dart
@@ -2,12 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show TypeMask; -import 'type_mask_test_helper.dart'; -import 'compiler_helper.dart'; +import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ returnNum1(a) { @@ -724,7 +726,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); compiler.diagnosticHandler = createHandler(compiler, TEST); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal;
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_try_catch_test.dart similarity index 95% rename from tests/compiler/dart2js/simple_inferrer_try_catch_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_try_catch_test.dart index bb2c812..8105bd0 100644 --- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_try_catch_test.dart
@@ -2,12 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/types/types.dart' show TypeMask; -import 'compiler_helper.dart'; import 'type_mask_test_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ returnInt1() { @@ -165,7 +167,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/inference/simple_inferrer_unregister_call_test.dart similarity index 89% rename from tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart rename to tests/compiler/dart2js/inference/simple_inferrer_unregister_call_test.dart index 6a3cd40..5356f65 100644 --- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart +++ b/tests/compiler/dart2js/inference/simple_inferrer_unregister_call_test.dart
@@ -2,10 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = """ var a = ''; @@ -30,7 +32,7 @@ void main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); asyncTest(() => compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal;
diff --git a/tests/compiler/dart2js/inference/swarm_test.dart b/tests/compiler/dart2js/inference/swarm_test.dart index 47feef7..c374b3f 100644 --- a/tests/compiler/dart2js/inference/swarm_test.dart +++ b/tests/compiler/dart2js/inference/swarm_test.dart
@@ -4,11 +4,21 @@ import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; +import '../equivalence/id_equivalence.dart'; import 'inference_equivalence.dart'; main(List<String> args) { asyncTest(() async { Expect.isTrue( - await mainInternal(['samples-dev/swarm/swarm.dart']..addAll(args))); + await mainInternal(['samples-dev/swarm/swarm.dart']..addAll(args), + whiteList: (Uri uri, Id id) { + if (uri.pathSegments.last == 'date_time.dart' && + '$id' == 'IdKind.node:15944') { + // DateTime.== uses `if (!(other is DateTime))` for which kernel is + // smarter. + return true; + } + return false; + })); }); }
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/inference/type_combination_test.dart similarity index 99% rename from tests/compiler/dart2js/type_combination_test.dart rename to tests/compiler/dart2js/inference/type_combination_test.dart index b5b0c40..dbbd030 100644 --- a/tests/compiler/dart2js/type_combination_test.dart +++ b/tests/compiler/dart2js/inference/type_combination_test.dart
@@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +// TODO(johnniwinther): Port this test to be frontend agnostic. + import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend; @@ -10,7 +12,7 @@ import 'package:compiler/src/world.dart'; import 'package:compiler/src/universe/use.dart'; import 'package:compiler/src/universe/world_impact.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'type_mask_test_helper.dart'; TypeMask nullType;
diff --git a/tests/compiler/dart2js/type_inference6_test.dart b/tests/compiler/dart2js/inference/type_inference6_test.dart similarity index 87% rename from tests/compiler/dart2js/type_inference6_test.dart rename to tests/compiler/dart2js/inference/type_inference6_test.dart index 8be0c1d..0c899a5 100644 --- a/tests/compiler/dart2js/type_inference6_test.dart +++ b/tests/compiler/dart2js/inference/type_inference6_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import "package:async_helper/async_helper.dart"; import "package:expect/expect.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'type_mask_test_helper.dart'; import 'dart:async'; @@ -22,7 +24,7 @@ Future runTest() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); return compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/type_inference7_test.dart b/tests/compiler/dart2js/inference/type_inference7_test.dart similarity index 91% rename from tests/compiler/dart2js/type_inference7_test.dart rename to tests/compiler/dart2js/inference/type_inference7_test.dart index 8875fb3..fd12b55 100644 --- a/tests/compiler/dart2js/type_inference7_test.dart +++ b/tests/compiler/dart2js/inference/type_inference7_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import "package:async_helper/async_helper.dart"; import "package:expect/expect.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'type_mask_test_helper.dart'; import 'dart:async'; @@ -21,7 +23,7 @@ Uri uri = new Uri(scheme: 'source'); { // Assertions enabled: - var compiler = compilerFor(TEST, uri, enableUserAssertions: true); + var compiler = mockCompilerFor(TEST, uri, enableUserAssertions: true); await compiler.run(uri); var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld; @@ -52,7 +54,7 @@ { // Assertions disabled: - var compiler = compilerFor(TEST, uri, enableUserAssertions: false); + var compiler = mockCompilerFor(TEST, uri, enableUserAssertions: false); await compiler.run(uri); var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/type_inference8_test.dart b/tests/compiler/dart2js/inference/type_inference8_test.dart similarity index 93% rename from tests/compiler/dart2js/type_inference8_test.dart rename to tests/compiler/dart2js/inference/type_inference8_test.dart index 1a77ca5..18c4aa7 100644 --- a/tests/compiler/dart2js/type_inference8_test.dart +++ b/tests/compiler/dart2js/inference/type_inference8_test.dart
@@ -2,11 +2,13 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import "package:async_helper/async_helper.dart"; import "package:compiler/src/constants/values.dart"; import "package:compiler/src/types/types.dart"; import "package:expect/expect.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'dart:async'; @@ -31,7 +33,7 @@ Future runTest1() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST1, uri); + var compiler = mockCompilerFor(TEST1, uri); return compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var commonMasks = typesInferrer.closedWorld.commonMasks; @@ -74,7 +76,7 @@ Future runTest2() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST2, uri); + var compiler = mockCompilerFor(TEST2, uri); return compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var commonMasks = typesInferrer.closedWorld.commonMasks;
diff --git a/tests/compiler/dart2js/type_inference_switch_test.dart b/tests/compiler/dart2js/inference/type_inference_switch_test.dart similarity index 94% rename from tests/compiler/dart2js/type_inference_switch_test.dart rename to tests/compiler/dart2js/inference/type_inference_switch_test.dart index 8b0b8e4..20da364 100644 --- a/tests/compiler/dart2js/type_inference_switch_test.dart +++ b/tests/compiler/dart2js/inference/type_inference_switch_test.dart
@@ -2,9 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +/// TODO(johnniwinther): Port this test to use the equivalence framework. + import "package:async_helper/async_helper.dart"; import "package:expect/expect.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'type_mask_test_helper.dart'; import 'dart:async'; @@ -132,7 +134,7 @@ Future runTest(String test, checker) { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(test, uri); + var compiler = mockCompilerFor(test, uri); return compiler.run(uri).then((_) { var typesInferrer = compiler.globalInference.typesInferrerInternal; var closedWorld = typesInferrer.closedWorld;
diff --git a/tests/compiler/dart2js/type_mask2_test.dart b/tests/compiler/dart2js/inference/type_mask2_test.dart similarity index 83% rename from tests/compiler/dart2js/type_mask2_test.dart rename to tests/compiler/dart2js/inference/type_mask2_test.dart index 5c6e159..2f2362a 100644 --- a/tests/compiler/dart2js/type_mask2_test.dart +++ b/tests/compiler/dart2js/inference/type_mask2_test.dart
@@ -7,10 +7,10 @@ import 'dart:async'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'type_test_helper.dart'; -import 'package:compiler/src/elements/elements.dart' show ClassElement; +import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/types/types.dart'; import 'package:compiler/src/world.dart' show ClosedWorld; +import '../type_test_helper.dart'; isCheckedMode() { try { @@ -24,18 +24,25 @@ } void main() { + runTests(CompileMode compileMode) async { + await testUnionTypeMaskFlatten(compileMode); + await testStringSubtypes(compileMode); + } + asyncTest(() async { - await testUnionTypeMaskFlatten(); - await testStringSubtypes(); + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); }); } -checkMasks(ClosedWorld closedWorld, List<ClassElement> allClasses, +checkMasks(ClosedWorld closedWorld, List<ClassEntity> allClasses, List<FlatTypeMask> masks, {FlatTypeMask result, List<FlatTypeMask> disjointMasks, FlatTypeMask flattened, - List<ClassElement> containedClasses}) { + List<ClassEntity> containedClasses}) { List<FlatTypeMask> disjoint = <FlatTypeMask>[]; UnionTypeMask.unionOfHelper(masks, disjoint, closedWorld); Expect.listEquals(disjointMasks, disjoint, @@ -72,7 +79,7 @@ result, union, 'Unexpected union of $masks: $union, expected $result.'); } if (containedClasses != null) { - for (ClassElement cls in allClasses) { + for (ClassEntity cls in allClasses) { if (containedClasses.contains(cls)) { Expect.isTrue(union.contains(cls, closedWorld), 'Expected $union to contain $cls.'); @@ -85,7 +92,7 @@ return union; } -Future testUnionTypeMaskFlatten() async { +Future testUnionTypeMaskFlatten(CompileMode compileMode) async { TypeEnvironment env = await TypeEnvironment.create(r""" class A {} class B {} @@ -100,24 +107,24 @@ new D(); new E(); } - """, compileMode: CompileMode.memory); + """, compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; - ClassElement Object_ = env.getElement("Object"); - ClassElement A = env.getElement("A"); - ClassElement B = env.getElement("B"); - ClassElement C = env.getElement("C"); - ClassElement D = env.getElement("D"); - ClassElement E = env.getElement("E"); + ClassEntity Object_ = env.getElement("Object"); + ClassEntity A = env.getElement("A"); + ClassEntity B = env.getElement("B"); + ClassEntity C = env.getElement("C"); + ClassEntity D = env.getElement("D"); + ClassEntity E = env.getElement("E"); - List<ClassElement> allClasses = <ClassElement>[Object_, A, B, C, D, E]; + List<ClassEntity> allClasses = <ClassEntity>[Object_, A, B, C, D, E]; check(List<FlatTypeMask> masks, {FlatTypeMask result, List<FlatTypeMask> disjointMasks, FlatTypeMask flattened, - List<ClassElement> containedClasses}) { + List<ClassEntity> containedClasses}) { return checkMasks(closedWorld, allClasses, masks, result: result, disjointMasks: disjointMasks, @@ -203,19 +210,19 @@ containedClasses: [A, B, E]); } -Future testStringSubtypes() async { +Future testStringSubtypes(CompileMode compileMode) async { TypeEnvironment env = await TypeEnvironment.create('', mainSource: r""" main() { '' is String; } """, - compileMode: CompileMode.memory); + compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; - ClassElement Object_ = env.getElement("Object"); - ClassElement String_ = env.getElement("String"); - ClassElement JSString = closedWorld.commonElements.jsStringClass; + ClassEntity Object_ = env.getElement("Object"); + ClassEntity String_ = env.getElement("String"); + ClassEntity JSString = closedWorld.commonElements.jsStringClass; Expect.isFalse(closedWorld.isDirectlyInstantiated(Object_)); Expect.isTrue(closedWorld.isIndirectlyInstantiated(Object_));
diff --git a/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart new file mode 100644 index 0000000..f67dd0a --- /dev/null +++ b/tests/compiler/dart2js/inference/type_mask_disjoint_test.dart
@@ -0,0 +1,210 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/common_elements.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:compiler/src/types/types.dart'; +import 'package:compiler/src/world.dart'; + +import '../memory_compiler.dart'; + +const String CODE = """ +class A {} +class B extends A {} +class C extends A {} + +class D implements A {} + +class E {} +class F extends E {} +class G implements E {} + +class H {} +class I implements H {} +class J extends D implements I {} + +class K {} +class M extends K with A {} + +class N extends H with I {} + +main() { + print([new A(), new B(), new C(), new D(), new E(), new F(), new G(), + new H(), new I(), new J(), new K(), new M(), new N()]); +} +"""; + +main() { + runTests({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': CODE}, + options: useKernel ? [Flags.useKernel] : []); + Expect.isTrue(result.isSuccess); + Compiler compiler = result.compiler; + ClosedWorld world = compiler.backendClosedWorldForTesting; + ElementEnvironment elementEnvironment = world.elementEnvironment; + + /// Checks the expectation of `isDisjoint` for two mask. Also checks that + /// the result is consistent with an equivalent (but slower) implementation + /// based on intersection. + checkMask(TypeMask m1, TypeMask m2, {areDisjoint: false}) { + print('masks: $m1 $m2'); + Expect.equals(areDisjoint, m1.isDisjoint(m2, world)); + Expect.equals(areDisjoint, m2.isDisjoint(m1, world)); + var i1 = m1.intersection(m2, world); + Expect.equals(areDisjoint, i1.isEmpty && !i1.isNullable); + var i2 = m2.intersection(m1, world); + Expect.equals(areDisjoint, i2.isEmpty && !i2.isNullable); + } + + Map _maskCache = {}; + Map _elementCache = {}; + + /// Parses a descriptor of a flat mask. A descriptor is of the form "AXY" + /// where: + /// A: either a type T or " " (base class or empty) + /// X: can be either ! or " " (nullable/nonnullable) + /// Y: can be either " " (no flag), = (exact), < (subclass), * (subtype) + /// + /// Examples: + /// "-! " - empty, non-null + /// "- " - null + /// "Type!=" - non-null exact Type + /// "Type =" - nullable exact Type + /// "Type!<" - non-null subclass of Type + /// "Type!*" - non-null subtype of Type + TypeMask maskOf(String descriptor) => + _maskCache.putIfAbsent(descriptor, () { + Expect.isTrue(descriptor.length >= 3); + var type = descriptor.substring(0, descriptor.length - 2); + bool isNullable = descriptor[descriptor.length - 2] != '!'; + bool isExact = descriptor[descriptor.length - 1] == '='; + bool isSubclass = descriptor[descriptor.length - 1] == '<'; + bool isSubtype = descriptor[descriptor.length - 1] == '*'; + + if (type == " ") { + Expect.isFalse(isExact || isSubclass || isSubtype); + return isNullable + ? new TypeMask.empty() + : new TypeMask.nonNullEmpty(); + } + + Expect.isTrue(isExact || isSubclass || isSubtype); + var element = _elementCache.putIfAbsent(type, () { + if (type == " ") return null; + ClassEntity cls = elementEnvironment.lookupClass( + elementEnvironment.mainLibrary, type); + Expect.isNotNull(cls, "No class '$type' found."); + return cls; + }); + + var mask = isExact + ? new TypeMask.nonNullExact(element, world) + : (isSubclass + ? new TypeMask.nonNullSubclass(element, world) + : new TypeMask.nonNullSubtype(element, world)); + return isNullable ? mask.nullable() : mask; + }); + + /// Checks the expectation of `isDisjoint` for two mask descriptors (see + /// [maskOf] for details). + check(String typeMaskDescriptor1, String typeMaskDescriptor2, + {areDisjoint: true}) { + print('[$typeMaskDescriptor1] & [$typeMaskDescriptor2]'); + checkMask(maskOf(typeMaskDescriptor1), maskOf(typeMaskDescriptor2), + areDisjoint: areDisjoint); + } + + checkUnions(List<String> descriptors1, List<String> descriptors2, + {areDisjoint: true}) { + print('[$descriptors1] & [$descriptors2]'); + var m1 = new TypeMask.unionOf(descriptors1.map(maskOf).toList(), world); + var m2 = new TypeMask.unionOf(descriptors2.map(maskOf).toList(), world); + checkMask(m1, m2, areDisjoint: areDisjoint); + } + + // Empty + check(' ! ', ' ! '); // both non-null + check(' ! ', ' '); // one non-null + check(' ', ' ! '); // one non-null + check(' ', ' ', areDisjoint: false); // null is common + + // Exact + check('A!=', 'A!=', areDisjoint: false); + check('A!=', 'B!='); + check('A!=', 'E!='); + check('A =', 'E =', areDisjoint: false); // null is common + check('M!=', 'K!='); + check('M!=', 'A!='); + + // Exact with subclass + check('A!=', 'A!<', areDisjoint: false); + check('B!=', 'A!<', areDisjoint: false); + check('A!=', 'B!<'); + check('A!=', 'E!<'); + check('A =', 'E!<'); + check('A =', 'E <', areDisjoint: false); + check('M!=', 'K!<', areDisjoint: false); + check('M!=', 'A!<'); + + // Exact with subtype + check('A!=', 'A!*', areDisjoint: false); + check('B!=', 'A!*', areDisjoint: false); + check('A!=', 'B!*'); + check('A!=', 'E!*'); + check('A!=', 'I!*'); + check('J!=', 'H!*', areDisjoint: false); + check('M!=', 'K!*', areDisjoint: false); + check('M!=', 'A!*', areDisjoint: false); + + // Subclass with subclass + check('A!<', 'A!<', areDisjoint: false); + check('A!<', 'B!<', areDisjoint: false); + check('A!<', 'E!<'); + check('A!<', 'H!<'); + check('D!<', 'I!<'); + check('H!<', 'I!*', areDisjoint: false); + + // Subclass with subtype + check('A!<', 'A!*', areDisjoint: false); + check('A!<', 'B!*', areDisjoint: false); + check('A!<', 'E!*'); + check('A!<', 'H!*'); + check('D!<', 'I!*', areDisjoint: false); + + // Subtype with subtype + check('A!*', 'A!*', areDisjoint: false); + check('A!*', 'B!*', areDisjoint: false); + check('A!*', 'E!*'); + check('A!*', 'H!*', areDisjoint: false); + check('D!*', 'I!*', areDisjoint: false); + + // Unions! + checkUnions(['B!=', 'C!='], ['A!=']); + checkUnions(['B!=', 'C!='], ['A =']); + checkUnions(['B!=', 'C ='], ['A ='], areDisjoint: false); + + checkUnions(['B!=', 'C!='], ['A!<'], areDisjoint: false); + checkUnions(['B!=', 'C!='], ['B!='], areDisjoint: false); + checkUnions(['A!<', 'E!<'], ['C!='], areDisjoint: false); + checkUnions(['A!<', 'E!<'], ['F!='], areDisjoint: false); + + checkUnions(['A!=', 'E!='], ['C!=', 'F!=']); + checkUnions(['A!=', 'E!='], ['A!=', 'F!='], areDisjoint: false); + checkUnions(['B!=', 'E!='], ['A!<', 'F!='], areDisjoint: false); + checkUnions(['A!<', 'E!<'], ['C!=', 'F!='], areDisjoint: false); + checkUnions(['A!=', 'E!='], ['C!=', 'F!=']); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/inference/type_mask_test.dart b/tests/compiler/dart2js/inference/type_mask_test.dart new file mode 100644 index 0000000..fc668d0 --- /dev/null +++ b/tests/compiler/dart2js/inference/type_mask_test.dart
@@ -0,0 +1,146 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import 'package:compiler/src/types/types.dart'; + +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/common_elements.dart'; +import 'package:compiler/src/compiler.dart'; +import 'package:compiler/src/world.dart'; +import '../memory_compiler.dart'; + +const String CODE = """ +class A {} +class B extends A {} +class C implements A {} +class D implements A {} +main() { + print([new A(), new B(), new C(), new D()]); +} +"""; + +main() { + runTests({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': CODE}, + options: useKernel ? [Flags.useKernel] : []); + Expect.isTrue(result.isSuccess); + Compiler compiler = result.compiler; + ClosedWorld closedWorld = compiler.backendClosedWorldForTesting; + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; + + dynamic classA = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'A'); + dynamic classB = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'B'); + dynamic classC = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'C'); + dynamic classD = + elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'D'); + + var exactA = new TypeMask.nonNullExact(classA, closedWorld); + var exactB = new TypeMask.nonNullExact(classB, closedWorld); + var exactC = new TypeMask.nonNullExact(classC, closedWorld); + var exactD = new TypeMask.nonNullExact(classD, closedWorld); + + var subclassA = new TypeMask.nonNullSubclass(classA, closedWorld); + var subtypeA = new TypeMask.nonNullSubtype(classA, closedWorld); + + var subclassObject = new TypeMask.nonNullSubclass( + closedWorld.commonElements.objectClass, closedWorld); + + var unionABC = UnionTypeMask.unionOf([exactA, exactB, exactC], closedWorld); + var unionABnC = + UnionTypeMask.unionOf([exactA, exactB.nullable(), exactC], closedWorld); + var unionAB = UnionTypeMask.unionOf([exactA, exactB], closedWorld); + var unionSubtypeAC = UnionTypeMask.unionOf([subtypeA, exactC], closedWorld); + var unionSubclassAC = + UnionTypeMask.unionOf([subclassA, exactC], closedWorld); + var unionBCD = UnionTypeMask.unionOf([exactB, exactC, exactD], closedWorld); + var unionBCDn = + UnionTypeMask.unionOf([exactB, exactC, exactD.nullable()], closedWorld); + + Expect.isFalse(unionABC.isNullable); + Expect.isTrue(unionABnC.isNullable); + Expect.isFalse(unionBCD.isNullable); + Expect.isTrue(unionBCDn.isNullable); + + rule(a, b, c) => Expect.equals(c, a.isInMask(b, closedWorld)); + + rule(exactA, exactA, true); + rule(exactA, exactB, false); + rule(exactA, exactC, false); + rule(exactA, subclassA, true); + rule(exactA, subtypeA, true); + + rule(exactB, exactA, false); + rule(exactB, exactB, true); + rule(exactB, exactC, false); + rule(exactB, subclassA, true); + rule(exactB, subtypeA, true); + + rule(exactC, exactA, false); + rule(exactC, exactB, false); + rule(exactC, exactC, true); + rule(exactC, subclassA, false); + rule(exactC, subtypeA, true); + + rule(subclassA, exactA, false); + rule(subclassA, exactB, false); + rule(subclassA, exactC, false); + rule(subclassA, subclassA, true); + rule(subclassA, subtypeA, true); + + rule(subtypeA, exactA, false); + rule(subtypeA, exactB, false); + rule(subtypeA, exactC, false); + rule(subtypeA, subclassA, false); + rule(subtypeA, subtypeA, true); + + rule(unionABC, unionSubtypeAC, true); + rule(unionSubtypeAC, unionABC, true); + rule(unionAB, unionSubtypeAC, true); + rule(unionSubtypeAC, unionAB, false); + rule(unionABC, unionSubclassAC, true); + rule(unionSubclassAC, unionABC, true); + rule(unionAB, unionSubclassAC, true); + rule(unionSubclassAC, unionAB, false); + rule(unionAB, subclassA, true); + rule(subclassA, unionAB, true); + rule(unionABC, subtypeA, true); + rule(subtypeA, unionABC, true); + rule(unionABC, subclassA, false); + rule(subclassA, unionABC, true); + rule(unionAB, subclassA, true); + rule(subclassA, unionAB, true); + + rule(exactA, subclassObject, true); + rule(exactB, subclassObject, true); + rule(subclassA, subclassObject, true); + rule(subtypeA, subclassObject, true); + rule(unionABC, subclassObject, true); + rule(unionAB, subclassObject, true); + rule(unionSubtypeAC, subclassObject, true); + rule(unionSubclassAC, subclassObject, true); + + rule(unionABnC, unionABC, false); + rule(unionABC, unionABnC, true); + rule(exactA.nullable(), unionABnC, true); + rule(exactA.nullable(), unionABC, false); + rule(exactB, unionABnC, true); + rule(unionBCDn, unionBCD, false); + rule(unionBCD, unionBCDn, true); + rule(exactB.nullable(), unionBCDn, true); + rule(exactB.nullable(), unionBCD, false); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/type_mask_test_helper.dart b/tests/compiler/dart2js/inference/type_mask_test_helper.dart similarity index 100% rename from tests/compiler/dart2js/type_mask_test_helper.dart rename to tests/compiler/dart2js/inference/type_mask_test_helper.dart
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/inference/union_type_test.dart similarity index 72% rename from tests/compiler/dart2js/union_type_test.dart rename to tests/compiler/dart2js/inference/union_type_test.dart index 8f6259a..6b0bcdf 100644 --- a/tests/compiler/dart2js/union_type_test.dart +++ b/tests/compiler/dart2js/inference/union_type_test.dart
@@ -6,10 +6,10 @@ import "package:expect/expect.dart"; import "package:compiler/src/types/types.dart"; import "package:compiler/src/world.dart"; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; main() { - asyncTest(() async { + runTest(CompileMode compileMode) async { TypeEnvironment env = await TypeEnvironment.create(r""" class A {} class B {} @@ -18,12 +18,19 @@ new A(); new B(); } - """, compileMode: CompileMode.memory); + """, compileMode: compileMode); ClosedWorld world = env.closedWorld; FlatTypeMask mask1 = new FlatTypeMask.exact(env.getClass('A')); FlatTypeMask mask2 = new FlatTypeMask.exact(env.getClass('B')); UnionTypeMask union1 = mask1.nonNullable().union(mask2, world); UnionTypeMask union2 = mask2.nonNullable().union(mask1, world); Expect.equals(union1, union2); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTest(CompileMode.kernel); }); }
diff --git a/tests/compiler/dart2js/inferrer_factory_test.dart b/tests/compiler/dart2js/inferrer_factory_test.dart deleted file mode 100644 index 2639517..0000000 --- a/tests/compiler/dart2js/inferrer_factory_test.dart +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST1 = r""" -class A implements List { - factory A() { - // Avoid inlining by using try/catch. - try { - return new List(); - } catch (e) { - } - } -} - -main() { - new A()[0] = 42; -} -"""; - -main() { - asyncTest(() => compileAll(TEST1).then((generated) { - // Check that we're using the index operator on the object returned - // by the A factory. - Expect.isTrue(generated.contains('[0] = 42')); - })); -}
diff --git a/tests/compiler/dart2js/inlining/data/conditional.dart b/tests/compiler/dart2js/inlining/data/conditional.dart new file mode 100644 index 0000000..5203943 --- /dev/null +++ b/tests/compiler/dart2js/inlining/data/conditional.dart
@@ -0,0 +1,63 @@ +// 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. + +// Tests for the heuristics on conditional expression whose condition is a +// parameter for which the max, instead of the sum, of the branch sizes is used. + +// ignore: IMPORT_INTERNAL_LIBRARY +import 'dart:_js_helper'; + +/*element: main:[]*/ +main() { + conditionalField(); + conditionalParameter(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Conditional expression on a non-parameter (here a top-level field). The +// size of the condition is the sum of the nodes in the conditional expression. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method1:[_conditionalField]*/ +_method1() => 42; + +var _field1; + +/*element: _conditionalField:[]*/ +_conditionalField() { + return _field1 + ? _method1() + _method1() + _method1() + : _method1() + _method1() + _method1(); +} + +/*element: conditionalField:[]*/ +@NoInline() +conditionalField() { + _field1 = false; + _conditionalField(); + _field1 = true; + _conditionalField(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Conditional expression on a parameter. The size of the condition is the +// max of the branches + the condition itself. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method2:[conditionalParameter]*/ +_method2() => 42; + +/*element: _conditionalParameter:[conditionalParameter]*/ +_conditionalParameter(o) { + return o + ? _method2() + _method2() + _method2() + : _method2() + _method2() + _method2(); +} + +/*element: conditionalParameter:[]*/ +@NoInline() +conditionalParameter() { + _conditionalParameter(true); + _conditionalParameter(false); +}
diff --git a/tests/compiler/dart2js/inlining/data/heuristics.dart b/tests/compiler/dart2js/inlining/data/heuristics.dart index 76e346d..6433d50 100644 --- a/tests/compiler/dart2js/inlining/data/heuristics.dart +++ b/tests/compiler/dart2js/inlining/data/heuristics.dart
@@ -11,6 +11,10 @@ outsideLoopNoArgsCalledTwice(); outsideLoopOneArgCalledOnce(); outsideLoopOneArgCalledTwice(); + insideLoopNoArgsCalledOnce(); + insideLoopNoArgsCalledTwice(); + insideLoopOneArgCalledOnce(); + insideLoopOneArgCalledTwice(); } //////////////////////////////////////////////////////////////////////////////// @@ -145,3 +149,177 @@ _outsideLoopOneArg2(0); _outsideLoopOneArg2(0); } + +//////////////////////////////////////////////////////////////////////////////// +// Inline a method with no parameters called once based regardless the number of +// static no-arg calls in its body. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method5:[insideLoopNoArgsCalledOnce]*/ +_method5() {} + +/*element: _insideLoopNoArgsCalledOnce:[insideLoopNoArgsCalledOnce]*/ +_insideLoopNoArgsCalledOnce() { + _method5(); + _method5(); + _method5(); + _method5(); + _method5(); + _method5(); + _method5(); + _method5(); + _method5(); + // This would be one too many calls if this method were called twice. + _method5(); +} + +/*element: insideLoopNoArgsCalledOnce:loop*/ +@NoInline() +insideLoopNoArgsCalledOnce() { + // ignore: UNUSED_LOCAL_VARIABLE + for (var e in [1, 2, 3, 4]) { + _insideLoopNoArgsCalledOnce(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Inline a method with no parameters called twice based on the number of +// static no-arg calls in its body. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method6:[_insideLoopNoArgs2,insideLoopNoArgsCalledTwice]*/ +_method6() {} + +/*element: _insideLoopNoArgs1:[insideLoopNoArgsCalledTwice]*/ +_insideLoopNoArgs1() { + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); +} + +/*element: _insideLoopNoArgs2:[]*/ +_insideLoopNoArgs2() { + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + _method6(); + // One too many calls: + _method6(); +} + +/*element: insideLoopNoArgsCalledTwice:loop*/ +@NoInline() +insideLoopNoArgsCalledTwice() { + // ignore: UNUSED_LOCAL_VARIABLE + for (var e in [1, 2, 3, 4]) { + _insideLoopNoArgs1(); + _insideLoopNoArgs1(); + _insideLoopNoArgs2(); + _insideLoopNoArgs2(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Inline a method with one parameter called once based regardless the number of +// static no-arg calls in its body. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method7:[insideLoopOneArgCalledOnce]*/ +_method7() {} + +/*element: _insideLoopOneArgCalledOnce:[insideLoopOneArgCalledOnce]*/ +_insideLoopOneArgCalledOnce(arg) { + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + // This would be too many calls if this method were called twice. + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); + _method7(); +} + +/*element: insideLoopOneArgCalledOnce:loop*/ +@NoInline() +insideLoopOneArgCalledOnce() { + for (var e in [1, 2, 3, 4]) { + _insideLoopOneArgCalledOnce(e); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Inline a method with one parameter called twice based on the number of +// static no-arg calls in its body. +//////////////////////////////////////////////////////////////////////////////// + +/*element: _method8:[_insideLoopOneArg2,insideLoopOneArgCalledTwice]*/ +_method8() {} + +/*element: _insideLoopOneArg1:[insideLoopOneArgCalledTwice]*/ +_insideLoopOneArg1(arg) { + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + // Extra calls granted by one parameter. + _method8(); + _method8(); +} + +/*element: _insideLoopOneArg2:[]*/ +_insideLoopOneArg2(arg) { + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + _method8(); + // Extra calls granted by one parameter. + _method8(); + _method8(); + // One too many calls: + _method8(); +} + +/*element: insideLoopOneArgCalledTwice:loop*/ +@NoInline() +insideLoopOneArgCalledTwice() { + for (var e in [1, 2, 3, 4]) { + _insideLoopOneArg1(e); + _insideLoopOneArg1(e); + _insideLoopOneArg2(e); + _insideLoopOneArg2(e); + } +}
diff --git a/tests/compiler/dart2js/meta_annotations2_test.dart b/tests/compiler/dart2js/inlining/meta_annotations2_test.dart similarity index 77% rename from tests/compiler/dart2js/meta_annotations2_test.dart rename to tests/compiler/dart2js/inlining/meta_annotations2_test.dart index d615372..2797238 100644 --- a/tests/compiler/dart2js/meta_annotations2_test.dart +++ b/tests/compiler/dart2js/inlining/meta_annotations2_test.dart
@@ -7,7 +7,8 @@ import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; import 'package:compiler/compiler_new.dart'; -import 'memory_compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': r''' @@ -38,10 +39,12 @@ }; void main() { - asyncTest(() async { + runTests({bool useKernel}) async { OutputCollector collector = new OutputCollector(); await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); // Simply check that the constants of the small functions are still in the // output, and that we don't see the result of constant folding. String jsOutput = collector.getOutput('', OutputType.js); @@ -62,5 +65,12 @@ hasNot('211109'); hasNot('82155031'); hasNot('4712'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/meta_annotations3_test.dart b/tests/compiler/dart2js/inlining/meta_annotations3_test.dart similarity index 80% rename from tests/compiler/dart2js/meta_annotations3_test.dart rename to tests/compiler/dart2js/inlining/meta_annotations3_test.dart index 005cbf1..37d1b76 100644 --- a/tests/compiler/dart2js/meta_annotations3_test.dart +++ b/tests/compiler/dart2js/inlining/meta_annotations3_test.dart
@@ -7,7 +7,8 @@ import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; import 'package:compiler/compiler_new.dart'; -import 'memory_compiler.dart'; +import 'package:compiler/src/commandline_options.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': r''' @@ -50,10 +51,12 @@ }; void main() { - asyncTest(() async { + runTests({bool useKernel}) async { OutputCollector collector = new OutputCollector(); await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector); + memorySourceFiles: MEMORY_SOURCE_FILES, + outputProvider: collector, + options: useKernel ? [Flags.useKernel] : []); String jsOutput = collector.getOutput('', OutputType.js); void has(String text) { @@ -77,5 +80,12 @@ hasNot('48000993'); has('48001992'); has('48001993'); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/meta_annotations_test.dart b/tests/compiler/dart2js/inlining/meta_annotations_test.dart similarity index 70% rename from tests/compiler/dart2js/meta_annotations_test.dart rename to tests/compiler/dart2js/inlining/meta_annotations_test.dart index f3ad7fb..2eaee34 100644 --- a/tests/compiler/dart2js/meta_annotations_test.dart +++ b/tests/compiler/dart2js/inlining/meta_annotations_test.dart
@@ -4,11 +4,13 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/common_elements.dart'; import 'package:compiler/src/compiler.dart'; -import 'package:compiler/src/elements/elements.dart'; +import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/js_backend/annotations.dart' as optimizerHints; import 'package:compiler/src/world.dart' show ClosedWorld; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const Map MEMORY_SOURCE_FILES = const { 'main.dart': r""" @@ -32,12 +34,14 @@ }; main() { - asyncTest(() async { - CompilationResult result = - await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); + runTests({bool useKernel}) async { + CompilationResult result = await runCompiler( + memorySourceFiles: MEMORY_SOURCE_FILES, + options: useKernel ? [Flags.useKernel] : []); Compiler compiler = result.compiler; ClosedWorld closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; Expect.isFalse(compiler.compilationFailed, 'Unsuccessful compilation'); Expect.isNotNull(closedWorld.commonElements.metaNoInlineClass, 'NoInlineClass is unresolved.'); @@ -46,9 +50,9 @@ void test(String name, {bool expectNoInline: false, bool expectTryInline: false}) { - LibraryElement mainApp = - compiler.frontendStrategy.elementEnvironment.mainLibrary; - MethodElement method = mainApp.find(name); + LibraryEntity mainLibrary = elementEnvironment.mainLibrary; + FunctionEntity method = + elementEnvironment.lookupLibraryMember(mainLibrary, name); Expect.isNotNull(method); Expect.equals( expectNoInline, @@ -65,5 +69,12 @@ test('method'); test('methodNoInline', expectNoInline: true); test('methodTryInline', expectTryInline: true); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/instantiated_classes_test.dart b/tests/compiler/dart2js/instantiated_classes_test.dart index 1b9d1d0f..11a276a 100644 --- a/tests/compiler/dart2js/instantiated_classes_test.dart +++ b/tests/compiler/dart2js/instantiated_classes_test.dart
@@ -12,66 +12,82 @@ import 'type_test_helper.dart'; void main() { - asyncTest(() => Future.forEach([ - () => test("class Class {}", ["Class"]), - () => test("""abstract class A {} - class Class extends A {}""", ["Class"]), - () => test("""class A {} - class Class extends A {}""", ["Class"]), - () => test("""class A {} + Future runTests({bool useKernel}) async { + Future test(String source, List<String> directlyInstantiatedClasses, + [List<String> newClasses = const <String>["Class"]]) async { + StringBuffer mainSource = new StringBuffer(); + mainSource.write('main() {\n'); + for (String newClass in newClasses) { + mainSource.write(' new $newClass();\n'); + } + mainSource.write('}'); + dynamic env = await TypeEnvironment.create(source, + mainSource: mainSource.toString(), + compileMode: useKernel ? CompileMode.kernel : CompileMode.memory); + LibraryEntity mainLibrary = + env.compiler.frontendStrategy.elementEnvironment.mainLibrary; + Iterable<ClassEntity> expectedClasses = + directlyInstantiatedClasses.map(env.getElement); + Iterable<ClassEntity> actualClasses = env + .compiler.resolutionWorldBuilder.directlyInstantiatedClasses + .where((c) => c.library == mainLibrary); + Expect.setEquals( + expectedClasses, + actualClasses, + "Instantiated classes mismatch: " + "Expected $expectedClasses, actual: $actualClasses"); + } + + await test("class Class {}", ["Class"]); + await test("""abstract class A {} + class Class extends A {}""", ["Class"]); + await test("""class A {} + class Class extends A {}""", ["Class"]); + await test("""class A {} class B {} - class Class extends A {}""", ["Class"]), - () => test("""class A {} - class Class implements A {}""", ["Class"]), - () => test("""class A {} - class Class extends Object with A {}""", ["Class"]), - () => test("""class A {} + class Class extends A {}""", ["Class"]); + await test("""class A {} + class Class implements A {}""", ["Class"]); + await test("""class A {} + class Class extends Object with A {}""", ["Class"]); + await test("""class A {} class B {} class Class extends Object with B implements A {}""", - ["Class"]), + ["Class"]); - () => test("""class A {} - class Class {}""", ["Class", "A"], ["Class", "A"]), - () => test("""class A {} - class Class extends A {}""", ["Class", "A"], ["Class", "A"]), - () => test("""class A {} + await test("""class A {} + class Class {}""", ["Class", "A"], ["Class", "A"]); + await test("""class A {} + class Class extends A {}""", ["Class", "A"], ["Class", "A"]); + await test("""class A {} class Class implements A {}""", ["Class", "A"], - ["Class", "A"]), - () => test("""class A {} + ["Class", "A"]); + await test("""class A {} class B extends A {} - class Class extends B {}""", ["Class", "A"], ["Class", "A"]), - () => test("""class A {} + class Class extends B {}""", ["Class", "A"], ["Class", "A"]); + await test("""class A {} class B {} class Class extends B with A {}""", ["Class", "A"], - ["Class", "A"]), + ["Class", "A"]); - // TODO(johnniwinther): Avoid registration of `Class` as instantiated. - () => test("""class A {} - class Class implements A { - factory Class() = A; - }""", ["Class", "A"], ["Class"]), - ], (f) => f())); -} - -Future test(String source, List<String> directlyInstantiatedClasses, - [List<String> newClasses = const <String>["Class"]]) { - StringBuffer mainSource = new StringBuffer(); - mainSource.write('main() {\n'); - for (String newClass in newClasses) { - mainSource.write(' new $newClass();\n'); + if (!useKernel) { + // TODO(johnniwinther): Avoid registration of `Class` as instantiated. + await test("""class A {} + class Class implements A { + factory Class() = A; + }""", ["Class", "A"], ["Class"]); + } else { + await test("""class A {} + class Class implements A { + factory Class() = A; + }""", ["A"], ["Class"]); + } } - mainSource.write('}'); - return TypeEnvironment - .create(source, - mainSource: mainSource.toString(), compileMode: CompileMode.mock) - .then((dynamic env) { - LibraryEntity mainLibrary = - env.compiler.frontendStrategy.elementEnvironment.mainLibrary; - Iterable<ClassEntity> expectedClasses = - directlyInstantiatedClasses.map(env.getElement); - Iterable<ClassEntity> actualClasses = env - .compiler.resolutionWorldBuilder.directlyInstantiatedClasses - .where((c) => c.library == mainLibrary); - Expect.setEquals(expectedClasses, actualClasses); + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/interceptor_almost_constant_test.dart b/tests/compiler/dart2js/interceptor_almost_constant_test.dart deleted file mode 100644 index 72838d76..0000000 --- a/tests/compiler/dart2js/interceptor_almost_constant_test.dart +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" - foo(b) { - var a = b ? [1,2,3] : null; - print(a.first); - } -"""; - -main() { - asyncTest(() => Future.wait([ - // Check that almost-constant interceptor is used. - compile(TEST_ONE, entry: 'foo', check: (String generated) { - String re = r'a && [\w\.]*_methods'; - Expect.isTrue(generated.contains(new RegExp(re)), 'contains /$re/'); - }) - ])); -}
diff --git a/tests/compiler/dart2js/interceptor_test.dart b/tests/compiler/dart2js/interceptor_test.dart deleted file mode 100644 index b7d375d..0000000 --- a/tests/compiler/dart2js/interceptor_test.dart +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" - foo(a) { - var myVariableName = a.toString(); - print(myVariableName); - print(myVariableName); - } -"""; - -const String TEST_TWO = r""" - class A { - var length; - } - foo(a) { - print([]); // Make sure the array class is instantiated. - return new A().length + a.length; - } -"""; - -main() { - asyncTest(() => Future.wait([ - // Check that one-shot interceptors preserve variable names, see - // https://code.google.com/p/dart/issues/detail?id=8106. - compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isTrue( - generated.contains(new RegExp(r'[$A-Z]+\.toString\$0\$\(a\)'))); - Expect.isTrue(generated.contains('myVariableName')); - }), - // Check that an intercepted getter that does not need to be - // intercepted, is turned into a regular getter call or field - // access. - compile(TEST_TWO, entry: 'foo', check: (String generated) { - Expect.isFalse(generated.contains(r'a.get$length()')); - Expect.isTrue( - generated.contains(new RegExp(r'[$A-Z]+\.A\$\(\)\.length'))); - Expect.isTrue( - generated.contains(new RegExp(r'[$A-Z]+\.get\$length\$as\(a\)'))); - }), - ])); -}
diff --git a/tests/compiler/dart2js/interop_anonymous_unreachable_test.dart b/tests/compiler/dart2js/interop_anonymous_unreachable_test.dart deleted file mode 100644 index 33b8ea3..0000000 --- a/tests/compiler/dart2js/interop_anonymous_unreachable_test.dart +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -library tests.dart2js.interop_anonymous_unreachable_test; - -import 'package:test/test.dart'; -import 'compiler_helper.dart'; - -main() { - test("unreachable code doesn't crash the compiler", () async { - // This test is a regression for Issue #24974 - String generated = await compile(""" - import 'package:js/js.dart'; - - @JS() @anonymous - class UniqueLongNameForTesting_A { - external factory UniqueLongNameForTesting_A(); - } - main() {} - """, returnAll: true); - - // the code should not be included in the output either. - expect(generated, isNot(contains("UniqueLongNameForTesting_A"))); - }); - - group('tree-shaking interop types', () { - String program = """ - import 'package:js/js.dart'; - - // reachable and allocated - @JS() @anonymous - class UniqueLongNameForTesting_A { - external bool get x; - external UniqueLongNameForTesting_D get d; - external UniqueLongNameForTesting_E get e; - external factory UniqueLongNameForTesting_A( - {UniqueLongNameForTesting_B arg0}); - } - - // visible through the parameter above, but not used. - @JS() @anonymous - class UniqueLongNameForTesting_B { - external factory UniqueLongNameForTesting_B(); - } - - // unreachable - @JS() @anonymous - class UniqueLongNameForTesting_C { - external factory UniqueLongNameForTesting_C(); - } - - // visible and reached through `d`. - @JS() @anonymous - class UniqueLongNameForTesting_D { - external factory UniqueLongNameForTesting_D(); - } - - // visible through `e`, but not reached. - @JS() @anonymous - class UniqueLongNameForTesting_E { - external factory UniqueLongNameForTesting_E(); - } - - main() { - print(new UniqueLongNameForTesting_A().x); - print(new UniqueLongNameForTesting_A().d); - } - """; - - test('no tree-shaking by default', () async { - String generated = await compile(program, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - expect(generated.contains("UniqueLongNameForTesting_D"), isTrue); - - expect(generated.contains("UniqueLongNameForTesting_B"), isTrue); - expect(generated.contains("UniqueLongNameForTesting_C"), isTrue); - expect(generated.contains("UniqueLongNameForTesting_E"), isTrue); - }); - - test('tree-shake when using flag', () async { - String generated = await compile(program, - trustJSInteropTypeAnnotations: true, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - expect(generated.contains("UniqueLongNameForTesting_D"), isTrue); - - expect(generated.contains("UniqueLongNameForTesting_B"), isFalse); - expect(generated.contains("UniqueLongNameForTesting_C"), isFalse); - expect(generated.contains("UniqueLongNameForTesting_E"), isFalse); - }); - }); - - group('tree-shaking other native types', () { - String program = """ - import 'dart:html'; - import 'package:js/js.dart'; - - @JS() @anonymous - class UniqueLongNameForTesting_A { - external dynamic get x; - } - - @JS() @anonymous - class UniqueLongNameForTesting_B { - external dynamic get y; - } - - main() { - print(new UniqueLongNameForTesting_A().x); - } - """; - - test('allocation effect of dynamic excludes native types', () async { - String generated = await compile(program, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - // any js-interop type could be allocated by `get x` - expect(generated.contains("UniqueLongNameForTesting_B"), isTrue); - // but we exclude other native types like HTMLAudioElement - expect(generated.contains("HTMLAudioElement"), isFalse); - }); - - test('allocation effect of dynamic excludes native types [flag]', () async { - // Trusting types doesn't make a difference. - String generated = await compile(program, - trustJSInteropTypeAnnotations: true, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - expect(generated.contains("UniqueLongNameForTesting_B"), isTrue); - expect(generated.contains("HTMLAudioElement"), isFalse); - }); - - test('declared native types are included in allocation effect', () async { - String program2 = """ - import 'dart:html'; - import 'package:js/js.dart'; - - @JS() @anonymous - class UniqueLongNameForTesting_A { - external AudioElement get x; - } - - main() { - print(new UniqueLongNameForTesting_A().x is AudioElement); - } - """; - - String generated = await compile(program2, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - expect(generated.contains("HTMLAudioElement"), isTrue); - - program2 = """ - import 'dart:html'; - import 'package:js/js.dart'; - - @JS() @anonymous - class UniqueLongNameForTesting_A { - external dynamic get x; - } - - main() { - print(new UniqueLongNameForTesting_A().x is AudioElement); - } - """; - - generated = await compile(program2, returnAll: true); - expect(generated.contains("UniqueLongNameForTesting_A"), isTrue); - // This extra check is to make sure that we don't include HTMLAudioElement - // just because of the is-check. It is optimized away in this case because - // we believe it was never instantiated. - expect(generated.contains("HTMLAudioElement"), isFalse); - }); - }); -}
diff --git a/tests/compiler/dart2js/interpolation_folding_test.dart b/tests/compiler/dart2js/interpolation_folding_test.dart deleted file mode 100644 index ad99195..0000000 --- a/tests/compiler/dart2js/interpolation_folding_test.dart +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -// Tests for -const String TEST_1 = r""" - foo() { - int a = 120; - String b = 'hello'; - return 'u${a}v${b}w'; - } -"""; - -const String TEST_2 = r""" - foo(a, b) { - return 'aaaaa${a}xxxxx' - "yyyyy${b}zzzzz"; - } -"""; - -const String TEST_3 = r""" - foo(a) { - var b = '$a#'; - return '${b}x${b}'; - } -"""; - -const String TEST_4 = r""" - foo(a) { - var b = []; - if (a) b.add(123); - return '${b.length}'; - } -"""; - -main() { - Future check(String test, String contained) { - return compile(test, entry: 'foo').then((String generated) { - Expect.isTrue(generated.contains(contained), contained); - }); - } - - asyncTest(() => Future.wait([ - // Full substitution. - check(TEST_1, r'"u120vhellow"'), - - // Adjacent string fragments get merged. - check(TEST_2, r'"xxxxxyyyyy"'), - - // 1. No merging of fragments that are multi-use. Prevents exponential code - // and keeps author's manual CSE. - // 2. Know string values require no stringification. - check(TEST_3, r'return b + "x" + b'), - - // Known int value can be formatted directly. - check(TEST_4, r'return "" + b.length'), - ])); -}
diff --git a/tests/compiler/dart2js/inverse_operator_test.dart b/tests/compiler/dart2js/inverse_operator_test.dart deleted file mode 100644 index 44c10de..0000000 --- a/tests/compiler/dart2js/inverse_operator_test.dart +++ /dev/null
@@ -1,22 +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. - -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String MAIN = r""" -int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1)); -main() { - var x = 1; - if (inscrutable(x) == 0) { - main(); - x = 2; - } - print(!(1 < x)); -}"""; - -main() { - // Make sure we don't introduce a new variable. - asyncTest(() => compileAndMatchFuzzy(MAIN, 'main', "1 >= x")); -}
diff --git a/tests/compiler/dart2js/is_inference2_test.dart b/tests/compiler/dart2js/is_inference2_test.dart deleted file mode 100644 index 9177a11..0000000 --- a/tests/compiler/dart2js/is_inference2_test.dart +++ /dev/null
@@ -1,24 +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. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_IF_BOOL_FIRST_INSTRUCTION = r""" -negate(x) { - if (x is bool) return !x; - return x; -} -"""; - -main() { - asyncTest(() => compile(TEST_IF_BOOL_FIRST_INSTRUCTION, entry: 'negate', - check: (String generated) { - Expect.isTrue(generated.contains("!")); // We want to see !x. - Expect.isFalse(generated.contains("!=")); // And not !== true. - Expect.isFalse(generated.contains("true")); - Expect.isFalse(generated.contains("false")); - })); -}
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart deleted file mode 100644 index e1952b7..0000000 --- a/tests/compiler/dart2js/issue13354_test.dart +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; -import 'type_mask_test_helper.dart'; - -const String TEST = """ -bar() => 42; -baz() => bar; - -class A { - foo() => 42; -} - -class B extends A { - foo() => super.foo; -} - -main() { - baz(); - new B().foo(); -} -"""; - -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; - - checkReturn(String name, type) { - MemberElement element = findElement(compiler, name); - Expect.equals( - type, - simplify( - typesInferrer.getReturnTypeOfMember(element), closedWorld), - name); - } - - checkReturnInClass(String className, String methodName, type) { - dynamic cls = findElement(compiler, className); - var element = cls.lookupLocalMember(methodName); - Expect.equals( - type, - simplify( - typesInferrer.getReturnTypeOfMember(element), closedWorld)); - } - - checkReturn('bar', commonMasks.uint31Type); - checkReturn('baz', commonMasks.functionType); - - checkReturnInClass('A', 'foo', commonMasks.uint31Type); - checkReturnInClass('B', 'foo', commonMasks.functionType); - })); -}
diff --git a/tests/compiler/dart2js/js/js_constant_test.dart b/tests/compiler/dart2js/js/js_constant_test.dart new file mode 100644 index 0000000..b9754d3 --- /dev/null +++ b/tests/compiler/dart2js/js/js_constant_test.dart
@@ -0,0 +1,52 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; +import '../memory_compiler.dart'; + +const String TEST_1 = r""" + import 'dart:_foreign_helper'; + main() { + JS('', '#.toString()', -5); + // absent: "5.toString" + // present: "(-5).toString" + } +"""; + +main() { + runTest({bool useKernel}) async { + check(String test) async { + // Pretend this is a dart2js_native test to allow use of 'native' keyword + // and import of private libraries. + String main = 'sdk/tests/compiler/dart2js_native/main.dart'; + Uri entryPoint = Uri.parse('memory:$main'); + var result = await runCompiler( + entryPoint: entryPoint, + memorySourceFiles: {main: test}, + options: useKernel ? [Flags.useKernel] : []); + Expect.isTrue(result.isSuccess); + var compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; + + MemberEntity element = elementEnvironment.mainFunction; + var backend = compiler.backend; + String generated = backend.getGeneratedCode(element); + checkerForAbsentPresent(test)(generated); + } + + await check(TEST_1); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTest(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTest(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/js/js_parser_statements_test.dart b/tests/compiler/dart2js/js/js_parser_statements_test.dart new file mode 100644 index 0000000..d5d1de7 --- /dev/null +++ b/tests/compiler/dart2js/js/js_parser_statements_test.dart
@@ -0,0 +1,476 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:compiler/src/js/js.dart' as jsAst; +import 'package:compiler/src/js/js.dart' show js; + +testStatement(String statement, arguments, String expect) { + jsAst.Node node = js.statement(statement, arguments); + String jsText = jsAst.prettyPrint(node, allowVariableMinification: false); + Expect.stringEquals(expect.trim(), jsText.trim()); +} + +testError(String statement, arguments, [String expect = ""]) { + bool doCheck(exception) { + String message = '$exception'; + Expect.isTrue(message.contains(expect), '"$message" contains "$expect"'); + return true; + } + + void action() { + js.statement(statement, arguments); + } + + Expect.throws(action, doCheck); +} + +// Function declaration and named function. +const NAMED_FUNCTION_1 = r''' +function foo/*function declaration*/() { + return function harry/*named function*/() { return #; } +}'''; + +const NAMED_FUNCTION_1_NAMED_HOLE = r''' +function foo/*function declaration*/() { + return function harry/*named function*/() { return #hole; } +}'''; + +const NAMED_FUNCTION_1_ONE = r''' +function foo() { + return function harry() { + return 1; + }; +}'''; + +const MISC_1 = r''' +function foo() { + /a/; + #; +}'''; + +const MISC_1_NAMED_HOLE = r''' +function foo() { + /a/; + #hole; +}'''; + +const MISC_1_1 = r''' +function foo() { + /a/; + 1; + 2; +}'''; + +void main() { + var eOne = js('1'); + var eTwo = js('2'); + var eTrue = js('true'); + var eVar = js('x'); + var block12 = js.statement('{ 1; 2; }'); + var stm = js.statement('foo();'); + var seq1 = js('1, 2, 3'); + + Expect.isTrue(eOne is jsAst.LiteralNumber); + Expect.isTrue(eTrue is jsAst.LiteralBool); + Expect.isTrue(block12 is jsAst.Block); + + // Interpolated Expressions are upgraded to ExpressionStatements. + testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'); + testStatement('{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'); + + // Interpolated sub-blocks are spliced. + testStatement( + '{ #; #; }', [block12, block12], '{\n 1;\n 2;\n 1;\n 2;\n}\n'); + testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, + '{\n 1;\n 2;\n 1;\n 2;\n}\n'); + + // If-condition. Dart booleans are evaluated, JS Expression booleans are + // substituted. + testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'); + testStatement('if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'); + testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'); + testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'); + testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'); + testStatement('if (#) #;', [false, block12], ';'); + testStatement('if (#) 3; else #;', [true, block12], '3;'); + testStatement('if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'); + testStatement( + 'if (#a) #b', {'a': eOne, 'b': block12}, 'if (1) {\n 1;\n 2;\n}'); + testStatement( + 'if (#a) #b;', {'a': eTrue, 'b': block12}, 'if (true) {\n 1;\n 2;\n}'); + testStatement( + 'if (#a) #b;', {'a': eVar, 'b': block12}, 'if (x) {\n 1;\n 2;\n}'); + testStatement( + 'if (#a) #b;', {'a': 'a', 'b': block12}, 'if (a) {\n 1;\n 2;\n}'); + testStatement('if (#a) #b;', {'a': true, 'b': block12}, '{\n 1;\n 2;\n}'); + testStatement('if (#a) #b;', {'a': false, 'b': block12}, ';'); + testStatement('if (#a) 3; else #b;', {'a': true, 'b': block12}, '3;'); + testStatement( + 'if (#a) 3; else #b;', {'a': false, 'b': block12}, '{\n 1;\n 2;\n}'); + + testStatement('while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'); + testStatement( + 'while (#) #;', [eTrue, block12], 'while (true) {\n 1;\n 2;\n}'); + testStatement('while (#) #;', [eVar, block12], 'while (x) {\n 1;\n 2;\n}'); + testStatement('while (#) #;', ['a', block12], 'while (a) {\n 1;\n 2;\n}'); + testStatement('while (#) #;', ['a', stm], 'while (a)\n foo();'); + + testStatement( + 'do { {print(1);} do while(true); while (false) } while ( true )', [], ''' +do { + print(1); + do + while (true) + ; + while (false); +} while (true); +'''); + testStatement( + 'do #; while ( # )', [block12, eOne], 'do {\n 1;\n 2;\n} while (1); '); + testStatement('do #; while ( # )', [block12, eTrue], + 'do {\n 1;\n 2;\n} while (true); '); + testStatement( + 'do #; while ( # );', [block12, eVar], 'do {\n 1;\n 2;\n} while (x);'); + testStatement( + 'do { # } while ( # )', [block12, 'a'], 'do {\n 1;\n 2;\n} while (a);'); + testStatement('do #; while ( # )', [stm, 'a'], 'do\n foo();\nwhile (a);'); + + testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'); + testStatement(''' + switch (#) { + case #: { # } + }''', [eTrue, eOne, block12], + 'switch (true) {\n case 1:\n 1;\n 2;\n}'); + testStatement(''' + switch (#) { + case #: { # } + break; + case #: { # } + default: { # } + }''', [eTrue, eOne, block12, eTwo, block12, stm], ''' +switch (true) { + case 1: + 1; + 2; + break; + case 2: + 1; + 2; + default: + foo(); +}'''); + + testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE); + testStatement( + NAMED_FUNCTION_1_NAMED_HOLE, {'hole': eOne}, NAMED_FUNCTION_1_ONE); + + testStatement(MISC_1, [block12], MISC_1_1); + testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1); + + // Argument list splicing. + testStatement('foo(#)', [[]], 'foo();'); + testStatement( + 'foo(#)', + [ + [eOne] + ], + 'foo(1);'); + testStatement('foo(#)', [eOne], 'foo(1);'); + testStatement( + 'foo(#)', + [ + [eTrue, eOne] + ], + 'foo(true, 1);'); + testStatement('foo(#a)', {'a': []}, 'foo();'); + testStatement( + 'foo(#a)', + { + 'a': [eOne] + }, + 'foo(1);'); + testStatement('foo(#a)', {'a': eOne}, 'foo(1);'); + testStatement( + 'foo(#a)', + { + 'a': [eTrue, eOne] + }, + 'foo(true, 1);'); + + testStatement('foo(2,#)', [[]], 'foo(2);'); + testStatement( + 'foo(2,#)', + [ + [eOne] + ], + 'foo(2, 1);'); + testStatement('foo(2,#)', [eOne], 'foo(2, 1);'); + testStatement( + 'foo(2,#)', + [ + [eTrue, eOne] + ], + 'foo(2, true, 1);'); + testStatement('foo(2,#a)', {'a': []}, 'foo(2);'); + testStatement( + 'foo(2,#a)', + { + 'a': [eOne] + }, + 'foo(2, 1);'); + testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'); + testStatement( + 'foo(2,#a)', + { + 'a': [eTrue, eOne] + }, + 'foo(2, true, 1);'); + + testStatement('foo(#,3)', [[]], 'foo(3);'); + testStatement( + 'foo(#,3)', + [ + [eOne] + ], + 'foo(1, 3);'); + testStatement('foo(#,3)', [eOne], 'foo(1, 3);'); + testStatement( + 'foo(#,3)', + [ + [eTrue, eOne] + ], + 'foo(true, 1, 3);'); + testStatement('foo(#a,3)', {'a': []}, 'foo(3);'); + testStatement( + 'foo(#a,3)', + { + 'a': [eOne] + }, + 'foo(1, 3);'); + testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'); + testStatement( + 'foo(#a,3)', + { + 'a': [eTrue, eOne] + }, + 'foo(true, 1, 3);'); + + testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'); + testStatement( + 'foo(2,#,3)', + [ + [eOne] + ], + 'foo(2, 1, 3);'); + testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'); + testStatement( + 'foo(2,#,3)', + [ + [eTrue, eOne] + ], + 'foo(2, true, 1, 3);'); + testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'); + testStatement( + 'foo(2,#a,3)', + { + 'a': [eOne] + }, + 'foo(2, 1, 3);'); + testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'); + testStatement( + 'foo(2,#a,3)', + { + 'a': [eTrue, eOne] + }, + 'foo(2, true, 1, 3);'); + + // Interpolated Literals + testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'); + testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'); + // Maybe we should make this work? + testError('a = {#: 1}', [1], 'is not a Literal: 1'); + testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'); + + // Interpolated parameter splicing. + testStatement( + 'function foo(#){}', [new jsAst.Parameter('x')], 'function foo(x) {\n}'); + testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'); + testStatement('function foo(#){}', [[]], 'function foo() {\n}'); + testStatement( + 'function foo(#){}', + [ + ['x'] + ], + 'function foo(x) {\n}'); + testStatement( + 'function foo(#){}', + [ + ['x', 'y'] + ], + 'function foo(x, y) {\n}'); + testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, + 'function foo(x) {\n}'); + testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'); + testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'); + testStatement( + 'function foo(#a){}', + { + 'a': ['x'] + }, + 'function foo(x) {\n}'); + testStatement( + 'function foo(#a){}', + { + 'a': ['x', 'y'] + }, + 'function foo(x, y) {\n}'); + + testStatement('function foo() async {}', [], 'function foo() async {\n}'); + testStatement('function foo() sync* {}', [], 'function foo() sync* {\n}'); + testStatement('function foo() async* {}', [], 'function foo() async* {\n}'); + + testStatement('a = #.#', [eVar, eOne], 'a = x[1];'); + testStatement('a = #.#', [eVar, 'foo'], 'a = x.foo;'); + testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'); + testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'); + + testStatement('function f(#) { return #.#; }', ['x', eVar, 'foo'], + 'function f(x) {\n return x.foo;\n}'); + testStatement('function f(#a) { return #b.#c; }', + {'a': 'x', 'b': eVar, 'c': 'foo'}, 'function f(x) {\n return x.foo;\n}'); + + testStatement( + '#.prototype.# = function(#) { return #.# };', + [ + 'className', + 'getterName', + ['r', 'y'], + 'r', + 'fieldName' + ], + 'className.prototype.getterName = function(r, y) {\n' + ' return r.fieldName;\n' + '};'); + testStatement( + '#a.prototype.#b = function(#c) { return #d.#e };', + { + 'a': 'className', + 'b': 'getterName', + 'c': ['r', 'y'], + 'd': 'r', + 'e': 'fieldName' + }, + 'className.prototype.getterName = function(r, y) {\n' + ' return r.fieldName;\n' + '};'); + + testStatement( + 'function foo(r, #) { return #[r](#) }', + [ + ['a', 'b'], + 'g', + ['b', 'a'] + ], + 'function foo(r, a, b) {\n return g[r](b, a);\n}'); + testStatement( + 'function foo(r, #a) { return #b[r](#c) }', + { + 'a': ['a', 'b'], + 'b': 'g', + 'c': ['b', 'a'] + }, + 'function foo(r, a, b) {\n return g[r](b, a);\n}'); + + // Sequence is printed flattened + testStatement('x = #', [seq1], 'x = (1, 2, 3);'); + testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'); + testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'); + testStatement('for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], + 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'); + testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'); + testStatement( + 'x = (#a, #b)', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3, 1, 2, 3);'); + testStatement( + 'x = #a, #b', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3), 1, 2, 3;'); + testStatement('for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', {'a': seq1}, + 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'); + + // Use the same name several times. + testStatement( + '#a.prototype.#a = function(#b) { return #c.#c };', + { + 'a': 'name1_2', + 'b': ['r', 'y'], + 'c': 'name4_5' + }, + 'name1_2.prototype.name1_2 = function(r, y) {\n' + ' return name4_5.name4_5;\n' + '};'); + + testStatement('label: while (a) { label2: break label;}', [], + 'label:\n while (a)\n label2:\n break label;\n '); + + testStatement('var # = 3', ['x'], 'var x = 3;'); + testStatement( + 'var # = 3', [new jsAst.VariableDeclaration('x')], 'var x = 3;'); + testStatement( + 'var # = 3, # = #', ['x', 'y', js.number(2)], 'var x = 3, y = 2;'); + testStatement('var #a = 3, #b = #c', {"a": 'x', "b": 'y', "c": js.number(2)}, + 'var x = 3, y = 2;'); + testStatement('function #() {}', ['x'], 'function x() {\n}'); + testStatement('function #() {}', [new jsAst.VariableDeclaration('x')], + 'function x() {\n}'); + testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'); + testStatement('try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}'); + testStatement('try {} catch (#a) {}', + {"a": new jsAst.VariableDeclaration('x')}, 'try {\n} catch (x) {\n}'); + + // Test that braces around a single-statement block are removed by printer. + testStatement('while (a) {foo()}', [], 'while (a)\n foo();'); + testStatement('if (a) {foo();}', [], 'if (a)\n foo();'); + testStatement('if (a) {foo();} else {foo2();}', [], + 'if (a)\n foo();\nelse\n foo2();'); + testStatement( + 'if (a) foo(); else {foo2();}', [], 'if (a)\n foo();\nelse\n foo2();'); + testStatement('do {foo();} while(a);', [], 'do\n foo();\nwhile (a);'); + testStatement('label: {foo();}', [], 'label:\n foo();'); + testStatement( + 'for (var key in a) {foo();}', [], 'for (var key in a)\n foo();'); + // `label: break label;` gives problems on IE. Test that it is avoided. + testStatement('label: {break label;}', [], ';'); + // This works on IE: + testStatement('label: {label2: {break label;}}', [], + 'label:\n label2:\n break label;\n'); + // Test dangling else: + testStatement('if (a) {if (b) {foo1();}} else {foo2();}', [], """ +if (a) { + if (b) + foo1(); +} else + foo2();"""); + testStatement('if (a) {if (b) {foo1();} else {foo2();}}', [], """ +if (a) + if (b) + foo1(); + else + foo2(); +"""); + testStatement( + 'if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', [], """ +if (a) + if (b) + foo1(); + else + foo2(); +else + foo3();"""); + testStatement('if (a) {while (true) if (b) {foo1();}} else {foo2();}', [], """ +if (a) { + while (true) + if (b) + foo1(); +} else + foo2();"""); +}
diff --git a/tests/compiler/dart2js/js/js_parser_test.dart b/tests/compiler/dart2js/js/js_parser_test.dart new file mode 100644 index 0000000..7d76533 --- /dev/null +++ b/tests/compiler/dart2js/js/js_parser_test.dart
@@ -0,0 +1,191 @@ +// 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:compiler/src/js/js.dart' as jsAst; +import 'package:compiler/src/js/js.dart' show js; + +testExpression(String expression, [String expect = ""]) { + jsAst.Node node = js(expression); + String jsText = jsAst.prettyPrint(node, allowVariableMinification: false); + if (expect == "") { + Expect.stringEquals(expression, jsText); + } else { + Expect.stringEquals(expect, jsText); + } +} + +testError(String expression, [String expect = ""]) { + bool doCheck(exception) { + Expect.isTrue(exception.toString().contains(expect)); + return true; + } + + Expect.throws(() => js(expression), doCheck); +} + +void main() { + // Asterisk indicates deviations from real JS. + // Simple var test. + testExpression('var a = ""'); + // Parse and print will normalize whitespace. + testExpression(' var a = "" ', 'var a = ""'); + // Operator precedence. + testExpression('x = a + b * c'); + testExpression('x = a * b + c'); + testExpression('x = a + b * c + d'); + testExpression('x = a * b + c * d'); + testExpression( + 'remaining = (remaining / 88) | 0', 'remaining = remaining / 88 | 0'); + // Binary operators have left associativity. + testExpression('x = a + b + c'); + // We can cope with relational operators and non-relational. + testExpression('a + b == c + d'); + // The prettyprinter will insert braces where needed. + testExpression('a + (b == c) + d'); + // We can handle () for calls. + testExpression('foo(bar)'); + testExpression('foo(bar, baz)'); + // Chained calls without parentheses. + testExpression('foo(bar)(baz)'); + // Chained calls with and without new. + testExpression('new foo(bar)(baz)'); + testExpression('new foo.bar(bar)(baz)'); + testExpression('foo.bar(bar)(baz)'); + testExpression('constructor = new Function(str)()'); + // The prettyprinter understands chained calls without extra parentheses. + testExpression('(foo(bar))(baz)', 'foo(bar)(baz)'); + // Chains of dotting and calls. + testExpression('foo.bar(baz)'); + // String literal. + testExpression('var x = "fisk"'); + // String literal with \n. + testExpression(r'var x = "\n"'); + // String literal with escaped quote. + testExpression(r'var x = "\""'); + // *No clever escapes. + testError(r'var x = "\x42"', 'escapes are not allowed in literals'); + // Operator new. + testExpression('new Foo()'); + // New with dotted access. + testExpression('new Frobinator.frobinate()'); + testExpression('new Frobinator().frobinate()'); + // The prettyprinter strips some superfluous parentheses. + testExpression( + '(new Frobinator()).frobinate()', 'new Frobinator().frobinate()'); + // *We want a bracket on 'new'. + testError('new Foo', 'Parentheses are required'); + testError('(new Foo)', 'Parentheses are required'); + // Bogus operators. + testError('a +++ b', 'Unknown operator'); + // This isn't perl. There are rules. + testError('a <=> b', 'Unknown operator'); + // Typeof. + testExpression('typeof foo == "number"'); + // Strange relation. + testExpression('a < b < c'); + // Chained var. + testExpression('var x = 0, y = 1.2, z = 42'); + // Empty object literal. + testExpression('foo({}, {})'); + // *Can't handle non-empty object literals + testExpression('foo({meaning: 42})'); + // Literals. + testExpression('x(false, true, null)'); + // *We should really throw here. + testExpression('var false = 42'); + testExpression('var new = 42'); + // Bad keyword. + testError('var typeof = 42', "Expected ALPHA"); + // Malformed decimal/hex. + testError('var x = 1.1.1', "Unparseable number"); + testError('var x = 0xabcdefga', "Unparseable number"); + testError('var x = 0xabcdef\$a', "Unparseable number"); + testError('var x = 0x ', "Unparseable number"); + // Good hex constants. + testExpression('var x = 0xff'); + testExpression('var x = 0xff + 0xff'); + testExpression('var x = 0xaF + 0x0123456789abcdefABCDEF'); + // All sorts of keywords are allowed as property names in ES5. + testExpression('x.new = 0'); + testExpression('x.delete = 0'); + testExpression('x.for = 0'); + testExpression('x.instanceof = 0'); + testExpression('x.in = 0'); + testExpression('x.void = 0'); + testExpression('x.continue = 0'); + // More unary. + testExpression('x = !x'); + testExpression('!x == false'); + testExpression('var foo = void 0'); + testExpression('delete foo.bar'); + testExpression('delete foo'); + testExpression('x in y'); + testExpression('x instanceof y'); + testExpression('a * b in c * d'); + testExpression('a * b instanceof c * d'); + testError('x typeof y', 'Unparsed junk'); + testExpression('x &= ~mask'); + // Await is parsed as an unary prefix operator. + testExpression('var foo = await 0'); + testExpression('await x++'); + testExpression('void (await (x++))', 'void await x++'); + testExpression('void (await x)++'); + testExpression('++(await x)++'); + // Adjacent tokens. + testExpression('foo[x[bar]]'); + testExpression('foo[[bar]]'); + // Prefix ++ etc. + testExpression("++x"); + testExpression("++foo.bar"); + testExpression("+x"); + testExpression("+foo.bar"); + testExpression("-x"); + testExpression("-foo.bar"); + testExpression("--x"); + testExpression("--foo.bar"); + // Postfix ++ etc. + testExpression("x++"); + testExpression("foo.bar++"); + testExpression("x--"); + testExpression("foo.bar--"); + // Both! + testExpression("++x++"); + testExpression("++foo.bar++"); + testExpression("--x--"); + testExpression("--foo.bar--"); + // *We can't handle stacked unary operators (apart from !). + testError("x++ ++"); + testError("++ typeof x"); + testExpression(r"var $supportsProtoName = !!{}.__proto__"); + // ++ used as a binary operator. + testError("x++ ++ 42"); + // Shift operators. + testExpression("x << 5"); + testExpression("x << y + 1"); + testExpression("x <<= y + 1"); + // Array initializers. + testExpression("x = ['foo', 'bar', x[4]]"); + testExpression("[]"); + testError("[42 42]"); + testExpression('beebop([1, 2, 3])'); + // Array literals with holes in them. + testExpression("[1,, 2]"); + testExpression("[1,]", "[1]"); + testExpression("[1,,]", "[1,,]"); + testExpression("[,]"); + testExpression("[,,]"); + testExpression("[, 42]"); + // Ternary operator. + testExpression("x = a ? b : c"); + testExpression("y = a == null ? b : a"); + testExpression("y = a == null ? b + c : a + c"); + testExpression("foo = a ? b : c ? d : e"); + testExpression("foo = a ? b ? c : d : e"); + testExpression("foo = (a = v) ? b = w : c = x ? d = y : e = z"); + testExpression("foo = (a = v) ? b = w ? c = x : d = y : e = z"); + // Stacked assignment. + testExpression("a = b = c"); + testExpression("var a = b = c"); +}
diff --git a/tests/compiler/dart2js/js_safety_test.dart b/tests/compiler/dart2js/js/js_safety_test.dart similarity index 100% rename from tests/compiler/dart2js/js_safety_test.dart rename to tests/compiler/dart2js/js/js_safety_test.dart
diff --git a/tests/compiler/dart2js/js_spec_optimization_test.dart b/tests/compiler/dart2js/js/js_spec_optimization_test.dart similarity index 67% rename from tests/compiler/dart2js/js_spec_optimization_test.dart rename to tests/compiler/dart2js/js/js_spec_optimization_test.dart index 439299a..9cd6a88 100644 --- a/tests/compiler/dart2js/js_spec_optimization_test.dart +++ b/tests/compiler/dart2js/js/js_spec_optimization_test.dart
@@ -2,9 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:async'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/elements/entities.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; +import '../memory_compiler.dart'; const String TEST_1 = r""" import 'dart:_foreign_helper'; @@ -84,23 +87,37 @@ """; main() { - Future check(String test) { - var checker = checkerForAbsentPresent(test); - Uri uri = new Uri(scheme: 'dart', path: 'test'); - var compiler = compilerFor(test, uri, expectedErrors: 0); - return compiler.run(uri).then((_) { - MemberElement element = findElement(compiler, 'main'); + runTests({bool useKernel}) async { + check(String test) async { + var checker = checkerForAbsentPresent(test); + String main = 'sdk/tests/compiler/dart2js_native/main.dart'; + Uri entryPoint = Uri.parse('memory:$main'); + var result = await runCompiler( + entryPoint: entryPoint, + memorySourceFiles: {main: test}, + options: useKernel ? [Flags.useKernel] : []); + Expect.isTrue(result.isSuccess); + var compiler = result.compiler; + var closedWorld = compiler.backendClosedWorldForTesting; + var elementEnvironment = closedWorld.elementEnvironment; + + MemberEntity element = elementEnvironment.mainFunction; var backend = compiler.backend; String generated = backend.getGeneratedCode(element); checker(generated); - }); + } + + await check(TEST_1); + await check(TEST_2); + await check(TEST_3); + await check(TEST_4); + await check(TEST_5); } - asyncTest(() => Future.wait([ - check(TEST_1), - check(TEST_2), - check(TEST_3), - check(TEST_4), - check(TEST_5), - ])); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js/js_spec_string_test.dart b/tests/compiler/dart2js/js/js_spec_string_test.dart similarity index 100% rename from tests/compiler/dart2js/js_spec_string_test.dart rename to tests/compiler/dart2js/js/js_spec_string_test.dart
diff --git a/tests/compiler/dart2js/js_throw_behavior_test.dart b/tests/compiler/dart2js/js/js_throw_behavior_test.dart similarity index 100% rename from tests/compiler/dart2js/js_throw_behavior_test.dart rename to tests/compiler/dart2js/js/js_throw_behavior_test.dart
diff --git a/tests/compiler/dart2js/js_constant_test.dart b/tests/compiler/dart2js/js_constant_test.dart deleted file mode 100644 index 0438606..0000000 --- a/tests/compiler/dart2js/js_constant_test.dart +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_1 = r""" - import 'dart:_foreign_helper'; - main() { - JS('', '#.toString()', -5); - // absent: "5.toString" - // present: "(-5).toString" - } -"""; - -main() { - Future check(String test) { - Uri uri = new Uri(scheme: 'dart', path: 'test'); - var compiler = compilerFor(test, uri, expectedErrors: 0); - return compiler.run(uri).then((_) { - MemberElement element = findElement(compiler, 'main'); - var backend = compiler.backend; - String generated = backend.getGeneratedCode(element); - checkerForAbsentPresent(test)(generated); - }); - } - - asyncTest(() => Future.wait([ - check(TEST_1), - ])); -}
diff --git a/tests/compiler/dart2js/js_parser_statements_test.dart b/tests/compiler/dart2js/js_parser_statements_test.dart deleted file mode 100644 index 775e2e2..0000000 --- a/tests/compiler/dart2js/js_parser_statements_test.dart +++ /dev/null
@@ -1,508 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'mock_compiler.dart'; -import 'package:compiler/src/js/js.dart' as jsAst; -import 'package:compiler/src/js/js.dart' show js; - -Future testStatement(String statement, arguments, String expect) { - jsAst.Node node = js.statement(statement, arguments); - return MockCompiler.create((MockCompiler compiler) { - String jsText = jsAst.prettyPrint(node, compiler.options, - allowVariableMinification: false); - - Expect.stringEquals(expect.trim(), jsText.trim()); - }); -} - -Future testError(String statement, arguments, [String expect = ""]) { - return new Future.sync(() { - bool doCheck(exception) { - String message = '$exception'; - Expect.isTrue(message.contains(expect), '"$message" contains "$expect"'); - return true; - } - - void action() { - js.statement(statement, arguments); - } - - Expect.throws(action, doCheck); - }); -} - -// Function declaration and named function. -const NAMED_FUNCTION_1 = r''' -function foo/*function declaration*/() { - return function harry/*named function*/() { return #; } -}'''; - -const NAMED_FUNCTION_1_NAMED_HOLE = r''' -function foo/*function declaration*/() { - return function harry/*named function*/() { return #hole; } -}'''; - -const NAMED_FUNCTION_1_ONE = r''' -function foo() { - return function harry() { - return 1; - }; -}'''; - -const MISC_1 = r''' -function foo() { - /a/; - #; -}'''; - -const MISC_1_NAMED_HOLE = r''' -function foo() { - /a/; - #hole; -}'''; - -const MISC_1_1 = r''' -function foo() { - /a/; - 1; - 2; -}'''; - -void main() { - var eOne = js('1'); - var eTwo = js('2'); - var eTrue = js('true'); - var eVar = js('x'); - var block12 = js.statement('{ 1; 2; }'); - var stm = js.statement('foo();'); - var seq1 = js('1, 2, 3'); - - Expect.isTrue(eOne is jsAst.LiteralNumber); - Expect.isTrue(eTrue is jsAst.LiteralBool); - Expect.isTrue(block12 is jsAst.Block); - - asyncTest(() => Future.wait([ - // Interpolated Expressions are upgraded to ExpressionStatements. - testStatement('{ #; #; }', [eOne, eOne], '{\n 1;\n 1;\n}'), - testStatement( - '{ #a; #b; }', {'a': eOne, 'b': eOne}, '{\n 1;\n 1;\n}'), - - // Interpolated sub-blocks are spliced. - testStatement( - '{ #; #; }', [block12, block12], '{\n 1;\n 2;\n 1;\n 2;\n}\n'), - testStatement('{ #a; #b; }', {'a': block12, 'b': block12}, - '{\n 1;\n 2;\n 1;\n 2;\n}\n'), - - // If-condition. Dart booleans are evaluated, JS Expression booleans are - // substituted. - testStatement('if (#) #', [eOne, block12], 'if (1) {\n 1;\n 2;\n}'), - testStatement( - 'if (#) #;', [eTrue, block12], 'if (true) {\n 1;\n 2;\n}'), - testStatement('if (#) #;', [eVar, block12], 'if (x) {\n 1;\n 2;\n}'), - testStatement('if (#) #;', ['a', block12], 'if (a) {\n 1;\n 2;\n}'), - testStatement('if (#) #;', [true, block12], '{\n 1;\n 2;\n}'), - testStatement('if (#) #;', [false, block12], ';'), - testStatement('if (#) 3; else #;', [true, block12], '3;'), - testStatement( - 'if (#) 3; else #;', [false, block12], '{\n 1;\n 2;\n}'), - testStatement( - 'if (#a) #b', {'a': eOne, 'b': block12}, 'if (1) {\n 1;\n 2;\n}'), - testStatement('if (#a) #b;', {'a': eTrue, 'b': block12}, - 'if (true) {\n 1;\n 2;\n}'), - testStatement('if (#a) #b;', {'a': eVar, 'b': block12}, - 'if (x) {\n 1;\n 2;\n}'), - testStatement( - 'if (#a) #b;', {'a': 'a', 'b': block12}, 'if (a) {\n 1;\n 2;\n}'), - testStatement( - 'if (#a) #b;', {'a': true, 'b': block12}, '{\n 1;\n 2;\n}'), - testStatement('if (#a) #b;', {'a': false, 'b': block12}, ';'), - testStatement('if (#a) 3; else #b;', {'a': true, 'b': block12}, '3;'), - testStatement('if (#a) 3; else #b;', {'a': false, 'b': block12}, - '{\n 1;\n 2;\n}'), - - testStatement( - 'while (#) #', [eOne, block12], 'while (1) {\n 1;\n 2;\n}'), - testStatement( - 'while (#) #;', [eTrue, block12], 'while (true) {\n 1;\n 2;\n}'), - testStatement( - 'while (#) #;', [eVar, block12], 'while (x) {\n 1;\n 2;\n}'), - testStatement( - 'while (#) #;', ['a', block12], 'while (a) {\n 1;\n 2;\n}'), - testStatement('while (#) #;', ['a', stm], 'while (a)\n foo();'), - - testStatement( - 'do { {print(1);} do while(true); while (false) } while ( true )', - [], - ''' -do { - print(1); - do - while (true) - ; - while (false); -} while (true); -'''), - testStatement('do #; while ( # )', [block12, eOne], - 'do {\n 1;\n 2;\n} while (1); '), - testStatement('do #; while ( # )', [block12, eTrue], - 'do {\n 1;\n 2;\n} while (true); '), - testStatement('do #; while ( # );', [block12, eVar], - 'do {\n 1;\n 2;\n} while (x);'), - testStatement('do { # } while ( # )', [block12, 'a'], - 'do {\n 1;\n 2;\n} while (a);'), - testStatement( - 'do #; while ( # )', [stm, 'a'], 'do\n foo();\nwhile (a);'), - - testStatement('switch (#) {}', [eOne], 'switch (1) {\n}'), - testStatement(''' - switch (#) { - case #: { # } - }''', [eTrue, eOne, block12], - 'switch (true) {\n case 1:\n 1;\n 2;\n}'), - testStatement(''' - switch (#) { - case #: { # } - break; - case #: { # } - default: { # } - }''', [eTrue, eOne, block12, eTwo, block12, stm], ''' -switch (true) { - case 1: - 1; - 2; - break; - case 2: - 1; - 2; - default: - foo(); -}'''), - - testStatement(NAMED_FUNCTION_1, [eOne], NAMED_FUNCTION_1_ONE), - testStatement( - NAMED_FUNCTION_1_NAMED_HOLE, {'hole': eOne}, NAMED_FUNCTION_1_ONE), - - testStatement(MISC_1, [block12], MISC_1_1), - testStatement(MISC_1_NAMED_HOLE, {'hole': block12}, MISC_1_1), - - // Argument list splicing. - testStatement('foo(#)', [[]], 'foo();'), - testStatement( - 'foo(#)', - [ - [eOne] - ], - 'foo(1);'), - testStatement('foo(#)', [eOne], 'foo(1);'), - testStatement( - 'foo(#)', - [ - [eTrue, eOne] - ], - 'foo(true, 1);'), - testStatement('foo(#a)', {'a': []}, 'foo();'), - testStatement( - 'foo(#a)', - { - 'a': [eOne] - }, - 'foo(1);'), - testStatement('foo(#a)', {'a': eOne}, 'foo(1);'), - testStatement( - 'foo(#a)', - { - 'a': [eTrue, eOne] - }, - 'foo(true, 1);'), - - testStatement('foo(2,#)', [[]], 'foo(2);'), - testStatement( - 'foo(2,#)', - [ - [eOne] - ], - 'foo(2, 1);'), - testStatement('foo(2,#)', [eOne], 'foo(2, 1);'), - testStatement( - 'foo(2,#)', - [ - [eTrue, eOne] - ], - 'foo(2, true, 1);'), - testStatement('foo(2,#a)', {'a': []}, 'foo(2);'), - testStatement( - 'foo(2,#a)', - { - 'a': [eOne] - }, - 'foo(2, 1);'), - testStatement('foo(2,#a)', {'a': eOne}, 'foo(2, 1);'), - testStatement( - 'foo(2,#a)', - { - 'a': [eTrue, eOne] - }, - 'foo(2, true, 1);'), - - testStatement('foo(#,3)', [[]], 'foo(3);'), - testStatement( - 'foo(#,3)', - [ - [eOne] - ], - 'foo(1, 3);'), - testStatement('foo(#,3)', [eOne], 'foo(1, 3);'), - testStatement( - 'foo(#,3)', - [ - [eTrue, eOne] - ], - 'foo(true, 1, 3);'), - testStatement('foo(#a,3)', {'a': []}, 'foo(3);'), - testStatement( - 'foo(#a,3)', - { - 'a': [eOne] - }, - 'foo(1, 3);'), - testStatement('foo(#a,3)', {'a': eOne}, 'foo(1, 3);'), - testStatement( - 'foo(#a,3)', - { - 'a': [eTrue, eOne] - }, - 'foo(true, 1, 3);'), - - testStatement('foo(2,#,3)', [[]], 'foo(2, 3);'), - testStatement( - 'foo(2,#,3)', - [ - [eOne] - ], - 'foo(2, 1, 3);'), - testStatement('foo(2,#,3)', [eOne], 'foo(2, 1, 3);'), - testStatement( - 'foo(2,#,3)', - [ - [eTrue, eOne] - ], - 'foo(2, true, 1, 3);'), - testStatement('foo(2,#a,3)', {'a': []}, 'foo(2, 3);'), - testStatement( - 'foo(2,#a,3)', - { - 'a': [eOne] - }, - 'foo(2, 1, 3);'), - testStatement('foo(2,#a,3)', {'a': eOne}, 'foo(2, 1, 3);'), - testStatement( - 'foo(2,#a,3)', - { - 'a': [eTrue, eOne] - }, - 'foo(2, true, 1, 3);'), - - // Interpolated Literals - testStatement('a = {#: 1}', [eOne], 'a = {1: 1};'), - testStatement('a = {#a: 1}', {'a': eOne}, 'a = {1: 1};'), - // Maybe we should make this work? - testError('a = {#: 1}', [1], 'is not a Literal: 1'), - testError('a = {#a: 1}', {'a': 1}, 'is not a Literal: 1'), - - // Interpolated parameter splicing. - testStatement('function foo(#){}', [new jsAst.Parameter('x')], - 'function foo(x) {\n}'), - testStatement('function foo(#){}', ['x'], 'function foo(x) {\n}'), - testStatement('function foo(#){}', [[]], 'function foo() {\n}'), - testStatement( - 'function foo(#){}', - [ - ['x'] - ], - 'function foo(x) {\n}'), - testStatement( - 'function foo(#){}', - [ - ['x', 'y'] - ], - 'function foo(x, y) {\n}'), - testStatement('function foo(#a){}', {'a': new jsAst.Parameter('x')}, - 'function foo(x) {\n}'), - testStatement('function foo(#a){}', {'a': 'x'}, 'function foo(x) {\n}'), - testStatement('function foo(#a){}', {'a': []}, 'function foo() {\n}'), - testStatement( - 'function foo(#a){}', - { - 'a': ['x'] - }, - 'function foo(x) {\n}'), - testStatement( - 'function foo(#a){}', - { - 'a': ['x', 'y'] - }, - 'function foo(x, y) {\n}'), - - testStatement( - 'function foo() async {}', [], 'function foo() async {\n}'), - testStatement( - 'function foo() sync* {}', [], 'function foo() sync* {\n}'), - testStatement( - 'function foo() async* {}', [], 'function foo() async* {\n}'), - - testStatement('a = #.#', [eVar, eOne], 'a = x[1];'), - testStatement('a = #.#', [eVar, 'foo'], 'a = x.foo;'), - testStatement('a = #a.#b', {'a': eVar, 'b': eOne}, 'a = x[1];'), - testStatement('a = #a.#b', {'a': eVar, 'b': 'foo'}, 'a = x.foo;'), - - testStatement('function f(#) { return #.#; }', ['x', eVar, 'foo'], - 'function f(x) {\n return x.foo;\n}'), - testStatement( - 'function f(#a) { return #b.#c; }', - {'a': 'x', 'b': eVar, 'c': 'foo'}, - 'function f(x) {\n return x.foo;\n}'), - - testStatement( - '#.prototype.# = function(#) { return #.# };', - [ - 'className', - 'getterName', - ['r', 'y'], - 'r', - 'fieldName' - ], - 'className.prototype.getterName = function(r, y) {\n' - ' return r.fieldName;\n' - '};'), - testStatement( - '#a.prototype.#b = function(#c) { return #d.#e };', - { - 'a': 'className', - 'b': 'getterName', - 'c': ['r', 'y'], - 'd': 'r', - 'e': 'fieldName' - }, - 'className.prototype.getterName = function(r, y) {\n' - ' return r.fieldName;\n' - '};'), - - testStatement( - 'function foo(r, #) { return #[r](#) }', - [ - ['a', 'b'], - 'g', - ['b', 'a'] - ], - 'function foo(r, a, b) {\n return g[r](b, a);\n}'), - testStatement( - 'function foo(r, #a) { return #b[r](#c) }', - { - 'a': ['a', 'b'], - 'b': 'g', - 'c': ['b', 'a'] - }, - 'function foo(r, a, b) {\n return g[r](b, a);\n}'), - - // Sequence is printed flattened - testStatement('x = #', [seq1], 'x = (1, 2, 3);'), - testStatement('x = (#, #)', [seq1, seq1], 'x = (1, 2, 3, 1, 2, 3);'), - testStatement('x = #, #', [seq1, seq1], 'x = (1, 2, 3), 1, 2, 3;'), - testStatement('for (i = 0, j = #, k = 0; ; ++i, ++j, ++k){}', [seq1], - 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), - testStatement('x = #a', {'a': seq1}, 'x = (1, 2, 3);'), - testStatement( - 'x = (#a, #b)', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3, 1, 2, 3);'), - testStatement( - 'x = #a, #b', {'a': seq1, 'b': seq1}, 'x = (1, 2, 3), 1, 2, 3;'), - testStatement( - 'for (i = 0, j = #a, k = 0; ; ++i, ++j, ++k){}', - {'a': seq1}, - 'for (i = 0, j = (1, 2, 3), k = 0;; ++i, ++j, ++k) {\n}'), - - // Use the same name several times. - testStatement( - '#a.prototype.#a = function(#b) { return #c.#c };', - { - 'a': 'name1_2', - 'b': ['r', 'y'], - 'c': 'name4_5' - }, - 'name1_2.prototype.name1_2 = function(r, y) {\n' - ' return name4_5.name4_5;\n' - '};'), - - testStatement('label: while (a) { label2: break label;}', [], - 'label:\n while (a)\n label2:\n break label;\n '), - - testStatement('var # = 3', ['x'], 'var x = 3;'), - testStatement( - 'var # = 3', [new jsAst.VariableDeclaration('x')], 'var x = 3;'), - testStatement( - 'var # = 3, # = #', ['x', 'y', js.number(2)], 'var x = 3, y = 2;'), - testStatement('var #a = 3, #b = #c', - {"a": 'x', "b": 'y', "c": js.number(2)}, 'var x = 3, y = 2;'), - testStatement('function #() {}', ['x'], 'function x() {\n}'), - testStatement('function #() {}', [new jsAst.VariableDeclaration('x')], - 'function x() {\n}'), - testStatement('try {} catch (#) {}', ['x'], 'try {\n} catch (x) {\n}'), - testStatement( - 'try {} catch (#a) {}', {"a": 'x'}, 'try {\n} catch (x) {\n}'), - testStatement( - 'try {} catch (#a) {}', - {"a": new jsAst.VariableDeclaration('x')}, - 'try {\n} catch (x) {\n}'), - - // Test that braces around a single-statement block are removed by printer. - testStatement('while (a) {foo()}', [], 'while (a)\n foo();'), - testStatement('if (a) {foo();}', [], 'if (a)\n foo();'), - testStatement('if (a) {foo();} else {foo2();}', [], - 'if (a)\n foo();\nelse\n foo2();'), - testStatement('if (a) foo(); else {foo2();}', [], - 'if (a)\n foo();\nelse\n foo2();'), - testStatement('do {foo();} while(a);', [], 'do\n foo();\nwhile (a);'), - testStatement('label: {foo();}', [], 'label:\n foo();'), - testStatement( - 'for (var key in a) {foo();}', [], 'for (var key in a)\n foo();'), - // `label: break label;` gives problems on IE. Test that it is avoided. - testStatement('label: {break label;}', [], ';'), - // This works on IE: - testStatement('label: {label2: {break label;}}', [], - 'label:\n label2:\n break label;\n'), - // Test dangling else: - testStatement('if (a) {if (b) {foo1();}} else {foo2();}', [], """ -if (a) { - if (b) - foo1(); -} else - foo2();"""), - testStatement('if (a) {if (b) {foo1();} else {foo2();}}', [], """ -if (a) - if (b) - foo1(); - else - foo2(); -"""), - testStatement( - 'if (a) {if (b) {foo1();} else {foo2();}} else {foo3();}', [], """ -if (a) - if (b) - foo1(); - else - foo2(); -else - foo3();"""), - testStatement( - 'if (a) {while (true) if (b) {foo1();}} else {foo2();}', [], """ -if (a) { - while (true) - if (b) - foo1(); -} else - foo2();"""), - ])); -}
diff --git a/tests/compiler/dart2js/js_parser_test.dart b/tests/compiler/dart2js/js_parser_test.dart deleted file mode 100644 index 21b763e..0000000 --- a/tests/compiler/dart2js/js_parser_test.dart +++ /dev/null
@@ -1,201 +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 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'mock_compiler.dart'; -import 'package:compiler/src/js/js.dart' as jsAst; -import 'package:compiler/src/js/js.dart' show js; - -Future testExpression(String expression, [String expect = ""]) { - jsAst.Node node = js(expression); - return MockCompiler.create((MockCompiler compiler) { - String jsText = jsAst.prettyPrint(node, compiler.options, - allowVariableMinification: false); - if (expect == "") { - Expect.stringEquals(expression, jsText); - } else { - Expect.stringEquals(expect, jsText); - } - }); -} - -Future testError(String expression, [String expect = ""]) { - return new Future.sync(() { - bool doCheck(exception) { - Expect.isTrue(exception.toString().contains(expect)); - return true; - } - - Expect.throws(() => js(expression), doCheck); - }); -} - -void main() { - asyncTest(() => Future.wait([ - // Asterisk indicates deviations from real JS. - // Simple var test. - testExpression('var a = ""'), - // Parse and print will normalize whitespace. - testExpression(' var a = "" ', 'var a = ""'), - // Operator precedence. - testExpression('x = a + b * c'), - testExpression('x = a * b + c'), - testExpression('x = a + b * c + d'), - testExpression('x = a * b + c * d'), - testExpression('remaining = (remaining / 88) | 0', - 'remaining = remaining / 88 | 0'), - // Binary operators have left associativity. - testExpression('x = a + b + c'), - // We can cope with relational operators and non-relational. - testExpression('a + b == c + d'), - // The prettyprinter will insert braces where needed. - testExpression('a + (b == c) + d'), - // We can handle () for calls. - testExpression('foo(bar)'), - testExpression('foo(bar, baz)'), - // Chained calls without parentheses. - testExpression('foo(bar)(baz)'), - // Chained calls with and without new. - testExpression('new foo(bar)(baz)'), - testExpression('new foo.bar(bar)(baz)'), - testExpression('foo.bar(bar)(baz)'), - testExpression('constructor = new Function(str)()'), - // The prettyprinter understands chained calls without extra parentheses. - testExpression('(foo(bar))(baz)', 'foo(bar)(baz)'), - // Chains of dotting and calls. - testExpression('foo.bar(baz)'), - // String literal. - testExpression('var x = "fisk"'), - // String literal with \n. - testExpression(r'var x = "\n"'), - // String literal with escaped quote. - testExpression(r'var x = "\""'), - // *No clever escapes. - testError(r'var x = "\x42"', 'escapes are not allowed in literals'), - // Operator new. - testExpression('new Foo()'), - // New with dotted access. - testExpression('new Frobinator.frobinate()'), - testExpression('new Frobinator().frobinate()'), - // The prettyprinter strips some superfluous parentheses. - testExpression( - '(new Frobinator()).frobinate()', 'new Frobinator().frobinate()'), - // *We want a bracket on 'new'. - testError('new Foo', 'Parentheses are required'), - testError('(new Foo)', 'Parentheses are required'), - // Bogus operators. - testError('a +++ b', 'Unknown operator'), - // This isn't perl. There are rules. - testError('a <=> b', 'Unknown operator'), - // Typeof. - testExpression('typeof foo == "number"'), - // Strange relation. - testExpression('a < b < c'), - // Chained var. - testExpression('var x = 0, y = 1.2, z = 42'), - // Empty object literal. - testExpression('foo({}, {})'), - // *Can't handle non-empty object literals - testExpression('foo({meaning: 42})'), - // Literals. - testExpression('x(false, true, null)'), - // *We should really throw here. - testExpression('var false = 42'), - testExpression('var new = 42'), - // Bad keyword. - testError('var typeof = 42', "Expected ALPHA"), - // Malformed decimal/hex. - testError('var x = 1.1.1', "Unparseable number"), - testError('var x = 0xabcdefga', "Unparseable number"), - testError('var x = 0xabcdef\$a', "Unparseable number"), - testError('var x = 0x ', "Unparseable number"), - // Good hex constants. - testExpression('var x = 0xff'), - testExpression('var x = 0xff + 0xff'), - testExpression('var x = 0xaF + 0x0123456789abcdefABCDEF'), - // All sorts of keywords are allowed as property names in ES5. - testExpression('x.new = 0'), - testExpression('x.delete = 0'), - testExpression('x.for = 0'), - testExpression('x.instanceof = 0'), - testExpression('x.in = 0'), - testExpression('x.void = 0'), - testExpression('x.continue = 0'), - // More unary. - testExpression('x = !x'), - testExpression('!x == false'), - testExpression('var foo = void 0'), - testExpression('delete foo.bar'), - testExpression('delete foo'), - testExpression('x in y'), - testExpression('x instanceof y'), - testExpression('a * b in c * d'), - testExpression('a * b instanceof c * d'), - testError('x typeof y', 'Unparsed junk'), - testExpression('x &= ~mask'), - // Await is parsed as an unary prefix operator. - testExpression('var foo = await 0'), - testExpression('await x++'), - testExpression('void (await (x++))', 'void await x++'), - testExpression('void (await x)++'), - testExpression('++(await x)++'), - // Adjacent tokens. - testExpression('foo[x[bar]]'), - testExpression('foo[[bar]]'), - // Prefix ++ etc. - testExpression("++x"), - testExpression("++foo.bar"), - testExpression("+x"), - testExpression("+foo.bar"), - testExpression("-x"), - testExpression("-foo.bar"), - testExpression("--x"), - testExpression("--foo.bar"), - // Postfix ++ etc. - testExpression("x++"), - testExpression("foo.bar++"), - testExpression("x--"), - testExpression("foo.bar--"), - // Both! - testExpression("++x++"), - testExpression("++foo.bar++"), - testExpression("--x--"), - testExpression("--foo.bar--"), - // *We can't handle stacked unary operators (apart from !). - testError("x++ ++"), - testError("++ typeof x"), - testExpression(r"var $supportsProtoName = !!{}.__proto__"), - // ++ used as a binary operator. - testError("x++ ++ 42"), - // Shift operators. - testExpression("x << 5"), - testExpression("x << y + 1"), - testExpression("x <<= y + 1"), - // Array initializers. - testExpression("x = ['foo', 'bar', x[4]]"), - testExpression("[]"), - testError("[42 42]"), - testExpression('beebop([1, 2, 3])'), - // Array literals with holes in them. - testExpression("[1,, 2]"), - testExpression("[1,]", "[1]"), - testExpression("[1,,]", "[1,,]"), - testExpression("[,]"), - testExpression("[,,]"), - testExpression("[, 42]"), - // Ternary operator. - testExpression("x = a ? b : c"), - testExpression("y = a == null ? b : a"), - testExpression("y = a == null ? b + c : a + c"), - testExpression("foo = a ? b : c ? d : e"), - testExpression("foo = a ? b ? c : d : e"), - testExpression("foo = (a = v) ? b = w : c = x ? d = y : e = z"), - testExpression("foo = (a = v) ? b = w ? c = x : d = y : e = z"), - // Stacked assignment. - testExpression("a = b = c"), - testExpression("var a = b = c"), - ])); -}
diff --git a/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart b/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart new file mode 100644 index 0000000..97b27a6 --- /dev/null +++ b/tests/compiler/dart2js/jsinterop/interop_anonymous_unreachable_test.dart
@@ -0,0 +1,192 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library tests.dart2js.interop_anonymous_unreachable_test; + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; +import '../compiler_helper.dart'; + +testUnreachableCrash({bool useKernel}) async { + print("-- unreachable code doesn't crash the compiler --"); + // This test is a regression for Issue #24974 + String generated = await compile(""" + import 'package:js/js.dart'; + + @JS() @anonymous + class UniqueLongNameForTesting_A { + external factory UniqueLongNameForTesting_A(); + } + main() {} + """, returnAll: true, useKernel: useKernel); + + // the code should not be included in the output either. + Expect.isFalse(generated.contains("UniqueLongNameForTesting_A")); +} + +testTreeShakingJsInteropTypes({bool useKernel}) async { + print('-- tree-shaking interop types --'); + String program = """ + import 'package:js/js.dart'; + + // reachable and allocated + @JS() @anonymous + class UniqueLongNameForTesting_A { + external bool get x; + external UniqueLongNameForTesting_D get d; + external UniqueLongNameForTesting_E get e; + external factory UniqueLongNameForTesting_A( + {UniqueLongNameForTesting_B arg0}); + } + + // visible through the parameter above, but not used. + @JS() @anonymous + class UniqueLongNameForTesting_B { + external factory UniqueLongNameForTesting_B(); + } + + // unreachable + @JS() @anonymous + class UniqueLongNameForTesting_C { + external factory UniqueLongNameForTesting_C(); + } + + // visible and reached through `d`. + @JS() @anonymous + class UniqueLongNameForTesting_D { + external factory UniqueLongNameForTesting_D(); + } + + // visible through `e`, but not reached. + @JS() @anonymous + class UniqueLongNameForTesting_E { + external factory UniqueLongNameForTesting_E(); + } + + main() { + print(new UniqueLongNameForTesting_A().x); + print(new UniqueLongNameForTesting_A().d); + } + """; + + print(' - no tree-shaking by default -'); + String generated1 = + await compile(program, returnAll: true, useKernel: useKernel); + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_A")); + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_D")); + + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_B")); + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_C")); + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_E")); + + print(' - tree-shake when using flag -'); + String generated2 = await compile(program, + trustJSInteropTypeAnnotations: true, + returnAll: true, + useKernel: useKernel); + Expect.isTrue(generated2.contains("UniqueLongNameForTesting_A")); + Expect.isTrue(generated2.contains("UniqueLongNameForTesting_D")); + + Expect.isFalse(generated2.contains("UniqueLongNameForTesting_B")); + Expect.isFalse(generated2.contains("UniqueLongNameForTesting_C")); + Expect.isFalse(generated2.contains("UniqueLongNameForTesting_E")); +} + +testTreeShakingNativeTypes({bool useKernel}) async { + print('-- tree-shaking other native types --'); + + String program = """ + import 'dart:html'; + import 'package:js/js.dart'; + + @JS() @anonymous + class UniqueLongNameForTesting_A { + external dynamic get x; + } + + @JS() @anonymous + class UniqueLongNameForTesting_B { + external dynamic get y; + } + + main() { + print(new UniqueLongNameForTesting_A().x); + } + """; + + print(' - allocation effect of dynamic excludes native types -'); + String generated1 = + await compile(program, returnAll: true, useKernel: useKernel); + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_A")); + // any js-interop type could be allocated by `get x` + Expect.isTrue(generated1.contains("UniqueLongNameForTesting_B")); + // but we exclude other native types like HTMLAudioElement + Expect.isFalse(generated1.contains("HTMLAudioElement")); + + print(' - allocation effect of dynamic excludes native types [flag] -'); + // Trusting types doesn't make a difference. + String generated2 = await compile(program, + trustJSInteropTypeAnnotations: true, + returnAll: true, + useKernel: useKernel); + Expect.isTrue(generated2.contains("UniqueLongNameForTesting_A")); + Expect.isTrue(generated2.contains("UniqueLongNameForTesting_B")); + Expect.isFalse(generated2.contains("HTMLAudioElement")); + + print(' - declared native types are included in allocation effect -'); + String program2 = """ + import 'dart:html'; + import 'package:js/js.dart'; + + @JS() @anonymous + class UniqueLongNameForTesting_A { + external AudioElement get x; + } + + main() { + print(new UniqueLongNameForTesting_A().x is AudioElement); + } + """; + + String generated3 = + await compile(program2, returnAll: true, useKernel: useKernel); + Expect.isTrue(generated3.contains("UniqueLongNameForTesting_A")); + Expect.isTrue(generated3.contains("HTMLAudioElement")); + + program2 = """ + import 'dart:html'; + import 'package:js/js.dart'; + + @JS() @anonymous + class UniqueLongNameForTesting_A { + external dynamic get x; + } + + main() { + print(new UniqueLongNameForTesting_A().x is AudioElement); + } + """; + + generated3 = await compile(program2, returnAll: true, useKernel: useKernel); + Expect.isTrue(generated3.contains("UniqueLongNameForTesting_A")); + // This extra check is to make sure that we don't include HTMLAudioElement + // just because of the is-check. It is optimized away in this case because + // we believe it was never instantiated. + Expect.isFalse(generated3.contains("HTMLAudioElement")); +} + +main() { + runTests({bool useKernel}) async { + await testUnreachableCrash(useKernel: useKernel); + await testTreeShakingJsInteropTypes(useKernel: useKernel); + await testTreeShakingNativeTypes(useKernel: useKernel); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); +}
diff --git a/tests/compiler/dart2js/kernel/closed_world2_test.dart b/tests/compiler/dart2js/kernel/closed_world2_test.dart index 1cbd0a0..8a1990b 100644 --- a/tests/compiler/dart2js/kernel/closed_world2_test.dart +++ b/tests/compiler/dart2js/kernel/closed_world2_test.dart
@@ -196,13 +196,15 @@ print('---- analyze-only ------------------------------------------------'); DiagnosticCollector collector = new DiagnosticCollector(); - Compiler compiler1 = compilerFor( + CompilationResult result = await runCompiler( entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, diagnosticHandler: collector, - options: [Flags.analyzeOnly, Flags.enableAssertMessage]); - compiler1.impactCacheDeleter.retainCachesForTesting = true; - await compiler1.run(entryPoint); + options: [Flags.analyzeOnly, Flags.enableAssertMessage], + beforeRun: (compiler) { + compiler.impactCacheDeleter.retainCachesForTesting = true; + }); + Compiler compiler1 = result.compiler; if (collector.crashes.isNotEmpty) { print('Skipping due to crashes.'); return ResultKind.crashes;
diff --git a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart index 7b2e86c..758d342 100644 --- a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart +++ b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
@@ -113,13 +113,15 @@ print('---- analyze-only ------------------------------------------------'); DiagnosticCollector collector = new DiagnosticCollector(); - Compiler compiler1 = compilerFor( + ElementResolutionWorldBuilder.useInstantiationMap = true; + CompilationResult result = await runCompiler( entryPoint: entryPoint, diagnosticHandler: collector, - options: [Flags.analyzeOnly, Flags.enableAssertMessage]); - ElementResolutionWorldBuilder.useInstantiationMap = true; - compiler1.impactCacheDeleter.retainCachesForTesting = true; - await compiler1.run(entryPoint); + options: [Flags.analyzeOnly, Flags.enableAssertMessage], + beforeRun: (compiler) { + compiler.impactCacheDeleter.retainCachesForTesting = true; + }); + Compiler compiler1 = result.compiler; if (collector.crashes.isNotEmpty) { print('Skipping due to crashes.'); return ResultKind.crashes;
diff --git a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart index b94a8e9..9332d51 100644 --- a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart +++ b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
@@ -388,15 +388,17 @@ print('---- compile from ast ----------------------------------------------'); DiagnosticCollector collector = new DiagnosticCollector(); OutputCollector collector1 = new OutputCollector(); - Compiler compiler1 = compilerFor( + ElementResolutionWorldBuilder.useInstantiationMap = true; + CompilationResult result = await runCompiler( entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, diagnosticHandler: collector, outputProvider: collector1, - options: <String>[]..addAll(commonOptions)..addAll(options)); - ElementResolutionWorldBuilder.useInstantiationMap = true; - compiler1.impactCacheDeleter.retainCachesForTesting = true; - await compiler1.run(entryPoint); + options: <String>[]..addAll(commonOptions)..addAll(options), + beforeRun: (compiler) { + compiler.impactCacheDeleter.retainCachesForTesting = true; + }); + Compiler compiler1 = result.compiler; if (collector.crashes.isNotEmpty) { print('Skipping due to crashes.'); return ResultKind.crashes;
diff --git a/tests/compiler/dart2js/kernel/compiler_helper.dart b/tests/compiler/dart2js/kernel/compiler_helper.dart index 05a434b..56d9b7d 100644 --- a/tests/compiler/dart2js/kernel/compiler_helper.dart +++ b/tests/compiler/dart2js/kernel/compiler_helper.dart
@@ -21,42 +21,6 @@ import 'package:kernel/ast.dart' as ir; import '../memory_compiler.dart'; -typedef Future<Compiler> CompileFunction(); - -/// Create multiple compilations for a list of [sources]. -/// -/// This methods speeds up testing kernel based compilation by creating the IR -/// nodes for all [sources] at the same time. The returned list of -/// [CompileFunction]s compiles one of the [source] at a time using the kernel -/// based compiler. -/// -/// Currently, the returned compile function only runs with '--analyze-only' -/// flag. -Future<List<CompileFunction>> compileMultiple(List<String> sources) async { - Uri entryPoint = Uri.parse('memory:main.dart'); - - List<CompileFunction> compilers = <CompileFunction>[]; - for (String source in sources) { - compilers.add(() async { - Compiler compiler = compilerFor( - entryPoint: entryPoint, - memorySourceFiles: { - 'main.dart': source - }, - options: [ - Flags.analyzeOnly, - Flags.enableAssertMessage, - Flags.useKernel - ]); - ElementResolutionWorldBuilder.useInstantiationMap = true; - compiler.impactCacheDeleter.retainCachesForTesting = true; - await compiler.run(entryPoint); - return compiler; - }); - } - return compilers; -} - /// Analyze [memorySourceFiles] with [entryPoint] as entry-point using the /// kernel based element model. The returned [Pair] contains the compiler used /// to create the IR and the kernel based compiler. @@ -66,24 +30,26 @@ if (printSteps) { print('---- analyze-all -------------------------------------------------'); } - Compiler compiler = compilerFor( + CompilationResult result1 = await runCompiler( entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, - options: [Flags.analyzeAll, Flags.enableAssertMessage]); - compiler.impactCacheDeleter.retainCachesForTesting = true; - await compiler.run(entryPoint); + options: [Flags.analyzeAll, Flags.enableAssertMessage], + beforeRun: (compiler) { + compiler.impactCacheDeleter.retainCachesForTesting = true; + }); if (printSteps) { print('---- closed world from kernel ------------------------------------'); } - Compiler compiler2 = compilerFor( + ElementResolutionWorldBuilder.useInstantiationMap = true; + CompilationResult result2 = await runCompiler( entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, - options: [Flags.analyzeOnly, Flags.enableAssertMessage, Flags.useKernel]); - ElementResolutionWorldBuilder.useInstantiationMap = true; - compiler2.impactCacheDeleter.retainCachesForTesting = true; - await compiler2.run(entryPoint); - return new Pair<Compiler, Compiler>(compiler, compiler2); + options: [Flags.analyzeOnly, Flags.enableAssertMessage, Flags.useKernel], + beforeRun: (compiler) { + compiler.impactCacheDeleter.retainCachesForTesting = true; + }); + return new Pair<Compiler, Compiler>(result1.compiler, result2.compiler); } class MemoryKernelLibraryLoaderTask extends KernelLibraryLoaderTask { @@ -125,17 +91,18 @@ if (printSteps) { print('---- compile from dill -------------------------------------------'); } - Compiler compiler = compilerFor( + CompilationResult result = await runCompiler( entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, options: [Flags.useKernel]..addAll(options), diagnosticHandler: diagnosticHandler, - outputProvider: compilerOutput); - ElementResolutionWorldBuilder.useInstantiationMap = true; - compiler.impactCacheDeleter.retainCachesForTesting = true; - if (beforeRun != null) { - beforeRun(compiler); - } - await compiler.run(entryPoint); - return compiler; + outputProvider: compilerOutput, + beforeRun: (compiler) { + ElementResolutionWorldBuilder.useInstantiationMap = true; + compiler.impactCacheDeleter.retainCachesForTesting = true; + if (beforeRun != null) { + beforeRun(compiler); + } + }); + return result.compiler; }
diff --git a/tests/compiler/dart2js/licm_test.dart b/tests/compiler/dart2js/licm_test.dart deleted file mode 100644 index 438d174..0000000 --- a/tests/compiler/dart2js/licm_test.dart +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Check that we hoist instructions in a loop condition, even if that -// condition involves control flow. - -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST = ''' -var a = [1]; - -main() { - int count = int.parse('42') == 42 ? 42 : null; - for (int i = 0; i < count && i < a[0]; i++) { - print(i); - } - a.removeLast(); - // Ensure we don't try to generate a bailout method based on a check - // of [count]. - count.removeLast(); -} -'''; - -main() { - asyncTest(() => compileAndMatch(TEST, 'main', - new RegExp('if \\(typeof count !== "number"\\)(.|\\n)*while'))); -}
diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart deleted file mode 100644 index 3e1d17b..0000000 --- a/tests/compiler/dart2js/list_tracer2_test.dart +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// We used to always nullify the element type of a list we are tracing in -// the presence of a fixed length list constructor call. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'package:compiler/src/types/types.dart' show ContainerTypeMask; - -import 'compiler_helper.dart'; -import 'type_mask_test_helper.dart'; - -const String TEST = r''' -var myList = [42]; -main() { - var a = new List(42); - return myList[0]; -} -'''; - -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; - - checkType(String name, type) { - MemberElement element = findElement(compiler, name); - ContainerTypeMask mask = typesInferrer.getTypeOfMember(element); - Expect.equals(type, simplify(mask.elementType, closedWorld), name); - } - - checkType('myList', typesInferrer.closedWorld.commonMasks.uint31Type); - })); -}
diff --git a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart b/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart deleted file mode 100644 index 3e082fd..0000000 --- a/tests/compiler/dart2js/list_tracer_typed_data_length_test.dart +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'package:compiler/src/elements/elements.dart'; -import 'package:compiler/src/types/types.dart' show ContainerTypeMask, TypeMask; -import 'package:compiler/src/compiler.dart'; -import 'package:compiler/src/world.dart' show ClosedWorld; - -import 'memory_compiler.dart'; -import 'compiler_helper.dart' show findElement; -import 'type_mask_test_helper.dart'; - -const TEST = const { - 'main.dart': r''' -import 'dart:typed_data'; - -var myList = new Float32List(42); -var myOtherList = new Uint8List(32); - -main() { - var a = new Float32List(9); - return myList[0] + myOtherList[0]; -} -''' -}; - -void main() { - asyncTest(() async { - CompilationResult result = await runCompiler(memorySourceFiles: TEST); - Compiler compiler = result.compiler; - var typesInferrer = compiler.globalInference.typesInferrerInternal; - ClosedWorld closedWorld = typesInferrer.closedWorld; - - checkType(String name, type, length) { - MemberElement element = findElement(compiler, name); - TypeMask mask = typesInferrer.getTypeOfMember(element); - Expect.isTrue(mask.isContainer); - ContainerTypeMask container = mask; - Expect.equals(type, simplify(container.elementType, closedWorld), name); - Expect.equals(container.length, length); - } - - checkType('myList', closedWorld.commonMasks.numType, 42); - checkType('myOtherList', closedWorld.commonMasks.uint31Type, 32); - }); -}
diff --git a/tests/compiler/dart2js/literal_list_test.dart b/tests/compiler/dart2js/literal_list_test.dart deleted file mode 100644 index 32120bf..0000000 --- a/tests/compiler/dart2js/literal_list_test.dart +++ /dev/null
@@ -1,24 +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() { - print([1, 2]); - print([3]); - var c = [4, 5]; - print(c); -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains('print([1, 2]);')); - Expect.isTrue(generated.contains('print([3]);')); - Expect.isTrue(generated.contains('print([4, 5]);')); - })); -}
diff --git a/tests/compiler/dart2js/literal_map_test.dart b/tests/compiler/dart2js/literal_map_test.dart deleted file mode 100644 index e460618..0000000 --- a/tests/compiler/dart2js/literal_map_test.dart +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST = """ -foo() { - var a = {}; - var index = foo(); // Make sure we want to optimize this method. - while (true) a[index] = 1; -} -"""; - -main() { - asyncTest(() => compile(TEST, entry: 'foo', check: (String generated) { - // Make sure we have all the type information we need. - Expect.isFalse(generated.contains('bailout')); - Expect.isFalse(generated.contains('interceptor')); - // Make sure we don't go through an interceptor. - Expect.isTrue(generated.contains(r'a.$indexSet(a') || - generated.contains(r'.$indexSet(0')); - })); -}
diff --git a/tests/compiler/dart2js/logical_expression_test.dart b/tests/compiler/dart2js/logical_expression_test.dart deleted file mode 100644 index 423a73a..0000000 --- a/tests/compiler/dart2js/logical_expression_test.dart +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Test that logical or-expressions don't introduce unnecessary nots. - -import 'dart:async'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -foo(bar, gee) { - bool cond1 = bar(); - if (cond1 || gee()) gee(); - if (cond1 || gee()) gee(); -} -"""; - -const String TEST_TWO = r""" -void foo(list, bar) { - if (list == null) bar(); - if (list == null || bar()) bar(); - if (list == null || bar()) bar(); -} -"""; - -main() { - asyncTest(() => Future.wait([ - // We want something like: - // var t1 = bar.call$0() === true; - // if (t1 || gee.call$0() === true) gee.call$0(); - // if (t1 || gee.call$0() === true) gee.call$0(); - compileAndDoNotMatchFuzzy( - TEST_ONE, 'foo', r"""var x = [a-zA-Z0-9$.]+\(\) == true; - if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+; - if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+;"""), - - // We want something like: - // var t1 = list == null; - // if (t1) bar.call$0(); - // if (t1 || bar.call$0() === true) bar.call$0(); - // if (t1 || bar.call$0() === true) bar.call$0(); - compileAndMatchFuzzy(TEST_TWO, 'foo', r"""var x = x == null; - if \(x\) [^;]+; - if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+; - if \(x \|\| [a-zA-Z0-9$.]+\(\) === true\) [^;]+;"""), - ])); -}
diff --git a/tests/compiler/dart2js/loop_test.dart b/tests/compiler/dart2js/loop_test.dart deleted file mode 100644 index c622d72..0000000 --- a/tests/compiler/dart2js/loop_test.dart +++ /dev/null
@@ -1,71 +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. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -foo(a) { - int x = 0; - for (int i = 0; i < 10; i++) { - x += i; - } - return x; -} -"""; - -const String TEST_TWO = r""" -foo(a) { - int x = 0; - int i = 0; - while (i < 10) { - x += i; - i++; - } - return x; -} -"""; - -const String TEST_THREE = r""" -foo(a) { - int x = 0; - for (int i = 0; i < 10; i++) { - if (i == 5) continue; - x += i; - } - return x; -} -"""; - -const String TEST_FOUR = r""" -foo(a) { - int x = 0; - int i = 0; - while (i < 10) { - i++; - if (i == 5) continue; - x += i; - } - return x; -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains(r'for (')); - }), - compile(TEST_TWO, entry: 'foo', check: (String generated) { - Expect.isTrue(!generated.contains(r'break')); - }), - compile(TEST_THREE, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains(r'continue')); - }), - compile(TEST_FOUR, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains(r'continue')); - }), - ])); -}
diff --git a/tests/compiler/dart2js/map_tracer_const_test.dart b/tests/compiler/dart2js/map_tracer_const_test.dart deleted file mode 100644 index d208996..0000000 --- a/tests/compiler/dart2js/map_tracer_const_test.dart +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; - -import 'compiler_helper.dart'; -import 'type_mask_test_helper.dart'; - -const String TEST = ''' -int closure(int x) { - return x; -} - -class A { - static const DEFAULT = const {'fun' : closure}; - - final map; - - A([maparg]) : map = maparg == null ? DEFAULT : maparg; -} - -main() { - var a = new A(); - a.map['fun'](3.3); - print(closure(22)); -} -'''; - -void main() { - Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri, expectedErrors: 0, expectedWarnings: 0); - compiler.stopAfterTypeInference = true; - asyncTest(() => compiler.run(uri).then((_) { - var typesInferrer = compiler.globalInference.typesInferrerInternal; - var closedWorld = typesInferrer.closedWorld; - var commonMasks = closedWorld.commonMasks; - MemberElement element = findElement(compiler, 'closure'); - var mask = typesInferrer.getReturnTypeOfMember(element); - Expect.equals(commonMasks.numType, simplify(mask, closedWorld)); - })); -}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart index 3f992ba..4fc6919 100644 --- a/tests/compiler/dart2js/memory_compiler.dart +++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -20,9 +20,11 @@ show LibraryEntity, MemberEntity; import 'package:compiler/src/enqueue.dart' show ResolutionEnqueuer; import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput; -import 'package:compiler/src/library_loader.dart' show LoadedLibraries; +import 'package:compiler/src/library_loader.dart' + show LoadedLibraries, KernelLibraryLoaderTask; import 'package:compiler/src/options.dart' show CompilerOptions; +import 'package:front_end/src/api_unstable/dart2js.dart' as fe; import 'package:front_end/src/compute_platform_binaries_location.dart' show computePlatformBinariesLocation; @@ -70,6 +72,8 @@ Expando<MemorySourceFileProvider> expando = new Expando<MemorySourceFileProvider>(); +fe.InitializedCompilerState kernelInitializedCompilerState; + /// memorySourceFiles can contain a map of string filename to string file /// contents or string file name to binary file contents (hence the `dynamic` /// type for the second parameter). @@ -107,7 +111,13 @@ beforeRun(compiler); } bool isSuccess = await compiler.run(entryPoint); - return new CompilationResult(compiler, isSuccess: isSuccess); + if (compiler.libraryLoader is KernelLibraryLoaderTask) { + KernelLibraryLoaderTask loader = compiler.libraryLoader; + kernelInitializedCompilerState = loader.initializedCompilerState; + } + return new CompilationResult(compiler, + isSuccess: isSuccess, + kernelInitializedCompilerState: kernelInitializedCompilerState); } CompilerImpl compilerFor( @@ -175,7 +185,8 @@ environment: {}, platformBinaries: platformBinaries, packageConfig: packageConfig, - packagesDiscoveryProvider: packagesDiscoveryProvider)); + packagesDiscoveryProvider: packagesDiscoveryProvider) + ..kernelInitializedCompilerState = kernelInitializedCompilerState); if (cachedCompiler != null) { Map copiedLibraries = {};
diff --git a/tests/compiler/dart2js/minify_many_locals_test.dart b/tests/compiler/dart2js/minify_many_locals_test.dart deleted file mode 100644 index a44002f..0000000 --- a/tests/compiler/dart2js/minify_many_locals_test.dart +++ /dev/null
@@ -1,52 +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. -// Test that parameters keep their names in the output. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -// TODO(johnniwinther): This value is some what arbitrary. With the old -// [ResolvedVisitor] we could handle 2000, with the new [ResolvedVisitor] build -// upon the [SemanticVisitor] we can handle <=1000. Update (increase) the value -// when the [SssBuilder] is no longer build upon the [ResolvedVisitor] . -const int NUMBER_OF_PARAMETERS = 1000; - -main() { - var buffer = new StringBuffer(); - buffer.write("foo("); - for (int i = 0; i < NUMBER_OF_PARAMETERS; i++) { - buffer.write("x$i, "); - } - buffer.write("x) { int i = "); - for (int i = 0; i < NUMBER_OF_PARAMETERS; i++) { - buffer.write("x$i+"); - } - buffer.write("$NUMBER_OF_PARAMETERS; return i; }"); - String code = buffer.toString(); - - asyncTest( - () => compile(code, entry: 'foo', minify: true).then((String generated) { - RegExp re = new RegExp(r"\(a,b,c"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"x,y,z,a0,a1,a2"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"y,z,a0,a1,a2,a3,a4,a5,a6"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"g8,g9,h0,h1"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"z8,z9,aa0,aa1,aa2"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"aa9,ab0,ab1"); - Expect.isTrue(re.hasMatch(generated)); - - re = new RegExp(r"az9,ba0,ba1"); - Expect.isTrue(re.hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/deferred_mirrors_test.dart b/tests/compiler/dart2js/mirrors/deferred_mirrors_test.dart similarity index 99% rename from tests/compiler/dart2js/deferred_mirrors_test.dart rename to tests/compiler/dart2js/mirrors/deferred_mirrors_test.dart index 105c847..40a6746 100644 --- a/tests/compiler/dart2js/deferred_mirrors_test.dart +++ b/tests/compiler/dart2js/mirrors/deferred_mirrors_test.dart
@@ -9,7 +9,7 @@ import 'dart:async'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; Future runTest(String mainScript, test) async { CompilationResult result = await runCompiler(
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/mirrors/import_mirrors_test.dart similarity index 99% rename from tests/compiler/dart2js/import_mirrors_test.dart rename to tests/compiler/dart2js/mirrors/import_mirrors_test.dart index 37e4ad7..6ab3053 100644 --- a/tests/compiler/dart2js/import_mirrors_test.dart +++ b/tests/compiler/dart2js/mirrors/import_mirrors_test.dart
@@ -12,7 +12,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/diagnostics/messages.dart' show MessageKind, MessageTemplate; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const DIRECT_IMPORT = const { '/main.dart': '''
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirrors/mirror_final_field_inferrer2_test.dart similarity index 87% rename from tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart rename to tests/compiler/dart2js/mirrors/mirror_final_field_inferrer2_test.dart index bedd0e4..092657c 100644 --- a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart +++ b/tests/compiler/dart2js/mirrors/mirror_final_field_inferrer2_test.dart
@@ -6,9 +6,9 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart' show runCompiler; -import 'compiler_helper.dart' show findElement; -import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart' show runCompiler; +import '../compiler_helper.dart' show findElement; +import '../inference/type_mask_test_helper.dart'; const MEMORY_SOURCE_FILES = const <String, String>{ 'main.dart': """
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart b/tests/compiler/dart2js/mirrors/mirror_final_field_inferrer_test.dart similarity index 87% rename from tests/compiler/dart2js/mirror_final_field_inferrer_test.dart rename to tests/compiler/dart2js/mirrors/mirror_final_field_inferrer_test.dart index 5df3510..6b2af55 100644 --- a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart +++ b/tests/compiler/dart2js/mirrors/mirror_final_field_inferrer_test.dart
@@ -6,9 +6,9 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart' show runCompiler; -import 'compiler_helper.dart' show findElement; -import 'type_mask_test_helper.dart'; +import '../memory_compiler.dart' show runCompiler; +import '../compiler_helper.dart' show findElement; +import '../inference/type_mask_test_helper.dart'; const MEMORY_SOURCE_FILES = const <String, String>{ 'main.dart': """
diff --git a/tests/compiler/dart2js/mirror_private_name_inheritance_test.dart b/tests/compiler/dart2js/mirrors/mirror_private_name_inheritance_test.dart similarity index 92% rename from tests/compiler/dart2js/mirror_private_name_inheritance_test.dart rename to tests/compiler/dart2js/mirrors/mirror_private_name_inheritance_test.dart index 7ac00ad..b017527 100644 --- a/tests/compiler/dart2js/mirror_private_name_inheritance_test.dart +++ b/tests/compiler/dart2js/mirrors/mirror_private_name_inheritance_test.dart
@@ -6,8 +6,8 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart' show runCompiler; -import 'compiler_helper.dart' show findElement; +import '../memory_compiler.dart' show runCompiler; +import '../compiler_helper.dart' show findElement; const MEMORY_SOURCE_FILES = const <String, String>{ 'main.dart': """
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirrors/mirror_tree_shaking_test.dart similarity index 98% rename from tests/compiler/dart2js/mirror_tree_shaking_test.dart rename to tests/compiler/dart2js/mirrors/mirror_tree_shaking_test.dart index f3340f5..a430c36 100644 --- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart +++ b/tests/compiler/dart2js/mirrors/mirror_tree_shaking_test.dart
@@ -9,7 +9,7 @@ import 'package:compiler/src/js_backend/js_backend.dart' show JavaScriptBackend; import 'package:compiler/src/js_backend/mirrors_analysis.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; main() { DiagnosticCollector collector = new DiagnosticCollector();
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors/mirrors_used_test.dart similarity index 99% rename from tests/compiler/dart2js/mirrors_used_test.dart rename to tests/compiler/dart2js/mirrors/mirrors_used_test.dart index 57922bd..f82d85d 100644 --- a/tests/compiler/dart2js/mirrors_used_test.dart +++ b/tests/compiler/dart2js/mirrors/mirrors_used_test.dart
@@ -11,7 +11,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart' show runCompiler; +import '../memory_compiler.dart' show runCompiler; import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
diff --git a/tests/compiler/dart2js/preserve_uris_test.dart b/tests/compiler/dart2js/mirrors/preserve_uris_test.dart similarity index 95% rename from tests/compiler/dart2js/preserve_uris_test.dart rename to tests/compiler/dart2js/mirrors/preserve_uris_test.dart index fdf660f..8429c81 100644 --- a/tests/compiler/dart2js/preserve_uris_test.dart +++ b/tests/compiler/dart2js/mirrors/preserve_uris_test.dart
@@ -5,7 +5,7 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; -import 'memory_compiler.dart' show runCompiler, OutputCollector; +import '../memory_compiler.dart' show runCompiler, OutputCollector; const MEMORY_SOURCE_FILES = const <String, String>{ 'main.dart': """
diff --git a/tests/compiler/dart2js/needs_no_such_method_test.dart b/tests/compiler/dart2js/needs_no_such_method_test.dart index 93a005b2..01e467e 100644 --- a/tests/compiler/dart2js/needs_no_such_method_test.dart +++ b/tests/compiler/dart2js/needs_no_such_method_test.dart
@@ -5,7 +5,7 @@ import 'dart:async'; import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; -import 'package:compiler/src/elements/elements.dart' show ClassElement; +import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/names.dart'; import 'package:compiler/src/universe/call_structure.dart'; import 'package:compiler/src/universe/selector.dart'; @@ -14,7 +14,10 @@ void main() { asyncTest(() async { - await testClassSets(); + print('--test from ast---------------------------------------------------'); + await testClassSets(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await testClassSets(CompileMode.kernel); }); } @@ -30,10 +33,10 @@ } """; -testClassSets() async { +testClassSets(CompileMode compileMode) async { Selector foo, bar, baz; ClosedWorld closedWorld; - ClassElement superclass, subclass, subtype; + ClassEntity superclass, subclass, subtype; String testMode; Future run(List<String> instantiated) async { @@ -46,7 +49,7 @@ testMode = '$instantiated'; var env = await TypeEnvironment.create(CLASSES, - mainSource: main.toString(), compileMode: CompileMode.memory); + mainSource: main.toString(), compileMode: compileMode); foo = new Selector.call(const PublicName('foo'), CallStructure.NO_ARGS); bar = new Selector.call(const PublicName('bar'), CallStructure.NO_ARGS); baz = new Selector.call(const PublicName('baz'), CallStructure.NO_ARGS); @@ -57,9 +60,15 @@ subtype = env.getElement('Subtype'); } - void check(ClassElement cls, ClassQuery query, Selector selector, + void check(ClassEntity cls, ClassQuery query, Selector selector, bool expectedResult) { - bool result = closedWorld.needsNoSuchMethod(cls, selector, query); + bool result; + if (closedWorld.getClassSet(cls) == null) { + // The class isn't live, so it can't need a noSuchMethod for [selector]. + result = false; + } else { + result = closedWorld.needsNoSuchMethod(cls, selector, query); + } Expect.equals( expectedResult, result,
diff --git a/tests/compiler/dart2js/no_constructor_body_test.dart b/tests/compiler/dart2js/no_constructor_body_test.dart deleted file mode 100644 index 495f2d9..0000000 --- a/tests/compiler/dart2js/no_constructor_body_test.dart +++ /dev/null
@@ -1,25 +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. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST = r""" -class A { - A.foo() {} - A(); -} -main() { - new A(); - new A.foo(); -} -"""; - -main() { - asyncTest(() => compileAll(TEST).then((generated) { - Expect.isTrue(generated - .contains(new RegExp('A: {[ \n]*"\\^": "Object;",[ \n]*static:'))); - })); -}
diff --git a/tests/compiler/dart2js/no_duplicate_constructor_body2_test.dart b/tests/compiler/dart2js/no_duplicate_constructor_body2_test.dart deleted file mode 100644 index ab1aa74..0000000 --- a/tests/compiler/dart2js/no_duplicate_constructor_body2_test.dart +++ /dev/null
@@ -1,30 +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. - -import 'compiler_helper.dart'; -import "package:async_helper/async_helper.dart"; - -const String CODE = """ -var x = 0; -class A { - A() { x++; } -} - -class B extends A { - B(); -} - -main() { - new B(); - new A(); -} -"""; - -main() { - asyncTest(() => compileAll(CODE).then((generated) { - RegExp regexp = new RegExp(r'A\$0: function'); - Iterator<Match> matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 1); - })); -}
diff --git a/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart b/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart deleted file mode 100644 index 135b87d..0000000 --- a/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart +++ /dev/null
@@ -1,24 +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. - -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String CODE = """ -class A { - A(String b) { b.length; } -} - -main() { - new A("foo"); -} -"""; - -main() { - asyncTest(() => compileAll(CODE).then((generated) { - RegExp regexp = new RegExp(r'\A: {[ \n]*"\^": "[A-Za-z]+;"'); - Iterator<Match> matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 1); - })); -}
diff --git a/tests/compiler/dart2js/no_duplicate_stub_test.dart b/tests/compiler/dart2js/no_duplicate_stub_test.dart deleted file mode 100644 index 5327507..0000000 --- a/tests/compiler/dart2js/no_duplicate_stub_test.dart +++ /dev/null
@@ -1,37 +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. - -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST = r""" -class A { - foo({a, b}) {} -} - -class B extends A { -} - -main() { - var a = [bar, baz]; - a[0](new A()); - a[1](new A()); -} - -bar(a) { - if (a is A) a.foo(a: 42); -} - -baz(a) { - if (a is B) a.foo(a: 42); -} -"""; - -main() { - asyncTest(() => compileAll(TEST).then((generated) { - RegExp regexp = new RegExp('foo\\\$1\\\$a: function'); - Iterator<Match> matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 1); - })); -}
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/no_such_method_enabled_test.dart index ca6310e..74c1826 100644 --- a/tests/compiler/dart2js/no_such_method_enabled_test.dart +++ b/tests/compiler/dart2js/no_such_method_enabled_test.dart
@@ -3,14 +3,14 @@ // BSD-style license that can be found in the LICENSE file. import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/common_elements.dart'; import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/js_backend/no_such_method_registry.dart'; import 'package:compiler/src/world.dart'; import 'package:expect/expect.dart'; -import 'kernel/compiler_helper.dart'; -import 'compiler_helper.dart'; +import 'memory_compiler.dart'; class NoSuchMethodInfo { final String className; @@ -159,7 +159,7 @@ const NoSuchMethodTest(""" class A { noSuchMethod(Invocation x) { - throw new UnsupportedException(); + throw new UnsupportedError(); } } main() { @@ -206,63 +206,55 @@ ]; main() { - asyncTest(() async { + runTests({bool useKernel}) async { for (NoSuchMethodTest test in TESTS) { print('---- testing -------------------------------------------------'); print(test.code); - Uri uri = new Uri(scheme: 'source'); - Compiler compiler = compilerFor(test.code, uri); - await compiler.run(uri); - checkTest(compiler, test, testComplexReturns: true); + CompilationResult result = await runCompiler( + memorySourceFiles: {'main.dart': test.code}, + options: useKernel ? [Flags.useKernel] : []); + Compiler compiler = result.compiler; + checkTest(compiler, test); } + } - List<String> sources = <String>[]; - for (NoSuchMethodTest test in TESTS) { - sources.add(test.code); - } - - print('---- preparing for kernel tests ----------------------------------'); - List<CompileFunction> results = await compileMultiple(sources); - for (int index = 0; index < results.length; index++) { - print('---- testing with kernel --------------------------------------'); - print(sources[index]); - Compiler compiler = await results[index](); - compiler.resolutionWorldBuilder.closeWorld(); - // Complex returns are computed during inference. - checkTest(compiler, TESTS[index], testComplexReturns: false); - } + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); } -checkTest(Compiler compiler, NoSuchMethodTest test, {bool testComplexReturns}) { - ElementEnvironment elementEnvironment = +checkTest(Compiler compiler, NoSuchMethodTest test) { + ElementEnvironment frontendEnvironment = compiler.frontendStrategy.elementEnvironment; NoSuchMethodRegistryImpl registry = compiler.backend.noSuchMethodRegistry; NoSuchMethodResolver resolver = registry.internalResolverForTesting; - FunctionEntity ObjectNSM = elementEnvironment.lookupClassMember( + FunctionEntity ObjectNSM = frontendEnvironment.lookupClassMember( compiler.frontendStrategy.commonElements.objectClass, 'noSuchMethod'); - ClosedWorld closedWorld = - compiler.resolutionWorldBuilder.closedWorldForTesting; - NoSuchMethodDataImpl data = closedWorld.noSuchMethodData; + ClosedWorld backendClosedWorld = compiler.backendClosedWorldForTesting; + ElementEnvironment backendEnvironment = backendClosedWorld.elementEnvironment; + NoSuchMethodDataImpl data = backendClosedWorld.noSuchMethodData; // Test [NoSuchMethodResolver] results for each method. for (NoSuchMethodInfo info in test.methods) { - ClassEntity cls = elementEnvironment.lookupClass( - elementEnvironment.mainLibrary, info.className); + ClassEntity cls = frontendEnvironment.lookupClass( + frontendEnvironment.mainLibrary, info.className); Expect.isNotNull(cls, "Class ${info.className} not found."); FunctionEntity noSuchMethod = - elementEnvironment.lookupClassMember(cls, 'noSuchMethod'); + frontendEnvironment.lookupClassMember(cls, 'noSuchMethod'); Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls."); if (info.superClassName == null) { Expect.equals(ObjectNSM, resolver.getSuperNoSuchMethod(noSuchMethod)); } else { - ClassEntity superclass = elementEnvironment.lookupClass( - elementEnvironment.mainLibrary, info.superClassName); + ClassEntity superclass = frontendEnvironment.lookupClass( + frontendEnvironment.mainLibrary, info.superClassName); Expect.isNotNull( superclass, "Superclass ${info.superClassName} not found."); FunctionEntity superNoSuchMethod = - elementEnvironment.lookupClassMember(superclass, 'noSuchMethod'); + frontendEnvironment.lookupClassMember(superclass, 'noSuchMethod'); Expect.isNotNull( superNoSuchMethod, "noSuchMethod not found in $superclass."); Expect.equals( @@ -285,39 +277,51 @@ // the [NoSuchMethodResolver] results which are therefore tested for all // methods first. for (NoSuchMethodInfo info in test.methods) { - ClassEntity cls = elementEnvironment.lookupClass( - elementEnvironment.mainLibrary, info.className); - Expect.isNotNull(cls, "Class ${info.className} not found."); - FunctionEntity noSuchMethod = - elementEnvironment.lookupClassMember(cls, 'noSuchMethod'); - Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls."); + ClassEntity frontendClass = frontendEnvironment.lookupClass( + frontendEnvironment.mainLibrary, info.className); + Expect.isNotNull(frontendClass, "Class ${info.className} not found."); + FunctionEntity frontendNoSuchMethod = + frontendEnvironment.lookupClassMember(frontendClass, 'noSuchMethod'); + Expect.isNotNull( + frontendNoSuchMethod, "noSuchMethod not found in $frontendClass."); - Expect.equals(info.isDefault, registry.defaultImpls.contains(noSuchMethod), - "Unexpected isDefault result on $noSuchMethod."); + Expect.equals( + info.isDefault, + registry.defaultImpls.contains(frontendNoSuchMethod), + "Unexpected isDefault result on $frontendNoSuchMethod."); Expect.equals( info.isThrowing, - registry.throwingImpls.contains(noSuchMethod), - "Unexpected isThrowing result on $noSuchMethod."); - Expect.equals(info.isOther, registry.otherImpls.contains(noSuchMethod), - "Unexpected isOther result on $noSuchMethod."); + registry.throwingImpls.contains(frontendNoSuchMethod), + "Unexpected isThrowing result on $frontendNoSuchMethod."); + Expect.equals( + info.isOther, + registry.otherImpls.contains(frontendNoSuchMethod), + "Unexpected isOther result on $frontendNoSuchMethod."); Expect.equals( info.isNotApplicable, - registry.notApplicableImpls.contains(noSuchMethod), - "Unexpected isNotApplicable result on $noSuchMethod."); - if (testComplexReturns) { - Expect.equals( - info.isComplexNoReturn, - data.complexNoReturnImpls.contains(noSuchMethod), - "Unexpected isComplexNoReturn result on $noSuchMethod."); - Expect.equals( - info.isComplexReturn, - data.complexReturningImpls.contains(noSuchMethod), - "Unexpected isComplexReturn result on $noSuchMethod."); - } + registry.notApplicableImpls.contains(frontendNoSuchMethod), + "Unexpected isNotApplicable result on $frontendNoSuchMethod."); + + ClassEntity backendClass = backendEnvironment.lookupClass( + backendEnvironment.mainLibrary, info.className); + Expect.isNotNull(backendClass, "Class ${info.className} not found."); + FunctionEntity backendNoSuchMethod = + backendEnvironment.lookupClassMember(backendClass, 'noSuchMethod'); + Expect.isNotNull( + backendNoSuchMethod, "noSuchMethod not found in $backendClass."); + + Expect.equals( + info.isComplexNoReturn, + data.complexNoReturnImpls.contains(backendNoSuchMethod), + "Unexpected isComplexNoReturn result on $backendNoSuchMethod."); + Expect.equals( + info.isComplexReturn, + data.complexReturningImpls.contains(backendNoSuchMethod), + "Unexpected isComplexReturn result on $backendNoSuchMethod."); } Expect.equals( test.isNoSuchMethodUsed, - closedWorld.backendUsage.isNoSuchMethodUsed, + backendClosedWorld.backendUsage.isNoSuchMethodUsed, "Unexpected isNoSuchMethodUsed result."); }
diff --git a/tests/compiler/dart2js/null_check_test.dart b/tests/compiler/dart2js/null_check_test.dart deleted file mode 100644 index 5d82a62..0000000 --- a/tests/compiler/dart2js/null_check_test.dart +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import "package:expect/expect.dart"; -import 'compiler_helper.dart'; -import "package:async_helper/async_helper.dart"; - -const String TEST1 = r""" -main() { - var foo; - if (main() == 5) { - foo = [0]; - } - return foo[0]; -} -"""; - -main() { - asyncTest(() => compileAll(TEST1).then((generated) { - Expect.isFalse(generated.contains('foo.length')); - })); -}
diff --git a/tests/compiler/dart2js/null_type_test.dart b/tests/compiler/dart2js/null_type_test.dart deleted file mode 100644 index d64c431..0000000 --- a/tests/compiler/dart2js/null_type_test.dart +++ /dev/null
@@ -1,20 +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. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -foo() { - var c = null; - while (true) c = 1 + c; -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isFalse(generated.contains('typeof (void 0)')); - })); -}
diff --git a/tests/compiler/dart2js/old_frontend/analyze_dart2js_test.dart b/tests/compiler/dart2js/old_frontend/analyze_dart2js_test.dart index 3b15544..7abf3d1 100644 --- a/tests/compiler/dart2js/old_frontend/analyze_dart2js_test.dart +++ b/tests/compiler/dart2js/old_frontend/analyze_dart2js_test.dart
@@ -8,7 +8,7 @@ import 'package:compiler/src/filenames.dart'; import 'package:compiler/src/compiler.dart'; import 'analyze_helper.dart'; -import '../related_types.dart'; +import 'related_types.dart'; /** * Map of whitelisted warnings and errors.
diff --git a/tests/compiler/dart2js/old_frontend/async_await_syntax_test.dart b/tests/compiler/dart2js/old_frontend/async_await_syntax_test.dart index 1823e93..16be073 100644 --- a/tests/compiler/dart2js/old_frontend/async_await_syntax_test.dart +++ b/tests/compiler/dart2js/old_frontend/async_await_syntax_test.dart
@@ -5,7 +5,7 @@ // Test that dart2js produces the expected static type warnings and // compile-time errors for these tests. -import '../frontend_checker.dart'; +import 'frontend_checker.dart'; /// Map of test files to run together with their associated whitelist. ///
diff --git a/tests/compiler/dart2js/old_frontend/begin_end_token_test.dart b/tests/compiler/dart2js/old_frontend/begin_end_token_test.dart index 33a6853..0a0ce7a 100644 --- a/tests/compiler/dart2js/old_frontend/begin_end_token_test.dart +++ b/tests/compiler/dart2js/old_frontend/begin_end_token_test.dart
@@ -4,7 +4,7 @@ import 'package:compiler/src/tree/tree.dart'; import 'package:expect/expect.dart'; -import '../parser_helper.dart'; +import 'parser_helper.dart'; void testNode(Node node, String expected, String text, [bool hard = true]) { var debug = 'text=$text,expected=$expected,node:${node}';
diff --git a/tests/compiler/dart2js/old_frontend/check_members_test.dart b/tests/compiler/dart2js/old_frontend/check_members_test.dart index 08c4718..26a5a53 100644 --- a/tests/compiler/dart2js/old_frontend/check_members_test.dart +++ b/tests/compiler/dart2js/old_frontend/check_members_test.dart
@@ -6,7 +6,7 @@ // bound language tests. This ensures that the analyzer and dart2js agrees // on these tests. -import '../warnings_checker.dart'; +import 'warnings_checker.dart'; /// Map from test files to a map of their expected status. If the status map is /// `null` no warnings must be missing or unexpected, otherwise the status map
diff --git a/tests/compiler/dart2js/old_frontend/compile_with_empty_libraries_test.dart b/tests/compiler/dart2js/old_frontend/compile_with_empty_libraries_test.dart index 5b6c354..d16fe9e 100644 --- a/tests/compiler/dart2js/old_frontend/compile_with_empty_libraries_test.dart +++ b/tests/compiler/dart2js/old_frontend/compile_with_empty_libraries_test.dart
@@ -6,7 +6,7 @@ /// references to core library definitions. import 'package:async_helper/async_helper.dart'; -import '../mock_compiler.dart'; +import 'mock_compiler.dart'; const String TEST = r"main() {}";
diff --git a/tests/compiler/dart2js/old_frontend/compiler_test.dart b/tests/compiler/dart2js/old_frontend/compiler_test.dart index a2b10f3..82db42a 100644 --- a/tests/compiler/dart2js/old_frontend/compiler_test.dart +++ b/tests/compiler/dart2js/old_frontend/compiler_test.dart
@@ -10,7 +10,7 @@ import "package:compiler/src/old_to_new_api.dart"; import "package:expect/expect.dart"; -import "../mock_compiler.dart"; +import "mock_compiler.dart"; Future testErrorHandling() { // Test that compiler.currentElement is set correctly when
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/old_frontend/diagnose_ambiguous_test.dart similarity index 97% rename from tests/compiler/dart2js/diagnose_ambiguous_test.dart rename to tests/compiler/dart2js/old_frontend/diagnose_ambiguous_test.dart index 268db44..7617530 100644 --- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart +++ b/tests/compiler/dart2js/old_frontend/diagnose_ambiguous_test.dart
@@ -5,7 +5,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart' show Diagnostic; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void main() { DiagnosticCollector collector = new DiagnosticCollector();
diff --git a/tests/compiler/dart2js/duplicate_library_test.dart b/tests/compiler/dart2js/old_frontend/duplicate_library_test.dart similarity index 98% rename from tests/compiler/dart2js/duplicate_library_test.dart rename to tests/compiler/dart2js/old_frontend/duplicate_library_test.dart index 57800dc..8dce246 100644 --- a/tests/compiler/dart2js/duplicate_library_test.dart +++ b/tests/compiler/dart2js/old_frontend/duplicate_library_test.dart
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart'; import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/diagnostics/messages.dart' show MessageKind; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; void check(String kind, Iterable<CollectedMessage> messages, List<MessageKind> expectedMessageKinds) {
diff --git a/tests/compiler/dart2js/erroneous_element_test.dart b/tests/compiler/dart2js/old_frontend/erroneous_element_test.dart similarity index 100% rename from tests/compiler/dart2js/erroneous_element_test.dart rename to tests/compiler/dart2js/old_frontend/erroneous_element_test.dart
diff --git a/tests/compiler/dart2js/error_token_test.dart b/tests/compiler/dart2js/old_frontend/error_token_test.dart similarity index 97% rename from tests/compiler/dart2js/error_token_test.dart rename to tests/compiler/dart2js/old_frontend/error_token_test.dart index 6386ca1..7cdd28f 100644 --- a/tests/compiler/dart2js/error_token_test.dart +++ b/tests/compiler/dart2js/old_frontend/error_token_test.dart
@@ -10,7 +10,7 @@ import 'package:async_helper/async_helper.dart'; import "package:compiler/src/diagnostics/messages.dart"; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; Future runTest(String code, {MessageKind error, int expectedWarningCount: 0}) async {
diff --git a/tests/compiler/dart2js/find_my_name_test.dart b/tests/compiler/dart2js/old_frontend/find_my_name_test.dart similarity index 100% rename from tests/compiler/dart2js/find_my_name_test.dart rename to tests/compiler/dart2js/old_frontend/find_my_name_test.dart
diff --git a/tests/compiler/dart2js/flatten_test.dart b/tests/compiler/dart2js/old_frontend/flatten_test.dart similarity index 98% rename from tests/compiler/dart2js/flatten_test.dart rename to tests/compiler/dart2js/old_frontend/flatten_test.dart index 68e97a5..5e08375 100644 --- a/tests/compiler/dart2js/flatten_test.dart +++ b/tests/compiler/dart2js/old_frontend/flatten_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; import 'package:compiler/src/elements/resolution_types.dart'; import "package:compiler/src/elements/elements.dart" show ClassElement;
diff --git a/tests/compiler/dart2js/frontend_checker.dart b/tests/compiler/dart2js/old_frontend/frontend_checker.dart similarity index 96% rename from tests/compiler/dart2js/frontend_checker.dart rename to tests/compiler/dart2js/old_frontend/frontend_checker.dart index c210ba2..7699405 100644 --- a/tests/compiler/dart2js/frontend_checker.dart +++ b/tests/compiler/dart2js/old_frontend/frontend_checker.dart
@@ -11,11 +11,11 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/util/uri_extras.dart' show relativize; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; -import '../../../tools/testing/dart/multitest.dart' +import '../../../../tools/testing/dart/multitest.dart' show extractTestsFromMultitest; -import '../../../tools/testing/dart/path.dart' show Path; +import '../../../../tools/testing/dart/path.dart' show Path; /// Check the analysis of the multitests in [testFiles] to result in the /// expected static warnings and compile-time errors.
diff --git a/tests/compiler/dart2js/generic_method_type_usage_test.dart b/tests/compiler/dart2js/old_frontend/generic_method_type_usage_test.dart similarity index 98% rename from tests/compiler/dart2js/generic_method_type_usage_test.dart rename to tests/compiler/dart2js/old_frontend/generic_method_type_usage_test.dart index 9354cbad..1e34c9a 100644 --- a/tests/compiler/dart2js/generic_method_type_usage_test.dart +++ b/tests/compiler/dart2js/old_frontend/generic_method_type_usage_test.dart
@@ -16,7 +16,7 @@ import 'package:async_helper/async_helper.dart'; import "package:compiler/src/diagnostics/messages.dart"; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'type_variable_is_dynamic.dart': '''
diff --git a/tests/compiler/dart2js/import_test.dart b/tests/compiler/dart2js/old_frontend/import_test.dart similarity index 98% rename from tests/compiler/dart2js/import_test.dart rename to tests/compiler/dart2js/old_frontend/import_test.dart index 8684fe1..de6daee 100644 --- a/tests/compiler/dart2js/import_test.dart +++ b/tests/compiler/dart2js/old_frontend/import_test.dart
@@ -9,7 +9,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/diagnostics/messages.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': '''
diff --git a/tests/compiler/dart2js/least_upper_bound_language_test.dart b/tests/compiler/dart2js/old_frontend/least_upper_bound_language_test.dart similarity index 100% rename from tests/compiler/dart2js/least_upper_bound_language_test.dart rename to tests/compiler/dart2js/old_frontend/least_upper_bound_language_test.dart
diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/old_frontend/least_upper_bound_test.dart similarity index 99% rename from tests/compiler/dart2js/least_upper_bound_test.dart rename to tests/compiler/dart2js/old_frontend/least_upper_bound_test.dart index 6cdbb02..bb2f12d 100644 --- a/tests/compiler/dart2js/least_upper_bound_test.dart +++ b/tests/compiler/dart2js/old_frontend/least_upper_bound_test.dart
@@ -9,7 +9,7 @@ import 'package:compiler/src/elements/resolution_types.dart'; import 'package:compiler/src/elements/elements.dart' show ClassElement; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; void main() { testInterface1();
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart similarity index 98% rename from tests/compiler/dart2js/library_resolution_test.dart rename to tests/compiler/dart2js/old_frontend/library_resolution_test.dart index 7487a13..34742a3 100644 --- a/tests/compiler/dart2js/library_resolution_test.dart +++ b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
@@ -8,7 +8,7 @@ import "dart:async"; -import "memory_source_file_helper.dart"; +import "../memory_source_file_helper.dart"; import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/lookup_member_test.dart b/tests/compiler/dart2js/old_frontend/lookup_member_test.dart similarity index 98% rename from tests/compiler/dart2js/lookup_member_test.dart rename to tests/compiler/dart2js/old_frontend/lookup_member_test.dart index 4a4e9f8..30d58c7 100644 --- a/tests/compiler/dart2js/lookup_member_test.dart +++ b/tests/compiler/dart2js/old_frontend/lookup_member_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; import 'package:compiler/src/elements/resolution_types.dart'; import "package:compiler/src/elements/elements.dart" show ClassElement, MemberSignature;
diff --git a/tests/compiler/dart2js/malformed_uri_test.dart b/tests/compiler/dart2js/old_frontend/malformed_uri_test.dart similarity index 95% rename from tests/compiler/dart2js/malformed_uri_test.dart rename to tests/compiler/dart2js/old_frontend/malformed_uri_test.dart index f36bef0..a3b52ea 100644 --- a/tests/compiler/dart2js/malformed_uri_test.dart +++ b/tests/compiler/dart2js/old_frontend/malformed_uri_test.dart
@@ -9,7 +9,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': '''
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/old_frontend/members_test.dart similarity index 99% rename from tests/compiler/dart2js/members_test.dart rename to tests/compiler/dart2js/old_frontend/members_test.dart index 301ad51..f0f03cb 100644 --- a/tests/compiler/dart2js/members_test.dart +++ b/tests/compiler/dart2js/old_frontend/members_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; import 'package:compiler/src/elements/resolution_types.dart'; import "package:compiler/src/elements/elements.dart" show ClassElement, MemberSignature;
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/old_frontend/message_kind_helper.dart similarity index 99% rename from tests/compiler/dart2js/message_kind_helper.dart rename to tests/compiler/dart2js/old_frontend/message_kind_helper.dart index bd1f19c..0703acd 100644 --- a/tests/compiler/dart2js/message_kind_helper.dart +++ b/tests/compiler/dart2js/old_frontend/message_kind_helper.dart
@@ -13,7 +13,7 @@ show MessageKind, MessageTemplate; import 'package:compiler/compiler_new.dart' show Diagnostic; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const String ESCAPE_REGEXP = r'[[\]{}()*+?.\\^$|]';
diff --git a/tests/compiler/dart2js/message_kind_test.dart b/tests/compiler/dart2js/old_frontend/message_kind_test.dart similarity index 100% rename from tests/compiler/dart2js/message_kind_test.dart rename to tests/compiler/dart2js/old_frontend/message_kind_test.dart
diff --git a/tests/compiler/dart2js/message_span_test.dart b/tests/compiler/dart2js/old_frontend/message_span_test.dart similarity index 97% rename from tests/compiler/dart2js/message_span_test.dart rename to tests/compiler/dart2js/old_frontend/message_span_test.dart index 5fe26df..9fff9b5 100644 --- a/tests/compiler/dart2js/message_span_test.dart +++ b/tests/compiler/dart2js/old_frontend/message_span_test.dart
@@ -8,8 +8,8 @@ import 'package:compiler/src/diagnostics/messages.dart'; import 'package:compiler/src/io/source_file.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; -import 'memory_source_file_helper.dart'; +import '../memory_compiler.dart'; +import '../memory_source_file_helper.dart'; const List<Test> TESTS = const <Test>[ const Test('''
diff --git a/tests/compiler/dart2js/metadata_test.dart b/tests/compiler/dart2js/old_frontend/metadata_test.dart similarity index 98% rename from tests/compiler/dart2js/metadata_test.dart rename to tests/compiler/dart2js/old_frontend/metadata_test.dart index d1e94a6..9130973 100644 --- a/tests/compiler/dart2js/metadata_test.dart +++ b/tests/compiler/dart2js/old_frontend/metadata_test.dart
@@ -5,7 +5,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/src/constants/values.dart' show PrimitiveConstantValue; import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'package:compiler/src/parser/partial_elements.dart' show PartialMetadataAnnotation; import 'package:compiler/src/diagnostics/diagnostic_listener.dart' @@ -168,7 +168,7 @@ Uri uri = new Uri(scheme: 'source', path: 'main.dart'); - var compiler = compilerFor(source, uri, analyzeOnly: true) + var compiler = mockCompilerFor(source, uri, analyzeOnly: true) ..registerSource(partUri, partSource) ..registerSource(libUri, libSource);
diff --git a/tests/compiler/dart2js/minimal_resolution_test.dart b/tests/compiler/dart2js/old_frontend/minimal_resolution_test.dart similarity index 98% rename from tests/compiler/dart2js/minimal_resolution_test.dart rename to tests/compiler/dart2js/old_frontend/minimal_resolution_test.dart index a571f55..5cebcf2 100644 --- a/tests/compiler/dart2js/minimal_resolution_test.dart +++ b/tests/compiler/dart2js/old_frontend/minimal_resolution_test.dart
@@ -10,7 +10,7 @@ import 'package:compiler/src/elements/elements.dart'; import 'package:compiler/src/enqueue.dart'; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; main() { asyncTest(() async {
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/old_frontend/missing_file_test.dart similarity index 98% rename from tests/compiler/dart2js/missing_file_test.dart rename to tests/compiler/dart2js/old_frontend/missing_file_test.dart index e34315c..92c4891 100644 --- a/tests/compiler/dart2js/missing_file_test.dart +++ b/tests/compiler/dart2js/old_frontend/missing_file_test.dart
@@ -10,7 +10,7 @@ import 'package:async_helper/async_helper.dart'; import "package:compiler/src/diagnostics/messages.dart"; import 'package:expect/expect.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': '''
diff --git a/tests/compiler/dart2js/mixin_language_test.dart b/tests/compiler/dart2js/old_frontend/mixin_language_test.dart similarity index 100% rename from tests/compiler/dart2js/mixin_language_test.dart rename to tests/compiler/dart2js/old_frontend/mixin_language_test.dart
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/old_frontend/mock_compiler.dart similarity index 98% rename from tests/compiler/dart2js/mock_compiler.dart rename to tests/compiler/dart2js/old_frontend/mock_compiler.dart index 2f8e494..239aceb 100644 --- a/tests/compiler/dart2js/mock_compiler.dart +++ b/tests/compiler/dart2js/old_frontend/mock_compiler.dart
@@ -42,9 +42,9 @@ show AstDeferredLoadTask; import 'mock_libraries.dart'; -import 'diagnostic_helper.dart'; +import '../diagnostic_helper.dart'; -export 'diagnostic_helper.dart'; +export '../diagnostic_helper.dart'; final Uri PATCH_CORE = new Uri(scheme: 'patch', path: 'core'); @@ -372,7 +372,7 @@ } // TODO(herhut): Disallow warnings and errors during compilation by default. -MockCompiler compilerFor(String code, Uri uri, +MockCompiler mockCompilerFor(String code, Uri uri, {bool analyzeAll: false, bool analyzeOnly: false, Map<String, String> coreSource,
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/old_frontend/mock_libraries.dart similarity index 100% rename from tests/compiler/dart2js/mock_libraries.dart rename to tests/compiler/dart2js/old_frontend/mock_libraries.dart
diff --git a/tests/compiler/dart2js/no_such_method_codegen_test.dart b/tests/compiler/dart2js/old_frontend/no_such_method_codegen_test.dart similarity index 90% rename from tests/compiler/dart2js/no_such_method_codegen_test.dart rename to tests/compiler/dart2js/old_frontend/no_such_method_codegen_test.dart index b40d311..4c531f5 100644 --- a/tests/compiler/dart2js/no_such_method_codegen_test.dart +++ b/tests/compiler/dart2js/old_frontend/no_such_method_codegen_test.dart
@@ -11,7 +11,7 @@ // As a consequence, all operator[] had to be compiled, and due to // missing backend dependencies, some of them were not resolved. -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String TEST = ''' main() => foo[42]; @@ -19,6 +19,6 @@ main() { Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri); + var compiler = mockCompilerFor(TEST, uri); compiler.run(uri); }
diff --git a/tests/compiler/dart2js/null_is_bottom_test.dart b/tests/compiler/dart2js/old_frontend/null_is_bottom_test.dart similarity index 100% rename from tests/compiler/dart2js/null_is_bottom_test.dart rename to tests/compiler/dart2js/old_frontend/null_is_bottom_test.dart
diff --git a/tests/compiler/dart2js/options_helper.dart b/tests/compiler/dart2js/old_frontend/options_helper.dart similarity index 100% rename from tests/compiler/dart2js/options_helper.dart rename to tests/compiler/dart2js/old_frontend/options_helper.dart
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/old_frontend/override_inheritance_test.dart similarity index 99% rename from tests/compiler/dart2js/override_inheritance_test.dart rename to tests/compiler/dart2js/old_frontend/override_inheritance_test.dart index 1390b50..271b498 100644 --- a/tests/compiler/dart2js/override_inheritance_test.dart +++ b/tests/compiler/dart2js/old_frontend/override_inheritance_test.dart
@@ -4,7 +4,7 @@ import 'dart:async'; import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import 'package:compiler/src/resolution/class_members.dart' show MembersCreator; main() {
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/old_frontend/package_root_test.dart similarity index 96% rename from tests/compiler/dart2js/package_root_test.dart rename to tests/compiler/dart2js/old_frontend/package_root_test.dart index 1552a81..2e60fc9 100644 --- a/tests/compiler/dart2js/package_root_test.dart +++ b/tests/compiler/dart2js/old_frontend/package_root_test.dart
@@ -14,8 +14,8 @@ import 'package:compiler/src/diagnostics/messages.dart' show MessageKind; import 'package:package_config/packages.dart'; -import 'memory_compiler.dart'; -import 'memory_source_file_helper.dart'; +import '../memory_compiler.dart'; +import '../memory_source_file_helper.dart'; const MEMORY_SOURCE_FILES = const { 'main.dart': '''
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/old_frontend/parser_helper.dart similarity index 100% rename from tests/compiler/dart2js/parser_helper.dart rename to tests/compiler/dart2js/old_frontend/parser_helper.dart
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/old_frontend/parser_test.dart similarity index 100% rename from tests/compiler/dart2js/parser_test.dart rename to tests/compiler/dart2js/old_frontend/parser_test.dart
diff --git a/tests/compiler/dart2js/part_of_test.dart b/tests/compiler/dart2js/old_frontend/part_of_test.dart similarity index 100% rename from tests/compiler/dart2js/part_of_test.dart rename to tests/compiler/dart2js/old_frontend/part_of_test.dart
diff --git a/tests/compiler/dart2js/partial_parser_test.dart b/tests/compiler/dart2js/old_frontend/partial_parser_test.dart similarity index 100% rename from tests/compiler/dart2js/partial_parser_test.dart rename to tests/compiler/dart2js/old_frontend/partial_parser_test.dart
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/old_frontend/patch_test.dart similarity index 100% rename from tests/compiler/dart2js/patch_test.dart rename to tests/compiler/dart2js/old_frontend/patch_test.dart
diff --git a/tests/compiler/dart2js/platform_consistency_test.dart b/tests/compiler/dart2js/old_frontend/platform_consistency_test.dart similarity index 100% rename from tests/compiler/dart2js/platform_consistency_test.dart rename to tests/compiler/dart2js/old_frontend/platform_consistency_test.dart
diff --git a/tests/compiler/dart2js/private_test.dart b/tests/compiler/dart2js/old_frontend/private_test.dart similarity index 100% rename from tests/compiler/dart2js/private_test.dart rename to tests/compiler/dart2js/old_frontend/private_test.dart
diff --git a/tests/compiler/dart2js/proxy_test.dart b/tests/compiler/dart2js/old_frontend/proxy_test.dart similarity index 100% rename from tests/compiler/dart2js/proxy_test.dart rename to tests/compiler/dart2js/old_frontend/proxy_test.dart
diff --git a/tests/compiler/dart2js/reexport_handled_test.dart b/tests/compiler/dart2js/old_frontend/reexport_handled_test.dart similarity index 100% rename from tests/compiler/dart2js/reexport_handled_test.dart rename to tests/compiler/dart2js/old_frontend/reexport_handled_test.dart
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/old_frontend/related_types.dart similarity index 99% rename from tests/compiler/dart2js/related_types.dart rename to tests/compiler/dart2js/old_frontend/related_types.dart index 9ae51bc..9a64e22 100644 --- a/tests/compiler/dart2js/related_types.dart +++ b/tests/compiler/dart2js/old_frontend/related_types.dart
@@ -18,7 +18,7 @@ import 'package:compiler/src/universe/call_structure.dart'; import 'package:compiler/src/universe/selector.dart'; import 'package:compiler/src/world.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; main(List<String> arguments) async { if (arguments.isNotEmpty) {
diff --git a/tests/compiler/dart2js/related_types_test.dart b/tests/compiler/dart2js/old_frontend/related_types_test.dart similarity index 99% rename from tests/compiler/dart2js/related_types_test.dart rename to tests/compiler/dart2js/old_frontend/related_types_test.dart index ecc40d0..dda4a76 100644 --- a/tests/compiler/dart2js/related_types_test.dart +++ b/tests/compiler/dart2js/old_frontend/related_types_test.dart
@@ -11,7 +11,7 @@ import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/diagnostics/messages.dart'; import 'package:compiler/src/elements/elements.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; import 'related_types.dart';
diff --git a/tests/compiler/dart2js/resolution_test.dart b/tests/compiler/dart2js/old_frontend/resolution_test.dart similarity index 96% rename from tests/compiler/dart2js/resolution_test.dart rename to tests/compiler/dart2js/old_frontend/resolution_test.dart index 1d90607..ed0c2c9 100644 --- a/tests/compiler/dart2js/resolution_test.dart +++ b/tests/compiler/dart2js/old_frontend/resolution_test.dart
@@ -8,7 +8,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; import 'package:compiler/src/apiimpl.dart'; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const String NO_RUNTIME_TYPE = r""" import 'dart:core' as prefix; @@ -94,7 +94,7 @@ void test(String code, void check(CompilerImpl compiler)) { Uri uri = new Uri(scheme: 'source'); - dynamic compiler = compilerFor(code, uri); + dynamic compiler = mockCompilerFor(code, uri); asyncTest(() => compiler.run(uri).then((_) { check(compiler); }));
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/old_frontend/resolver_test.dart similarity index 99% rename from tests/compiler/dart2js/resolver_test.dart rename to tests/compiler/dart2js/old_frontend/resolver_test.dart index bf3427d..41a7f81 100644 --- a/tests/compiler/dart2js/resolver_test.dart +++ b/tests/compiler/dart2js/old_frontend/resolver_test.dart
@@ -20,8 +20,8 @@ import 'package:compiler/src/universe/use.dart'; import 'package:compiler/src/universe/world_impact.dart'; -import 'compiler_helper.dart'; -import 'link_helper.dart'; +import '../compiler_helper.dart'; +import '../link_helper.dart'; import 'parser_helper.dart'; Node buildIdentifier(String name) => new Identifier(scan(name)); @@ -1165,7 +1165,7 @@ Future compileScript(String source) { Uri uri = new Uri(scheme: 'source'); - MockCompiler compiler = compilerFor(source, uri); + MockCompiler compiler = mockCompilerFor(source, uri); compiler.diagnosticHandler = createHandler(compiler, source); return compiler.run(uri).then((_) { return compiler;
diff --git a/tests/compiler/dart2js/scanner_offset_length_test.dart b/tests/compiler/dart2js/old_frontend/scanner_offset_length_test.dart similarity index 100% rename from tests/compiler/dart2js/scanner_offset_length_test.dart rename to tests/compiler/dart2js/old_frontend/scanner_offset_length_test.dart
diff --git a/tests/compiler/dart2js/scanner_test.dart b/tests/compiler/dart2js/old_frontend/scanner_test.dart similarity index 100% rename from tests/compiler/dart2js/scanner_test.dart rename to tests/compiler/dart2js/old_frontend/scanner_test.dart
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/old_frontend/semantic_visitor_test.dart similarity index 99% rename from tests/compiler/dart2js/semantic_visitor_test.dart rename to tests/compiler/dart2js/old_frontend/semantic_visitor_test.dart index f6720b5..f72ea16 100644 --- a/tests/compiler/dart2js/semantic_visitor_test.dart +++ b/tests/compiler/dart2js/old_frontend/semantic_visitor_test.dart
@@ -22,7 +22,7 @@ import 'package:compiler/src/tree/tree.dart'; import 'package:compiler/src/universe/call_structure.dart' show CallStructure; import 'package:compiler/src/universe/selector.dart' show Selector; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; part 'semantic_visitor_test_send_data.dart'; part 'semantic_visitor_test_send_visitor.dart';
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/old_frontend/semantic_visitor_test_decl_data.dart similarity index 100% rename from tests/compiler/dart2js/semantic_visitor_test_decl_data.dart rename to tests/compiler/dart2js/old_frontend/semantic_visitor_test_decl_data.dart
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart b/tests/compiler/dart2js/old_frontend/semantic_visitor_test_decl_visitor.dart similarity index 100% rename from tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart rename to tests/compiler/dart2js/old_frontend/semantic_visitor_test_decl_visitor.dart
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/old_frontend/semantic_visitor_test_send_data.dart similarity index 100% rename from tests/compiler/dart2js/semantic_visitor_test_send_data.dart rename to tests/compiler/dart2js/old_frontend/semantic_visitor_test_send_data.dart
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart b/tests/compiler/dart2js/old_frontend/semantic_visitor_test_send_visitor.dart similarity index 100% rename from tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart rename to tests/compiler/dart2js/old_frontend/semantic_visitor_test_send_visitor.dart
diff --git a/tests/compiler/dart2js/size_test.dart b/tests/compiler/dart2js/old_frontend/size_test.dart similarity index 96% rename from tests/compiler/dart2js/size_test.dart rename to tests/compiler/dart2js/old_frontend/size_test.dart index 39bc9e9..af9817a 100644 --- a/tests/compiler/dart2js/size_test.dart +++ b/tests/compiler/dart2js/old_frontend/size_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 = "main() => [];";
diff --git a/tests/compiler/dart2js/space_test.dart b/tests/compiler/dart2js/old_frontend/space_test.dart similarity index 81% rename from tests/compiler/dart2js/space_test.dart rename to tests/compiler/dart2js/old_frontend/space_test.dart index 9146f27..0f01fab 100644 --- a/tests/compiler/dart2js/space_test.dart +++ b/tests/compiler/dart2js/old_frontend/space_test.dart
@@ -9,8 +9,8 @@ main() { Uri currentDirectory = Uri.base; Uri script = currentDirectory.resolveUri(Platform.script); - Uri libraryRoot = script.resolve('../../../sdk/'); - Directory.current = script.resolve("path with spaces").toFilePath(); + Uri libraryRoot = script.resolve('../../../../sdk/'); + Directory.current = script.resolve("../path with spaces").toFilePath(); return dart2js.main([ "--library-root=${libraryRoot.toFilePath()}",
diff --git a/tests/compiler/dart2js/tag_mapping_test.dart b/tests/compiler/dart2js/old_frontend/tag_mapping_test.dart similarity index 97% rename from tests/compiler/dart2js/tag_mapping_test.dart rename to tests/compiler/dart2js/old_frontend/tag_mapping_test.dart index 8080942..9eff042 100644 --- a/tests/compiler/dart2js/tag_mapping_test.dart +++ b/tests/compiler/dart2js/old_frontend/tag_mapping_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; const MAIN_CODE = """ import 'library.dart';
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/old_frontend/type_checker_test.dart similarity index 100% rename from tests/compiler/dart2js/type_checker_test.dart rename to tests/compiler/dart2js/old_frontend/type_checker_test.dart
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/old_frontend/type_equals_test.dart similarity index 98% rename from tests/compiler/dart2js/type_equals_test.dart rename to tests/compiler/dart2js/old_frontend/type_equals_test.dart index 45b36a0..f36b82e 100644 --- a/tests/compiler/dart2js/type_equals_test.dart +++ b/tests/compiler/dart2js/old_frontend/type_equals_test.dart
@@ -5,7 +5,7 @@ import "package:expect/expect.dart"; import "package:async_helper/async_helper.dart"; import 'package:compiler/src/elements/resolution_types.dart'; -import "compiler_helper.dart"; +import "../compiler_helper.dart"; test(compiler, String name1, String name2, {bool expect}) { Expect.isTrue((expect != null), 'required parameter "expect" not given'); @@ -53,7 +53,7 @@ void main() { var uri = new Uri(scheme: 'source'); - var compiler = compilerFor(r""" + var compiler = mockCompilerFor(r""" typedef int Typedef1<X,Y>(String s1); typedef void Typedef2<Z>(T t1, S s1);
diff --git a/tests/compiler/dart2js/type_order_test.dart b/tests/compiler/dart2js/old_frontend/type_order_test.dart similarity index 98% rename from tests/compiler/dart2js/type_order_test.dart rename to tests/compiler/dart2js/old_frontend/type_order_test.dart index 91b688b..be592dc 100644 --- a/tests/compiler/dart2js/type_order_test.dart +++ b/tests/compiler/dart2js/old_frontend/type_order_test.dart
@@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; import 'package:compiler/src/elements/resolution_types.dart'; import "package:compiler/src/elements/elements.dart" show ClassElement, TypedefElement;
diff --git a/tests/compiler/dart2js/type_promotion_test.dart b/tests/compiler/dart2js/old_frontend/type_promotion_test.dart similarity index 100% rename from tests/compiler/dart2js/type_promotion_test.dart rename to tests/compiler/dart2js/old_frontend/type_promotion_test.dart
diff --git a/tests/compiler/dart2js/type_variable_bound_test.dart b/tests/compiler/dart2js/old_frontend/type_variable_bound_test.dart similarity index 97% rename from tests/compiler/dart2js/type_variable_bound_test.dart rename to tests/compiler/dart2js/old_frontend/type_variable_bound_test.dart index c5d25f6..e01e18e 100644 --- a/tests/compiler/dart2js/type_variable_bound_test.dart +++ b/tests/compiler/dart2js/old_frontend/type_variable_bound_test.dart
@@ -4,13 +4,13 @@ import 'dart:async'; import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; +import '../compiler_helper.dart'; import "package:expect/expect.dart"; Future compile(String source) { Uri uri = Uri.parse('test:code'); - var compiler = - compilerFor(source, uri, analyzeOnly: true, enableTypeAssertions: true); + var compiler = mockCompilerFor(source, uri, + analyzeOnly: true, enableTypeAssertions: true); compiler.diagnosticHandler = createHandler(compiler, source); return compiler.run(uri).then((_) { return compiler;
diff --git a/tests/compiler/dart2js/type_variable_occurrence_test.dart b/tests/compiler/dart2js/old_frontend/type_variable_occurrence_test.dart similarity index 98% rename from tests/compiler/dart2js/type_variable_occurrence_test.dart rename to tests/compiler/dart2js/old_frontend/type_variable_occurrence_test.dart index 11b73b2..a85c307 100644 --- a/tests/compiler/dart2js/type_variable_occurrence_test.dart +++ b/tests/compiler/dart2js/old_frontend/type_variable_occurrence_test.dart
@@ -10,7 +10,7 @@ import 'package:compiler/src/elements/types.dart'; import 'package:expect/expect.dart'; -import 'type_test_helper.dart'; +import '../type_test_helper.dart'; void main() { testTypeVariableOccurrence();
diff --git a/tests/compiler/dart2js/unparser2_test.dart b/tests/compiler/dart2js/old_frontend/unparser2_test.dart similarity index 100% rename from tests/compiler/dart2js/unparser2_test.dart rename to tests/compiler/dart2js/old_frontend/unparser2_test.dart
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/old_frontend/unparser_test.dart similarity index 100% rename from tests/compiler/dart2js/unparser_test.dart rename to tests/compiler/dart2js/old_frontend/unparser_test.dart
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/old_frontend/warnings_checker.dart similarity index 98% rename from tests/compiler/dart2js/warnings_checker.dart rename to tests/compiler/dart2js/old_frontend/warnings_checker.dart index 9e98299..b974781 100644 --- a/tests/compiler/dart2js/warnings_checker.dart +++ b/tests/compiler/dart2js/old_frontend/warnings_checker.dart
@@ -9,7 +9,7 @@ import 'dart:io'; import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; -import 'memory_compiler.dart'; +import '../memory_compiler.dart'; import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/filenames.dart'; import 'package:compiler/src/io/source_file.dart';
diff --git a/tests/compiler/dart2js/output_type_test.dart b/tests/compiler/dart2js/output_type_test.dart index 915096e..85338dd 100644 --- a/tests/compiler/dart2js/output_type_test.dart +++ b/tests/compiler/dart2js/output_type_test.dart
@@ -37,9 +37,12 @@ CompileFunc oldCompileFunc; Future<Null> test(List<String> arguments, List<String> expectedOutput, - {List<String> groupOutputs: const <String>[]}) async { + {List<String> groupOutputs: const <String>[], bool useKernel}) async { List<String> options = new List<String>.from(arguments) - ..add("--library-root=${Platform.script.resolve('../../../sdk/')}"); + ..add("--library-root=${Uri.base.resolve('sdk/')}"); + if (useKernel) { + options.add(Flags.useKernel); + } print('--------------------------------------------------------------------'); print('dart2js ${options.join(' ')}'); TestRandomAccessFileOutputProvider outputProvider; @@ -64,13 +67,15 @@ Expect.notEquals(0, countBefore - outputs.length, 'Expected output group ${outputGroup}'); } - Expect.setEquals(expectedOutput, outputs); + Expect.setEquals(expectedOutput, outputs, + "Output mismatch. Expected $expectedOutput, actual $outputs."); } main() { enableWriteString = false; oldCompileFunc = compileFunc; - asyncTest(() async { + + runTests({bool useKernel}) async { PRINT_GRAPH = true; TRACE_FILTER_PATTERN_FOR_TEST = 'x'; await test([ @@ -86,27 +91,48 @@ 'dart.cfg', // From TRACE_FILTER_PATTERN_FOR_TEST ], groupOutputs: [ '.dot', // From PRINT_GRAPH - ]); + ], useKernel: useKernel); + PRINT_GRAPH = false; TRACE_FILTER_PATTERN_FOR_TEST = null; - await test([ - 'tests/compiler/dart2js/data/deferred_helper.dart', - Flags.useContentSecurityPolicy, - Flags.useMultiSourceInfo, - ], [ + List<String> additionOptionals = <String>[]; + List<String> expectedOutput = <String>[ 'out.js', 'out.js.map', - 'out.js.map.v2', 'out.js_1.part.js', 'out.js_1.part.js.map', - 'out.js_1.part.js.map.v2', - ]); - await test([ - 'tests/compiler/dart2js/data/deferred_helper.dart', - '--out=custom.data', - '--resolve-only', - ], [ - 'custom.data', - ]); + ]; + if (!useKernel) { + // Option --use-multi-source-info is only supported for the old frontend. + expectedOutput.add('out.js.map.v2'); + expectedOutput.add('out.js_1.part.js.map.v2'); + additionOptionals.add(Flags.useMultiSourceInfo); + } + + await test( + [ + 'tests/compiler/dart2js/data/deferred_helper.dart', + Flags.useContentSecurityPolicy, + ]..addAll(additionOptionals), + expectedOutput, + useKernel: useKernel); + + if (!useKernel) { + // Option --resolve-only is only supported for the old frontend. + await test([ + 'tests/compiler/dart2js/data/deferred_helper.dart', + '--out=custom.data', + '--resolve-only', + ], [ + 'custom.data', + ], useKernel: useKernel); + } + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/parameter_phi_elimination_test.dart b/tests/compiler/dart2js/parameter_phi_elimination_test.dart deleted file mode 100644 index a60d874..0000000 --- a/tests/compiler/dart2js/parameter_phi_elimination_test.dart +++ /dev/null
@@ -1,22 +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. - -// Regression test. Failed due to trying to detach an HLocal twice. - -// VMOptions=--enable_asserts - -import 'compiler_helper.dart'; - -const String SOURCE = r""" -bool baz(int a, int b) { - while (a == b || a < b) { - a = a + b; - } - return a == b; -} -"""; - -main() { - compile(SOURCE, entry: "baz"); -}
diff --git a/tests/compiler/dart2js/pretty_parameter_test.dart b/tests/compiler/dart2js/pretty_parameter_test.dart deleted file mode 100644 index e075e68..0000000 --- a/tests/compiler/dart2js/pretty_parameter_test.dart +++ /dev/null
@@ -1,104 +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. -// 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 FOO = r""" -void foo(var a, var b) { -} -"""; - -const String BAR = r""" -void bar(var eval, var $eval) { -} -"""; - -const String PARAMETER_AND_TEMP = r""" -void bar(var t0, var b) { - { - var t0 = 2; - if (b) { - bar(1, 2); - t0 = 4; - } else { - t0 = 3; - } - print(t0); - } - print(t0); -} -"""; - -const String NO_LOCAL = r""" -foo(bar, baz) { - if (bar) { - baz = 2; - } else { - baz = 3; - } - return baz; -} -"""; - -const String MULTIPLE_PHIS_ONE_LOCAL = r""" -foo(param1, param2, param3) { - var a = 2; - if (param1) { - if (param2) { - if (param3) { - a = 42; - } - print(a); - } - print(a); - } - print(a); -} -"""; - -const String PARAMETER_INIT = r""" -int foo(var start, bool test) { - var result = start; - if (test) { - foo(1, 2); - result = 42; - } - print(result); -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(FOO, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains(r"function(a, b) {")); - }), - compile(BAR, entry: 'bar', check: (String generated) { - Expect.isTrue(generated.contains(r"function($eval, $$eval) {")); - }), - compile(PARAMETER_AND_TEMP, entry: 'bar', check: (String generated) { - Expect.isTrue(generated.contains(r"print(t00)")); - // Check that the second 't0' got another name. - Expect.isTrue(generated.contains(r"print(t01)")); - }), - compile(MULTIPLE_PHIS_ONE_LOCAL, entry: 'foo', - check: (String generated) { - Expect.isTrue(generated.contains("var a;")); - // Check that there is only one var declaration. - checkNumberOfMatches( - new RegExp("var").allMatches(generated).iterator, 1); - }), - compile(NO_LOCAL, entry: 'foo', check: (String generated) { - Expect.isFalse(generated.contains('var')); - }), - compile(PARAMETER_INIT, entry: 'foo', check: (String generated) { - // Check that there is only one var declaration. - checkNumberOfMatches( - new RegExp("var").allMatches(generated).iterator, 1); - }), - ])); -}
diff --git a/tests/compiler/dart2js/quarantined/http_test.dart b/tests/compiler/dart2js/quarantined/http_test.dart index d28805f..309fc5f 100644 --- a/tests/compiler/dart2js/quarantined/http_test.dart +++ b/tests/compiler/dart2js/quarantined/http_test.dart
@@ -15,7 +15,7 @@ import 'package:expect/expect.dart'; import 'package:path/path.dart' as path; -import '../launch_helper.dart' show launchDart2Js; +import '../end_to_end/launch_helper.dart' show launchDart2Js; Uri pathOfData = Platform.script.resolve('http_launch_data/'); Directory tempDir;
diff --git a/tests/compiler/dart2js/receiver_type_test.dart b/tests/compiler/dart2js/receiver_type_test.dart index aeb6e81..c408182 100644 --- a/tests/compiler/dart2js/receiver_type_test.dart +++ b/tests/compiler/dart2js/receiver_type_test.dart
@@ -13,7 +13,9 @@ main() { asyncTest(() async { + print('--test from ast---------------------------------------------------'); await runTest(CompileMode.memory); + print('--test from kernel------------------------------------------------'); await runTest(CompileMode.kernel); }); }
diff --git a/tests/compiler/dart2js/redundant_phi_eliminator_test.dart b/tests/compiler/dart2js/redundant_phi_eliminator_test.dart deleted file mode 100644 index da81d94..0000000 --- a/tests/compiler/dart2js/redundant_phi_eliminator_test.dart +++ /dev/null
@@ -1,44 +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 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -void foo(bar) { - var toBeRemoved = 1; - if (bar) { - } else { - } - print(toBeRemoved); -} -"""; - -const String TEST_TWO = r""" -void foo() { - var temp = 0; - var toBeRemoved = temp; - for (var i = 0; i == 0; i = i + 1) { - toBeRemoved = temp; - } - print(toBeRemoved); -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(TEST_ONE, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp("toBeRemoved"); - Expect.isTrue(!regexp.hasMatch(generated)); - }), - compile(TEST_TWO, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp("toBeRemoved"); - Expect.isTrue(!regexp.hasMatch(generated)); - regexp = new RegExp("temp"); - Expect.isTrue(!regexp.hasMatch(generated)); - }), - ])); -}
diff --git a/tests/compiler/dart2js/regress_10231_test.dart b/tests/compiler/dart2js/regress_10231_test.dart deleted file mode 100644 index 9031931..0000000 --- a/tests/compiler/dart2js/regress_10231_test.dart +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Regression test for http://dartbug.com/10231. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'codegen_helper.dart'; - -void main() { - asyncTest(() => generate(SOURCE).then((result) { - var code = result['test']; - Expect.isNotNull(code); - Expect.equals(0, new RegExp('add').allMatches(code).length); - Expect.equals(3, new RegExp('\\+').allMatches(code).length); - })); -} - -const String SOURCE = """ -test(a, b, c, d) { - if (a is !num) throw 'a not num'; - if (b is !num) throw 'b not num'; - if (c is !num) throw 'c not num'; - if (d is !num) throw 'd not num'; - return a + b + c + d; -} - -main() { - test(1, 2, 3, 4); - test('x', 'y', 'z', 'w'); - test([], {}, [], {}); -} -""";
diff --git a/tests/compiler/dart2js/side_effect_tdiv_regression_test.dart b/tests/compiler/dart2js/side_effect_tdiv_regression_test.dart deleted file mode 100644 index 8db68c8..0000000 --- a/tests/compiler/dart2js/side_effect_tdiv_regression_test.dart +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; - -import 'compiler_helper.dart'; - -const String TEST = r''' -class A { - var field = 42; -} -main() { - var a = new A(); - var b = [42, -1]; - // Force a setter on [field]. - if (false) a.field = 12; - var c = a.field; - print(b[0] ~/ b[1]); - return c + a.field; -} -'''; - -void main() { - asyncTest(() => compileAll(TEST).then((generated) { - Expect.isTrue(generated.contains('return c + c;')); - })); -}
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart index ef9957d..70a70c1 100644 --- a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart +++ b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_helper.dart
@@ -315,26 +315,31 @@ if (options.contains(Flags.disableInlining)) { if (verbose) print('Inlining disabled'); } - api.CompilerImpl compiler = await compilerFor( + CompilationResult result = await runCompiler( + entryPoint: inputUri, outputProvider: outputProvider, // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics. options: ['--out=$targetUri', '--source-map=$sourceMapFileUri'] - ..addAll(options)); - - JavaScriptBackend backend = compiler.backend; - dynamic handler = compiler.handler; - SourceFileProvider sourceFileProvider = handler.provider; - sourceFileManager = - new ProviderSourceFileManager(sourceFileProvider, outputProvider); - RecordingSourceInformationStrategy strategy = - new RecordingSourceInformationStrategy( - backend.sourceInformationStrategy); - backend.sourceInformationStrategy = strategy; - await compiler.run(inputUri); - if (compiler.compilationFailed) { + ..addAll(options), + beforeRun: (compiler) { + JavaScriptBackend backend = compiler.backend; + dynamic handler = compiler.handler; + SourceFileProvider sourceFileProvider = handler.provider; + sourceFileManager = + new ProviderSourceFileManager(sourceFileProvider, outputProvider); + RecordingSourceInformationStrategy strategy = + new RecordingSourceInformationStrategy( + backend.sourceInformationStrategy); + backend.sourceInformationStrategy = strategy; + }); + if (!result.isSuccess) { throw "Compilation failed."; } + api.CompilerImpl compiler = result.compiler; + JavaScriptBackend backend = compiler.backend; + RecordingSourceInformationStrategy strategy = + backend.sourceInformationStrategy; SourceMapInfo mainSourceMapInfo; Map<MemberEntity, SourceMapInfo> elementSourceMapInfos = <MemberEntity, SourceMapInfo>{}; @@ -509,7 +514,8 @@ .trim(); } - void addLocation(SourceLocation sourceLocation, String jsCode) { + void addLocation( + SourceLocation sourceLocation, String jsCode, int targetOffset) { if (sourceLocation == null) { if (expectInfo) { SourceInformation sourceInformation = node.sourceInformation; @@ -519,23 +525,24 @@ sourceLocation = sourceInformation.sourceLocations.first; dartCode = dartCodeFromSourceLocation(sourceLocation); } - codePoints.add(new CodePoint(kind, jsCode, sourceLocation, dartCode, + codePoints.add(new CodePoint( + kind, jsCode, targetOffset, sourceLocation, dartCode, isMissing: true)); } } else { - codePoints.add(new CodePoint(kind, jsCode, sourceLocation, + codePoints.add(new CodePoint(kind, jsCode, targetOffset, sourceLocation, dartCodeFromSourceLocation(sourceLocation))); } } Map<int, List<SourceLocation>> locationMap = nodeMap[node]; if (locationMap == null) { - addLocation(null, nodeToString(node)); + addLocation(null, nodeToString(node), null); } else { locationMap.forEach((int targetOffset, List<SourceLocation> locations) { String jsCode = nodeToString(node); for (SourceLocation location in locations) { - addLocation(location, jsCode); + addLocation(location, jsCode, targetOffset); } }); } @@ -546,11 +553,13 @@ class CodePoint { final StepKind kind; final String jsCode; + final int targetOffset; final SourceLocation sourceLocation; final String dartCode; final bool isMissing; - CodePoint(this.kind, this.jsCode, this.sourceLocation, this.dartCode, + CodePoint(this.kind, this.jsCode, this.targetOffset, this.sourceLocation, + this.dartCode, {this.isMissing: false}); String toString() {
diff --git a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_html_helper.dart b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_html_helper.dart index 10259db..e4b8c95 100644 --- a/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_html_helper.dart +++ b/tests/compiler/dart2js/sourcemaps/helpers/sourcemap_html_helper.dart
@@ -623,7 +623,7 @@ buffer.write('<tr>'); } buffer.write('<td>${codePoint.kind}</td>'); - buffer.write('<td class="code">${jsCode}</td>'); + buffer.write('<td class="code">${codePoint.targetOffset}:${jsCode}</td>'); if (codePoint.sourceLocation == null) { //buffer.write('<td></td>'); } else {
diff --git a/tests/compiler/dart2js/location_collector_test.dart b/tests/compiler/dart2js/sourcemaps/location_collector_test.dart similarity index 98% rename from tests/compiler/dart2js/location_collector_test.dart rename to tests/compiler/dart2js/sourcemaps/location_collector_test.dart index d34f636..f044fba 100644 --- a/tests/compiler/dart2js/location_collector_test.dart +++ b/tests/compiler/dart2js/sourcemaps/location_collector_test.dart
@@ -9,7 +9,7 @@ import 'package:expect/expect.dart'; import 'package:kernel/ast.dart' show Location; -import 'output_collector.dart'; +import '../output_collector.dart'; test(List events, Map<int, List<int>> expectedPositions) { BufferedOutputSink sink = new BufferedOutputSink();
diff --git a/tests/compiler/dart2js/sourcemaps/source_mapping2_test.dart b/tests/compiler/dart2js/sourcemaps/source_mapping2_test.dart index 4076263..bd74cbe 100644 --- a/tests/compiler/dart2js/sourcemaps/source_mapping2_test.dart +++ b/tests/compiler/dart2js/sourcemaps/source_mapping2_test.dart
@@ -12,9 +12,9 @@ import 'package:compiler/src/js_emitter/full_emitter/emitter.dart' as full show Emitter; -import '../mock_compiler.dart'; +import '../old_frontend/mock_compiler.dart'; -Future<CodeBuffer> compileAll(SourceFile sourceFile) { +Future<CodeOutput> compileAll(SourceFile sourceFile) { MockCompiler compiler = new MockCompiler.internal(); Uri uri = new Uri(path: sourceFile.filename); compiler.sourceFiles[uri.toString()] = sourceFile; @@ -23,8 +23,6 @@ // TODO(floitsch): the outputBuffers are only accessible in the full // emitter. full.Emitter fullEmitter = backend.emitter.emitter; - // CodeOutput isn't assignable to CodeBuffer. - // ignore: RETURN_OF_INVALID_TYPE_FROM_CLOSURE return fullEmitter .outputBuffers[compiler.backend.outputUnitData.mainOutputUnit]; });
diff --git a/tests/compiler/dart2js/sourcemaps/stepping/print.dart b/tests/compiler/dart2js/sourcemaps/stepping/print.dart new file mode 100644 index 0000000..934bbc9 --- /dev/null +++ b/tests/compiler/dart2js/sourcemaps/stepping/print.dart
@@ -0,0 +1,9 @@ +// 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. + +main() { + /*bl*/ + /*s:1*/ print("Hello, World!"); +/*s:2*/ +}
diff --git a/tests/compiler/dart2js/sourcemaps/stepping/print_class_fields.dart b/tests/compiler/dart2js/sourcemaps/stepping/print_class_fields.dart new file mode 100644 index 0000000..dec796a --- /dev/null +++ b/tests/compiler/dart2js/sourcemaps/stepping/print_class_fields.dart
@@ -0,0 +1,33 @@ +// 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. + +/*Debugger:stepOver*/ +main() { + /*bl*/ + Foo foo = new /*s:1*/ Foo(1, 2); + /*s:2*/ print(foo.x); + /*s:3*/ print(foo.y); + /*s:4*/ print(foo.z); + + foo = new /*s:5*/ Foo.named(); + /*s:6*/ print(foo.x); + /*s:7*/ print(foo.y); + /*s:8*/ print(foo.z); +} + +class Foo { + var x, y, z; + + Foo(a, b) + : this.x = a, + this.y = b { + z = a + b; + } + + Foo.named() + : this.x = 42, + this.y = 88 { + z = 28; + } +}
diff --git a/tests/compiler/dart2js/sourcemaps/stepping/print_top_level_invoke.dart b/tests/compiler/dart2js/sourcemaps/stepping/print_top_level_invoke.dart new file mode 100644 index 0000000..147fa73 --- /dev/null +++ b/tests/compiler/dart2js/sourcemaps/stepping/print_top_level_invoke.dart
@@ -0,0 +1,12 @@ +// 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. + +main() { + print(/*bc:1*/ foo()); +} + +foo() { + /*s:2*/ return "foo!"; +/*s:3*/ +}
diff --git a/tests/compiler/dart2js/sourcemaps/stepping/top_level_invoke.dart b/tests/compiler/dart2js/sourcemaps/stepping/top_level_invoke.dart new file mode 100644 index 0000000..7108d8e --- /dev/null +++ b/tests/compiler/dart2js/sourcemaps/stepping/top_level_invoke.dart
@@ -0,0 +1,14 @@ +// 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. + +main() { + /*bl*/ + /*s:1*/ foo(); +/*s:4*/ +} + +foo() { + /*s:2*/ print("hello"); +/*s:3*/ +}
diff --git a/tests/compiler/dart2js/sourcemaps/stepping_test.dart b/tests/compiler/dart2js/sourcemaps/stepping_test.dart new file mode 100644 index 0000000..a0bf75e --- /dev/null +++ b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
@@ -0,0 +1,96 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:async_helper/async_helper.dart'; +import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; +import 'package:compiler/src/dart2js.dart' as entry; +import 'package:expect/expect.dart'; +import 'package:sourcemap_testing/src/annotated_code_helper.dart'; +import 'package:sourcemap_testing/src/stepping_helper.dart'; + +void main(List<String> args) { + ArgParser argParser = new ArgParser(allowTrailingOptions: true); + argParser.addFlag('debug', abbr: 'd', defaultsTo: false); + argParser.addFlag('verbose', abbr: 'v', defaultsTo: false); + argParser.addFlag('continued', abbr: 'c', defaultsTo: false); + ArgResults argResults = argParser.parse(args); + Directory dataDir = + new Directory.fromUri(Platform.script.resolve('stepping')); + asyncTest(() async { + bool continuing = false; + await for (FileSystemEntity entity in dataDir.list()) { + String name = entity.uri.pathSegments.last; + if (argResults.rest.isNotEmpty && + !argResults.rest.contains(name) && + !continuing) { + continue; + } + print('----------------------------------------------------------------'); + print('Checking ${entity.uri}'); + print('----------------------------------------------------------------'); + String annotatedCode = await new File.fromUri(entity.uri).readAsString(); + await testAnnotatedCode(annotatedCode, + verbose: argResults['verbose'], debug: argResults['debug']); + if (argResults['continued']) { + continuing = true; + } + } + }); +} + +const String astMarker = 'ast.'; +const String kernelMarker = 'kernel.'; + +Future testAnnotatedCode(String code, + {bool debug: false, bool verbose: false}) async { + AnnotatedCode annotatedCode = + new AnnotatedCode.fromText(code, commentStart, commentEnd); + print(annotatedCode.sourceCode); + Map<String, AnnotatedCode> split = + splitByPrefixes(annotatedCode, [astMarker, kernelMarker]); + print('---from ast---------------------------------------------------------'); + await runTest(split[astMarker], astMarker, debug: debug, verbose: verbose); + print('---from kernel------------------------------------------------------'); + await runTest(split[kernelMarker], kernelMarker, + debug: debug, verbose: verbose); +} + +Future runTest(AnnotatedCode annotatedCode, String config, + {bool debug: false, + bool verbose: false, + List<String> options: const <String>[]}) async { + Directory dir = Directory.systemTemp.createTempSync('stepping_test'); + String path = dir.path; + String inputFile = '$path/test.dart'; + new File(inputFile).writeAsStringSync(annotatedCode.sourceCode); + String outputFile = '$path/js.js'; + List<String> arguments = <String>[ + '--out=$outputFile', + inputFile, + Flags.disableInlining, + ]; + if (config == kernelMarker) { + arguments.add(Flags.useKernel); + } else { + arguments.add(Flags.useNewSourceInfo); + } + CompilationResult compilationResult = await entry.internalMain(arguments); + Expect.isTrue(compilationResult.isSuccess); + List<String> scriptD8Command = [ + 'sdk/lib/_internal/js_runtime/lib/preambles/d8.js', + outputFile + ]; + ProcessResult result = runD8AndStep(dir.path, annotatedCode, scriptD8Command); + List<String> d8output = result.stdout.split("\n"); + if (verbose) { + d8output.forEach(print); + } + checkD8Steps(dir.path, d8output, annotatedCode, debug: debug); + dir.deleteSync(recursive: true); +}
diff --git a/tests/compiler/dart2js/ssa_phi_codegen_test.dart b/tests/compiler/dart2js/ssa_phi_codegen_test.dart deleted file mode 100644 index 57ee1b0..0000000 --- a/tests/compiler/dart2js/ssa_phi_codegen_test.dart +++ /dev/null
@@ -1,91 +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:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -void foo(bar) { - var a = 1; - if (bar) { - a = 2; - } else { - a = 3; - } - print(a); - print(a); -} -"""; - -const String TEST_TWO = r""" -void main() { - var t = 0; - for (var i = 0; i == 0; i = i + 1) { - t = t + 10; - } - print(t); -} -"""; - -const String TEST_THREE = r""" -foo(b, c, d) { - var val = 42; - if (b) { - c = c && d; - if (c) { - val = 43; - } - } - return val; -} -"""; - -const String TEST_FOUR = r""" -foo() { - var a = true; - var b = false; - for (var i = 0; a; i = i + 1) { - if (i == 9) a = false; - for (var j = 0; b; j = j + 1) { - if (j == 9) b = false; - } - } - print(a); - print(b); -} -"""; - -const String TEST_FIVE = r""" -void main() { - var hash = 0; - for (var i = 0; i == 0; i = i + 1) { - hash = hash + 10; - hash = hash + 42; - } - print(t); -} -"""; - -main() { - asyncTest(() => Future.wait([ - compileAndMatchFuzzy(TEST_ONE, 'foo', "var x = x === true \\? 2 : 3;"), - compileAndMatchFuzzy(TEST_ONE, 'foo', "print\\(x\\);"), - - compileAndMatchFuzzy(TEST_TWO, 'main', "x \\+= 10"), - compileAndMatchFuzzy(TEST_TWO, 'main', "\\+\\+x"), - - // Check that we don't have 'd = d' (using regexp back references). - compileAndDoNotMatchFuzzy(TEST_THREE, 'foo', '(x) = \1'), - compileAndMatchFuzzy(TEST_THREE, 'foo', 'return x'), - // Check that a store just after the declaration of the local - // only generates one instruction. - compileAndMatchFuzzy(TEST_THREE, 'foo', 'x = 42'), - - compileAndDoNotMatchFuzzy(TEST_FOUR, 'foo', '(x) = \1;'), - - compileAndDoNotMatch(TEST_FIVE, 'main', new RegExp('hash0')), - ])); -}
diff --git a/tests/compiler/dart2js/static_closure_test.dart b/tests/compiler/dart2js/static_closure_test.dart deleted file mode 100644 index f242806..0000000 --- a/tests/compiler/dart2js/static_closure_test.dart +++ /dev/null
@@ -1,25 +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 static functions are closurized as expected. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -main() { - asyncTest(() => compileAll(r'''main() { print(main); }''').then((code) { - // At some point, we will have to closurize global functions - // differently, at which point this test will break. Then it is time - // to implement a way to call a Dart closure from JS foreign - // functions. - - // If this test fail, please take a look at the use of - // toStringWrapper in captureStackTrace in js_helper.dart. - Expect.isTrue( - code.contains( - new RegExp(r'print\([$A-Z]+\.lib___main\$closure\(\)\);')), - code); - })); -}
diff --git a/tests/compiler/dart2js/strength_eq_test.dart b/tests/compiler/dart2js/strength_eq_test.dart deleted file mode 100644 index ffc082e..0000000 --- a/tests/compiler/dart2js/strength_eq_test.dart +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Test constant folding on numbers. - -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String CODE = """ -class A { - var link; -} -int foo(x) { - if (new DateTime.now().millisecondsSinceEpoch == 42) return null; - var a = new A(); - if (new DateTime.now().millisecondsSinceEpoch == 42) return a; - a.link = a; - return a; -} -void main() { - var x = foo(0); - return x == x.link; -} -"""; - -main() { - // The `==` is strengthened to a HIdentity instruction. The HIdentity follows - // `x.link`, so x cannot be `null`. - var compare = new RegExp(r'x === x\.get\$link\(\)'); - asyncTest(() => compileAndMatch(CODE, 'main', compare)); -}
diff --git a/tests/compiler/dart2js/string_add_test.dart b/tests/compiler/dart2js/string_add_test.dart deleted file mode 100644 index 0a045c7..0000000 --- a/tests/compiler/dart2js/string_add_test.dart +++ /dev/null
@@ -1,14 +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. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -main() { - asyncTest( - () => compileAll(r'''main() { return "foo" + "bar"; }''').then((code) { - Expect.isTrue(!code.contains(r'$add')); - })); -}
diff --git a/tests/compiler/dart2js/string_escapes_test.dart b/tests/compiler/dart2js/string_escapes_test.dart deleted file mode 100644 index b792e7d..0000000 --- a/tests/compiler/dart2js/string_escapes_test.dart +++ /dev/null
@@ -1,72 +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 'dart:async'; -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'compiler_helper.dart'; - -// Test that the compiler handles string literals containing line terminators. - -Future<String> compileExpression(String expression) { - var source = "foo() { return $expression; }"; - return compile(source, entry: "foo"); -} - -main() { - asyncTest(() => Future.wait([ - compileExpression("''' \n\r\u2028\u2029'''").then((String generated) { - Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || - generated.contains(r"'\r\u2028\u2029'")); - }), - compileExpression("r''' \n\r\u2028\u2029'''").then((String generated) { - Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || - generated.contains(r"'\r\u2028\u2029'")); - }), - compileExpression("r''' \r\n\u2028\u2029'''").then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - compileExpression("r''' \r\u2028\u2029'''").then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - compileExpression("r''' \n\u2028\u2029'''").then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - compileExpression("r'''\t\t \t\t \t\t \t \t \n\r\u2028\u2029'''") - .then((String generated) { - Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || - generated.contains(r"'\r\u2028\u2029'")); - }), - compileExpression( - "r'''\\\t\\\t \\ \\ \t\\\t \t \\\n\r\u2028\u2029'''") - .then((String generated) { - Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || - generated.contains(r"'\r\u2028\u2029'")); - }), - compileExpression( - "r'''\t\t \t\t \t\t \t \t \\\n\r\u2028\u2029'''") - .then((String generated) { - Expect.isTrue(generated.contains(r'"\r\u2028\u2029"') || - generated.contains(r"'\r\u2028\u2029'")); - }), - compileExpression( - "r'''\\\t\\\t \\ \\ \t\\\t \\\r\n\u2028\u2029'''") - .then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - compileExpression("r'''\\\t\\\t \\ \\ \t\\\t \\\r\u2028\u2029'''") - .then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - compileExpression("'\u2028\u2029'").then((String generated) { - Expect.isTrue(generated.contains(r'"\u2028\u2029"') || - generated.contains(r"'\u2028\u2029'")); - }), - ])); -}
diff --git a/tests/compiler/dart2js/string_interpolation_test.dart b/tests/compiler/dart2js/string_interpolation_test.dart deleted file mode 100644 index ae49b85..0000000 --- a/tests/compiler/dart2js/string_interpolation_test.dart +++ /dev/null
@@ -1,20 +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. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -main() { - asyncTest(() => - compileAll(r'''main() { return "${2}${true}${'a'}${3.14}"; }''') - .then((code) { - Expect.isTrue(code.contains(r'2truea3.14')); - })); - - asyncTest(() => - compileAll(r'''main() { return "foo ${new Object()}"; }''').then((code) { - Expect.isFalse(code.contains(r'$add')); - })); -}
diff --git a/tests/compiler/dart2js/subtype_test.dart b/tests/compiler/dart2js/subtype_test.dart index 7f0c366..719a484 100644 --- a/tests/compiler/dart2js/subtype_test.dart +++ b/tests/compiler/dart2js/subtype_test.dart
@@ -14,7 +14,9 @@ void main() { asyncTest(() async { + print('--test from ast---------------------------------------------------'); await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); await runTests(CompileMode.kernel); }); }
diff --git a/tests/compiler/dart2js/subtypeset_test.dart b/tests/compiler/dart2js/subtypeset_test.dart index 780d0ca..9a43016 100644 --- a/tests/compiler/dart2js/subtypeset_test.dart +++ b/tests/compiler/dart2js/subtypeset_test.dart
@@ -9,12 +9,21 @@ import 'package:expect/expect.dart'; import 'package:async_helper/async_helper.dart'; import 'type_test_helper.dart'; -import 'package:compiler/src/elements/elements.dart' show ClassElement; +import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/universe/class_set.dart'; import 'package:compiler/src/world.dart'; void main() { - asyncTest(() => TypeEnvironment.create(r""" + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); + }); +} + +runTests(CompileMode compileMode) async { + var env = await TypeEnvironment.create(r""" /// A /// / \ /// B C @@ -34,45 +43,44 @@ class I implements H {} """, mainSource: r""" main() { - new A(); + new A().call; new C(); new D(); new E(); new F(); new G(); } - """, compileMode: CompileMode.memory).then((env) { - ClosedWorld world = env.closedWorld; + """, compileMode: compileMode); + ClosedWorld world = env.closedWorld; - ClassElement A = env.getElement("A"); - ClassElement B = env.getElement("B"); - ClassElement C = env.getElement("C"); - ClassElement D = env.getElement("D"); - ClassElement E = env.getElement("E"); - ClassElement F = env.getElement("F"); - ClassElement G = env.getElement("G"); - ClassElement H = env.getElement("H"); - ClassElement I = env.getElement("I"); + ClassEntity A = env.getElement("A"); + ClassEntity B = env.getElement("B"); + ClassEntity C = env.getElement("C"); + ClassEntity D = env.getElement("D"); + ClassEntity E = env.getElement("E"); + ClassEntity F = env.getElement("F"); + ClassEntity G = env.getElement("G"); + ClassEntity H = env.getElement("H"); + ClassEntity I = env.getElement("I"); - void checkClass(ClassElement cls, List<ClassElement> subtypes) { - ClassSet node = world.getClassSet(cls); - print('$cls:\n${node}'); - Expect.listEquals( - subtypes, - node.subtypes().toList(), - "Unexpected subtypes of ${cls.name}:\n" - "Expected: $subtypes\n" - "Found : ${node.subtypes().toList()}"); - } + void checkClass(ClassEntity cls, List<ClassEntity> subtypes) { + ClassSet node = world.getClassSet(cls); + print('$cls:\n${node}'); + Expect.setEquals( + subtypes, + node.subtypes().toList(), + "Unexpected subtypes of ${cls.name}:\n" + "Expected: $subtypes\n" + "Found : ${node.subtypes().toList()}"); + } - checkClass(A, [A, C, E, F, G, B, D, H, I]); - checkClass(B, [B, D, E]); - checkClass(C, [C, E, F, G, H, B, D, I]); - checkClass(D, [D]); - checkClass(E, [E]); - checkClass(F, [F]); - checkClass(G, [G]); - checkClass(H, [H, I]); - checkClass(I, [I]); - })); + checkClass(A, [A, C, E, F, G, B, D, H, I]); + checkClass(B, [B, D, E]); + checkClass(C, [C, E, F, G, H, B, D, I]); + checkClass(D, [D]); + checkClass(E, [E]); + checkClass(F, [F]); + checkClass(G, [G]); + checkClass(H, [H, I]); + checkClass(I, [I]); }
diff --git a/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart b/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart deleted file mode 100644 index 158a1bc..0000000 --- a/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -main() { - var f = use; - if (false) { - // This statement and the use of 'foo' should be optimized away, causing - // 'foo' to be absent from the final code. - f(foo); - } - f(bar); -} - -foo() => 'Tarantula!'; -bar() => 'Coelacanth!'; - -use(x) { - print(x()); -} -"""; - -main() { - asyncTest(() => Future.wait([ - compileAll(TEST_ONE).then((String generated) { - Expect.isFalse( - generated.contains('Tarantula!'), "failed to remove 'foo'"); - Expect.isTrue(generated.contains('Coelacanth!')); - }), - ])); -}
diff --git a/tests/compiler/dart2js/tree_shaking_test.dart b/tests/compiler/dart2js/tree_shaking_test.dart deleted file mode 100644 index ceec29c..0000000 --- a/tests/compiler/dart2js/tree_shaking_test.dart +++ /dev/null
@@ -1,34 +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. - -import "package:expect/expect.dart"; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST = r""" -class A { - foo() => bar(); - bar() => 42; -} -class B extends A { - bar() => 54; -} -class C implements A { - bar() => 68; -} -main() { - new A(); - new B(); - new C(); - new A().foo(); -} -"""; - -void main() { - asyncTest(() => compileAll(TEST).then((generated) { - Expect.isTrue(generated.contains('return 42')); - Expect.isTrue(generated.contains('return 54')); - Expect.isFalse(generated.contains('return 68')); - })); -}
diff --git a/tests/compiler/dart2js/trust_type_annotations2_test.dart b/tests/compiler/dart2js/trust_type_annotations2_test.dart deleted file mode 100644 index 71ad9ca..0000000 --- a/tests/compiler/dart2js/trust_type_annotations2_test.dart +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; - -const MEMORY_SOURCE_FILES = const { - 'main.dart': ''' - -foo(int x, int y) { - return x + y; -} - -main (x, y) { - if (x != null) { - if (y != null) { - return foo(x, y); - } - } -} -''', -}; - -main() { - asyncTest(() async { - var result = await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, - options: ['--trust-type-annotations']); - var compiler = result.compiler; - var element = compiler.frontendStrategy.elementEnvironment.mainFunction; - var code = compiler.backend.getGeneratedCode(element); - Expect.isTrue(code.contains('+'), code); - }); -}
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart deleted file mode 100644 index a804f0e..0000000 --- a/tests/compiler/dart2js/trust_type_annotations_test.dart +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST = """ -class A { - int aField; - - A(this.aField); - - // Test return type annotation. - int foo(a) => a; - // Test parameter type annotation. - faa (int a) => a; - // Test annotations on locals. - baz(x) { - int y = x; - return y; - } - // Test tear-off closure type annotations. - int bar(x) => x; - int tear(x) { - var torn = bar; - // Have torn escape through closure to disable tracing. - var fail = (() => torn)(); - return fail(x); - } -} - -main () { - var a = new A("42"); - print(a.aField); - print(a.foo("42")); - print(a.foo(42)); - print(a.faa("42")); - print(a.faa(42)); - print(a.baz("42")); - print(a.baz(42)); - // Test trusting types of tear off closures. - print(a.tear("42")); - print(a.tear(42)); -} -"""; - -void main() { - Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(TEST, uri, trustTypeAnnotations: true); - asyncTest(() => compiler.run(uri).then((_) { - var typesInferrer = compiler.globalInference.typesInferrerInternal; - var closedWorld = typesInferrer.closedWorld; - - ClassElement classA = findElement(compiler, "A"); - - checkReturn(String name, TypeMask type) { - MemberElement element = classA.lookupMember(name); - var mask = typesInferrer.getReturnTypeOfMember(element); - Expect.isTrue(type.containsMask(mask, closedWorld)); - } - - checkType(String name, type) { - MemberElement element = classA.lookupMember(name); - Expect.isTrue(type.containsMask( - typesInferrer.getTypeOfMember(element), closedWorld)); - } - - var intMask = new TypeMask.subtype( - closedWorld.commonElements.intClass, closedWorld); - - checkReturn('foo', intMask); - checkReturn('faa', intMask); - checkType('aField', intMask); - checkReturn('bar', intMask); - checkReturn('baz', intMask); - checkReturn('tear', intMask); - })); -}
diff --git a/tests/compiler/dart2js/type_guard_unuser_test.dart b/tests/compiler/dart2js/type_guard_unuser_test.dart deleted file mode 100644 index e2e100e..0000000 --- a/tests/compiler/dart2js/type_guard_unuser_test.dart +++ /dev/null
@@ -1,72 +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 'dart:async'; -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -foo(a) { - int b = foo(true); - if (a) b = foo(2); - return b; -} -"""; - -const String TEST_TWO = r""" -bar(a) {} -foo(d) { - int a = 1; - int c = foo(1); - if (true) {} - return a + c; -} -"""; - -const String TEST_THREE = r""" -foo(int a, int b) { - return 0 + a + b; -} -"""; - -const String TEST_THREE_WITH_BAILOUT = r""" -foo(int a, int b) { - var t; - for (int i = 0; i < 1; i++) { - t = 0 + a + b; - } - return t; -} -"""; - -main() { - asyncTest(() => Future.wait([ - compile(TEST_ONE, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp(getIntTypeCheck(anyIdentifier)); - Iterator<Match> matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 0); - Expect.isTrue(generated.contains( - new RegExp(r'return a === true \? [$A-Z]+\.foo\(2\) : b;'))); - }), - compile(TEST_TWO, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp("foo\\(1\\)"); - Iterator<Match> matches = regexp.allMatches(generated).iterator; - checkNumberOfMatches(matches, 1); - }), - compile(TEST_THREE, entry: 'foo', check: (String generated) { - RegExp regexp = new RegExp(getNumberTypeCheck('a')); - Expect.isTrue(regexp.hasMatch(generated)); - regexp = new RegExp(getNumberTypeCheck('b')); - Expect.isTrue(regexp.hasMatch(generated)); - }), - compile(TEST_THREE_WITH_BAILOUT, entry: 'foo', - check: (String generated) { - RegExp regexp = new RegExp(getNumberTypeCheck('a')); - Expect.isTrue(regexp.hasMatch(generated)); - regexp = new RegExp(getNumberTypeCheck('b')); - Expect.isTrue(regexp.hasMatch(generated)); - }) - ])); -}
diff --git a/tests/compiler/dart2js/type_inference2_test.dart b/tests/compiler/dart2js/type_inference2_test.dart deleted file mode 100644 index 5e5f224..0000000 --- a/tests/compiler/dart2js/type_inference2_test.dart +++ /dev/null
@@ -1,18 +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:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -sum(param0, param1) { - var sum = 0; - for (var i = param0; i < param1; i += 1) sum = sum + i; - return sum; -} -"""; - -main() { - asyncTest(() => compileAndMatchFuzzy(TEST_ONE, 'sum', r"\+\+x")); -}
diff --git a/tests/compiler/dart2js/type_inference3_test.dart b/tests/compiler/dart2js/type_inference3_test.dart deleted file mode 100644 index 87b1585..0000000 --- a/tests/compiler/dart2js/type_inference3_test.dart +++ /dev/null
@@ -1,22 +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. - -import 'package:expect/expect.dart'; -import 'package:async_helper/async_helper.dart'; -import 'compiler_helper.dart'; - -const String TEST_ONE = r""" -sum(param0, param1) { - var sum = 0; - for (var i = param0; i < param1; i += 1) sum = sum + i; - return sum; -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'sum', check: (String generated) { - RegExp regexp = new RegExp(getNumberTypeCheck('(param1|b)')); - Expect.isTrue(regexp.hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/type_inference4_test.dart b/tests/compiler/dart2js/type_inference4_test.dart deleted file mode 100644 index 48cb603..0000000 --- a/tests/compiler/dart2js/type_inference4_test.dart +++ /dev/null
@@ -1,29 +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(j) { - var array = [1, 2, 3]; - if (j < 0) j = 0; - for (var i = j; i < 3; i++) { - array[i]; - } -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - // Test for absence of an illegal argument exception. This means that the - // arguments are known to be integers. - Expect.isFalse(generated.contains('iae')); - // Also make sure that we are not just in bailout mode without speculative - // types by grepping for the integer-bailout check on argument j. - RegExp regexp = new RegExp(getIntTypeCheck('[aji]')); - Expect.isTrue(regexp.hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/type_inference5_test.dart b/tests/compiler/dart2js/type_inference5_test.dart deleted file mode 100644 index 7d6ef4c..0000000 --- a/tests/compiler/dart2js/type_inference5_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(j) { - var a = [1, 2, 3]; - for (var i = j; i < 3; i++) { - a[i]; - } -} -"""; - -main() { - asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) { - // Test for absence of an illegal argument exception. This means that the - // arguments are known to be integers. - Expect.isFalse(generated.contains('iae')); - // Also make sure that we are not just in bailout mode without speculative - // types by grepping for the integer-bailout check on argument j. - var argname = new RegExp(r'function(?: [a-z]+)?\(([a-zA-Z0-9_]+)\)') - .firstMatch(generated)[1]; - print(argname); - RegExp regexp = new RegExp(getIntTypeCheck("(i|$argname)")); - Expect.isTrue(regexp.hasMatch(generated)); - })); -}
diff --git a/tests/compiler/dart2js/type_mask_disjoint_test.dart b/tests/compiler/dart2js/type_mask_disjoint_test.dart deleted file mode 100644 index 18e36f9..0000000 --- a/tests/compiler/dart2js/type_mask_disjoint_test.dart +++ /dev/null
@@ -1,185 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'package:compiler/src/types/types.dart'; - -import 'compiler_helper.dart'; - -const String CODE = """ -class A {} -class B extends A {} -class C extends A {} - -class D implements A {} - -class E {} -class F extends E {} -class G implements E {} - -class H {} -class I implements H {} -class J extends D implements I {} - -class K {} -class M extends K with A {} - -class N extends H with I {} - -main() { - print([new A(), new B(), new C(), new D(), new E(), new F(), new G(), - new H(), new I(), new J(), new K(), new M(), new N()]); -} -"""; - -Uri uri = new Uri(scheme: 'source'); -var compiler = compilerFor(CODE, uri); -dynamic world = compiler.resolutionWorldBuilder.closedWorldForTesting; - -main() { - asyncTest(() => compiler.run(uri).then((_) { - // Empty - check(' ! ', ' ! '); // both non-null - check(' ! ', ' '); // one non-null - check(' ', ' ! '); // one non-null - check(' ', ' ', areDisjoint: false); // null is common - - // Exact - check('A!=', 'A!=', areDisjoint: false); - check('A!=', 'B!='); - check('A!=', 'E!='); - check('A =', 'E =', areDisjoint: false); // null is common - check('M!=', 'K!='); - check('M!=', 'A!='); - - // Exact with subclass - check('A!=', 'A!<', areDisjoint: false); - check('B!=', 'A!<', areDisjoint: false); - check('A!=', 'B!<'); - check('A!=', 'E!<'); - check('A =', 'E!<'); - check('A =', 'E <', areDisjoint: false); - check('M!=', 'K!<', areDisjoint: false); - check('M!=', 'A!<'); - - // Exact with subtype - check('A!=', 'A!*', areDisjoint: false); - check('B!=', 'A!*', areDisjoint: false); - check('A!=', 'B!*'); - check('A!=', 'E!*'); - check('A!=', 'I!*'); - check('J!=', 'H!*', areDisjoint: false); - check('M!=', 'K!*', areDisjoint: false); - check('M!=', 'A!*', areDisjoint: false); - - // Subclass with subclass - check('A!<', 'A!<', areDisjoint: false); - check('A!<', 'B!<', areDisjoint: false); - check('A!<', 'E!<'); - check('A!<', 'H!<'); - check('D!<', 'I!<'); - check('H!<', 'I!*', areDisjoint: false); - - // Subclass with subtype - check('A!<', 'A!*', areDisjoint: false); - check('A!<', 'B!*', areDisjoint: false); - check('A!<', 'E!*'); - check('A!<', 'H!*'); - check('D!<', 'I!*', areDisjoint: false); - - // Subtype with subtype - check('A!*', 'A!*', areDisjoint: false); - check('A!*', 'B!*', areDisjoint: false); - check('A!*', 'E!*'); - check('A!*', 'H!*', areDisjoint: false); - check('D!*', 'I!*', areDisjoint: false); - - // Unions! - checkUnions(['B!=', 'C!='], ['A!=']); - checkUnions(['B!=', 'C!='], ['A =']); - checkUnions(['B!=', 'C ='], ['A ='], areDisjoint: false); - - checkUnions(['B!=', 'C!='], ['A!<'], areDisjoint: false); - checkUnions(['B!=', 'C!='], ['B!='], areDisjoint: false); - checkUnions(['A!<', 'E!<'], ['C!='], areDisjoint: false); - checkUnions(['A!<', 'E!<'], ['F!='], areDisjoint: false); - - checkUnions(['A!=', 'E!='], ['C!=', 'F!=']); - checkUnions(['A!=', 'E!='], ['A!=', 'F!='], areDisjoint: false); - checkUnions(['B!=', 'E!='], ['A!<', 'F!='], areDisjoint: false); - checkUnions(['A!<', 'E!<'], ['C!=', 'F!='], areDisjoint: false); - checkUnions(['A!=', 'E!='], ['C!=', 'F!=']); - })); -} - -/// Checks the expectation of `isDisjoint` for two mask. Also checks that the -/// result is consistent with an equivalent (but slower) implementation based on -/// intersection. -checkMask(TypeMask m1, TypeMask m2, {areDisjoint: false}) { - print('masks: $m1 $m2'); - Expect.equals(areDisjoint, m1.isDisjoint(m2, world)); - Expect.equals(areDisjoint, m2.isDisjoint(m1, world)); - var i1 = m1.intersection(m2, world); - Expect.equals(areDisjoint, i1.isEmpty && !i1.isNullable); - var i2 = m2.intersection(m1, world); - Expect.equals(areDisjoint, i2.isEmpty && !i2.isNullable); -} - -/// Checks the expectation of `isDisjoint` for two mask descriptors (see -/// [maskOf] for details). -check(String typeMaskDescriptor1, String typeMaskDescriptor2, - {areDisjoint: true}) { - print('[$typeMaskDescriptor1] & [$typeMaskDescriptor2]'); - checkMask(maskOf(typeMaskDescriptor1), maskOf(typeMaskDescriptor2), - areDisjoint: areDisjoint); -} - -checkUnions(List<String> descriptors1, List<String> descriptors2, - {areDisjoint: true}) { - print('[$descriptors1] & [$descriptors2]'); - var m1 = new TypeMask.unionOf(descriptors1.map(maskOf).toList(), world); - var m2 = new TypeMask.unionOf(descriptors2.map(maskOf).toList(), world); - checkMask(m1, m2, areDisjoint: areDisjoint); -} - -Map _maskCache = {}; -Map _elementCache = {}; - -/// Parses a descriptor of a flat mask. A descriptor is of the form "AXY" where: -/// A: either a type T or " " (base class or empty) -/// X: can be either ! or " " (nullable/nonnullable) -/// Y: can be either " " (no flag), = (exact), < (subclass), * (subtype) -/// -/// Examples: -/// "-! " - empty, non-null -/// "- " - null -/// "Type!=" - non-null exact Type -/// "Type =" - nullable exact Type -/// "Type!<" - non-null subclass of Type -/// "Type!*" - non-null subtype of Type -TypeMask maskOf(String descriptor) => _maskCache.putIfAbsent(descriptor, () { - Expect.isTrue(descriptor.length >= 3); - var type = descriptor.substring(0, descriptor.length - 2); - bool isNullable = descriptor[descriptor.length - 2] != '!'; - bool isExact = descriptor[descriptor.length - 1] == '='; - bool isSubclass = descriptor[descriptor.length - 1] == '<'; - bool isSubtype = descriptor[descriptor.length - 1] == '*'; - - if (type == " ") { - Expect.isFalse(isExact || isSubclass || isSubtype); - return isNullable ? new TypeMask.empty() : new TypeMask.nonNullEmpty(); - } - - Expect.isTrue(isExact || isSubclass || isSubtype); - var element = _elementCache.putIfAbsent( - type, () => type == " " ? null : findElement(compiler, type)); - - var mask = isExact - ? new TypeMask.nonNullExact(element, world) - : (isSubclass - ? new TypeMask.nonNullSubclass(element, world) - : new TypeMask.nonNullSubtype(element, world)); - return isNullable ? mask.nullable() : mask; - });
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart deleted file mode 100644 index 7da68ac..0000000 --- a/tests/compiler/dart2js/type_mask_test.dart +++ /dev/null
@@ -1,129 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:async_helper/async_helper.dart'; -import 'package:expect/expect.dart'; -import 'package:compiler/src/types/types.dart'; - -import 'compiler_helper.dart'; - -const String CODE = """ -class A {} -class B extends A {} -class C implements A {} -class D implements A {} -main() { - print([new A(), new B(), new C(), new D()]); -} -"""; - -main() { - Uri uri = new Uri(scheme: 'source'); - var compiler = compilerFor(CODE, uri); - asyncTest(() => compiler.run(uri).then((_) { - var closedWorld = compiler.resolutionWorldBuilder.closedWorldForTesting; - dynamic classA = findElement(compiler, 'A'); - dynamic classB = findElement(compiler, 'B'); - dynamic classC = findElement(compiler, 'C'); - dynamic classD = findElement(compiler, 'D'); - - var exactA = new TypeMask.nonNullExact(classA, closedWorld); - var exactB = new TypeMask.nonNullExact(classB, closedWorld); - var exactC = new TypeMask.nonNullExact(classC, closedWorld); - var exactD = new TypeMask.nonNullExact(classD, closedWorld); - - var subclassA = new TypeMask.nonNullSubclass(classA, closedWorld); - var subtypeA = new TypeMask.nonNullSubtype(classA, closedWorld); - - var subclassObject = new TypeMask.nonNullSubclass( - closedWorld.commonElements.objectClass, closedWorld); - - var unionABC = - UnionTypeMask.unionOf([exactA, exactB, exactC], closedWorld); - var unionABnC = UnionTypeMask - .unionOf([exactA, exactB.nullable(), exactC], closedWorld); - var unionAB = UnionTypeMask.unionOf([exactA, exactB], closedWorld); - var unionSubtypeAC = - UnionTypeMask.unionOf([subtypeA, exactC], closedWorld); - var unionSubclassAC = - UnionTypeMask.unionOf([subclassA, exactC], closedWorld); - var unionBCD = - UnionTypeMask.unionOf([exactB, exactC, exactD], closedWorld); - var unionBCDn = UnionTypeMask - .unionOf([exactB, exactC, exactD.nullable()], closedWorld); - - Expect.isFalse(unionABC.isNullable); - Expect.isTrue(unionABnC.isNullable); - Expect.isFalse(unionBCD.isNullable); - Expect.isTrue(unionBCDn.isNullable); - - rule(a, b, c) => Expect.equals(c, a.isInMask(b, closedWorld)); - - rule(exactA, exactA, true); - rule(exactA, exactB, false); - rule(exactA, exactC, false); - rule(exactA, subclassA, true); - rule(exactA, subtypeA, true); - - rule(exactB, exactA, false); - rule(exactB, exactB, true); - rule(exactB, exactC, false); - rule(exactB, subclassA, true); - rule(exactB, subtypeA, true); - - rule(exactC, exactA, false); - rule(exactC, exactB, false); - rule(exactC, exactC, true); - rule(exactC, subclassA, false); - rule(exactC, subtypeA, true); - - rule(subclassA, exactA, false); - rule(subclassA, exactB, false); - rule(subclassA, exactC, false); - rule(subclassA, subclassA, true); - rule(subclassA, subtypeA, true); - - rule(subtypeA, exactA, false); - rule(subtypeA, exactB, false); - rule(subtypeA, exactC, false); - rule(subtypeA, subclassA, false); - rule(subtypeA, subtypeA, true); - - rule(unionABC, unionSubtypeAC, true); - rule(unionSubtypeAC, unionABC, true); - rule(unionAB, unionSubtypeAC, true); - rule(unionSubtypeAC, unionAB, false); - rule(unionABC, unionSubclassAC, true); - rule(unionSubclassAC, unionABC, true); - rule(unionAB, unionSubclassAC, true); - rule(unionSubclassAC, unionAB, false); - rule(unionAB, subclassA, true); - rule(subclassA, unionAB, true); - rule(unionABC, subtypeA, true); - rule(subtypeA, unionABC, true); - rule(unionABC, subclassA, false); - rule(subclassA, unionABC, true); - rule(unionAB, subclassA, true); - rule(subclassA, unionAB, true); - - rule(exactA, subclassObject, true); - rule(exactB, subclassObject, true); - rule(subclassA, subclassObject, true); - rule(subtypeA, subclassObject, true); - rule(unionABC, subclassObject, true); - rule(unionAB, subclassObject, true); - rule(unionSubtypeAC, subclassObject, true); - rule(unionSubclassAC, subclassObject, true); - - rule(unionABnC, unionABC, false); - rule(unionABC, unionABnC, true); - rule(exactA.nullable(), unionABnC, true); - rule(exactA.nullable(), unionABC, false); - rule(exactB, unionABnC, true); - rule(unionBCDn, unionBCD, false); - rule(unionBCD, unionBCDn, true); - rule(exactB.nullable(), unionBCDn, true); - rule(exactB.nullable(), unionBCD, false); - })); -}
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart index a637ee8..9e20cbb 100644 --- a/tests/compiler/dart2js/type_representation_test.dart +++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +// TODO(johnniwinther): Port this test to be frontend agnostic. + library type_representation_test; import 'package:expect/expect.dart'; @@ -58,7 +60,8 @@ } String stringify(Expression expression) { - return prettyPrint(expression, env.compiler.options); + return prettyPrint(expression, + enableMinification: env.compiler.options.enableMinification); } void expect(ResolutionDartType type, String expectedRepresentation,
diff --git a/tests/compiler/dart2js/type_substitution_test.dart b/tests/compiler/dart2js/type_substitution_test.dart index fcdae4c..588f310 100644 --- a/tests/compiler/dart2js/type_substitution_test.dart +++ b/tests/compiler/dart2js/type_substitution_test.dart
@@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +// TODO(johnniwinther): Port this test to be frontend agnostic. + library type_substitution_test; import 'package:expect/expect.dart';
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart index 3ebebb8..7a064ab 100644 --- a/tests/compiler/dart2js/type_test_helper.dart +++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -49,6 +49,7 @@ bool stopAfterTypeInference: false, String mainSource, bool testBackendWorld: false, + List<String> options: const <String>[], Map<String, String> fieldTypeMap: const <String, String>{}}) async { Uri uri; Compiler compiler; @@ -75,38 +76,42 @@ memorySourceFiles: {'main.dart': source}, diagnosticHandler: collector, options: stopAfterTypeInference - ? [Flags.disableTypeInference] - : [ + ? ([Flags.disableTypeInference]..addAll(options)) + : ([ Flags.disableTypeInference, Flags.analyzeAll, Flags.analyzeOnly - ], + ]..addAll(options)), beforeRun: (Compiler compiler) { compiler.stopAfterTypeInference = stopAfterTypeInference; }); } else { if (compileMode == CompileMode.mock) { uri = new Uri(scheme: 'source'); - mock.MockCompiler mockCompiler = mock.compilerFor(source, uri, + mock.MockCompiler mockCompiler = mock.mockCompilerFor(source, uri, analyzeAll: !stopAfterTypeInference, analyzeOnly: !stopAfterTypeInference); mockCompiler.diagnosticHandler = mock.createHandler(mockCompiler, source); collector = mockCompiler.diagnosticCollector; compiler = mockCompiler; + compiler.stopAfterTypeInference = stopAfterTypeInference; + await compiler.run(uri); } else { collector = new memory.DiagnosticCollector(); uri = Uri.parse('memory:main.dart'); - compiler = memory.compilerFor( + memory.CompilationResult result = await memory.runCompiler( entryPoint: uri, memorySourceFiles: {'main.dart': source}, diagnosticHandler: collector, options: stopAfterTypeInference - ? [] - : [Flags.analyzeAll, Flags.analyzeOnly]); + ? options + : ([Flags.analyzeAll, Flags.analyzeOnly]..addAll(options)), + beforeRun: (compiler) { + compiler.stopAfterTypeInference = stopAfterTypeInference; + }); + compiler = result.compiler; } - compiler.stopAfterTypeInference = stopAfterTypeInference; - await compiler.run(uri); } if (expectNoErrors || expectNoWarningsOrErrors) { var errors = collector.errors;
diff --git a/tests/compiler/dart2js/types_of_captured_variables_test.dart b/tests/compiler/dart2js/types_of_captured_variables_test.dart deleted file mode 100644 index d08f543..0000000 --- a/tests/compiler/dart2js/types_of_captured_variables_test.dart +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'compiler_helper.dart'; - -const String TEST1 = r""" -main() { - var a = 52; - var f = () => a + 87; - f(); -} -"""; - -const String TEST2 = r""" -main() { - var a = 52; - var g = () { a = 48; }; - var f = () => a + 87; - f(); - g(); -} -"""; - -const String TEST3 = r""" -main() { - var a = 52; - var g = () { a = 'foo'; }; - var f = () => a + 87; - f(); - g(); -} -"""; - -main() { - // Test that we know the type of captured, non-mutated variables. - asyncTest(() => compileAll(TEST1).then((generated) { - Expect.isTrue(generated.contains('+ 87')); - })); - - // Test that we know the type of captured, mutated variables. - asyncTest(() => compileAll(TEST2).then((generated) { - Expect.isTrue(generated.contains('+ 87')); - })); - - // Test that we know when types of a captured, mutated variable - // conflict. - asyncTest(() => compileAll(TEST3).then((generated) { - Expect.isFalse(generated.contains('+ 87')); - })); -}
diff --git a/tests/compiler/dart2js/uri_retention_test.dart b/tests/compiler/dart2js/uri_retention_test.dart index 20bbb89..dc7d70f 100644 --- a/tests/compiler/dart2js/uri_retention_test.dart +++ b/tests/compiler/dart2js/uri_retention_test.dart
@@ -6,16 +6,18 @@ import 'dart:async'; -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; +import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler_new.dart'; - +import 'package:compiler/src/commandline_options.dart'; +import 'package:expect/expect.dart'; import 'memory_compiler.dart' show runCompiler, OutputCollector; -Future<String> compileSources(sources, {bool minify, bool preserveUri}) async { +Future<String> compileSources(sources, + {bool minify, bool preserveUri, bool useKernel}) async { var options = []; - if (minify) options.add("--minify"); - if (preserveUri) options.add("--preserve-uris"); + if (minify) options.add(Flags.minify); + if (preserveUri) options.add(Flags.preserveUris); + if (useKernel) options.add(Flags.useKernel); OutputCollector outputCollector = new OutputCollector(); await runCompiler( memorySourceFiles: sources, @@ -24,9 +26,9 @@ return outputCollector.getOutput('', OutputType.js); } -Future test(sources, {bool libName, bool fileName}) { - return compileSources(sources, minify: false, preserveUri: false) - .then((output) { +Future test(sources, {bool libName, bool fileName, bool useKernel}) { + return compileSources(sources, + minify: false, preserveUri: false, useKernel: useKernel).then((output) { // Unminified the sources should always contain the library name and the // file name. Expect.isTrue(output.contains("main_lib")); @@ -45,12 +47,22 @@ } void main() { - asyncTest(() { - return new Future.value() - .then( - (_) => test(MEMORY_SOURCE_FILES1, libName: false, fileName: false)) - .then((_) => test(MEMORY_SOURCE_FILES2, libName: true, fileName: false)) - .then((_) => test(MEMORY_SOURCE_FILES3, libName: true, fileName: true)); + runTests({bool useKernel}) async { + await test(MEMORY_SOURCE_FILES1, + libName: false, fileName: false, useKernel: useKernel); + if (!useKernel) { + await test(MEMORY_SOURCE_FILES2, + libName: true, fileName: false, useKernel: useKernel); + await test(MEMORY_SOURCE_FILES3, + libName: true, fileName: true, useKernel: useKernel); + } + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); }
diff --git a/tests/compiler/dart2js/use_checks_test.dart b/tests/compiler/dart2js/use_checks_test.dart deleted file mode 100644 index 830b372..0000000 --- a/tests/compiler/dart2js/use_checks_test.dart +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; - -const MEMORY_SOURCE_FILES = const { - 'main.dart': ''' -main (x, y) { - if (x != null) { - if (y != null) { - // Forces x and y to be int-checked. - int a = x; - int b = y; - // Now we must be able to do a direct "+" operation in JS. - return x + y; - } - } -} -''', -}; - -main() { - asyncTest(() async { - var result = await runCompiler( - memorySourceFiles: MEMORY_SOURCE_FILES, - options: ['--enable-checked-mode']); - var compiler = result.compiler; - var element = compiler.frontendStrategy.elementEnvironment.mainFunction; - var code = compiler.backend.getGeneratedCode(element); - Expect.isTrue(code.contains('+'), code); - }); -}
diff --git a/tests/compiler/dart2js/user_crash_test.dart b/tests/compiler/dart2js/user_crash_test.dart index 0af3e67..8d46c4b 100644 --- a/tests/compiler/dart2js/user_crash_test.dart +++ b/tests/compiler/dart2js/user_crash_test.dart
@@ -6,14 +6,16 @@ import 'package:async_helper/async_helper.dart'; import 'package:expect/expect.dart'; import 'package:compiler/compiler_new.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'memory_compiler.dart'; -final EXCEPTION = 'Crash'; +final EXCEPTION = 'Crash-marker'; main() { - asyncTest(() async { - test('Empty program', await run()); - test('Crash diagnostics', await run(diagnostics: new CrashingDiagnostics()), + runTests({bool useKernel}) async { + test('Empty program', await run(useKernel: useKernel)); + test('Crash diagnostics', + await run(useKernel: useKernel, diagnostics: new CrashingDiagnostics()), expectedLines: [ 'Uncaught exception in diagnostic handler: $EXCEPTION', null /* Stack trace*/ @@ -23,9 +25,11 @@ ]); test( 'Throw in package discovery', - await run(packagesDiscoveryProvider: (_) { - throw EXCEPTION; - }), + await run( + useKernel: useKernel, + packagesDiscoveryProvider: (_) { + throw EXCEPTION; + }), expectedLines: [ 'Uncaught exception in package discovery: $EXCEPTION', null /* Stack trace*/ @@ -36,15 +40,30 @@ test( 'new Future.error in package discovery', await run( + useKernel: useKernel, packagesDiscoveryProvider: (_) => new Future.error(EXCEPTION)), expectedExceptions: [EXCEPTION]); + + List<String> expectedLines; + if (useKernel) { + expectedLines = ['Error: Input file not found: memory:main.dart.']; + } else { + expectedLines = [ + 'Uncaught exception in input provider: $EXCEPTION', + null, // Stack trace + 'memory:main.dart:\nError: $EXCEPTION' /* READ_SELF_ERROR */ + ]; + } test('Throw in input provider', - await run(memorySourceFiles: new CrashingMap()), - expectedLines: [ - 'Uncaught exception in input provider: $EXCEPTION', - null, // Stack trace - 'memory:main.dart:\nError: $EXCEPTION' /* READ_SELF_ERROR */ - ]); + await run(useKernel: useKernel, memorySourceFiles: new CrashingMap()), + expectedLines: expectedLines); + } + + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); }); } @@ -71,7 +90,8 @@ Future<RunResult> run( {Map<String, String> memorySourceFiles: const {'main.dart': 'main() {}'}, CompilerDiagnostics diagnostics, - PackagesDiscoveryProvider packagesDiscoveryProvider}) async { + PackagesDiscoveryProvider packagesDiscoveryProvider, + bool useKernel}) async { RunResult result = new RunResult(); await runZoned(() async { try { @@ -79,7 +99,8 @@ entryPoint: Uri.parse('memory:main.dart'), memorySourceFiles: memorySourceFiles, diagnosticHandler: diagnostics, - packagesDiscoveryProvider: packagesDiscoveryProvider); + packagesDiscoveryProvider: packagesDiscoveryProvider, + options: useKernel ? [Flags.useKernel] : []); } catch (e) { result.exceptions.add(e); }
diff --git a/tests/compiler/dart2js/value_range3_test.dart b/tests/compiler/dart2js/value_range3_test.dart deleted file mode 100644 index e0f6c5f..0000000 --- a/tests/compiler/dart2js/value_range3_test.dart +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// Test that global analysis in dart2js propagates positive integers. - -import 'package:expect/expect.dart'; -import "package:async_helper/async_helper.dart"; -import 'memory_compiler.dart'; - -const MEMORY_SOURCE_FILES = const { - 'main.dart': ''' - -var a = [42]; - -main() { - var value = a[0]; - if (value < 42) { - return new List(42)[value]; - } -} -''', -}; - -main() { - asyncTest(() async { - var result = await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES); - var compiler = result.compiler; - var element = compiler.frontendStrategy.elementEnvironment.mainFunction; - var code = compiler.backend.getGeneratedCode(element); - Expect.isFalse(code.contains('ioore')); - }); -}
diff --git a/tests/compiler/dart2js/world_test.dart b/tests/compiler/dart2js/world_test.dart index 35020cb..9719d417 100644 --- a/tests/compiler/dart2js/world_test.dart +++ b/tests/compiler/dart2js/world_test.dart
@@ -8,22 +8,28 @@ import 'package:async_helper/async_helper.dart'; import 'type_test_helper.dart'; import 'package:compiler/src/common/names.dart'; -import 'package:compiler/src/elements/elements.dart' - show ClassElement, LibraryElement; +import 'package:compiler/src/common_elements.dart'; import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/universe/class_set.dart'; import 'package:compiler/src/world.dart' show ClassQuery, ClosedWorld; void main() { + runTests(CompileMode compileMode) async { + await testClassSets(compileMode); + await testProperties(compileMode); + await testNativeClasses(compileMode); + await testCommonSubclasses(compileMode); + } + asyncTest(() async { - await testClassSets(); - await testProperties(); - await testNativeClasses(); - await testCommonSubclasses(); + print('--test from ast---------------------------------------------------'); + await runTests(CompileMode.memory); + print('--test from kernel------------------------------------------------'); + await runTests(CompileMode.kernel); }); } -testClassSets() async { +testClassSets(CompileMode compileMode) async { var env = await TypeEnvironment.create(r""" class A implements X {} class B {} @@ -32,7 +38,7 @@ class D implements A {} class E extends B implements A {} class F extends Object with A implements B {} - class G extends Object with A, B {} + class G extends Object with B, A {} class X {} """, mainSource: r""" import 'dart:html' as html; @@ -47,18 +53,19 @@ html.window; new html.Worker(''); } - """, compileMode: CompileMode.memory); + """, compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; - ClassElement Object_ = env.getElement("Object"); - ClassElement A = env.getElement("A"); - ClassElement B = env.getElement("B"); - ClassElement C = env.getElement("C"); - ClassElement D = env.getElement("D"); - ClassElement E = env.getElement("E"); - ClassElement F = env.getElement("F"); - ClassElement G = env.getElement("G"); - ClassElement X = env.getElement("X"); + ClassEntity Object_ = env.getElement("Object"); + ClassEntity A = env.getElement("A"); + ClassEntity B = env.getElement("B"); + ClassEntity C = env.getElement("C"); + ClassEntity D = env.getElement("D"); + ClassEntity E = env.getElement("E"); + ClassEntity F = env.getElement("F"); + ClassEntity G = env.getElement("G"); + ClassEntity X = env.getElement("X"); void checkClasses(String property, ClassEntity cls, Iterable<ClassEntity> foundClasses, List<ClassEntity> expectedClasses, @@ -168,8 +175,12 @@ testStrictSubtypes(X, [A, C, D, E, F, G]); testMixinUses(Object_, []); - testMixinUses(A, [F.superclass, G.superclass.superclass]); - testMixinUses(B, [G.superclass]); + testMixinUses(A, [ + elementEnvironment.getSuperClass(F), + elementEnvironment.getSuperClass(G) + ]); + testMixinUses(B, + [elementEnvironment.getSuperClass(elementEnvironment.getSuperClass(G))]); testMixinUses(C, []); testMixinUses(D, []); testMixinUses(E, []); @@ -178,7 +189,7 @@ testMixinUses(X, []); } -testProperties() async { +testProperties(CompileMode compileMode) async { var env = await TypeEnvironment.create(r""" class A {} class A1 extends A {} @@ -233,11 +244,11 @@ new G3(); new H4(); } - """, compileMode: CompileMode.memory); + """, compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; check(String name, {bool hasStrictSubtype, bool hasOnlySubclasses}) { - ClassElement cls = env.getElement(name); + ClassEntity cls = env.getElement(name); Expect.equals(hasStrictSubtype, closedWorld.hasAnyStrictSubtype(cls), "Unexpected hasAnyStrictSubtype property on $cls."); Expect.equals(hasOnlySubclasses, closedWorld.hasOnlySubclasses(cls), @@ -299,7 +310,7 @@ check("H4", hasStrictSubtype: false, hasOnlySubclasses: true); } -testNativeClasses() async { +testNativeClasses(CompileMode compileMode) async { var env = await TypeEnvironment.create('', mainSource: r""" import 'dart:html' as html; @@ -310,20 +321,23 @@ ..getContext(''); // Creates CanvasRenderingContext2D } """, - compileMode: CompileMode.memory); + compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; - LibraryElement dart_html = - env.compiler.libraryLoader.lookupLibrary(Uris.dart_html); + ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; + LibraryEntity dart_html = elementEnvironment.lookupLibrary(Uris.dart_html); - ClassElement clsEventTarget = dart_html.findExported('EventTarget'); - ClassElement clsWindow = dart_html.findExported('Window'); - ClassElement clsAbstractWorker = dart_html.findExported('AbstractWorker'); - ClassElement clsWorker = dart_html.findExported('Worker'); - ClassElement clsCanvasElement = dart_html.findExported('CanvasElement'); - ClassElement clsCanvasRenderingContext = - dart_html.findExported('CanvasRenderingContext'); - ClassElement clsCanvasRenderingContext2D = - dart_html.findExported('CanvasRenderingContext2D'); + ClassEntity clsEventTarget = + elementEnvironment.lookupClass(dart_html, 'EventTarget'); + ClassEntity clsWindow = elementEnvironment.lookupClass(dart_html, 'Window'); + ClassEntity clsAbstractWorker = + elementEnvironment.lookupClass(dart_html, 'AbstractWorker'); + ClassEntity clsWorker = elementEnvironment.lookupClass(dart_html, 'Worker'); + ClassEntity clsCanvasElement = + elementEnvironment.lookupClass(dart_html, 'CanvasElement'); + ClassEntity clsCanvasRenderingContext = + elementEnvironment.lookupClass(dart_html, 'CanvasRenderingContext'); + ClassEntity clsCanvasRenderingContext2D = + elementEnvironment.lookupClass(dart_html, 'CanvasRenderingContext2D'); List<ClassEntity> allClasses = [ clsEventTarget, @@ -506,7 +520,7 @@ instantiatedSubtypeCount: 0); } -testCommonSubclasses() async { +testCommonSubclasses(CompileMode compileMode) async { var env = await TypeEnvironment.create('', mainSource: r""" class A {} @@ -532,18 +546,18 @@ new J(); } """, - compileMode: CompileMode.memory); + compileMode: compileMode); ClosedWorld closedWorld = env.closedWorld; - ClassElement A = env.getElement("A"); - ClassElement B = env.getElement("B"); - ClassElement C = env.getElement("C"); - ClassElement D = env.getElement("D"); - ClassElement F = env.getElement("F"); - ClassElement G = env.getElement("G"); - ClassElement H = env.getElement("H"); - ClassElement I = env.getElement("I"); - ClassElement J = env.getElement("J"); + ClassEntity A = env.getElement("A"); + ClassEntity B = env.getElement("B"); + ClassEntity C = env.getElement("C"); + ClassEntity D = env.getElement("D"); + ClassEntity F = env.getElement("F"); + ClassEntity G = env.getElement("G"); + ClassEntity H = env.getElement("H"); + ClassEntity I = env.getElement("I"); + ClassEntity J = env.getElement("J"); void check(ClassEntity cls1, ClassQuery query1, ClassEntity cls2, ClassQuery query2, List<ClassEntity> expectedResult) {
diff --git a/tests/compiler/dart2js/zero_termination_test.dart b/tests/compiler/dart2js/zero_termination_test.dart index 98690f9..f2c11cd 100644 --- a/tests/compiler/dart2js/zero_termination_test.dart +++ b/tests/compiler/dart2js/zero_termination_test.dart
@@ -12,10 +12,11 @@ import 'dart:convert'; import 'dart:io'; import 'package:async_helper/async_helper.dart'; +import 'package:compiler/src/commandline_options.dart'; import 'package:expect/expect.dart'; import 'package:path/path.dart' as path; -import 'launch_helper.dart' show launchDart2Js; +import 'end_to_end/launch_helper.dart' show launchDart2Js; Uri pathOfData = Platform.script; Directory tempDir; @@ -60,20 +61,22 @@ Expect.isFalse(stdout.contains(0)); } -Future testFile() async { +Future testFile({bool useKernel}) async { String inFilePath = pathOfData.resolve('data/one_line_dart_program.dart').path; List<String> args = [inFilePath, "--out=" + outFilePath]; + if (useKernel) args.add(Flags.useKernel); await cleanup(); check(await launchDart2Js(args, noStdoutEncoding: true)); await cleanup(); } -Future serverRunning(HttpServer server) async { +Future serverRunning(HttpServer server, {bool useKernel}) async { int port = server.port; String inFilePath = "http://127.0.0.1:$port/data/one_line_dart_program.dart"; List<String> args = [inFilePath, "--out=" + outFilePath]; + if (useKernel) args.add(Flags.useKernel); server.listen(handleRequest); try { @@ -85,25 +88,32 @@ } } -Future testHttp() { +Future testHttp({bool useKernel}) { return HttpServer .bind(InternetAddress.LOOPBACK_IP_V4, 0) - .then((HttpServer server) => serverRunning(server)); + .then((HttpServer server) => serverRunning(server, useKernel: useKernel)); } -runTests() async { +runTests({bool useKernel}) async { tempDir = Directory.systemTemp.createTempSync('directory_test'); outFilePath = path.join(tempDir.path, "out.js"); try { - await testFile(); - await testHttp(); + await testFile(useKernel: useKernel); + if (!useKernel) { + // TODO(johnniwinther): Handle this test for kernel. + await testHttp(useKernel: useKernel); + } } finally { await tempDir.delete(recursive: true); } } main() { - asyncStart(); - runTests().whenComplete(asyncEnd); + asyncTest(() async { + print('--test from ast---------------------------------------------------'); + await runTests(useKernel: false); + print('--test from kernel------------------------------------------------'); + await runTests(useKernel: true); + }); }
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status index 9c164b4..d77b085 100644 --- a/tests/compiler/dart2js_extra/dart2js_extra.status +++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -124,6 +124,10 @@ deferred_fail_and_retry_worker_test: SkipByDesign # Uses eval to simulate failed loading. js_interop_test: RuntimeError # Issue 31082 +[ $compiler == dart2js && $dart2js_with_kernel ] +dummy_compiler_test: Crash # Issue 31715 +recursive_import_test: Crash # Issue 31715 + [ $compiler == dart2js && $dart2js_with_kernel && $fast_startup ] 23056_test: Pass closure_capture2_test: RuntimeError
diff --git a/tests/compiler/dart2js_extra/dummy_compiler_test.dart b/tests/compiler/dart2js_extra/dummy_compiler_test.dart index 126e4ee..34d1c6e 100644 --- a/tests/compiler/dart2js_extra/dummy_compiler_test.dart +++ b/tests/compiler/dart2js_extra/dummy_compiler_test.dart
@@ -10,7 +10,7 @@ import 'package:async_helper/async_helper.dart'; import 'package:compiler/compiler.dart'; -import '../dart2js/mock_libraries.dart'; +import '../dart2js/old_frontend/mock_libraries.dart'; String libProvider(Uri uri) { if (uri.path.endsWith(".platform")) {
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status index 033f5d8..1455b3e 100644 --- a/tests/corelib_2/corelib_2.status +++ b/tests/corelib_2/corelib_2.status
@@ -63,13 +63,6 @@ symbol_test/02: MissingCompileTimeError symbol_test/03: MissingCompileTimeError -[ $compiler == dartkp ] -bit_twiddling_test/int64: CompileTimeError # Issue 31339 -integer_to_radix_string_test/01: CompileTimeError # Issue 31339 -integer_to_radix_string_test/02: CompileTimeError # Issue 31339 -integer_to_string_test/01: CompileTimeError # Issue 31339 -num_sign_test: CompileTimeError, Crash # Issue 31339 - [ $compiler == precompiler ] int_parse_radix_test: Pass, Timeout # --no_intrinsify integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify @@ -117,12 +110,6 @@ int_parse_radix_test/*: Pass, Slow integer_parsed_mul_div_vm_test: Pass, Slow -# Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which -# are to be triaged. Isolate tests are skipped on purpose due to the usage of -# batch mode. -[ $arch == simdbc64 && $compiler == dartk && $strong ] -iterable_to_set_test: RuntimeError # Please triage. - [ $arch == x64 && $system == windows ] stopwatch_test: Skip # Flaky test due to expected performance behaviour. @@ -427,15 +414,11 @@ [ $compiler == dartk && $runtime == vm && $strong ] apply3_test: CompileTimeError # Issue 31402 (Invocation arguments) bool_from_environment2_test/03: MissingCompileTimeError -collection_removes_test: RuntimeError compare_to2_test: RuntimeError -hash_set_test/01: RuntimeError -hash_set_test/none: RuntimeError int_modulo_arith_test/modPow: CompileTimeError # Issue 31402 (Assert statement) int_modulo_arith_test/none: CompileTimeError # Issue 31402 (Assert statement) iterable_empty_test: RuntimeError iterable_fold_test/02: RuntimeError -iterable_mapping_test/none: RuntimeError iterable_reduce_test/01: CompileTimeError # Issue 31533 iterable_reduce_test/none: RuntimeError iterable_to_list_test/01: RuntimeError @@ -445,9 +428,7 @@ list_set_all_test: RuntimeError null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments) null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments) -set_test: RuntimeError splay_tree_from_iterable_test: RuntimeError -splay_tree_test/none: RuntimeError string_case_test/01: RuntimeError string_from_environment3_test/03: MissingCompileTimeError string_trimlr_test/02: RuntimeError @@ -463,27 +444,14 @@ symbol_test/none: RuntimeError unicode_test: RuntimeError -# Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which -# are to be triaged. Isolate tests are skipped on purpose due to the usage of -# batch mode. -[ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ] -bit_twiddling_test/int64: CompileTimeError # Please triage. -integer_to_radix_string_test/02: CompileTimeError # Please triage. -integer_to_string_test/01: CompileTimeError # Please triage. -num_sign_test: CompileTimeError # Please triage. - # ===== dartkp + dart_precompiled status lines ===== [ $compiler == dartkp && $runtime == dart_precompiled && $strong ] bool_from_environment2_test/03: MissingCompileTimeError -collection_removes_test: RuntimeError compare_to2_test: RuntimeError -hash_set_test/01: RuntimeError -hash_set_test/none: RuntimeError int_modulo_arith_test/modPow: CompileTimeError # Issue 31402 (Assert statement) int_modulo_arith_test/none: CompileTimeError # Issue 31402 (Assert statement) iterable_empty_test: RuntimeError iterable_fold_test/02: RuntimeError -iterable_mapping_test/none: RuntimeError iterable_reduce_test/01: CompileTimeError # Issue 31533 iterable_reduce_test/none: RuntimeError iterable_to_list_test/01: RuntimeError @@ -494,9 +462,7 @@ null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments) null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments) regexp/stack-overflow_test: RuntimeError -set_test: RuntimeError splay_tree_from_iterable_test: RuntimeError -splay_tree_test/none: RuntimeError string_case_test/01: RuntimeError string_from_environment3_test/03: MissingCompileTimeError string_trimlr_test/02: RuntimeError @@ -686,7 +652,7 @@ [ $runtime == dart_precompiled || $runtime == vm ] integer_parsed_arith_vm_test/01: RuntimeError # Issue 31346 -integer_parsed_arith_vm_test/02: RuntimeError # Issue 31369 +integer_parsed_arith_vm_test/02: RuntimeError # Issue 31346 integer_parsed_div_rem_vm_test/01: RuntimeError # Issue 31346 integer_to_radix_string_test/01: RuntimeError # Issue 31346 string_split_test: RuntimeError # does not return List<String>
diff --git a/tests/corelib_2/integer_parsed_arith_vm_test.dart b/tests/corelib_2/integer_parsed_arith_vm_test.dart index 7ce266c..d3e273d 100644 --- a/tests/corelib_2/integer_parsed_arith_vm_test.dart +++ b/tests/corelib_2/integer_parsed_arith_vm_test.dart
@@ -65,9 +65,9 @@ one, // 64 bit overflow. //# 01: continued "-0x8000000000000000"); // //# 01: continued addSubParsed( // //# 02: ok - "0xFFFFFFFFFFFFFFFF", // //# 02: continued + minus_one, // //# 02: continued one, // 64 bit overflow. //# 02: continued - "0"); // //# 02: continued + zero); // //# 02: continued addSubParsed( "0x8000000", // 28 bit overflow. "0x8000000", @@ -81,9 +81,9 @@ "0x80000000000000", "0x100000000000000"); addSubParsed( // //# 02: continued - "0x8000000000000000", // 64 bit overflow. //# 02: continued - "0x8000000000000000", // //# 02: continued - "0"); // //# 02: continued + "-0x8000000000000000", // 64 bit overflow. //# 02: continued + "-0x8000000000000000", // //# 02: continued + zero); // //# 02: continued addSubParsed("-0x123", minus_one, "-0x124"); addSubParsed(minus_one, "-0x123", "-0x124");
diff --git a/tests/html/html.status b/tests/html/html.status index 629256f..66809df 100644 --- a/tests/html/html.status +++ b/tests/html/html.status
@@ -49,7 +49,6 @@ js_typed_interop_side_cast_exp_test: Pass, RuntimeError # Roll 50 failure mirrors_js_typed_interop_test: Pass, Slow svgelement_test/PathElement: Pass, RuntimeError # Roll 50 failure -websql_test/functional: Pass, Timeout # Roll 50 failure wrapping_collections_test: SkipByDesign # Testing an issue that is only relevant to Dartium xhr_test/xhr: Pass, RuntimeError # Roll 50 failure @@ -116,7 +115,7 @@ two_scripts_htmltest: Skip # Times out on IE. Issue 21537 webgl_1_test/functional: Fail # IE11 Feature support statuses - These results not yet noted in platform support annotations. All changes should be accompanied by platform support annotation changes. websocket_test/websocket: Fail # Issue 7875. Closed with "working as intended". -websql_test/supported: Fail # IE11 Feature support statuses - These results not yet noted in platform support annotations. All changes should be accompanied by platform support annotation changes. +websql_test: Fail # IE11 Feature support statuses - These results not yet noted in platform support annotations. All changes should be accompanied by platform support annotation changes. wheelevent_test: RuntimeError # Issue 23437 worker_test/functional: Pass, Fail # Issues 20659. xhr_test/json: Fail # IE10 returns string, not JSON object @@ -208,7 +207,7 @@ text_event_test: Fail # Issue 17893 touchevent_test/supported: Fail # Firefox Feature support statuses - All changes should be accompanied by platform support annotation changes. webgl_1_test: Pass, Fail # Issue 8219 -websql_test/supported: Fail # Firefox Feature support statuses - All changes should be accompanied by platform support annotation changes. +websql_test: Fail # Firefox Feature support statuses - All changes should be accompanied by platform support annotation changes. xhr_test/xhr: Pass, Fail # Issue 11602 [ $compiler == dart2js && $browser ]
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart index fa882c2..3e98cc5 100644 --- a/tests/html/websql_test.dart +++ b/tests/html/websql_test.dart
@@ -3,131 +3,126 @@ import 'dart:async'; import 'dart:html'; import 'dart:web_sql'; + import 'package:unittest/unittest.dart'; import 'package:unittest/html_individual_config.dart'; - -Future<SqlTransaction> transaction(SqlDatabase db) { - final completer = new Completer<SqlTransaction>.sync(); - - db.transaction((SqlTransaction transaction) { - completer.complete(transaction); - }, (SqlError error) { - completer.completeError(error); - }); - - return completer.future; -} +import 'package:async_helper/async_helper.dart'; Future<SqlResultSet> createTable( - SqlTransaction transaction, String tableName, String columnName) { - final completer = new Completer<SqlResultSet>.sync(); - - final sql = 'CREATE TABLE $tableName ($columnName)'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + SqlTransaction transaction, String tableName, String columnName) async { + return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []); } -Future<SqlResultSet> insert( - SqlTransaction transaction, String tableName, String columnName, value) { - final completer = new Completer<SqlResultSet>.sync(); - +Future<SqlResultSet> insertTable(SqlTransaction transaction, String tableName, + String columnName, value) async { final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)'; - transaction.executeSql(sql, [value], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, [value]); } -Future<SqlResultSet> queryTable(SqlTransaction transaction, String tableName) { - final completer = new Completer<SqlResultSet>.sync(); - +Future<SqlResultSet> queryTable( + SqlTransaction transaction, String tableName) async { final sql = 'SELECT * FROM $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, []); } Future<SqlResultSet> dropTable(SqlTransaction transaction, String tableName, - [bool ignoreFailure = false]) { - final completer = new Completer<SqlResultSet>.sync(); - - final sql = 'DROP TABLE $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - if (ignoreFailure) { - completer.complete(null); - } else { - completer.completeError(error); - } - }); - - return completer.future; + [bool ignoreFailure = false]) async { + try { + var result = await transaction.executeSql('DROP TABLE $tableName', []); + return result; + } catch (error) { + if (!ignoreFailure) throw error; + } } -main() { +final tableName = 'test_table'; +final columnName = 'test_data'; + +SqlDatabase db; +SqlTransaction tx; + +Future setup() async { + if (SqlDatabase.supported) { + db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(db, isNotNull, reason: 'Unable to open database'); + + tx = await db.transaction_future(); + expect(tx, isNotNull, reason: "Transaction not ready"); + } +} + +main() async { useHtmlIndividualConfiguration(); - group('supported', () { + await setup(); + + group('Database', () { test('supported', () { expect(SqlDatabase.supported, true); }); }); - group('functional', () { - test('unsupported throws', () { - var expectation = SqlDatabase.supported ? returnsNormally : throws; - expect(() { - window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); - }, expectation); - }); - test('Web Database', () { - // Skip if not supported. - if (!SqlDatabase.supported) { - return new Future.value(); + group('Database', () { + test('Open/Transaction', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + + // Should not succeed table doesn't exist to be dropped. + try { + await dropTable(tx, tableName); + expect(false, true, reason: "dropTable should fail"); + } catch (error) { + expect(error.message, + "could not prepare statement (1 no such table: test_table)"); } + }); - final tableName = 'test_table'; - final columnName = 'test_data'; + test('create', () async { + if (!SqlDatabase.supported) return; - final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet createResult = + await createTable(tx, tableName, columnName); + expect(createResult.insertId, 0); + } catch (error) { + expect(false, true, reason: "createTable failed - ${error.message}"); + } + }); - expect(db, isNotNull, reason: 'Unable to open database'); + test('insert', () async { + if (!SqlDatabase.supported) return; - var tx; - return transaction(db).then((transaction) { - tx = transaction; - }).then((_) { - // Attempt to clear out any tables which may be lurking from previous - // runs. - return dropTable(tx, tableName, true); - }).then((_) { - return createTable(tx, tableName, columnName); - }).then((_) { - return insert(tx, tableName, columnName, 'Some text data'); - }).then((_) { - return queryTable(tx, tableName); - }).then((resultSet) { - expect(resultSet.rows.length, 1); - var row = resultSet.rows.item(0); - expect(row.containsKey(columnName), isTrue); - expect(row[columnName], 'Some text data'); - expect(resultSet.rows[0], row); - }).then((_) { - return dropTable(tx, tableName); - }); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet insertResult = + await insertTable(tx, tableName, columnName, 'Some text data'); + expect(insertResult.insertId, 1); + expect(insertResult.rowsAffected, 1); + } catch (error) { + expect(false, true, reason: "insert failed - ${error.message}"); + } + }); + + test('query', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet queryResult = await queryTable(tx, tableName); + expect(queryResult.rows.length, 1); + expect(queryResult.rows[0]['test_data'], "Some text data"); + } catch (error) { + expect(false, true, reason: "queryTable failed - ${error.message}"); + } + }); + + test('cleanup', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + await dropTable(tx, tableName, true); }); }); }
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status index dce3ec3..b6b3e96 100644 --- a/tests/language/language_dart2js.status +++ b/tests/language/language_dart2js.status
@@ -391,9 +391,9 @@ regress_17382_test: RuntimeError regress_20394_test/01: MissingCompileTimeError regress_22936_test/01: RuntimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_26133_test: RuntimeError # Issue 26429 regress_27572_test: RuntimeError @@ -775,9 +775,9 @@ regress_17382_test: RuntimeError regress_20394_test/01: MissingCompileTimeError regress_22936_test/01: RuntimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_27572_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant @@ -1093,9 +1093,9 @@ regress_17382_test: RuntimeError regress_20394_test/01: MissingCompileTimeError regress_22936_test/01: RuntimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_27572_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant @@ -1431,9 +1431,9 @@ regress_20394_test/01: MissingCompileTimeError regress_21795_test: RuntimeError regress_22936_test/01: RuntimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_27572_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
diff --git a/tests/language_2/async_no_suspend/README.md b/tests/language_2/async_no_suspend/README.md new file mode 100644 index 0000000..a4dd590 --- /dev/null +++ b/tests/language_2/async_no_suspend/README.md
@@ -0,0 +1,7 @@ +# Feature tests for starting async methods without suspending + +This directory was created in order to hold tests pertaining to the Dart +feature which makes methods marked as `async` start executing the body +immediately, rather than returning a `Future` and suspending. For more +details, please check the +[language specification update](https://github.com/dart-lang/sdk/commit/2170830a9e41fa5b4067fde7bd44b76f5128c502).
diff --git a/tests/language_2/fixed_size_int/README.md b/tests/language_2/fixed_size_int/README.md new file mode 100644 index 0000000..a2ddb7c --- /dev/null +++ b/tests/language_2/fixed_size_int/README.md
@@ -0,0 +1,7 @@ +# Feature tests for fixed size integers + +This directory was created in order to hold tests pertaining to the Dart +feature which changes the `int` type to have a fixed-size representation +(as opposed to implicitly transitioning into an arbitrary bigint +representation when needed). For more details, please check the +[informal specification](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/int64.md).
diff --git a/tests/language_2/generalized_void_usage_test.dart b/tests/language_2/generalized_void_usage_test.dart new file mode 100644 index 0000000..262e40a --- /dev/null +++ b/tests/language_2/generalized_void_usage_test.dart
@@ -0,0 +1,37 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Dart test for static checks on situations where expressions of type void +// can be used. The point is simply that there are no compile-time errors. + +// We need expressions of type `void`; `void x` would do, but using +// `void get x` will work with tools that do not yet handle `void x`. +void get x => null; + +void use(dynamic x) {} + +main() { + // In an expressionStatement `e;`, e may have type void. + x; + + // In the initialization and increment expressions of a for-loop, + // `for (e1; e2; e3) {..}`, `e1` and `e3` may have type void. + for (x;; x) { + break; + } + + // In a typeCast `e as T`, `e` may have type void. + var y = x as Object; + + // In a parenthesized expression `(e)`, `e` may have type void. + (x); + + // In a return statement `return e;`, when the return type of the + // innermost enclosing function is the type void, e may have type void. + void f() => x; + + void g() { + return x; + } +}
diff --git a/tests/language_2/generic_method_types_test.dart b/tests/language_2/generic_method_types_test.dart index d618012..8fc355c 100644 --- a/tests/language_2/generic_method_types_test.dart +++ b/tests/language_2/generic_method_types_test.dart
@@ -32,9 +32,9 @@ test2() { var val = new Class<String>(); Expect.isTrue(val.convert2 is Convert2); - Expect.isFalse(val.convert2 is Convert1); + Expect.isTrue(val.convert2 is Convert1); Expect.isTrue(val.convert2 is Convert2<String>); - Expect.isFalse(val.convert2 is Convert2<int>); + Expect.isTrue(val.convert2 is Convert2<int>); Expect.isFalse(val.convert2 is Convert1<String>); Expect.isFalse(val.convert2 is Other); }
diff --git a/tests/language_2/implicit_creation/README.md b/tests/language_2/implicit_creation/README.md new file mode 100644 index 0000000..c6c3857e --- /dev/null +++ b/tests/language_2/implicit_creation/README.md
@@ -0,0 +1,10 @@ +# Feature tests for optional const and optional new + +This directory was created in order to hold tests pertaining to the +Dart feature that allows the `new` and `const` keywords on instance +creation expressions and composite literals (maps and lists) to be +omitted. For more details, please check the feature specifications +on +[optional const](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md) +and on +[optional new](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new.md). \ No newline at end of file
diff --git a/tests/language_2/initializer_assert/README.md b/tests/language_2/initializer_assert/README.md new file mode 100644 index 0000000..44d18b3 --- /dev/null +++ b/tests/language_2/initializer_assert/README.md
@@ -0,0 +1,7 @@ +# Feature tests for assert in initializer lists + +This directory was created in order to hold tests pertaining to the Dart +feature which allows an assertion (`assert(...)`) to occur in the +initializer list of a constructor, including `const` constructors. For +more details, please check the +[language specification update](https://github.com/dart-lang/sdk/commit/609d26a2274ccde0f74725f4df7e081ebc8ea020).
diff --git a/tests/language_2/instantiate_to_bound/README.md b/tests/language_2/instantiate_to_bound/README.md new file mode 100644 index 0000000..0c24c51 --- /dev/null +++ b/tests/language_2/instantiate_to_bound/README.md
@@ -0,0 +1,12 @@ +# Feature tests for instantiation to bounds, and super-bounded types + +This directory was created in order to hold tests pertaining to the +Dart feature _instantiate to bound_, which provides inference of +default values for omitted type arguments. In order to handle +F-bounded type parameters without introducing infinite types, this +feature relies on another feature, _super-bounded types_, which is +therefore also in focus for tests in this directory. For more details, +please check the feature specifications on +[super-bounded types](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/super-bounded-types.md) +and on +[instantiate to bound](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/instantiate-to-bound.md). \ No newline at end of file
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status index 634f34c..ec5c30a 100644 --- a/tests/language_2/language_2_dart2js.status +++ b/tests/language_2/language_2_dart2js.status
@@ -414,6 +414,7 @@ method_override6_test/none: Pass method_override7_test/03: MissingCompileTimeError method_override8_test/03: MissingCompileTimeError +method_override_test: RuntimeError mixin_illegal_constructor_test/13: MissingCompileTimeError mixin_illegal_constructor_test/14: MissingCompileTimeError mixin_illegal_constructor_test/15: MissingCompileTimeError @@ -1093,6 +1094,7 @@ call_function_apply_test: RuntimeError canonical_const2_test: RuntimeError check_member_static_test/02: MissingCompileTimeError +checked_method_error_order_test: RuntimeError class_cycle_test/02: MissingCompileTimeError class_cycle_test/03: MissingCompileTimeError closure_invoked_through_interface_target_field_test: MissingCompileTimeError @@ -1189,11 +1191,9 @@ constructor_redirect2_negative_test: Crash # Stack Overflow constructor_redirect2_test/01: MissingCompileTimeError constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2). -covariance_setter_test/none: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. covariance_type_parameter_test/01: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. covariance_type_parameter_test/02: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. covariance_type_parameter_test/03: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. -covariance_type_parameter_test/none: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. covariant_override/runtime_check_test: RuntimeError covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E. cyclic_constructor_test/01: Crash # Stack Overflow @@ -1353,7 +1353,7 @@ mixin_mixin_bound2_test: RuntimeError mixin_mixin_bound_test: RuntimeError mixin_mixin_test: RuntimeError -mixin_mixin_type_arguments_test: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null. +mixin_mixin_type_arguments_test: RuntimeError mixin_of_mixin_test/none: CompileTimeError mixin_super_2_test/none: CompileTimeError mixin_super_constructor_named_test/01: MissingCompileTimeError @@ -1425,9 +1425,9 @@ redirecting_factory_long_test: RuntimeError redirecting_factory_reflection_test: RuntimeError regress_20394_test/01: MissingCompileTimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: RuntimeError +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant regress_28217_test/01: MissingCompileTimeError @@ -1636,7 +1636,6 @@ type_inference_inconsistent_inheritance_test: MissingCompileTimeError [ $compiler == dart2js && $dart2js_with_kernel && $fast_startup ] -arithmetic_canonicalization_test: RuntimeError assertion_initializer_const_error2_test/none: CompileTimeError assertion_initializer_const_function_test/01: MissingCompileTimeError assertion_initializer_test: CompileTimeError @@ -1759,6 +1758,7 @@ covariant_subtyping_unsafe_call2_test: RuntimeError covariant_subtyping_unsafe_call3_test: RuntimeError cyclic_constructor_test/01: Crash # Stack Overflow +deferred_call_empty_before_load_test: RuntimeError deferred_closurize_load_library_test: RuntimeError deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary @@ -1806,6 +1806,9 @@ field_override4_test/02: MissingCompileTimeError final_attempt_reinitialization_test/01: MissingCompileTimeError final_attempt_reinitialization_test/02: MissingCompileTimeError +full_stacktrace1_test: RuntimeError +full_stacktrace2_test: RuntimeError +full_stacktrace3_test: RuntimeError function_subtype_bound_closure3_test: RuntimeError function_subtype_bound_closure4_test: RuntimeError function_subtype_bound_closure7_test: RuntimeError @@ -1836,10 +1839,7 @@ generalized_void_syntax_test: CompileTimeError generic_closure_test/01: RuntimeError generic_closure_test/none: RuntimeError -generic_field_mixin4_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(M.T) in () for j:constructor(C3.). -generic_field_mixin5_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(M.T) in () for j:constructor(C3.). generic_field_mixin6_test/none: RuntimeError -generic_field_mixin_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(M.T) in () for j:constructor(C3.). generic_function_bounds_test: Crash # Unsupported operation: Unsupported type parameter type node T. generic_function_dcall_test: Crash # Unsupported operation: Unsupported type parameter type node T. generic_function_typedef_test/01: RuntimeError @@ -2023,9 +2023,9 @@ redirecting_factory_long_test: RuntimeError redirecting_factory_reflection_test: RuntimeError regress_20394_test/01: MissingCompileTimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_24283_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant regress_28217_test/01: MissingCompileTimeError @@ -2038,6 +2038,9 @@ setter_override_test/00: MissingCompileTimeError setter_override_test/03: MissingCompileTimeError stacktrace_demangle_ctors_test: RuntimeError # Issue 12698 +stacktrace_rethrow_error_test/none: RuntimeError +stacktrace_rethrow_error_test/withtraceparameter: RuntimeError +stacktrace_rethrow_nonerror_test: RuntimeError stacktrace_test: RuntimeError # Issue 12698 super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null. switch_bad_case_test/01: MissingCompileTimeError @@ -2450,9 +2453,9 @@ redirecting_factory_long_test: RuntimeError redirecting_factory_reflection_test: RuntimeError regress_20394_test/01: MissingCompileTimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_23408_test: Crash # Assertion failure: Missing scope info for j:method(_loadLibraryWrapper). regress_24283_test: RuntimeError regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant @@ -2871,9 +2874,9 @@ redirecting_factory_reflection_test: RuntimeError regress_20394_test/01: MissingCompileTimeError regress_21795_test: RuntimeError -regress_22976_test/01: CompileTimeError -regress_22976_test/02: CompileTimeError -regress_22976_test/none: CompileTimeError +regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118 +regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118 regress_23408_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null. regress_24283_test: RuntimeError, OK # Requires 64 bit numbers. regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status index f86090e..8845ee6 100644 --- a/tests/language_2/language_2_dartdevc.status +++ b/tests/language_2/language_2_dartdevc.status
@@ -712,7 +712,6 @@ first_class_types_test: RuntimeError, OK # Strong mode reifies inferred type argument. forwarding_stub_tearoff_generic_test: RuntimeError fuzzy_arrows_test/03: RuntimeError # Issue 29630 -generic_method_types_test/02: RuntimeError getter_closure_execution_order_test: RuntimeError # Issue 29920 implicit_downcast_during_compound_assignment_test: RuntimeError implicit_downcast_during_indexed_compound_assignment_test: RuntimeError @@ -789,13 +788,11 @@ generic_closure_test/01: RuntimeError # ReferenceError: TToT is not defined generic_closure_test/none: RuntimeError # ReferenceError: TToT is not defined generic_list_checked_test: RuntimeError # Expect.throws fails: Did not throw -generic_method_types_test/02: RuntimeError generic_methods_unused_parameter_test: RuntimeError # Expect.isTrue(false) fails. generic_test: RuntimeError # ReferenceError: BOfT is not defined library_env_test/has_io_support: RuntimeError # Unsupported operation: bool.fromEnvironment can only be used as a const constructor library_env_test/has_mirror_support: RuntimeError # Unsupported operation: bool.fromEnvironment can only be used as a const constructor library_env_test/has_no_html_support: RuntimeError # Unsupported operation: bool.fromEnvironment can only be used as a const constructor -method_override_test: RuntimeError # Expect.isTrue(false) fails. mixin_bound_test: RuntimeError mixin_extends_field_test: RuntimeError # Expect.equals(expected: <M1-bar>, actual: <null>) fails. mixin_field_test: RuntimeError # NoSuchMethodError: method not found: 'bar'
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status index fbe1059..f6b4071 100644 --- a/tests/language_2/language_2_kernel.status +++ b/tests/language_2/language_2_kernel.status
@@ -12,14 +12,9 @@ # ===== Skip dartk and darkp in !$strong mode ==== [ $compiler == dartkp ] -bit_operations_test: CompileTimeError # Issue 31339 generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424 -identical_closure2_test: CompileTimeError # Issue 31339 -mint_arithmetic_test: CompileTimeError # Issue 31339 mock_writable_final_field_test: RuntimeError # Issue 31424 no_such_method_subtype_test: RuntimeError # Issue 31424 -vm/unaligned_integer_access_literal_index_test: CompileTimeError # Issue 31339 -vm/unaligned_integer_access_register_index_test: CompileTimeError # Issue 31339 [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ] bad_named_parameters_test/01: Crash # Issue(http://dartbug.com/31630) @@ -648,10 +643,8 @@ generic_function_type_as_type_argument_test/02: MissingCompileTimeError, OK # No type inference generic_function_typedef2_test/04: MissingCompileTimeError generic_instanceof2_test: RuntimeError -generic_instanceof_test: RuntimeError generic_is_check_test: RuntimeError generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration) -generic_method_types_test/02: RuntimeError generic_methods_bounds_test/01: MissingCompileTimeError generic_methods_overriding_test/01: MissingCompileTimeError generic_methods_overriding_test/03: MissingCompileTimeError @@ -687,7 +680,6 @@ initializing_formal_final_test: MissingCompileTimeError initializing_formal_type_annotation_test/01: MissingCompileTimeError initializing_formal_type_annotation_test/02: MissingCompileTimeError -instanceof2_test: RuntimeError instantiate_tearoff_after_contravariance_check_test: CompileTimeError instantiate_tearoff_of_call_test: CompileTimeError instantiate_tearoff_test: CompileTimeError @@ -803,7 +795,6 @@ malformed_test/23: MissingCompileTimeError malformed_test/24: MissingCompileTimeError malformed_type_test: MissingCompileTimeError -many_generic_instanceof_test: RuntimeError map_literal3_test/01: MissingCompileTimeError map_literal3_test/02: MissingCompileTimeError map_literal3_test/03: MissingCompileTimeError @@ -826,7 +817,6 @@ method_override6_test/03: MissingCompileTimeError method_override7_test/03: MissingCompileTimeError method_override8_test/03: MissingCompileTimeError -method_override_test: RuntimeError mixin_illegal_constructor_test/13: MissingCompileTimeError mixin_illegal_constructor_test/14: MissingCompileTimeError mixin_illegal_constructor_test/15: MissingCompileTimeError @@ -1197,9 +1187,6 @@ # are to be triaged. Isolate tests are skipped on purpose due to the usage of # batch mode. [ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ] -bit_operations_test/03: CompileTimeError # Please triage. -bit_operations_test/04: CompileTimeError # Please triage. -bit_operations_test/none: CompileTimeError # Please triage. class_cycle_test/02: MissingCompileTimeError # Please triage. class_cycle_test/03: MissingCompileTimeError # Please triage. duplicate_implements_test/01: MissingCompileTimeError # Please triage. @@ -1207,15 +1194,13 @@ duplicate_implements_test/03: MissingCompileTimeError # Please triage. duplicate_implements_test/04: MissingCompileTimeError # Please triage. generic_methods_generic_function_result_test/01: MissingCompileTimeError # Please triage. -identical_closure2_test: CompileTimeError # Please triage. +int64_literal_test/03: Pass +int64_literal_test/30: Pass issue23244_test: RuntimeError # Please triage. least_upper_bound_expansive_test/none: RuntimeError # Please triage. -mint_arithmetic_test: CompileTimeError # Please triage. mixin_black_listed_test/02: MissingCompileTimeError # Please triage. null_test/02: MissingCompileTimeError # Please triage. null_test/03: MissingCompileTimeError # Please triage. -vm/unaligned_integer_access_literal_index_test: CompileTimeError # Please triage. -vm/unaligned_integer_access_register_index_test: CompileTimeError # Please triage. [ $compiler == dartk && !$strong ] *: SkipByDesign # language_2 is only supported in strong mode. @@ -1887,11 +1872,9 @@ generic_function_typedef_test/01: Pass generic_function_typedef_test/01: RuntimeError generic_instanceof2_test: RuntimeError -generic_instanceof_test: RuntimeError generic_is_check_test: RuntimeError generic_list_checked_test: RuntimeError generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration) -generic_method_types_test/02: RuntimeError generic_methods_bounds_test/01: Crash generic_methods_bounds_test/01: MissingCompileTimeError generic_methods_generic_function_result_test/01: MissingCompileTimeError @@ -1961,7 +1944,6 @@ initializing_formal_type_annotation_test/01: MissingCompileTimeError initializing_formal_type_annotation_test/02: MissingCompileTimeError instance_creation_in_function_annotation_test: SkipByDesign -instanceof2_test: RuntimeError instanceof4_test/01: RuntimeError instanceof4_test/01: Pass instanceof4_test/none: Pass @@ -1969,8 +1951,6 @@ instantiate_tearoff_after_contravariance_check_test: CompileTimeError instantiate_tearoff_of_call_test: CompileTimeError instantiate_tearoff_test: CompileTimeError -int64_literal_test/03: MissingCompileTimeError # http://dartbug.com/31479 -int64_literal_test/30: MissingCompileTimeError # http://dartbug.com/31479 interface_test/00: MissingCompileTimeError invocation_mirror2_test: SkipByDesign invocation_mirror_invoke_on2_test: SkipByDesign @@ -2087,7 +2067,6 @@ malformed_test/23: MissingCompileTimeError malformed_test/24: MissingCompileTimeError malformed_type_test: MissingCompileTimeError -many_generic_instanceof_test: RuntimeError many_overridden_no_such_method_test: SkipByDesign map_literal3_test/01: MissingCompileTimeError map_literal3_test/02: MissingCompileTimeError @@ -2123,7 +2102,6 @@ method_override6_test/none: Pass method_override7_test/03: MissingCompileTimeError method_override8_test/03: MissingCompileTimeError -method_override_test: RuntimeError mixin_black_listed_test/02: MissingCompileTimeError mixin_illegal_constructor_test/13: MissingCompileTimeError mixin_illegal_constructor_test/14: MissingCompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status index 9cb5e23..117ba9f 100644 --- a/tests/language_2/language_2_precompiled.status +++ b/tests/language_2/language_2_precompiled.status
@@ -390,6 +390,7 @@ generic_function_typedef_test/01: RuntimeError generic_instanceof_test: RuntimeError generic_list_checked_test: RuntimeError +generic_method_types_test/02: RuntimeError, OK # No support for covariant tear-off in VM. generic_methods_bounds_test/01: MissingCompileTimeError generic_methods_bounds_test/02: MissingRuntimeError generic_methods_dynamic_test/01: MissingCompileTimeError @@ -608,6 +609,7 @@ method_override6_test/none: Pass method_override7_test/03: MissingCompileTimeError method_override8_test/03: MissingCompileTimeError +method_override_test: RuntimeError, OK # No support for covariant tear-off in VM. mixin_illegal_constructor_test/13: MissingCompileTimeError mixin_illegal_constructor_test/14: MissingCompileTimeError mixin_illegal_constructor_test/15: MissingCompileTimeError
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status index ec44f5d..8795fa1 100644 --- a/tests/language_2/language_2_vm.status +++ b/tests/language_2/language_2_vm.status
@@ -395,6 +395,7 @@ generic_function_type_as_type_argument_test/02: MissingCompileTimeError, OK # No type inference generic_function_typedef2_test/04: MissingCompileTimeError generic_instanceof_test: RuntimeError +generic_method_types_test/02: RuntimeError, OK # No support for covariant tear-off in VM. generic_methods_bounds_test/01: MissingCompileTimeError generic_methods_dynamic_test/01: MissingCompileTimeError generic_methods_dynamic_test/03: MissingCompileTimeError @@ -589,6 +590,7 @@ method_override6_test/03: MissingCompileTimeError method_override7_test/03: MissingCompileTimeError method_override8_test/03: MissingCompileTimeError +method_override_test: RuntimeError, OK # No support for covariant tear-off in VM. mixin_illegal_constructor_test/13: MissingCompileTimeError mixin_illegal_constructor_test/14: MissingCompileTimeError mixin_illegal_constructor_test/15: MissingCompileTimeError
diff --git a/tests/language_2/method_override_test.dart b/tests/language_2/method_override_test.dart index c5428d3..fe3b686 100644 --- a/tests/language_2/method_override_test.dart +++ b/tests/language_2/method_override_test.dart
@@ -19,8 +19,8 @@ Expect.isTrue(remove is RemoveFunctionType); Expect.isTrue(remove is RemoveFunctionType<int, int>); - Expect.isTrue(remove is! RemoveFunctionType<String, int>); - Expect.isTrue(remove is! RemoveFunctionType<MapBase<int, int>, int>); + Expect.isTrue(remove is RemoveFunctionType<String, int>); + Expect.isTrue(remove is RemoveFunctionType<MapBase<int, int>, int>); } }
diff --git a/tests/language_2/nosuchmethod_forwarding/README.md b/tests/language_2/nosuchmethod_forwarding/README.md new file mode 100644 index 0000000..15cf2d2 --- /dev/null +++ b/tests/language_2/nosuchmethod_forwarding/README.md
@@ -0,0 +1,8 @@ +# Feature tests for noSuchMethod forwarding + +This directory was created in order to hold tests pertaining to the +Dart feature which causes forwarding methods to be generated +implicitly for all method signatures in the interface of a class that +declares a non-trivial `noSuchMethod`. For more details, please check +the +[feature specification](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/nosuchmethod-forwarding.md). \ No newline at end of file
diff --git a/tests/language_2/subtyping_dynamic/README.md b/tests/language_2/subtyping_dynamic/README.md new file mode 100644 index 0000000..24c6b0d --- /dev/null +++ b/tests/language_2/subtyping_dynamic/README.md
@@ -0,0 +1,4 @@ +# Feature tests for the dynamic semantics of subtyping + +This directory was created in order to hold tests pertaining to the +dynamic behavior of Dart programs where it involves subtyping.
diff --git a/tests/language_2/subtyping_static/README.md b/tests/language_2/subtyping_static/README.md new file mode 100644 index 0000000..c634811 --- /dev/null +++ b/tests/language_2/subtyping_static/README.md
@@ -0,0 +1,4 @@ +# Feature tests for static analysis involving subtyping + +This directory was created in order to hold tests pertaining to the +static analysis of Dart where it involves subtyping.
diff --git a/tests/language_2/vm/type_vm_test.dart b/tests/language_2/vm/type_vm_test.dart index a5aa778..cd3059f 100644 --- a/tests/language_2/vm/type_vm_test.dart +++ b/tests/language_2/vm/type_vm_test.dart
@@ -127,7 +127,7 @@ { var a = new List(5); List a0 = a; - List<Object> ao = a; //# 29: runtime error + List<Object> ao = a; // No error. List<int> ai = a; //# 30: runtime error List<num> an = a; //# 31: runtime error List<String> as = a; //# 32: runtime error
diff --git a/tests/language_2/void/README.md b/tests/language_2/void/README.md new file mode 100644 index 0000000..d2a17c9 --- /dev/null +++ b/tests/language_2/void/README.md
@@ -0,0 +1,10 @@ +# Feature tests for void + +This directory was created in order to hold tests pertaining to the +Dart feature temporarily known as _generalized void_. This feature +allows the type `void` to occur in many locations where it was +previously a compile-time error, and it is intended to allow +developers to express the intent that the value of certain expressions +is of no interest, and help them to avoid using such values. For more +details, please check the +[feature specification](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generalized-void.md). \ No newline at end of file
diff --git a/tests/lib_2/html/websql_test.dart b/tests/lib_2/html/websql_test.dart index a066ea5..728b0fd 100644 --- a/tests/lib_2/html/websql_test.dart +++ b/tests/lib_2/html/websql_test.dart
@@ -5,127 +5,124 @@ import 'dart:web_sql'; import 'package:unittest/unittest.dart'; - -Future<SqlTransaction> transaction(SqlDatabase db) { - final completer = new Completer<SqlTransaction>.sync(); - - db.transaction((SqlTransaction transaction) { - completer.complete(transaction); - }, (SqlError error) { - completer.completeError(error); - }); - - return completer.future; -} +import 'package:unittest/html_config.dart'; +import 'package:async_helper/async_helper.dart'; Future<SqlResultSet> createTable( - SqlTransaction transaction, String tableName, String columnName) { - final completer = new Completer<SqlResultSet>.sync(); - - final sql = 'CREATE TABLE $tableName ($columnName)'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + SqlTransaction transaction, String tableName, String columnName) async { + return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []); } -Future<SqlResultSet> insert( - SqlTransaction transaction, String tableName, String columnName, value) { - final completer = new Completer<SqlResultSet>.sync(); - +Future<SqlResultSet> insertTable(SqlTransaction transaction, String tableName, + String columnName, value) async { final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)'; - transaction.executeSql(sql, [value], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, [value]); } -Future<SqlResultSet> queryTable(SqlTransaction transaction, String tableName) { - final completer = new Completer<SqlResultSet>.sync(); - +Future<SqlResultSet> queryTable( + SqlTransaction transaction, String tableName) async { final sql = 'SELECT * FROM $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, []); } Future<SqlResultSet> dropTable(SqlTransaction transaction, String tableName, - [bool ignoreFailure = false]) { - final completer = new Completer<SqlResultSet>.sync(); - - final sql = 'DROP TABLE $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - if (ignoreFailure) { - completer.complete(null); - } else { - completer.completeError(error); - } - }); - - return completer.future; + [bool ignoreFailure = false]) async { + try { + var result = await transaction.executeSql('DROP TABLE $tableName', []); + return result; + } catch (error) { + if (!ignoreFailure) throw error; + } } -main() { - group('supported', () { +final tableName = 'test_table'; +final columnName = 'test_data'; + +SqlDatabase db; +SqlTransaction tx; + +Future setup() async { + if (SqlDatabase.supported) { + db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(db, isNotNull, reason: 'Unable to open database'); + + tx = await db.transaction_future(); + expect(tx, isNotNull, reason: "Transaction not ready"); + } +} + +main() async { + useHtmlConfiguration(); + + await setup(); + + group('Database', () { test('supported', () { expect(SqlDatabase.supported, true); }); }); - group('functional', () { - test('unsupported throws', () { - var expectation = SqlDatabase.supported ? returnsNormally : throws; - expect(() { - window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); - }, expectation); - }); - test('Web Database', () { - // Skip if not supported. - if (!SqlDatabase.supported) { - return new Future.value(); + group('Database', () { + test('Open/Transaction', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + + // Should not succeed table doesn't exist to be dropped. + try { + await dropTable(tx, tableName); + expect(false, true, reason: "dropTable should fail"); + } catch (error) { + expect(error.message, + "could not prepare statement (1 no such table: test_table)"); } + }); - final tableName = 'test_table'; - final columnName = 'test_data'; + test('create', () async { + if (!SqlDatabase.supported) return; - final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet createResult = + await createTable(tx, tableName, columnName); + expect(createResult.insertId, 0); + } catch (error) { + expect(false, true, reason: "createTable failed - ${error.message}"); + } + }); - expect(db, isNotNull, reason: 'Unable to open database'); + test('insert', () async { + if (!SqlDatabase.supported) return; - var tx; - return transaction(db).then((transaction) { - tx = transaction; - }).then((_) { - // Attempt to clear out any tables which may be lurking from previous - // runs. - return dropTable(tx, tableName, true); - }).then((_) { - return createTable(tx, tableName, columnName); - }).then((_) { - return insert(tx, tableName, columnName, 'Some text data'); - }).then((_) { - return queryTable(tx, tableName); - }).then((resultSet) { - expect(resultSet.rows.length, 1); - var row = resultSet.rows.item(0); - expect(row.containsKey(columnName), isTrue); - expect(row[columnName], 'Some text data'); - expect(resultSet.rows[0], row); - }).then((_) { - return dropTable(tx, tableName); - }); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet insertResult = + await insertTable(tx, tableName, columnName, 'Some text data'); + expect(insertResult.insertId, 1); + expect(insertResult.rowsAffected, 1); + } catch (error) { + expect(false, true, reason: "insert failed - ${error.message}"); + } + }); + + test('query', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet queryResult = await queryTable(tx, tableName); + expect(queryResult.rows.length, 1); + expect(queryResult.rows[0]['test_data'], "Some text data"); + } catch (error) { + expect(false, true, reason: "queryTable failed - ${error.message}"); + } + }); + + test('cleanup', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + await dropTable(tx, tableName, true); }); }); }
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status index 8b36efd..4125ad3 100644 --- a/tests/lib_2/lib_2_dart2js.status +++ b/tests/lib_2/lib_2_dart2js.status
@@ -29,7 +29,6 @@ html/js_typed_interop_side_cast_exp_test: Pass, RuntimeError # Roll 50 failure html/mirrors_js_typed_interop_test: Pass, Slow html/svgelement_test/PathElement: Pass, RuntimeError # Roll 50 failure -html/websql_test: Pass, Timeout # Roll 50 failure html/wrapping_collections_test: SkipByDesign # Testing an issue that is only relevant to Dartium html/xhr_test/xhr: Pass, RuntimeError # Roll 50 failure isolate/browser/issue_12474_test: CompileTimeError # Issue 22529
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status index 9ad5f8f..e1fbe36 100644 --- a/tests/lib_2/lib_2_dartdevc.status +++ b/tests/lib_2/lib_2_dartdevc.status
@@ -29,7 +29,6 @@ html/scripts_htmltest: Skip # Issue 29919 html/transferables_test: CompileTimeError # Issue 30975 html/two_scripts_htmltest: Skip # Issue 29919 -html/websql_test: Pass, RuntimeError # Issue 31036 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538) js/null_test: RuntimeError # Issue 30652 math/double_pow_test: RuntimeError # Issue 29922
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status index 1ca7690..7b6db9d 100644 --- a/tests/lib_2/lib_2_kernel.status +++ b/tests/lib_2/lib_2_kernel.status
@@ -10,9 +10,6 @@ # missing a section you need, please reach out to sigmund@ to see the best way # to add them. -[ $compiler == dartkp ] -typed_data/int32x4_arithmetic_test/int64: CompileTimeError # Issue 31339 - [ $arch == x64 && $compiler == dartk && $mode == debug && $runtime == vm && $strong ] mirrors/invocation_fuzz_test: Skip # Because it times out, issue 29439. mirrors/variable_is_const_test/01: Crash @@ -29,7 +26,6 @@ mirrors/variable_is_const_test/01: Crash # Please triage. [ $compiler == dartk && $runtime == vm && $checked && $strong ] -mirrors/invocation_fuzz_test/smi: Crash mirrors/redirecting_factory_different_type_test/01: Crash # Issue 28424 mirrors/redirecting_factory_different_type_test/none: Crash # Issue 28424 mirrors/reflected_type_generics_test/02: Pass @@ -127,7 +123,6 @@ mirrors/empty_test: RuntimeError mirrors/enum_test: CompileTimeError # Issue 31402 (Invocation arguments) mirrors/equality_test: RuntimeError -mirrors/fake_function_without_call_test: RuntimeError mirrors/function_type_mirror_test: RuntimeError mirrors/generic_bounded_by_type_parameter_test/02: MissingCompileTimeError mirrors/generic_bounded_test/01: MissingCompileTimeError @@ -154,7 +149,6 @@ mirrors/invocation_fuzz_test/emptyarray: Crash mirrors/invocation_fuzz_test/false: Crash mirrors/invocation_fuzz_test/none: Crash -mirrors/invocation_fuzz_test/smi: RuntimeError mirrors/invocation_fuzz_test/string: Crash mirrors/invoke_private_test: RuntimeError mirrors/invoke_private_wrong_library_test: RuntimeError @@ -287,13 +281,7 @@ async/timer_isActive_test: RuntimeError async/timer_repeat_test: RuntimeError async/zone_run_unary_test: RuntimeError -convert/chunked_conversion_json_decode1_test: RuntimeError -convert/json_chunk_test: RuntimeError -convert/json_test: RuntimeError convert/json_toEncodable_reviver_test: CompileTimeError -convert/json_utf8_chunk_test: RuntimeError -convert/streamed_conversion_json_encode1_test: RuntimeError -convert/streamed_conversion_json_utf8_encode_test: RuntimeError isolate/count_test: Timeout isolate/cross_isolate_message_test: RuntimeError isolate/illegal_msg_function_test: RuntimeError @@ -334,7 +322,6 @@ mirrors/closures_test: RuntimeError mirrors/constructors_test: RuntimeError mirrors/fake_function_with_call_test: RuntimeError -mirrors/function_apply_test: RuntimeError mirrors/generic_bounded_by_type_parameter_test/none: RuntimeError mirrors/generic_bounded_test/none: RuntimeError mirrors/generic_class_declaration_test: RuntimeError @@ -355,9 +342,7 @@ mirrors/instance_members_with_override_test: RuntimeError mirrors/instantiate_abstract_class_test: RuntimeError mirrors/intercepted_class_test: RuntimeError -mirrors/invocation_fuzz_test/smi: Pass mirrors/invoke_closurization2_test: RuntimeError -mirrors/invoke_named_test/none: RuntimeError mirrors/library_declarations_test/01: RuntimeError mirrors/library_imports_bad_metadata_test/none: RuntimeError mirrors/metadata_const_map_test: Crash @@ -375,7 +360,6 @@ mirrors/reflected_type_test/02: MissingCompileTimeError mirrors/reflected_type_test/03: MissingCompileTimeError mirrors/regress_16321_test/none: Crash -mirrors/regress_19731_test: RuntimeError mirrors/return_type_test: RuntimeError mirrors/top_level_accessors_test/01: MissingCompileTimeError mirrors/type_argument_is_type_variable_test: RuntimeError @@ -384,19 +368,18 @@ typed_data/int32x4_static_test/01: MissingCompileTimeError typed_data/int32x4_static_test/02: MissingCompileTimeError -# Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which +# Enabling of dartk for sim{arm,arm64,dbc64} revealed these test failures, which # are to be triaged. Isolate tests are skipped on purpose due to the usage of # batch mode. [ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ] isolate/*: Skip -mirrors/invocation_fuzz_test/emptyarray: CompileTimeError # Please triage. -mirrors/invocation_fuzz_test/false: CompileTimeError # Please triage. +mirrors/invocation_fuzz_test/emptyarray: CompileTimeError, Pass # Please triage. +mirrors/invocation_fuzz_test/false: CompileTimeError, Pass # Please triage. mirrors/invocation_fuzz_test/none: CompileTimeError # Please triage. -mirrors/invocation_fuzz_test/smi: CompileTimeError # Please triage. -mirrors/invocation_fuzz_test/string: CompileTimeError # Please triage. +mirrors/invocation_fuzz_test/smi: CompileTimeError, DartkCrash, Crash, Pass # Please triage. +mirrors/invocation_fuzz_test/string: CompileTimeError, Pass # Please triage. mirrors/library_uri_io_test: CompileTimeError # Please triage. mirrors/spawn_function_root_library_test: Skip -typed_data/int32x4_arithmetic_test/int64: CompileTimeError # Please triage. # ===== Skip dartk and darkp in !$strong mode ==== [ $compiler == dartk && !$strong ] @@ -446,13 +429,7 @@ async/timer_repeat_test: CompileTimeError # Issue 31402 (Invocation arguments) async/timer_test: CompileTimeError # Issue 31402 (Invocation arguments) async/zone_run_unary_test: CompileTimeError # Issue 31537 -convert/chunked_conversion_json_decode1_test: RuntimeError -convert/json_chunk_test: RuntimeError -convert/json_test: RuntimeError convert/json_toEncodable_reviver_test: CompileTimeError -convert/json_utf8_chunk_test: RuntimeError -convert/streamed_conversion_json_encode1_test: RuntimeError -convert/streamed_conversion_json_utf8_encode_test: RuntimeError html/*: SkipByDesign # dart:html not supported on VM. isolate/compile_time_error_test/01: Crash isolate/compile_time_error_test/01: MissingCompileTimeError
diff --git a/tests/standalone_2/constant_left_shift_test.dart b/tests/standalone_2/constant_left_shift_test.dart index c3072c1..5f87650 100644 --- a/tests/standalone_2/constant_left_shift_test.dart +++ b/tests/standalone_2/constant_left_shift_test.dart
@@ -38,7 +38,7 @@ Expect.equals(2305843009213693952, shiftLeft1(61)); // Deoptimize on 64 bits. Expect.equals(4611686018427387904, shiftLeft1(62)); - Expect.equals(9223372036854775808, shiftLeft1(63)); + Expect.equals(-9223372036854775808, shiftLeft1(63)); Expect.equals(8448, shiftLeft8448(0)); Expect.equals(1081344, shiftLeft8448(7));
diff --git a/tests/standalone_2/int_array_test.dart b/tests/standalone_2/int_array_test.dart index f4a3c62..30d326a 100644 --- a/tests/standalone_2/int_array_test.dart +++ b/tests/standalone_2/int_array_test.dart
@@ -115,7 +115,7 @@ intArray[0] = 4611686018427387903; // SmiMax intArray[1] = -1; // 0xFFFFFFFFFFFFFFFF : 18446744073709551615 intArray[2] = 4611686018427387904; // SmiMax+1 - intArray[3] = 9223372036854775808; + intArray[3] = -9223372036854775808; var x = intArray[0]; var y = intArray[1]; var z = intArray[2]; @@ -123,7 +123,7 @@ Expect.equals(4611686018427387903, x); Expect.equals(-1, y); Expect.equals(4611686018427387904, z); - Expect.equals(9223372036854775808, w); + Expect.equals(-9223372036854775808, w); } main() {
diff --git a/tests/standalone_2/medium_integer_test.dart b/tests/standalone_2/medium_integer_test.dart index 26a62b0..28532f9 100644 --- a/tests/standalone_2/medium_integer_test.dart +++ b/tests/standalone_2/medium_integer_test.dart
@@ -28,7 +28,7 @@ Expect.equals(1234567890123456791, a + b); Expect.equals(1234567890123456791, b + a); a = 9223372036854775807; - Expect.equals(9223372036854775808, a + 1); + Expect.equals(-9223372036854775808, a + 1); // Mint and Mint. a = 100000000000000001;
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status index a28eedf..678a688 100644 --- a/tests/standalone_2/standalone_2.status +++ b/tests/standalone_2/standalone_2.status
@@ -58,9 +58,6 @@ [ !$strong ] float_array_static_test: MissingCompileTimeError -[ $arch == simdbc64 && $strong && ($compiler == dartk || $compiler == dartkp) ] -io/*: Skip # Issue 31695 - [ $builder_tag == swarming && $system == macos ] io/*: Skip # Issue 30618 @@ -107,7 +104,6 @@ io/http_redirect_test: RuntimeError io/http_reuse_server_port_test: RuntimeError io/http_server_response_test: RuntimeError -io/http_session_test: RuntimeError io/regress_10026_test: RuntimeError io/skipping_dart2js_compilations_test: CompileTimeError io/socket_upgrade_to_secure_test: RuntimeError
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status index 7ac601f..e854872 100644 --- a/tests/standalone_2/standalone_2_kernel.status +++ b/tests/standalone_2/standalone_2_kernel.status
@@ -10,11 +10,6 @@ # missing a section you need, please reach out to sigmund@ to see the best way # to add them. -[ $compiler == dartkp ] -bytedata_test: CompileTimeError # Issue 31339 -typed_array_int64_uint64_test: CompileTimeError, Crash # Issue 31339 -typed_data_view_test: CompileTimeError # Issue 31339 - [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ] io/file_lock_test: Slow, Pass io/raw_socket_test: Crash @@ -47,7 +42,22 @@ # are to be triaged. Isolate tests are skipped on purpose due to the usage of # batch mode. [ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ] -bytedata_test: CompileTimeError # Please triage. +io/directory_list_sync_test: Timeout, Pass # Please triage. +io/echo_server_stream_test: Skip # Uses isolates which don't work in batch mode. +io/file_blocking_lock_test: Pass, Crash # Please triage. +io/file_lock_test: RuntimeError # Please triage. +io/http_advanced_test: Skip # Uses isolates which don't work in batch mode. +io/http_basic_test: Skip # Uses isolates which don't work in batch mode. +io/http_read_test: Skip # Uses isolates which don't work in batch mode. +io/pipe_server_test: Skip # Uses isolates which don't work in batch mode. +io/platform_test: Skip # Uses isolates which don't work in batch mode. +io/raw_synchronous_socket_test: Skip # Uses isolates which don't work in batch mode. +io/socket_close_test: Skip # Uses isolates which don't work in batch mode. +io/socket_finalizer_test: Skip # Uses isolates which don't work in batch mode. +io/socket_many_connections_test: Skip # Uses isolates which don't work in batch mode. +io/stdio_socket_finalizer_test: Skip # Uses isolates which don't work in batch mode. +io/test_extension_fail_test: RuntimeError # Please traige. +io/test_extension_test: RuntimeError # Please traige. map_insert_remove_oom_test: Pass # Please triage. package/scenarios/invalid/invalid_utf8_test: Pass # Please triage. package/scenarios/invalid/non_existent_packages_file_test: Pass # Please triage. @@ -57,10 +67,9 @@ regress_26031_test: RuntimeError # Please triage. regress_28854_1_test: RuntimeError # Please triage. regress_28854_2_test: RuntimeError # Please triage. -typed_array_int64_uint64_test: CompileTimeError # Please triage. +typed_array_int64_uint64_test: RuntimeError # Please triage. typed_array_test: RuntimeError # Please triage. typed_data_isolate_test: RuntimeError # Please triage. -typed_data_view_test: CompileTimeError # Please triage. # ===== Skip dartk and darkp in !$strong mode ==== [ $compiler == dartk && !$strong ]
diff --git a/tools/VERSION b/tools/VERSION index e0fa1c0..18ad238 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 0 PATCH 0 -PRERELEASE 14 +PRERELEASE 15 PRERELEASE_PATCH 0
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py index 10647b0..9a793a1 100644 --- a/tools/dom/scripts/htmldartgenerator.py +++ b/tools/dom/scripts/htmldartgenerator.py
@@ -672,12 +672,51 @@ callback_info = GetCallbackInfo( self._database.GetInterface(info.callback_args[0].type_id)) + # If more than one callback then the second argument is the error callback. + # Some error callbacks have 2 args (e.g., executeSql) where the second arg + # is the error - this is the argument we want. + error_callback = "" + if len(info.callback_args) > 1: + error_callback_info = GetCallbackInfo( + self._database.GetInterface(info.callback_args[1].type_id)) + error_callbackNames = [] + for paramInfo in error_callback_info.param_infos: + error_callbackNames.append(paramInfo.name) + errorCallbackVariables = ", ".join(error_callbackNames) + errorName = error_callback_info.param_infos[-1].name + error_callback = (',\n %s(%s) { completer.completeError(%s); }' % + (('%s : ' % info.callback_args[1].name + if info.requires_named_arguments and + info.callback_args[1].is_optional else ''), + errorCallbackVariables, errorName)) + extensions = GetDDC_Extension(self._interface, info.declared_name) if extensions: ddc_extensions = "\n".join(extensions); else: ddc_extensions = '' + # Some callbacks have more than one parameters. If so use all of + # those parameters. However, if more than one argument use the + # type of the last argument to be returned e.g., executeSql the callback + # is (transaction, resultSet) and only the resultSet is returned SqlResultSet. + callbackArgsLen = len(callback_info.param_infos) + future_generic = '' + callbackVariables = '' + completerVariable = '' + if callbackArgsLen == 1: + callbackVariables = 'value' + completerVariable = callbackVariables + if callback_info.param_infos[0].type_id: + future_generic = '<%s>' % self._DartType(callback_info.param_infos[0].type_id) + elif callbackArgsLen > 1: + callbackNames = [] + for paramInfo in callback_info.param_infos: + callbackNames.append(paramInfo.name) + callbackVariables = ",".join(callbackNames) + completerVariable = callbackNames[-1] + future_generic = '<%s>' % self._DartType(callback_info.param_infos[-1].type_id) + param_list = info.ParametersAsArgumentList() metadata = '' if '_RenamingAnnotation' in dir(self): @@ -690,7 +729,7 @@ ' $ORIGINAL_FUNCTION($PARAMS_LIST\n' ' $NAMED_PARAM($VARIABLE_NAME) { ' '$DDC_EXTENSION\n' - 'completer.complete($VARIABLE_NAME); }' + 'completer.complete($COMPLETER_NAME); }' '$ERROR_CALLBACK);\n' ' return completer.future;\n' ' }\n', @@ -704,17 +743,12 @@ NAMED_PARAM=('%s : ' % info.callback_args[0].name if info.requires_named_arguments and info.callback_args[0].is_optional else ''), - VARIABLE_NAME= '' if len(callback_info.param_infos) == 0 else 'value', + VARIABLE_NAME=callbackVariables, + COMPLETER_NAME=completerVariable, DDC_EXTENSION=ddc_extensions, - ERROR_CALLBACK=('' if len(info.callback_args) == 1 else - (',\n %s(error) { completer.completeError(error); }' % - ('%s : ' % info.callback_args[1].name - if info.requires_named_arguments and - info.callback_args[1].is_optional else ''))), - FUTURE_GENERIC = ('' if len(callback_info.param_infos) == 0 or - not callback_info.param_infos[0].type_id else - '<%s>' % self._DartType(callback_info.param_infos[0].type_id)), - ORIGINAL_FUNCTION = html_name) + ERROR_CALLBACK=error_callback, + FUTURE_GENERIC=future_generic, + ORIGINAL_FUNCTION=html_name) def EmitHelpers(self, base_class): if not self._members_emitter:
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py index ad6b9b2..43cec32 100644 --- a/tools/dom/scripts/htmlrenamer.py +++ b/tools/dom/scripts/htmlrenamer.py
@@ -190,6 +190,7 @@ 'Notification.requestPermission', 'RTCPeerConnection.setLocalDescription', 'RTCPeerConnection.setRemoteDescription', + 'SQLTransaction.executeSql', 'StorageInfo.requestQuota', 'StorageQuota.requestQuota', 'Window.webkitRequestFileSystem', @@ -213,6 +214,12 @@ 'applyExtension(\'Blob\', value);' ] }, + 'SQLTransaction': { + 'executeSql': [ + 'applyExtension(\'SQLResultSet\', resultSet);' + 'applyExtension(\'SQLResultSetRowList\', resultSet.rows);' + ], + }, 'Window': { 'webkitRequestFileSystem':[ 'applyExtension(\'DOMFileSystem\', value);', @@ -447,12 +454,13 @@ 'Window.getComputedStyle', 'Window.clearInterval', 'Window.clearTimeout', + 'Window.openDatabase', # TODO(tll): These have been converted from int to double in Chrome 39 for # subpixel precision. Special case for backward compatibility. - 'Window.scrollX', - 'Window.scrollY', 'Window.pageXOffset', 'Window.pageYOffset', + 'Window.scrollX', + 'Window.scrollY', 'WindowTimers.clearInterval', 'WindowTimers.clearTimeout',
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate index 164e713..85a580b 100644 --- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate +++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -19,8 +19,8 @@ import 'dart:_internal' show FixedLengthListMixin; import 'dart:html'; import 'dart:html_common'; -import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName, Native, - JavaScriptIndexingBehavior; +import 'dart:_js_helper' show applyExtension, convertDartClosureToJS, Creates, + JSName, Native, JavaScriptIndexingBehavior; import 'dart:_foreign_helper' show JS; import 'dart:_interceptors' show Interceptor;
diff --git a/tools/dom/templates/html/impl/impl_Database.darttemplate b/tools/dom/templates/html/impl/impl_Database.darttemplate new file mode 100644 index 0000000..ef5d8bd --- /dev/null +++ b/tools/dom/templates/html/impl/impl_Database.darttemplate
@@ -0,0 +1,25 @@ +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of $LIBRARYNAME; + +@DocsEditable() +$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS { +$!MEMBERS + + @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; + } + +}
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate index d01250e..9da90cd 100644 --- a/tools/dom/templates/html/impl/impl_Window.darttemplate +++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -227,6 +227,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/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg index da718ee..6976275 100644 --- a/tools/infra/config/cq.cfg +++ b/tools/infra/config/cq.cfg
@@ -10,6 +10,7 @@ gerrit_cq_ability { committer_list: "project-dart-committers" dry_run_access_list: "project-dart-tryjob-access" + allow_submit_with_open_deps: true } sign_cla {} tree_status {
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart index be504f66..73470e5 100644 --- a/tools/testing/dart/compiler_configuration.dart +++ b/tools/testing/dart/compiler_configuration.dart
@@ -1044,6 +1044,13 @@ ]; args.add(arguments.where((name) => name.endsWith('.dart')).single); + if (_isStrong) { + // Pass environment variable to the gen_kernel script as + // arguments are not passed if gen_kernel runs in batch mode. + environmentOverrides = new Map.from(environmentOverrides); + environmentOverrides['DART_VM_FLAGS'] = '--limit-ints-to-64-bits'; + } + return Command.vmKernelCompilation(dillFile, true, bootstrapDependencies(), genKernel, args, environmentOverrides); }
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart index 0043d80..b2ca746 100644 --- a/tools/testing/dart/utils.dart +++ b/tools/testing/dart/utils.dart
@@ -438,7 +438,9 @@ static void deleteTempSnapshotDirectory(Configuration configuration) { if (configuration.compiler == Compiler.appJit || - configuration.compiler == Compiler.precompiler) { + configuration.compiler == Compiler.precompiler || + configuration.compiler == Compiler.dartk || + configuration.compiler == Compiler.dartkp) { var checked = configuration.isChecked ? '-checked' : ''; var strong = configuration.isStrong ? '-strong' : ''; var minified = configuration.isMinified ? '-minified' : ''; @@ -448,7 +450,9 @@ "$checked$strong$minified$csp$sdk"; var generatedPath = configuration.buildDirectory + "/generated_compilations/$dirName"; - TestUtils.deleteDirectory(generatedPath); + if (FileSystemEntity.isDirectorySync(generatedPath)) { + TestUtils.deleteDirectory(generatedPath); + } } }
diff --git a/utils/front_end/BUILD.gn b/utils/bazel/BUILD.gn similarity index 73% rename from utils/front_end/BUILD.gn rename to utils/bazel/BUILD.gn index 29b2df4..79a0a7e 100644 --- a/utils/front_end/BUILD.gn +++ b/utils/bazel/BUILD.gn
@@ -4,7 +4,7 @@ import("../application_snapshot.gni") -application_snapshot("front_end_worker") { - main_dart = "../../pkg/front_end/tool/bazel/worker.dart" +application_snapshot("kernel_summary_worker") { + main_dart = "kernel_summary_worker.dart" training_args = [ "--help" ] }
diff --git a/pkg/front_end/tool/bazel/worker.dart b/utils/bazel/kernel_summary_worker.dart similarity index 68% rename from pkg/front_end/tool/bazel/worker.dart rename to utils/bazel/kernel_summary_worker.dart index cd19f9f..7935027 100644 --- a/pkg/front_end/tool/bazel/worker.dart +++ b/utils/bazel/kernel_summary_worker.dart
@@ -1,16 +1,21 @@ // 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. + +/// A tool that invokes the CFE to compute kernel summary files. +/// +/// This script can be used as a command-line command or a persistent server. +/// The server is implemented using the bazel worker protocol, so it can be used +/// within bazel as is. Other tools (like pub-build and package-build) also +/// use this persistent worker via the same protocol. + import 'dart:async'; import 'dart:io'; import 'package:args/args.dart'; import 'package:bazel_worker/bazel_worker.dart'; -import 'package:front_end/src/api_prototype/front_end.dart' - hide FileSystemException; -import 'package:front_end/src/fasta/command_line_reporting.dart'; +import 'package:front_end/src/api_unstable/summary_worker.dart' as fe; import 'package:front_end/src/multi_root_file_system.dart'; -import 'package:front_end/src/api_prototype/physical_file_system.dart'; import 'package:kernel/target/targets.dart'; main(List<String> args) async { @@ -80,6 +85,7 @@ ..addOption('dart-sdk-summary') ..addOption('input-summary', allowMultiple: true) ..addOption('multi-root', allowMultiple: true) + ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-multi-root') ..addOption('packages-file') ..addOption('source', allowMultiple: true) ..addOption('output'); @@ -105,45 +111,41 @@ // Bazel creates an overlay file system where some files may be located in the // source tree, some in a gendir, and some in a bindir. The multi-root file // system hides this from the front end. - var fileSystem = new MultiRootFileSystem( - 'org-dartlang-multi-root', - parsedArgs['multi-root'].map(Uri.parse).toList(), - PhysicalFileSystem.instance); - var options = new CompilerOptions() - ..packagesFileUri = Uri.parse(parsedArgs['packages-file']) - ..inputSummaries = parsedArgs['input-summary'].map(Uri.parse).toList() - ..sdkSummary = Uri.parse(parsedArgs['dart-sdk-summary']) - ..fileSystem = fileSystem - ..target = new NoneTarget(new TargetFlags()); + var multiRoots = parsedArgs['multi-root'].map(Uri.base.resolve).toList(); + if (multiRoots.isEmpty) multiRoots.add(Uri.base); + var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'], + multiRoots, fe.PhysicalFileSystem.instance); - options.onError = (CompilationMessage error) { - var message = new StringBuffer() - ..write(severityName(error.severity, capitalized: true)) - ..write(': '); - if (error.span != null) { - message.writeln(error.span.message(error.message)); - } else { - message.writeln(error.message); - } - if (error.tip != null) { - message.writeln(error.tip); - } + var state = await fe.initializeCompiler( + // TODO(sigmund): pass an old state once we can make use of it. + null, + Uri.base.resolve(parsedArgs['dart-sdk-summary']), + Uri.base.resolve(parsedArgs['packages-file']), + parsedArgs['input-summary'].map(Uri.base.resolve).toList(), + new NoneTarget(new TargetFlags()), + fileSystem); + + void onProblem(problem, severity, String formatted, line, column) { if (outputBuffer != null) { - outputBuffer.writeln(message); + outputBuffer.writeln(formatted); } else { - print(message); + stderr.writeln(formatted); } - if (error.severity != Severity.nit) { + if (severity != fe.Severity.nit) { succeeded = false; } - }; + } var sources = parsedArgs['source'].map(Uri.parse).toList(); - var program = await summaryFor(sources, options); + var summary = await fe.compile(state, sources, onProblem); - var outputFile = new File(parsedArgs['output']); - outputFile.createSync(recursive: true); - outputFile.writeAsBytesSync(program); + if (summary != null) { + var outputFile = new File(parsedArgs['output']); + outputFile.createSync(recursive: true); + outputFile.writeAsBytesSync(summary); + } else { + assert(!succeeded); + } return succeeded; }
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn index b04d186..147a7bc 100644 --- a/utils/dartanalyzer/BUILD.gn +++ b/utils/dartanalyzer/BUILD.gn
@@ -3,6 +3,7 @@ # BSD-style license that can be found in the LICENSE file. import("../../build/compiled_action.gni") +import("../../build/prebuilt_dart_sdk.gni") import("../application_snapshot.gni") group("dartanalyzer") { @@ -47,8 +48,27 @@ assert(defined(invoker.type), "Must specify the summary type") type = invoker.type assert(type == "spec" || type == "strong") - compiled_action(target_name) { - tool = "../../runtime/bin:dart" + action(target_name) { + + if (!prebuilt_dart_exe_works) { + deps = [ "../../runtime/bin:dart_bootstrap($dart_host_toolchain)" ] + } + + script = "../../tools/run_dart.py" + + args = [] + if (!prebuilt_dart_exe_works) { + dart_out_dir = get_label_info( + "../../runtime/bin:dart_bootstrap($dart_host_toolchain)", + "root_out_dir") + dart_bootstrap = + rebase_path("$dart_out_dir/dart_bootstrap$executable_suffix") + args += [ + "--dart", + dart_bootstrap, + ] + } + inputs = sdk_lib_files + analyzer_files output = "$root_gen_dir/$type.sum" @@ -60,7 +80,8 @@ build_sdk_summaries = rebase_path("../../pkg/analyzer/tool/summary/build_sdk_summaries.dart") - args = [ + args += [ + "--quiet", "--packages=$dot_packages", build_sdk_summaries, "build-$type",